因此,当您设置树布局的“大小”时,您所做的就是设置树布局将插入 x 和 y 值的值。因此,您没有理由不能计算所需的宽度或高度,并在每次更新调用时在布局中更改它。
我将您提供的示例复制到jsFiddle http://jsfiddle.net/bSQ8U/1/并将以下内容添加到更新功能中:
// 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)的任何地方翻转。不要忘记对对角线投影执行相同的操作,以确保您的线条也翻转。