2017-06-01 38 views
1

我試圖改變移動專利訴訟示例以允許在一個方向上的多個鏈接。d3具有相同方向的多個鏈接的網絡

我有數據(是的,我知道吉姆實際上不是帕姆的老闆):

source   target   relationship   
Michael Scott Jan Levenson pro 
Jan Levenson Michael Scott personal 
Jim Halpert  Pam Beasley  pro 
Jim Halpert  Pam Beasley  personal 

美孚專利的多路徑功能的花色。例如讓前兩排,以正確呈現(二弧)。但是,最後兩行只顯示一個混合弧。

問:如何讓具有相同方向性的鏈接顯示爲多個圓弧而不是單個圓弧?

這裏是我的圓弧代碼(從手機專利示例直撕開):

function tick() { 
    path.attr("d", linkArc); 
    circle.attr("transform", transform); 
    text.attr("transform", transform); 
} 

function linkArc(d) { 
    var dx = d.target.x - d.source.x, 
     dy = d.target.y - d.source.y, 
     dr = Math.sqrt(dx * dx + dy * dy); 
    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 
} 

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

任何幫助都將不勝感激。謝謝!

回答

1

有可能有一些潛在的方法,可以很快想到:爲節點之間的每種類型關係使用不同的路徑生成器。你必須有一個屬性來表明關係的性質(你在你的問題中),並使用它來設置路徑對齊。

在下面的代碼片段中,我查看了正在繪製的關係,並將個人關係中的弧線半徑與專業關係弧線半徑相比減少了50%。相關部分是:

function linkArc(d) { 

    var dx = d.target.x - d.source.x, 
     dy = d.target.y - d.source.y, 
     dr = Math.sqrt(dx * dx + dy * dy); 
    if(d.relationship == "pro") { 
    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 
    } 
    else { 
    return "M" + d.source.x + "," + d.source.y + "A" + (dr * 0.3) + "," + (dr * 0.3) + " 0 0,1 " + d.target.x + "," + d.target.y; 
    } 
} 

這裏是在實踐中,整個事情:

var links = [ 
 
    { source: "Michael Scott", 
 
    target:"Jan Levenson", 
 
    relationship: "pro" 
 
    }, 
 
    { source:"Jan Levenson", 
 
    target:"Michael Scott", 
 
    relationship: "Personal" 
 
    }, 
 
    { source: "Jim Halpert", 
 
    target: "Pam Beasley", 
 
    relationship: "pro" 
 
    }, 
 
    { 
 
    source: "Jim Halpert", 
 
    target: "Pam Beasley", 
 
    relationship: "Personal" 
 
    } 
 
    ] 
 
    
 
    var nodes = {}; 
 

 
// Compute the distinct nodes from the links. 
 
links.forEach(function(link) { 
 
    link.source = nodes[link.source] || (nodes[link.source] = {name: link.source}); 
 
    link.target = nodes[link.target] || (nodes[link.target] = {name: link.target}); 
 
}); 
 

 
var width = 960, 
 
    height = 500; 
 

 
var force = d3.layout.force() 
 
    .nodes(d3.values(nodes)) 
 
    .links(links) 
 
    .size([width, height]) 
 
    .linkDistance(60) 
 
    .charge(-300) 
 
    .on("tick", tick) 
 
    .start(); 
 

 
var svg = d3.select("body").append("svg") 
 
    .attr("width", width) 
 
    .attr("height", height); 
 

 
// Per-type markers, as they don't inherit styles. 
 
svg.append("defs").selectAll("marker") 
 
    .data(["suit", "licensing", "resolved"]) 
 
    .enter().append("marker") 
 
    .attr("id", function(d) { return d; }) 
 
    .attr("viewBox", "0 -5 10 10") 
 
    .attr("refX", 15) 
 
    .attr("refY", -1.5) 
 
    .attr("markerWidth", 6) 
 
    .attr("markerHeight", 6) 
 
    .attr("orient", "auto") 
 
    .append("path") 
 
    .attr("d", "M0,-5L10,0L0,5"); 
 

 
var path = svg.append("g").selectAll("path") 
 
    .data(force.links()) 
 
    .enter().append("path") 
 
    .attr("class", function(d) { return "link " + d.type; }) 
 
    .attr("marker-end", function(d) { return "url(#" + d.type + ")"; }); 
 

 
var circle = svg.append("g").selectAll("circle") 
 
    .data(force.nodes()) 
 
    .enter().append("circle") 
 
    .attr("r", 6) 
 
    .call(force.drag); 
 

 
var text = svg.append("g").selectAll("text") 
 
    .data(force.nodes()) 
 
    .enter().append("text") 
 
    .attr("x", 8) 
 
    .attr("y", ".31em") 
 
    .text(function(d) { return d.name; }); 
 

 
// Use elliptical arc path segments to doubly-encode directionality. 
 
function tick() { 
 
    path.attr("d", linkArc); 
 
    circle.attr("transform", transform); 
 
    text.attr("transform", transform); 
 
} 
 

 
function linkArc(d) { 
 

 
    var dx = d.target.x - d.source.x, 
 
     dy = d.target.y - d.source.y, 
 
     dr = Math.sqrt(dx * dx + dy * dy); 
 
    if(d.relationship == "pro") { 
 
    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 
 
    } 
 
    else { 
 
    return "M" + d.source.x + "," + d.source.y + "A" + (dr * 0.3) + "," + (dr * 0.3) + " 0 0,1 " + d.target.x + "," + d.target.y; 
 
    } 
 
} 
 

 
function transform(d) { 
 
    return "translate(" + d.x + "," + d.y + ")"; 
 
}
.link { 
 
    fill: none; 
 
    stroke: #666; 
 
    stroke-width: 1.5px; 
 
} 
 

 
#licensing { 
 
    fill: green; 
 
} 
 

 
.link.licensing { 
 
    stroke: green; 
 
} 
 

 
.link.resolved { 
 
    stroke-dasharray: 0,2 1; 
 
} 
 

 
circle { 
 
    fill: #ccc; 
 
    stroke: #333; 
 
    stroke-width: 1.5px; 
 
} 
 

 
text { 
 
    font: 10px sans-serif; 
 
    pointer-events: none; 
 
    text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

相關問題