D3力布局:直线而不是曲线的链接(但仅适用于某些链接)

时间:2015-01-22 21:18:40

标签: javascript svg d3.js force-layout

我有D3 jsfiddle生成以下图表:

enter image description here

这个图表唯一令我烦恼的是,如果两个节点之间只有一个链接,则将其绘制为曲线。我认为如果这样的链接只是直线会更好(箭头就可以了)。让我们说微软和亚马逊之间应该只是一条直线(带箭头)。甲骨文和谷歌,索尼和LG等之间也是如此。

如何实现这一目标?

2 个答案:

答案 0 :(得分:6)

这很容易。在linkArc(d)方法中,如果只有一个孩子,则将dr参数设置为0;如果有更多孩子,则将其设置为默认值。这样就不会有节点之间的任何曲线。

然而,第一步是确定有多少邻居。

表示从链接定义节点后,一种简单的方法就像下面一样。

links.forEach(function(d) {
    if (nodes[d.source.name].children==undefined) {
        nodes[d.source.name].children=0;
    }
    nodes[d.source.name].children++
});

一旦这样做,您可以按如下方式调整线条的曲线:

function linkArc(d) {
  var dx = d.target.x - d.source.x,
      dy = d.target.y - d.source.y,
      dr = (nodes[d.target.name].children>1 & nodes[d.source.name].children>1)?Math.sqrt(dx * dx + dy * dy):0;
  return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}

结果如下:

here

我确信有更好的方法可以解决这个问题,但这是一个开始。 希望这会有所帮助。

答案 1 :(得分:1)

这是基于@Nikos的回答:

links.forEach(function(d) {
    d.straight = 1;
    links.forEach(function(d1) {
        if ((d.source == d1.target) && (d1.source == d.target))
            d.straight = 0;
    });
});

function linkArc(d) {
  var dx = d.target.x - d.source.x,
      dy = d.target.y - d.source.y,
      dr = (d.straight == 0)?Math.sqrt(dx * dx + dy * dy):0;
  return "M" + d.source.x + "," + d.source.y +
      "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}

屈服于正确的图表:(关于连接的直线性)

enter image description here

jsfiddle