D3树形布局 - 当儿童超过一定数量时自定义垂直布局

aug*_*aug 5 javascript tree svg data-visualization d3.js

我正在尝试使用D3 Tree Layout来创建各种各样的家谱,我注意到的一件事是,当我有很多子节点时,它会在屏幕上水平伸展.理想情况下,我希望这些节点有一个更垂直的布局,这样人们就不必在屏幕上滚动,只能继续向下看树.

这是我目前看到的:

在此输入图像描述

现在它可能不是那么糟糕,但如果我说了20个孩子,它将跨越整个屏幕,这是我有点想避免的.

我已经看到了这样的问题这样,但是这并不能帮助我,因为我想一个特定的布局,而不是简单地调整大小...我有大的节点,他们开始彼此,如果我尝试动态调整树碰撞-萎缩这棵树对我没有好处.对于有超过一定数量的孩子的情况,我特别需要不同的布局.

这是我想象/希望的那种.请注意,root不会生成此格式,因为它只有4个子节点.理想情况下,我想要它,如果父母有5个或更多的孩子,它将导致下面的布局.如果根有5个子节点,则会导致这种布局,如果用户想要查看根的孙子节点(A,B,C ......节点),布局应该只是垂直伸展.如果有必要,我可以得到一个图表: 在此输入图像描述

我找到了关于自定义儿童布局半类似问题,他说他必须使用实际的d3js代码.我有点想避免这种情况,所以我希望能够找到d3js是否可行,因为它现在就是这样,如果是这样,怎么去呢?我不需要一个完整的答案,但是一段代码证明这是可能的,这将是非常有帮助的.

如果有必要,我可以上传一个JSFiddle供人们玩.

lio*_*ion 6

看看这个小提琴:

http://jsfiddle.net/dyXzu/

我从http://bl.ocks.org/mbostock/4339083 中获取了示例代码并进行了一些修改。请注意,在示例中,绘制时 x 和 y 被切换,因此布局显示为垂直树。

我所做的重要事情是修改深度计算器:

原来的:

// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 180; });
Run Code Online (Sandbox Code Playgroud)

固定的:

// Normalize for fixed-depth.
nodes.forEach(function (d) {
    d.y = d.depth * 180;
    if (d.parent != null) {
        d.x =  d.parent.x - (d.parent.children.length-1)*30/2
        + (d.parent.children.indexOf(d))*30;
    }
    // if the node has too many children, go in and fix their positions to two columns.
    if (d.children != null && d.children.length > 4) {
        d.children.forEach(function (d, i) {
            d.y = (d.depth * 180 + i % 2 * 100);
            d.x =  d.parent.x - (d.parent.children.length-1)*30/4
            + (d.parent.children.indexOf(d))*30/2 - i % 2 * 15;
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

基本上,我手动计算每个节点的位置,覆盖 d3 的默认节点定位。请注意,现在 x 没有自动缩放。您可能可以通过首先遍历并计算打开的节点(如果存在,d.children 不为空,d._children 在节点关闭时存储节点),然后将总 x 相加来手动计算。

在两列布局中带有子节点的节点看起来有点古怪,但改变画线方法应该会有所改善。

  • 实际上,将空元素添加到数据中似乎是一个坏主意。我在 http://jsfiddle.net/dyXzu/3/ 更新了小提琴。我所做的是制作两个数组并将垂直布局路径放入单独的 d3 选择中。还添加了高度计算器和分隔(对于多行布局有点难以计算)。 (2认同)