2013-02-21 181 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