2013-02-21 178 views
18

我看着樣品http://bl.ocks.org/mbostock/raw/4063570/如何使用D3對角線函數繪製曲線?

enter image description here

它產生從源目標漂亮合併線從左至右。

在我的情況下,我需要手動佈局節點,並把x,y座標。在這種情況下,這些行不會在源節點處合併。下面是重現此問題的測試代碼:

var data = [ {name: "p1", children: [{name: "c1"}, {name: "c2"}, {name: "c3"}, {name: "c4"}]}]; 
var width = 400, height = 200, radius = 10, gap = 50; 

// test layout 
var nodes = []; 
var links = []; 
data.forEach(function(d, i) { 
    d.x = width/4; 
    d.y = height/2; 
    nodes.push(d); 
    d.children.forEach(function(c, i) { 
     c.x = 3*width/4; 
     c.y = gap * (i +1) -2*radius; 
     nodes.push(c); 
     links.push({source: d, target: c}); 
    }) 
}) 

var color = d3.scale.category20(); 

var svg = d3.select("#chart").append("svg") 
     .attr("width", width) 
     .attr("height", height) 
     .append("g"); 
var diagonal = d3.svg.diagonal() 
     .projection(function(d) { return [d.x, d.y]; }); 

var link = svg.selectAll(".link") 
     .data(links) 
     .enter().append("path") 
     .attr("class", "link") 
     .attr("d", diagonal); 

var circle = svg.selectAll(".circle") 
     .data(nodes) 
     .enter() 
     .append("g") 
     .attr("class", "circle"); 

var el = circle.append("circle") 
     .attr("cx", function(d) {return d.x}) 
     .attr("cy", function(d) {return d.y}) 
     .attr("r", radius) 
     .style("fill", function(d) {return color(d.name)}) 
     .append("title").text(function(d) {return d.name}); 

有一個在http://jsfiddle.net/zmagdum/qsEbd/的該樣品:

enter image description here

然而,它看起來像接近節點曲線的行爲是相反的期望。我希望他們在節點處水平直線開始,並在中間形成曲線。有沒有一個技巧來做到這一點?

回答

7

請注意,在塊示例中,x和y值在鏈接中交換。這通常會在錯誤的地方畫出鏈接,但他還提供了一個投影功能,將它們交換回來。

var diagonal = d3.svg.diagonal() 
    .projection(function(d) { return [d.y, d.x]; }); 

下面是使用這種技術應用於您的jsfiddle: http://jsfiddle.net/bmdhacks/qsEbd/5/

+0

如果我想讓兩個孩子之間的聯繫怎麼辦?像第一個孩子在第一行跟第二個孩子連在一起? – 2013-07-24 10:52:57

25

該解決方案是基於優秀@bmdhacks解決方案,但是,我相信我的是稍微好一點,因爲它不需要交換xy在數據本身之內。

的想法是,你可以使用diagonal.source()diagonal.target()交換xy

var diagonal = d3.svg.diagonal() 
    .source(function(d) { return {"x":d.source.y, "y":d.source.x}; })    
    .target(function(d) { return {"x":d.target.y, "y":d.target.x}; }) 
    .projection(function(d) { return [d.y, d.x]; }); 

所有x y交換現在被封裝上面的代碼中。

結果:

enter image description here

這裏也是jsfiddle

+0

感謝您給出這個例子,顯示'source'和'projection'的期望返回值是不同的。 – 2014-09-10 14:35:29

+0

如果兩個節點之間有多個鏈接會怎麼樣?我如何顯示它而不重疊? – Jerry 2017-05-17 11:06:17