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

时间:2016-02-17 09:09:18

标签: php d3.js

重叠线

我尝试通过多个数组(Source,Target,Value)显示节点之间的许多链接 但它没有显示。重叠的线条。

[我的例子] 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"},

我的例子没有显示关系。它重叠线条。 请告诉我原因。

1 个答案:

答案 0 :(得分:0)

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

您的线条重叠,因为连接相同节点的链接具有相同的结束点和起点,您需要的是区分它们的某种方式。这有点hacky,但它的作用是查看链接,并在.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;
    });

真正的hacky位是使用链接元素(存储在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+")");
    })
    ;