When creating a cardinal curve in d3 v3, I would use tension(.0)
to create a certain curve. However, in d3 v4, the tension seems to have been changed. To get the same curve, I need to use tension(-1.3)
. This shouldn't even work, since the tension should be between 0 and 1.
Fiddle for the v3: https://jsfiddle.net/diogoscf/5st4wk7c/
Fiddle for the v4 that should work but doesn't: https://jsfiddle.net/diogoscf/3xma5wxu/
Fiddle for the v4 that shouldn't work but does: https://jsfiddle.net/diogoscf/3xma5wxu/2/
Is this a bug in d3 v4? I don't want to exploit bugs since they could get patched and break my code, but this is the only way it seems to work. If there's another way, please inform.
It seems to me that the buggy version is the v3 one, not v4.
If you read the changelog, you'll see that Bostock says:
4.0 fixes the interpretation of the cardinal spline tension parameter, which is now specified as cardinal.tension and defaults to zero for a uniform Catmull–Rom spline. (emphasis mine)
We can easily see it in this demo. I'm using your code, drawing two paths. One of them, in yellow, uses d3.curveCardinal.tension(.0)
:
var line = d3.line()
.curve(d3.curveCardinal.tension(0));
In front of it I'm drawing other one, in blue, that uses d3.curveCatmullRom
:
var line2 = d3.line()
.curve(d3.curveCatmullRom.alpha(0));
As you can see, they are the same (I put red circles on your points):
var line = d3.line()
.curve(d3.curveCardinal.tension(0));
var line2 = d3.line()
.curve(d3.curveCatmullRom.alpha(0));
var svg = d3.select("svg")
.append("g")
.attr("transform", "translate(20,0)");
var points = [
[0, 80],
[100, 100],
[200, 30],
];
svg.append("path")
.datum(points)
.attr("d", line)
.style("stroke", "yellow")
.style("stroke-width", "6")
.style("fill", "none");
svg.append("path")
.datum(points)
.attr("d", line2)
.style("stroke", "blue")
.style("stroke-width", "2")
.style("fill", "none");
svg.selectAll(null)
.data(points)
.enter()
.append("circle")
.attr("r", 5)
.attr("fill", "red")
.attr("cx", d => d[0])
.attr("cy", d => d[1]);
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
Therefore, @Marcell's explanation is correct.
PS: do not use transparent
for the fill
, use none
instead.