/* * 데이터 구조 - spider_data: 스파이더 차트와 동일 - attr_tags: 속성별 태그 정보 * 옵션 구조: 스파이더 차트의 options와 동일하며 tags 필드명이 더 들어감 */ var _spidertag = { example: [ { name: "예제1", description: "감성 연관어 변화", sample: { "visible": true, "options": {"xlsx": true, "name": "brand", "attr": "label", "value": "score", "title": "설화수/sk2/라네즈 연관어 속성 표", "tags": "tags"}, "type": "spidertag", "id": "trend_2_1.chart", "data": { "attr_tags": [ {"label": "피부", "tags": ["#곱다", "#맑다", "#눈부시다"]}, {"label": "제품", "tags": ["#좋다", "#가성비", "#비싸다"]}, {"label": "브랜드", "tags": ["#고급스럽다", "#그닥이다"]}, {"label": "느낌", "tags": ["#좋다", "#상큼하다", "#순수하다"]}, {"label": "선물", "tags": ["#주다", "#받다", "#감사하다"]}, {"label": "수분", "tags": ["#유지되다", "#촉촉하다", "#스며들다"]} ], "spider_data": [ { "brand": "설화수", "data": [ {"score": 14830, "label": "피부"}, {"score": 12013, "label": "제품"}, {"score": 11028, "label": "브랜드"}, {"score": 3202, "label": "느낌"}, {"score": 5133, "label": "선물"}, {"score": 2516, "label": "수분"} ] }, { "brand": "sk2", "data": [ {"score": 20781, "label": "피부"}, {"score": 11474, "label": "제품"}, {"score": 2382, "label": "브랜드"}, {"score": 4239, "label": "느낌"}, {"score": 8712, "label": "선물"}, {"score": 3231, "label": "수분"} ] }, { "brand": "라네즈", "data": [ {"score": 21138, "label": "피부"}, {"score": 21098, "label": "제품"}, {"score": 10103, "label": "브랜드"}, {"score": 7988, "label": "느낌"}, {"score": 3504, "label": "선물"}, {"score": 7391, "label": "수분"} ] } ] } } } ], defaultOption : { "title": null, "xlsx": true, "name": "name", // 범례에 표시될 이름 "attr": "attr", // spider의 각 축에 표시될 필드 이름 "value": "value", // spider에 값으로 표시될 필드 이름 "attr_tags": "attr_tags", // 속성별 태그 데이터 필드 이름 "tags": "tags", // 태그 필드 이름 "precision": 0, "percent_precision": 2, "colors": RenderUtil.color_table_light, "color_table_name": null }, check_property: function(id, container, prefix, name) { if (!container.hasOwnProperty(name)) { console.error(prefix + "." + name + "does not exist : " + id); return false; } return true; }, validateData : function(unit) { var options = unit.options; var names; if (options == null || Object.keys(options).length == 0) { console.error("options is empty : " + unit.id); //return false; // 옵션이 없는 경우 default 옵션을 넣도록 함 options = unit.options = _spidertag.defaultOption; } // 누락된 option을 default 값으로 대체 Object.keys(_spidertag.defaultOption).forEach(function(name) { if (!options.hasOwnProperty(name)) { //console.error("unit.options." + name + " does not exist : " + unit.id); unit.options[name] = _spidertag.defaultOption[name]; } }); if (!unit.hasOwnProperty("id")) { console.error("unit.id does not exist : " + JSON.stringify(unit)); return false; } names = ["options", "data"]; for (var i = 0; i < names.length; i++) { if (!_spidertag.check_property(unit.id, unit, "unit", names[i])) return false; } names = ["name", "attr", "value"]; for (var i = 0; i < names.length; i++) { if (!_spidertag.check_property(unit.id, unit.options, "unit.options", names[i])) return false; } names = ["spider_data", "attr_tags"]; for (var i = 0; i < names.length; i++) { if (!_spidertag.check_property(unit.id, unit.data, "unit.data", names[i])) return false; } var attrs = []; names = [unit.options.name, "data"]; for (var i = 0; i < unit.data.spider_data.length; i++) { for (var j = 0; j < names.length; j++) { if (!_spidertag.check_property(unit.id, unit.data.spider_data[i], "unit.data.spider_data[" + i + "]", names[j])) return false; } var sub_names = [unit.options.attr, unit.options.value]; for (var j = 0; j < unit.data.spider_data[i].data.length; j++) { for (var k = 0; k < sub_names.length; k++) { if (!_spidertag.check_property(unit.id, unit.data.spider_data[i].data[j], "unit.data.spider_data[" + i + "].data[" + j + "]" , sub_names[k])) return false; } } var attrs_for_check = $.map(unit.data.spider_data[i].data, function (d) { return d[unit.options.attr]; }); if (i == 0) attrs = attrs_for_check; else if (JSON.stringify(attrs) != JSON.stringify(attrs_for_check)) { console.error("attrs are not consitent: " + unit.id); return false; } } if (attrs.length != 6) { console.error("number of attrs(" + attrs.length + ") is invalid: " + unit.id); return false; } if (unit.data.attr_tags.length != attrs.length) { console.error("number of attr_tags(" + unit.data.attr_tags.length + ") is invalid: " + unit.id); return false; } // 검사 결과를 바탕으로 추가 정보를 만들어줌 unit.names = $.map(unit.data.spider_data, function (d) { return d[unit.options.name]; }); unit.attrs = attrs; if (options.color_table_name && RenderUtil.hasOwnProperty(options.color_table_name)) unit.options.colors = RenderUtil[options.color_table_name]; return true; }, makeSpiderChartData : function(unit) { var options = unit.options; var nameArray = []; var attributeArray = []; // 순서를 보존하기 위해 var nameField = options.name; var attributeField = options.attr; var valueField = options.value; var map = {}; unit.data.spider_data.forEach(function(e) { var name = e[nameField]; nameArray.push(name); var dataArray = e.data; dataArray.forEach(function(data) { var attribute = data[attributeField]; var mergedData = map[attribute]; if (mergedData == null) { mergedData = {}; mergedData[attributeField] = attribute; map[attribute] = mergedData; attributeArray.push(attribute); } mergedData[name] = data[valueField]; }); }); var resultArray = []; attributeArray.forEach(function(attribute) { var mergedObject = map[attribute]; resultArray.push(mergedObject); }); var chartData = { names : nameArray, attributes : attributeArray, data : resultArray } return chartData; }, renderSpider : function($dom, unit) { var chartDivId = ReportRenderer.getUniqueDivId(); var $innerDiv = $("
"); $dom.append($innerDiv); var chartData = _spidertag.makeSpiderChartData(unit); var graphs = []; chartData.names.forEach(function(name) { graphs.push({ "balloonText": "[[category]] : [[value]]", "bullet": "round", "lineThickness": 2, "title": name, "valueField": name }); }); AmCharts.makeChart(chartDivId, { "type": "radar", "colors": unit.options.colors, "categoryField": unit.options.attr, "radius": "30%", "sequencedAnimation": false, "fontFamily": "NanumBarunGothic", "fontSize": 14, "percentPrecision": unit.options.percent_precision, "precision": unit.options.precision, "graphs": graphs, "guides": [], "valueAxes": [ { "axisTitleOffset": 20, "id": "ValueAxis-1", "minimum": 0, "axisAlpha": 0.15, "dashLength": 3 } ], "allLabels": [], "balloon": {}, "legend": { "enabled": true, "align": "center" }, "titles": [{ "text": unit.options.title ? unit.options.title : "_", "color": unit.options.title ? undefined : "#ffffff", "size": 16 }], "dataProvider": chartData.data }); }, renderTagData : function($dom, unit) { var data = unit.data; var options = unit.options; var $div = $("").addClass("keywordGroupWrap"); $dom.append($div); var attr_tags = data.attr_tags; for (i = 0; i < attr_tags.length; i++) { var $sub = $("").addClass("keywordGroup" + (i + 1)); $div.append($sub); var $ul = $("" + JSON.stringify(unit, null, 2) + ""); return; } var $containerDiv = $(""); $dom.append($containerDiv); _spidertag.renderSpider($containerDiv, unit); _spidertag.renderTagData($containerDiv, unit); return $containerDiv; } }; UnitRendererFactory.add("spidertag", _spidertag.render); UnitRendererFactory.addExample("spidertag", _spidertag.example);