根据子节点的数量动态调整d3树布局的大小

时间:2012-10-27 20:09:38

标签: javascript layout d3.js tree

从这个例子 http://mbostock.github.com/d3/talk/20111018/tree.html 我已经构建了一个d3 tree layout,其中根位于浏览器窗口的中间位置(root.x0 = width/2),节点位于向下方向而不是面向右方。

是否可以重新调整树的大小,使树的宽度依赖 在树的节点数量上,如果节点数量较少,则宽度较小 或者如果节点数量较大,那么宽度是否很大?

我还需要知道d3 tree layout当前如何计算“d.x”属性?如何操纵“d.x”属性来调整间距 在d3树布局的节点之间。

1 个答案:

答案 0 :(得分:38)

因此,当您设置树布局的“大小”时,您所做的就是设置树布局将x和y值插值的值。因此,没有理由无法计算所需的宽度或高度,并在每次更新调用的布局中更改它。

我将您提供的示例复制到jsFiddle,并将以下内容添加到更新功能中:

// compute the new height
var levelWidth = [1];
var childCount = function(level, n) {

  if(n.children && n.children.length > 0) {
    if(levelWidth.length <= level + 1) levelWidth.push(0);

    levelWidth[level+1] += n.children.length;
    n.children.forEach(function(d) {
      childCount(level + 1, d);
    });
  }
};
childCount(0, root);  
var newHeight = d3.max(levelWidth) * 20; // 20 pixels per line  
tree = tree.size([newHeight, w]);

请注意,这是一个非常粗略的计算,并不考虑孩子们在父母或其他任何地方的情况 - 但是你明白了。

至于操纵节点的x值,最简单的可能是在布局完成之后简单地修改节点。事实上,你可以看到这已经在y坐标的例子中完成了:

// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 180; }); 

他这样做是为了即使孩子被隐藏,给定级别的节点也会保持在同一个y位置,否则如果你折叠了所有孩子,剩下的水平会拉伸以占据整个宽度(尝试评论该线路和看看当你将整个关卡切换为不可见时会发生什么。

至于自上而下我觉得你几乎可以在你看到x和y(以及x0和y0)的任何地方翻转。不要忘记对对角投影做同样的事情,以确保你的线条也能翻转。