javascript D3:用 d3.svg.line() 替换 d3.svg.diagonal()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16070150/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
D3: Substituting d3.svg.diagonal() with d3.svg.line()
提问by Jakub Svec
I have implemented the following graph with the edges rendered with d3.svg.diagonal(). However, when I try substituting the diagonal with d3.svg.line(), it doesn't appear to pull the target and source data. What am I missing? Is there something I don't understand about d3.svg.line?
我已经使用 d3.svg.diagonal() 呈现的边缘实现了下图。但是,当我尝试用 d3.svg.line() 替换对角线时,它似乎没有提取目标和源数据。我错过了什么?我对 d3.svg.line 有什么不明白的地方吗?
The following is the code I am referring to, followed by the full code:
以下是我所指的代码,后面是完整的代码:
var line = d3.svg.line()
.x(function(d) { return d.lx; })
.y(function(d) { return d.ly; });
...
...
var link= svg.selectAll("path")
.data(links)
.enter().append("path")
.attr("d",d3.svg.diagonal())
.attr("class", ".link")
.attr("stroke", "black")
.attr("stroke-width", "2px")
.attr("shape-rendering", "auto")
.attr("fill", "none");
The entire code:
整个代码:
var margin = {top: 20, right: 20, bottom: 20, left: 20},
width =1500,
height = 1500,
diameter = Math.min(width, height),
radius = diameter / 2;
var balloon = d3.layout.balloon()
.size([width, height])
.value(function(d) { return d.size; })
.gap(50)
var line = d3.svg.line()
.x(function(d) { return d.lx; })
.y(function(d) { return d.ly; });
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + (margin.left + radius) + "," + (margin.top + radius) + ")")
root = "flare.json";
root.y0 = height / 2;
root.x0 = width / 2;
d3.json("flare.json", function(root) {
var nodes = balloon.nodes(root),
links = balloon.links(nodes);
var link= svg.selectAll("path")
.data(links)
.enter().append("path")
.attr("d",d3.svg.diagonal())
.attr("class", ".link")
.attr("stroke", "black")
.attr("stroke-width", "2px")
.attr("shape-rendering", "auto")
.attr("fill", "none");
var node = svg.selectAll("g.node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node");
node.append("circle")
.attr("r", function(d) { return d.r; })
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
node.append("text")
.attr("dx", function(d) { return d.x })
.attr("dy", function(d) { return d.y })
.attr("font-size", "5px")
.attr("fill", "white")
.style("text-anchor", function(d) { return d.children ? "middle" : "middle"; })
.text(function(d) { return d.name; })
});
A comparison of how the d attribute of the svg disappears when using "line."
svg 的 d 属性在使用“line”时如何消失的比较。
回答by elusive-code
Question is quite dated, but since I don't see an answer and someone might face the same problem, here it is.
问题已经过时了,但由于我没有看到答案,而且有人可能会遇到同样的问题,所以在这里。
The reason why simple replacement of diagonalwith lineis not working is because d3.svg.lineand d3.svg.diagonalreturn different results:
用line简单替换diagonal不起作用的原因是因为d3.svg.line和d3.svg.diagonal返回不同的结果:
- d3.svg.diagonalreturns function that accepts datum and its index and transforms it to path using projection. In other words diagonal.projectiondetermines how the function will get points' coordinates from supplied datum.
- d3.svg.linereturns function that accepts an array of points of the line and transforms it to path. Methods line.xand line.ydetermine how coordinates of the point retreived from the single element of supplied array
- d3.svg.diagonal返回接受数据及其索引并使用投影将其转换为路径的函数。换句话说,diagonal.projection确定函数如何从提供的数据中获取点的坐标。
- d3.svg.line返回接受线的点数组并将其转换为路径的函数。方法line.x和line.y确定如何从提供的数组的单个元素中检索点的坐标
So you can not use result of the d3.svg.linedirectly in d3 selections (at least when you want to draw multiple lines).
所以你不能直接在 d3 选择中使用d3.svg.line 的结果(至少当你想画多条线时)。
You need to wrap it in another function like this:
您需要将其包装在另一个函数中,如下所示:
var line = d3.svg.line()
.x( function(point) { return point.lx; })
.y( function(point) { return point.ly; });
function lineData(d){
// i'm assuming here that supplied datum
// is a link between 'source' and 'target'
var points = [
{lx: d.source.x, ly: d.source.y},
{lx: d.target.x, ly: d.target.y}
];
return line(points);
}
// usage:
var link= svg.selectAll("path")
.data(links)
.enter().append("path")
.attr("d",lineData)
.attr("class", ".link")
.attr("stroke", "black")
.attr("stroke-width", "2px")
.attr("shape-rendering", "auto")
.attr("fill", "none");
Here's working version of jsFiddle mobeetsposted: jsFiddle
这是 jsFiddle mobeets的工作版本:jsFiddle
回答by mobeets
回答by natanael
Perhaps encapsulating the diagonal function and editing its parameters could work for you:
也许封装对角线函数并编辑其参数可能对您有用:
var diagonal = d3.svg.diagonal();
var new_diagonal = function (obj, a, b) {
//Here you may change the reference a bit.
var nobj = {
source : {
x: obj.source.x,
y: obj.source.y
},
target : {
x: obj.target.x,
y: obj.target.y
}
}
return diagonal.apply(this, [nobj, a, b]);
}
var link= svg.selectAll("path")
.data(links)
.enter().append("path")
.attr("d",new_diagonal)
.attr("class", ".link")
.attr("stroke", "black")
.attr("stroke-width", "2px")
.attr("shape-rendering", "auto")
.attr("fill", "none");
回答by Christopher Chiche
Just set the d
attribute of link to line:
只需将d
链接的属性设置为行:
.attr("d", line)