将链接附加到D3树布局中矩形的边上

Append links to side of rectangles in D3 tree layout

本文关键字:布局 链接 D3      更新时间:2024-04-20

我正在尝试更改每个path,以便它们从每个矩形的右侧开始并连接到左侧。目前,它们似乎"穿过"矩形,并在矩形内的某个地方有一个起点/终点,这并不能补偿rect的大小。

我尝试过操纵这个代码:

        var diagonal = d3.svg.diagonal()
        .source(function (d) { return { "x": d.source.y, "y": d.source.x }; })
        .target(function (d) { return { "x": d.target.y - 10, "y": d.target.x }; })
        .projection(function (d) { return [d.y + 0, d.x + 0];
      });

但这只会以灾难告终,但我相信答案就在那里。

这是一个脚本的JSFiddlehttp://jsfiddle.net/ra26wnbb/.

更新我已经看到D3树方形节点不在所需的位置,但我不确定它是否适用于我的文本包装。

首先,在wrap()内部的工作完成后,您需要将生成的高度存储在文本的基准面上:d.height = 19 * (lineNumber + 1);。这样,高度就可以用于任何需要它的人。例如,您可以使用它从wrap()之外设置rect高度,而不是parentNode.children[0],这是更好的关注点分离。无论如何,这就是wrap()最终的样子:

    function wrap(text, width) {
        text.each(function (d) { // DIFF add param d
            var text = d3.select(this),
              // DIFF: use datum to get name, instead of element text
              words = d.name.split(/'s+/).reverse(), 
              word,
              line = [],
              lineNumber = 0,
              lineHeight = 1.1, // ems
              y = text.attr("y"),
              dy = parseFloat(text.attr("dy")),
              tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
            while (word = words.pop()) {
                line.push(word);
                tspan.text(line.join(" "));
                if (tspan.node().getComputedTextLength() > width) {
                    line.pop();
                    tspan.text(line.join(" "));
                    line = [word];
                    tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
                }
            }
            // DIFF: store the height via the datum, d
            d.height = 19 * (lineNumber + 1);
            d3.select(this.parentNode.children[0]).attr('height', 19 * (lineNumber + 1));
        });
    }
});

既然有了d.height,就可以使用它来计算对角线端点的必要偏移。

    // calculate source and target offsets
    // d.height gets set by the wrap() function
    var diagonal = d3.svg.diagonal()
        .source(function (d) {
            return {
                "x": d.source.x + d.source.height / 2,
                "y": d.source.y + 150
            };
        })
        .target(function (d) {
            return {
                "x": d.target.x + d.target.height / 2,
                "y": d.target.y
            };
        })
        .projection(function (d) { return [d.y + 0, d.x + 0];
      });

参见修改后的fiddle