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

28
从这个例子http://mbostock.github.com/d3/talk/20111018/tree.html中,我构建了一个“d3树布局”,其中根在浏览器窗口的中央(root.x0 = width/2),节点向下而不是向右。

是否可以重新调整树的大小,使得树的宽度取决于树的节点数,如果节点数较少,则宽度较小,否则如果节点数较多,则宽度较大?

我还需要知道如何计算"d.x"属性? 我如何操纵"d.x"属性来调整d3树状图布局中节点之间的间距?


你找到如何做了吗? - mariosangiorgio
1个回答

46

因此,当您设置树形布局的“大小”时,您所做的只是设置树形布局将插值x和y值的值。 因此,您可以计算您想要的宽度或高度,并在每次更新调用中更改它,这是完全没有问题的。

我将您提供的示例复制到jsFiddle中,并在update函数中添加了以下内容:

// 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)的地方翻转。不要忘记对对角线投影执行相同的操作,以确保您的线条也会翻转。

它在2018年仍然像魔法一样运行良好,感谢您先生!:D - rvandoni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接