聚类树状图中节点的不同高度 d3.js

Different height of nodes in a cluster dendrogram d3.js

我有一个关于 d3.js 的问题 我有这个基本示例 运行:http://i.imgur.com/DxPHuAC.png 和基本 json 格式:

{
  "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

要实现这一点,您可以使用递归函数降低树并修改每个子节点的 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]);
        }
      }    
    }
  }

注意:确保create_offset(nodes[0]);中的nodes[0]是根节点。我很确定它会,但你应该仔细检查