/* Данные для визуализации, для дендрограмм формат данных должен быть вида: { 'name': 'name1', 'children: [{ 'name': 'subname1', 'children: [...] }, { 'name': 'subname2' }] }, { 'name': 'name2', } */ var treeData = { "name": "Магазины", "children": [{ "name": "Группа 1", "children": [{ "name": "м1", "size": 3938 // эти поля не влияют на макет }, { "name": "м2", "size": 3812 }, { "name": "м3", "size": 6714 }, { "name": "м4", "size": 9743 }] }, { "name": "Группа 2", "children": [{ "name": "а1", "size": 3534 }, { "name": "а2", "size": 5731 }, { "name": "а3", "size": 7840 }, { "name": "а4", "size": 5914 }, { "name": "а5", "size": 3416 }] }, { "name": "Группа 3" }] }; // получаем координаты в декартовой системе координат function decart(d) { return [d.y, d.x]; } // получаем координаты в полярной системе координат function radial(d) { var r = d.y / 2 - 30, a = (d.x - 330) / 180 * Math.PI; return [r * Math.cos(a), r * Math.sin(a)]; } var paramDecart = { width: 300, height: 300, coord: decart, widthShift: 150, tranlateX: 75, tranlateY: 0 }, paramRadial = { width: 300, height: 300, coord: radial, widthShift: 0, tranlateX: 150, tranlateY: 150 }; // строит дендрограмму по заданным параметрам function makeDendrogram(parentD3, param) { // размеры svg // создаем svg-элемент и корневой узел var svg = parentD3.append("svg") .attr("style", 'border: solid 1px red;') .attr("width", param.width) .attr("height", param.height) .append("g") // передвигаем вправо для подписи корня .attr("transform", "translate(" + param.tranlateX + ", " + param.tranlateY + ")"); /* макет (компоновщик) для построения дендрограммы (иерархического дерева) */ var cluster = d3.layout.cluster() // задаем размеры для макета .size([param.height, param.width - param.widthShift]); // задаем систему координат var diagonal = d3.svg.diagonal() .projection(param.coord); // макет расставляет узлы и связи var nodes = cluster.nodes(treeData), links = cluster.links(nodes); // далее идет добавление и манипуляция svg-элементами // добавляем линии связей узлов, полученные с помощью макета var link = svg.selectAll(".link") .data(links) .enter() .append("path") .attr("class", "link") .attr("d", diagonal); // добавляем узлы и перемещаем в расчитанные позиции var node = svg.selectAll(".node") .data(nodes) .enter() .append("g") .attr("class", "node") .attr("transform", function(d) { return "translate(" + param.coord(d).join(",") + ")"; }) // добавляем в вершины узлов кружочки разного размера node.append("circle") .attr("r", function(d){ if(!d.size) return 3; return d.size / 700; }); // добавляем текстовые подписи полей name node.append("text") .attr("dx", function(d) { return d.children ? -8 : 12; }) .attr("dy", 4) .style("text-anchor", function(d) { return d.children ? "end" : "start"; }) .text(function(d) { return d.name + ' (' + d.depth + ')'; }); // фильтруем узлы по наличию поля size и отображаем в виде текста node.filter(function(d) { return d.size ? this : null; }) .append('text') .attr("class", "node-text-detail") .attr("dx", 12) .attr("dy", 14) .text(function(d) { return d.size; }); // d3.select(self.frameElement).style("height", param.height + "px"); } var bodyD3 = d3.select("body"); makeDendrogram(bodyD3, paramDecart); // в декартовой системе координат bodyD3.append('br'); makeDendrogram(bodyD3, paramRadial); // в полярной системе координат
.node circle { fill: #eff; stroke: steelblue; stroke-width: 1.5px; } .node { font: 10px sans-serif; } .link { fill: none; stroke: #ccc; stroke-width: 1.0px; } .node-text-detail { fill: rgba(255, 0, 0, .5); font: 9px sans-serif; }