水平 d3 树:如何让根从左上角而不是中间 y 轴开始?

ste*_*hay 5 javascript svg d3.js

实际上我对这棵树有一些疑问,但我会单独问他们。

我有一棵树(demo/code),这显然是一个库存的 d3 水平树,除了我附加到子节点的一个小工具提示之外。

问题是,如何让树从容器的左上角展开,而不是从 y 轴中间向外辐射?换句话说,我想以这样的方式结束:

START-----Parent 1-----Child 1
                  \
                   `---Child 2
Run Code Online (Sandbox Code Playgroud)

等等,其中 START 位于 SVG 容器的左上角。注意:子节点因此应向下和向右扩展。

我一直在研究 x 和 y 在这里如何工作,但我似乎不知道如何改变它。

int*_*ack 2

您可以通过修改 x 值来实现该效果

nodes.forEach(function(d) { d.x = /*yourValues*/; d.y = d.depth * 180; });
Run Code Online (Sandbox Code Playgroud)

正如您可能已经意识到的那样,您的特定问题的真正关键是为每个节点提供一个与其级别的节点(即兄弟节点)数量相关的值。由于您提供的示例已经depth为每个节点提供了一个值,因此您始终可以迭代节点并计算这些值,最终生成一个数组,如下所示:

node0 has 0 nodes before it in the same depth (depth 0)
node1 has 0 nodes before it in the same depth (depth 1)
node2 has 1 nodes before it in the same depth (depth 1)
Run Code Online (Sandbox Code Playgroud)

更新您可以通过将上面的代码替换为以下代码来找到同级值并达到所需的效果forEach

nodes.forEach(function(d) { //iterate through the nodes
    if(d.parent != null){ //if the node has a parent
        for(var i = 0; i < d.parent.children.length; i++){ //check parent children
            if(d.parent.children[i].name == d.name){ //find current node
                d.downset = i; //index is how far node must be moved down
            }
        }
        d.parentDownset = d.parent.downset; //must also account for parent downset
    }
    if(d.downset == null){ d.downset = 0; }
    if(d.parentDownset == null){ d.parentDownset = 0; }
    d.x = (d.downset * 40) + (d.parentDownset * 40) + 20;
    d.y = d.depth * 180;
});
Run Code Online (Sandbox Code Playgroud)

此外,根据示例中孩子的命名方式,您可以解析出后面的数字.

取出1Child 1.1,否则返回0Child 1Child 2

nodes.forEach(function(d,i) {
                              d.x = d.numberAfterPeriod * 40 + 20;
                              d.y = d.depth * 180;
                            });
Run Code Online (Sandbox Code Playgroud)