11

我正在使用 D3 树布局,例如这个: http: //mbostock.github.com/d3/talk/20111018/tree.html

我已根据需要对其进行了修改,但遇到了问题。这个例子也有同样的问题,如果你打开了太多的节点,那么它们就会变得紧凑,使阅读和交互变得困难。我想在重新调整舞台大小以允许这样的间距时定义节点之间的最小垂直空间。

我尝试修改分离算法以使其工作:

.separation(function (a, b) {
    return (a.parent == b.parent ? 1 : 2) / a.depth;
})

那没有用。我还尝试计算哪个深度的孩子最多,然后告诉舞台的高度children * spaceBetweenNodes。这让我更接近,但仍然不准确。

depthCounts = [];
nodes.forEach(function(d, i) { 
    d.y = d.depth * 180;

    if(!depthCounts[d.depth])
        depthCounts[d.depth] = 0;

    if(d.children)
    {
        depthCounts[d.depth] += d.children.length;
    }
});

tree_resize(largest_depth(depthCounts) * spaceBetweenNodes);

我也尝试x在下面计算y分离的方法中更改节点的值,但没有雪茄。我也会发布该更改,但我将其从我的代码中删除。

nodes.forEach(function(d, i) { 
    d.y = d.depth * 180;
});

如果您可以提出一种方法或知道一种方法,我可以在节点之间垂直实现最小间距,请发布。我将不胜感激。我可能错过了一些非常简单的东西。

4

4 回答 4

6

截至 2016 年,我仅使用

tree.nodeSize([height, width])

https://github.com/mbostock/d3/wiki/Tree-Layout#nodeSize

API 参考有点差,但工作起来很简单。请务必在之后使用它,tree.size([height, width])否则您将再次覆盖您的值。

更多参考:D3 Tree Layout Separation Between Nodes using NodeSize

于 2016-01-28T10:53:07.667 回答
4

在 Google Groups 上的一位用户的帮助下,我能够解决这个问题。我找不到帖子。该解决方案要求您在一处修改 D3.js,不建议这样做,但这是我能找到的唯一解决此问题的方法。

从行5724或此方法开始:d3_layout_treeVisitAfter

改变:

d3_layout_treeVisitAfter(root, function(node) {
    node.x = (node.x - x0) / (x1 - x0) * size[0];
    node.y = node.depth / y1 * size[1];
    delete node._tree;
});

至:

d3_layout_treeVisitAfter(root, function(node) {
    // make sure size is null, we will make it null when we create the tree
    if(size === undefined || size == null) 
    { 
        node.x = (node.x - x0) * elementsize[0]; 
        node.y = node.depth * elementsize[1]; 
    } 
    else 
    { 
        node.x = (node.x - x0) / (x1 - x0) * size[0];
        node.y = node.depth / y1 * size[1]; 
    } 
    delete node._tree;
});

下面添加一个名为:的新变量elementsize,并将其默认[ 1, 1 ]为第 5731 行

var hierarchy = d3.layout.hierarchy().sort(null).value(null)
    , separation = d3_layout_treeSeparation
    , elementsize = [ 1, 1 ] // Right here
    , size = [ 1, 1 ];

下面有一个方法叫做tree.size = function(x). 在该定义下方添加以下内容:

tree.elementsize = function(x) {
    if (!arguments.length) return elementsize;
    elementsize = x;
    return tree;
};

最后,当您创建树时,您可以更改elementsize类似的内容

var tree = d3.layout.tree()
             .size(null)
             .elementsize(50, 240);
于 2013-02-06T08:10:18.487 回答
3

我知道我不应该回复其他答案,但我没有足够的声誉来添加评论。

无论如何,我只是想为使用最新 d3.v3.js 文件的人更新它。(我认为这是因为新版本,因为接受的答案中的行引用对我来说是错误的。)

您正在编辑的 d3.layout.tree 函数位于第 6236 行和第 6345 行之间。d3_layout_treeVisitAfter 从第 6318 行开始。hierarchy 变量在第 6237 行声明。关于 tree.elementsize 的部分仍然存在 - 我把它放在第 6343 行。

最后(我认为这是一个错误):当您创建树时,将尺寸放在方括号内,就像您通常对“大小”所做的那样。所以:

var tree = d3.layout.tree()
         .size(null)
         .elementsize([50, 240]);
于 2013-09-12T10:34:50.667 回答
1

您建议的原始修复将起作用,您只需确保在将所有内容添加到画布后执行此操作。d3 会在您每次进入、退出、追加等时重新计算布局。完成所有这些后,您就可以使用 dy 来修复深度。

nodes.forEach(function(d) { d.y = d.depth * fixdepth});
于 2013-06-01T04:42:04.833 回答