I've got a fairly simple visualization I'm trying to put together, but having a slight issue with the processing.
If I use the following snippet then everything works as expected:
var lines = svg.selectAll("line")
.data(data.links)
.enter()
.append("svg:line")
.attr("x1", function(d) { return findNode(data.nodes, d.source).x;})
.attr("y1", function(d) { return findNode(data.nodes, d.source).y;})
.attr("x2", function(d) { return findNode(data.nodes, d.target).x;})
.attr("y2", function(d) { return findNode(data.nodes, d.target).y;})
.style("stroke", "#838383")
.style("stroke-width", 1)
.style("marker-end", "url(#end-arrow)");
If I switch this however to use a slightly different one, using paths:
var paths = svg.selectAll("path")
.data(data.links)
.enter()
.append("svg:path")
.attr("d", function(d) {
debugger;
var src = findNode(data.nodes, d.source);
var tgt = findNode(data.nodes, d.target);
var xi = d3.interpolateNumber(src.x, tgt.x);
var curvature = 0.8;
return "M" + src.x + "," + src.y
+ "C" + xi(curvature) + "," + src.y
+ " " + xi(1 - curvature) + "," + tgt.y
+ " " + tgt.x + "," + tgt.y;
})
.style("stroke", "#838383")
.attr("fill", "none");
Then for some reason the first 'link' is missing. Can anyone suggest why this might be? There's a JSFiddle here. The effect that expected is missing, is that I don't have nice rounded lines like I want.
The problem is that D3 matches your selection .selectAll("path")
to your data by index by default and there is already a path in the SVG (in the defs
). That is, the first data element matches the first path in the SVG, which is already there. Therefore, it is not in the .enter()
selection.
The way to fix this is to specify a function in the optional second argument of .data()
to tell D3 how to match elements, e.g.
.data(data.links, function(d, i) { return d + i; })
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With