在固定节点之间绘制多个链接

时间:2016-05-24 15:09:04

标签: javascript d3.js svg

我有一个力导向图,每个节点之间都有链接。现在一些节点对有多个相互连接的链接。我找到了这个例子:Drawing multiple edges between two nodes with d3

我认为这很有效。但是,如果您有固定节点并拖动,则路径最终会相互重叠。我已经整理了这个示例的编辑版本:http://jsfiddle.net/thatOneGuy/7HZcR/502/

单击按钮修复节点并移动它们以查看我的意思。

计算弧量的代码:

//sort links by source, then target
links.sort(function(a,b) {
    if (a.source > b.source) {return 1;}
    else if (a.source < b.source) {return -1;}
    else {
        if (a.target > b.target) {return 1;}
        if (a.target < b.target) {return -1;}
        else {return 0;}
    }
});
//any links with duplicate source and target get an incremented 'linknum'
for (var i=0; i<links.length; i++) {
    if (i != 0 &&
        links[i].source == links[i-1].source &&
        links[i].target == links[i-1].target) {
            links[i].linknum = links[i-1].linknum + 1;
        }
    else {links[i].linknum = 1;};
};

任何人都可以想到这样做的另一种方式或修复这种方式吗?我可以在两个节点之间有3个甚至4个链接。

2 个答案:

答案 0 :(得分:6)

重要的代码是给出弧的半径的代码。我提出以下功能:

/#{controller_name}

主要区别在于它与节点距离呈线性关系(我认为最好)。然后,我将这两个参数称为path.attr("d", function(d) { var curve=2; var homogeneous=3.2; var dx = d.target.x - d.source.x, dy = d.target.y - d.source.y, dr = Math.sqrt(dx*dx+dy*dy)*(d.linknum+homogeneous)/(curve*homogeneous); //linknum is defined above return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; }); curve:您应该使用它们,直到找到合适的值。

请参阅http://jsfiddle.net/7HZcR/504/

PS:当为弧提供的半径小于节点之间距离的一半时,重叠发生(然后半径增加到达到此值,并且所有弧都获得相同的半径)。

答案 1 :(得分:1)

根据上面的解决方案,我有一个精确的解决方案,使用椭圆的扫描参数均匀分布链接: http://jsfiddle.net/bigman73/v03x572h/

function tick() { 
   path.attr("d", function(d) { 
   let dx = d.target.x - d.source.x,
       dy = d.target.y - d.source.y,
       t = Math.sqrt(dx * dx + dy * dy),
       half_n = Math.floor(links.length / 2) + links.length % 2,
       dr =  d.linknum == half_n ? t * 100 : 2.25 * t * (half_n - 
       Math.abs(d.linknum - half_n)) / links.length,
       sweep = d.linknum <= half_n ? 1 : 0;
       return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0," + sweep + " " + d.target.x + "," + d.target.y;

});

曲线形状目前硬编码为2.25,但这很容易重构。 它也应该通常使用不同数量的链接(尽管我只在3上测试过)