如何在 D3 中显示按值分隔的许多链接.js强制有向图


How to show many links separate by value in D3.js forced directed graph

它重叠行

我尝试通过多数组(源,目标,值)显示节点之间的许多链接但它不是显示。它重叠了线条。

[我的例子] http://bl.ocks.org/Lovekiizzk/90cbfb9d8ee7fe9baa26

请参阅knet2.json。

{
"nodes":[
 {
"name":"Novak_Djokovic",
"thumbnail":"http:'/'/commons.wikimedia.org'/wiki'/Special:FilePath'/Flickr_-_Carine06_-_Novak_Djokovic_(4).jpg?width=300",
"uri":"http:'/'/dbpedia.org'/resource'/Novak_Djokovic",
"group":1},
{
"name":"Rafael_Nadal",
"thumbnail":"http:'/'/commons.wikimedia.org'/wiki'/Special:FilePath'/Rafael_Nadal_January_2015.jpg?width=300",
"uri":"http:'/'/dbpedia.org'/resource'/Rafael_Nadal",
"group":1},
{
"name":"Grand_Slam_(tennis)",
"thumbnail":null,
"uri":"http:'/'/dbpedia.org'/resource'/Grand_Slam_(tennis)",
"group":1},
{
"name":"Toni_Nadal",
"thumbnail":"http:'/'/commons.wikimedia.org'/wiki'/Special:FilePath'/Toni_Nadal.jpg?width=300",
"uri":"http:'/'/dbpedia.org'/resource'/Toni_Nadal",
"group":0},
{
"name":"Australian_Open",
"thumbnail":"http:'/'/commons.wikimedia.org'/wiki'/Special:FilePath'/Australian_Open_2007_Night_Session.JPG?width=300",
"uri":"http:'/'/dbpedia.org'/resource'/Australian_Open",
"group":0},
{
"name":"Tennis_at_the_2008_Summer_Olympics_'u2013_Men's_singles",
"thumbnail":"",
"uri":"http:'/'/dbpedia.org'/resource'/Tennis_at_the_2008_Summer_Olympics_%E2%80%93_Men's_singles",
"group":0},
{
"name":"The_Championships,_Wimbledon",
"thumbnail":"http:'/'/commons.wikimedia.org'/wiki'/Special:FilePath'/Spencer_gore.jpg?width=300",
"uri":"http:'/'/dbpedia.org'/resource'/The_Championships,_Wimbledon",
"group":0},
{
"name":"Big_Four_(tennis)",
"thumbnail":"http:'/'/commons.wikimedia.org'/wiki'/Special:FilePath'/R_federer.jpg?width=300",
"uri":"http:'/'/dbpedia.org'/resource'/Big_Four_(tennis)",
"group":0}
],
"links":[
 {"source":1,"target":3,"prop":"coach","value":"coach"},
{"source":4,"target":2,"prop":"title","value":"title"},
{"source":4,"target":0,"prop":"menCurrent","value":"menCurrent"},
{"source":3,"target":1,"prop":"coachplayers","value":"coachplayers"},
{"source":5,"target":0,"prop":"bronze","value":"bronze"},
{"source":5,"target":1,"prop":"gold","value":"gold"},
{"source":5,"target":1,"prop":"goldMedalist","value":"goldMedalist"},
{"source":5,"target":0,"prop":"bronzeMedalist","value":"bronzeMedalist"},
{"source":6,"target":0,"prop":"menCurrent","value":"menCurrent"},
{"source":6,"target":2,"prop":"title","value":"title"},
{"source":7,"target":0,"prop":"caption","value":"caption"},
{"source":7,"target":1,"prop":"caption","value":"caption"},
{"source":3,"target":2,"prop":"coachtournamentrecord","value":"coachtournamentrecord"}
]
}

下面的一些关系。

 {"source":5,"target":1,"prop":"gold","value":"gold"},
 {"source":5,"target":1,"prop":"goldMedalist","value":"goldMedalist"},

我的例子没有显示关系。它重叠了线条。请告诉我为什么。

> https://jsfiddle.net/71yrnaxe/5/

您的线路重叠是因为连接相同节点的链接具有相同的终点和起点,您需要的是某种方法来区分它们。这有点笨拙,但它的作用是查看链接并在 .multiLinkIndex 中为具有相同节点的链接提供不同的索引 -->

var mlink = d3.map();
graph.links.forEach (function(link) {
    var key = link.source+"-"+link.target;
    var i = mlink.has(key) ? mlink.get(key) + 1 : 0;
    mlink.set (key, i);
    link.multiLinkIndex = i;
});
然后,在绘制

链接时,我们使用此信息在节点之间绘制不同半径的弧。我认为确切的公式需要修补,但您可以在小提琴中看到链接是单独解决的。-->

var domLinks = [];
    link.attr("d", function(d,i) {
     domLinks[i] = this;
    var dx = d.target.x - d.source.x,
        dy = d.target.y - d.source.y,
        dr = Math.sqrt(dx * dx + dy * dy) / (d.multiLinkIndex + 1) ;
    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
    });

真正麻烦的一点是使用链接元素(存储在domLinks中)来计算链接文本元素在弯曲链接的中间位置,而不是节点之间的中间位置,因为它们仍然会相互覆盖。使用一些从 http://bl.ocks.org/mbostock/1705868 调整的代码

linkText
    /*
    .attr("x", function(d) {
        return ((d.source.x + d.target.x)/2);
    })
    .attr("y", function(d) {
        return ((d.source.y + d.target.y)/2);
    })
    */
    .attr("transform", function(d,i) {
            var domLink = domLinks[i];
         var l = domLink.getTotalLength();
         var p = domLink.getPointAtLength(l/2);
         return ("translate ("+p.x+","+p.y+")");
    })
    ;