因此,当您设置树形布局的“大小”时,您所做的只是设置树形布局将插值x和y值的值。 因此,您可以计算您想要的宽度或高度,并在每次更新调用中更改它,这是完全没有问题的。
我将您提供的示例复制到jsFiddle中,并在update函数中添加了以下内容:
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;
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)的地方翻转。不要忘记对对角线投影执行相同的操作,以确保您的线条也会翻转。