【问题标题】:Different height of nodes in a cluster dendrogram d3.js集群树状图d3.js中节点的不同高度
【发布时间】:2016-07-01 19:02:59
【问题描述】:

我有一个关于 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

【问题讨论】:

    标签: javascript d3.js tree cluster-computing dendrogram


    【解决方案1】:

    要实现这一点,您可以使用递归函数使树下降并修改每个子节点的 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] 是根节点。我相当肯定它会,但你应该仔细检查

    【讨论】:

    • 我删除了这条消息,因为它不正确。问题是这个递归函数给出了相同的值,并且一些节点的高度相同。使用反向形式它不起作用
    • 解决办法是把offset var放到函数外,不要使用reverse(),答案很好。谢谢
    猜你喜欢
    • 2013-10-21
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多