d3 v4 中的曲线张力很奇怪
Curve tension is weird in d3 v4
在 d3 v3 中创建基数曲线时,我会使用 tension(.0)
来创建某条曲线。然而,在 d3 v4 中,紧张局势似乎已经改变。要获得相同的曲线,我需要使用 tension(-1.3)
。这甚至不应该起作用,因为张力应该在 0 和 1 之间。
Fiddle 对于 v3:https://jsfiddle.net/diogoscf/5st4wk7c/
Fiddle 对于应该工作但不工作的 v4:https://jsfiddle.net/diogoscf/3xma5wxu/
Fiddle 对于 v4 不应该起作用但确实起作用:https://jsfiddle.net/diogoscf/3xma5wxu/2/
这是 d3 v4 中的错误吗?我不想利用漏洞,因为它们可能会被修补并破坏我的代码,但这是它似乎唯一可行的方法。如果有其他方法,请告知。
我不认为这是一个错误,因为 catmullRom
和 alpha 0 会产生相同的结果,curveNatural
给出最接近您预期的结果,使用负张力值是一个坏主意,它甚至不应该画线。
在我看来,有问题的版本是 v3,而不是 v4。
如果你阅读 changelog,你会看到 Bostock 说:
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)
我们可以很容易地在这个演示中看到它。我正在使用您的代码,绘制两条路径。其中一个为黄色,使用 d3.curveCardinal.tension(.0)
:
var line = d3.line()
.curve(d3.curveCardinal.tension(0));
我在它前面画了另一个蓝色的,使用 d3.curveCatmullRom
:
var line2 = d3.line()
.curve(d3.curveCatmullRom.alpha(0));
如你所见,它们是相同的(我在你的点上画了红圈):
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>
因此,解释正确。
PS:不要使用 transparent
作为 fill
,而是使用 none
。
在 d3 v3 中创建基数曲线时,我会使用 tension(.0)
来创建某条曲线。然而,在 d3 v4 中,紧张局势似乎已经改变。要获得相同的曲线,我需要使用 tension(-1.3)
。这甚至不应该起作用,因为张力应该在 0 和 1 之间。
Fiddle 对于 v3:https://jsfiddle.net/diogoscf/5st4wk7c/
Fiddle 对于应该工作但不工作的 v4:https://jsfiddle.net/diogoscf/3xma5wxu/
Fiddle 对于 v4 不应该起作用但确实起作用:https://jsfiddle.net/diogoscf/3xma5wxu/2/
这是 d3 v4 中的错误吗?我不想利用漏洞,因为它们可能会被修补并破坏我的代码,但这是它似乎唯一可行的方法。如果有其他方法,请告知。
我不认为这是一个错误,因为 catmullRom
和 alpha 0 会产生相同的结果,curveNatural
给出最接近您预期的结果,使用负张力值是一个坏主意,它甚至不应该画线。
在我看来,有问题的版本是 v3,而不是 v4。
如果你阅读 changelog,你会看到 Bostock 说:
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)
我们可以很容易地在这个演示中看到它。我正在使用您的代码,绘制两条路径。其中一个为黄色,使用 d3.curveCardinal.tension(.0)
:
var line = d3.line()
.curve(d3.curveCardinal.tension(0));
我在它前面画了另一个蓝色的,使用 d3.curveCatmullRom
:
var line2 = d3.line()
.curve(d3.curveCatmullRom.alpha(0));
如你所见,它们是相同的(我在你的点上画了红圈):
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>
因此,
PS:不要使用 transparent
作为 fill
,而是使用 none
。