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

落爺英雄遲暮 提交于 2020-01-15 03:45:38

问题


It overlapping lines

I try to show many links between nodes by multi array (Source,Target,Value) But It's not display.It overlapping lines.

[My Example] http://bl.ocks.org/Lovekiizzk/90cbfb9d8ee7fe9baa26

See in the 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"}
]
}

Some relation below.

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

My example don't show relation. It overlapping lines. Please tell me why.


回答1:


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

Your lines overlap because links connecting the same nodes have the same end and start points, what you need is some way to distinguish them. This is a bit hacky, but what it does is look through the links and give links with the same nodes different indexes in .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;
});

then, when drawing the links we use this info to draw arcs of different radii between the nodes. The exact formula will need tinkering with I think but you can see in the fiddle the links are resolved individually. -->

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;
    });

The really hacky bit is using the link elements (stored in domLinks) to calculate positions for the link text elements halfway along the curved links, rather than halfway between the nodes, because these would still overwrite each other. Uses some code adjusted from 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+")");
    })
    ;


来源:https://stackoverflow.com/questions/35452187/how-to-show-many-links-separate-by-value-in-d3-js-forced-directed-graph

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!