4

似乎如果 D3 强制布局中的两个节点之间存在多个链接,则 D3 只会选择一个而忽略其他节点。是否可以可视化多图?

4

2 回答 2

7

因此,事实证明 d3确实在节点之间渲染了多个链接,只是它将它们绘制在彼此之上。我解决这个问题的方法是将链接绘制为路径(而不是线),并为每条路径添加不同的曲线。这意味着每个链接对象都需要一些东西来将其与具有相同源节点和目标节点的其他对象区分开来。我的链接如下所示:

links: [
  {"source": 0,"target": 1,"count": 1}, 
  {"source": 1,"target": 2,"count": 1},
  {"source": 1,"target": 3,"count": 1}, 
  {"source": 1,"target": 4,"count": 1},

  // same source and target with greater count
  {"source": 1,"target": 4,"count": 2}, 
  {"source": 1,"target": 4,"count": 3}, 
  {"source": 1,"target": 4,"count": 4}
]

然后路径渲染代码看起来像

function tick() {
  link.attr("d", function(d) {
    var x1 = d.source.x,
        y1 = d.source.y,
        x2 = d.target.x,
        y2 = d.target.y,
        dx = x2 - x1,
        dy = y2 - y1,
        // Set dr to 0 for straight edges.
        // Set dr to Math.sqrt(dx * dx + dy * dy) for a simple curve.
        // Assuming a simple curve, decrease dr to space curves.
        // There's probably a better decay function that spaces things nice and evenly. 
        dr = Math.sqrt(dx * dx + dy * dy) - Math.sqrt(300*(d.count-1)); 

   return "M" + x1 + "," + y1 + "A" + dr + "," + dr + " 0 0,1 " + x2 + "," + y2;
  });

  node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}

这是一个演示该方法的jsfiddle 。

于 2013-07-13T01:12:51.600 回答
3

您可以通过创建一组链接将您的多重图简单地编码为一个图,其中每个链接都是以下形式的捆绑:

{"links": [/* one or more links*/], "source": …, "target": …}

然后,您可以像往常一样运行强制导向布局来定位节点。然后,您需要适当地表示每个捆绑包,例如通过绘制平行线。

相关:Mike Bostock 使用了一个简单的技巧来表示节点之间的两个平行链接,尽管这并不容易扩展到更多链接。

于 2012-12-08T01:46:39.980 回答