2016-07-01 3 views
0

У меня есть вопрос о d3.js У меня есть этот базовый пример работает: http://i.imgur.com/DxPHuAC.png и базовый формат JSON:Разная высота узлов в кластере дендрограммы d3.js

{ 
    "name": "root", 
    "children": [ 
    { 
    "name": "parent A", 
    "children": [ 
     {"name": "child A1"}, 
     {"name": "child A2"}, 
     {"name": "child A3"} 
    ] 
    },{ 
    "name": "parent B", 
    "children": [ 
     {"name": "child B1"}, 
     {"name": "child B2"} 
    ] 
    } 
    ] 
} 

Мой Javascript код здесь :

<!doctype html></html> 
<meta charset="utf-8" /> 
<style> 
.node circle {  
    fill: #fff;  
    stroke: steelblue;  
    stroke-width: 1.5px; 
} 
.node {  
    font: 20px sans-serif; 
} 
.link {  
    fill: none;  
    stroke: #ccc;  
    stroke-width: 1.5px; 
} 
</style> 
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> 
<script type="text/javascript"> 
var width = 600; 
var height = 500; 
var cluster = d3.layout.cluster()  
    .size([height, width-200]); 
var diagonal = d3.svg.diagonal()  
    .projection (function(d) { return [d.y, d.x];}); 
var svg = d3.select("body").append("svg")  
    .attr("width",width)  
    .attr("height",height)  
    .append("g")  
    .attr("transform","translate(100,0)"); 
d3.json("dendrogram03.json", function(error, root){  
    var nodes = cluster.nodes(root);  
    var links = cluster.links(nodes);  
    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(" + d.y + "," + d.x + ")"; });  
    node.append("circle")  
     .attr("r", 4.5);  
    node.append("text")  
     .attr("dx", function(d) { return d.children ? -8 : 8; })  
     .attr("dy", 3)  
     .style("text-anchor", function(d) { return d.children ? "end" : "start"; })  
     .text(function(d){ return d.name;}); 
}); 
</script> 

но проблема в том, что я искал d3 документации, но не так хорошо, поэтому я хочу, чтобы поместить каждый узел в разной высоте дерева, как таким образом: http://i.imgur.com/VoaCqpX.png

ответ

0

Для этого вы можете спуститься к дереву с помощью рекурсивной функции и изменить атрибут y для каждого дочернего элемента, введя количество изменений каждый раз, когда вы будете проходить через набор дочерних узлов.

Вам потребуется некоторая изменяющая функция после создания узлов, но до создания ссылок:

var nodes = cluster.nodes(root).reverse(); 
    create_offset(nodes[0]); 
    var links = cluster.links(nodes); 

функция для создания смещения может выглядеть примерно так:

function create_offset(node){ 
    if(node.children){ 
     //modify the y values of each child. increasing the offset each time 
     var offset = 0; 
     for(var i = 0; i<node.children.length;i++){ 
     node.children[i].y = node.children[i].depth * 100 + offset; 
     offset += 20; //change this to change the degree of offset 
     } 

     //check each child to see if it has it's own children. If so, decend the tree recursively 
     for(var i = 0; i<node.children.length;i++){ 
     if(node.children[i].children){ 
      create_offset(node.children[i]); 
     } 
     }  
    } 
    } 

Примечание: обязательно nodes[0] в create_offset(nodes[0]); является корневым узлом. Я уверен, что это будет, но вы должны дважды проверить

+0

Я удаляю сообщение, потому что оно не было правильным. Проблема в том, что эта рекурсивная функция дает одно и то же значение, а некоторые узлы находятся на одной высоте. С обратной формой он не работает – Thenotic2

+0

Решение ставится смещение var из функции и не использует обратное(), ответ хороший. благодаря – Thenotic2

Смежные вопросы