在 D3 中选择正确的插值以在路径(区域)内将路径(线)居中
choose the right interpolation in D3 to center a path (line) inside a path (area)
例如,考虑以下 D3 代码(只有相关部分,完整的 - 但只有不到十几行长 - 代码在 JSFiddle 上),它在带内绘制一条线。
var points = [
[200, 100],
[200, 200],
[100, 300],
[100, 400]
];
var areaGenerator=d3.area()
.curve(d3.curveMonotoneY)
.x0(function(d){return d[0]-20})
.x1(function(d){return d[0]+20})
.y0(function(d,i){return d[1]})
.y1(function(d,i){return d[1]})
;
var area = areaGenerator(points);
svg.append('path')
.attr('d', area);
svg.append("path")
.data([points])
.attr("d", d3.line()
.curve(d3.curveCardinal
.tension(0.8)))
.attr("id","line")
这是生成的 svg 对象的图像:
我已经为 .tension()
尝试了几个值,但我无法找到正确的插值函数来使线在其整个流程中(大约)位于频带的中间,受到线和带的第一部分和最后一部分应该完全垂直并且它们不能 "enlarge" 向左或向右的约束。
这是我要获取的,大概是:
我原来的回答没有经过深思熟虑。您可以简单地将相同的曲线 属性 应用于黑色路径,就像您对红色路径所做的那样:https://jsfiddle.net/s5o4hp3z/
只需将黑色路径更改为:
svg.append("path")
.data([points])
.attr("d", d3.line().curve(d3.curveMonotoneY))
.attr("id","line")
-------- 原回答 ------
您可以使用类似于用于红色区域的区域生成器,但具有使它看起来像一条线的宽度属性。
我修改了你的 JSFiddle 来展示这个:https://jsfiddle.net/6e03o42f/3/
我所做的是将路径创建更改为:
var lineAreaGenerator = d3.area()
.curve(d3.curveMonotoneY)
.x0(function(d){return d[0]-0.5})
.x1(function(d){return d[0]+0.5})
.y0(function(d,i){return d[1]})
.y1(function(d,i){return d[1]});
var lineArea = lineAreaGenerator(points);
svg.append("path")
.attr("d", lineArea)
.attr("id","line")
如果这确实是您选择的方法,那么人们会希望将区域生成器代码分离到一个函数中。我已经在这个 JSFiddle 中展示了如何做到这一点:https://jsfiddle.net/6e03o42f/4/
希望对您有所帮助!
例如,考虑以下 D3 代码(只有相关部分,完整的 - 但只有不到十几行长 - 代码在 JSFiddle 上),它在带内绘制一条线。
var points = [
[200, 100],
[200, 200],
[100, 300],
[100, 400]
];
var areaGenerator=d3.area()
.curve(d3.curveMonotoneY)
.x0(function(d){return d[0]-20})
.x1(function(d){return d[0]+20})
.y0(function(d,i){return d[1]})
.y1(function(d,i){return d[1]})
;
var area = areaGenerator(points);
svg.append('path')
.attr('d', area);
svg.append("path")
.data([points])
.attr("d", d3.line()
.curve(d3.curveCardinal
.tension(0.8)))
.attr("id","line")
这是生成的 svg 对象的图像:
我已经为 .tension()
尝试了几个值,但我无法找到正确的插值函数来使线在其整个流程中(大约)位于频带的中间,受到线和带的第一部分和最后一部分应该完全垂直并且它们不能 "enlarge" 向左或向右的约束。
这是我要获取的,大概是:
我原来的回答没有经过深思熟虑。您可以简单地将相同的曲线 属性 应用于黑色路径,就像您对红色路径所做的那样:https://jsfiddle.net/s5o4hp3z/
只需将黑色路径更改为:
svg.append("path")
.data([points])
.attr("d", d3.line().curve(d3.curveMonotoneY))
.attr("id","line")
-------- 原回答 ------
您可以使用类似于用于红色区域的区域生成器,但具有使它看起来像一条线的宽度属性。
我修改了你的 JSFiddle 来展示这个:https://jsfiddle.net/6e03o42f/3/
我所做的是将路径创建更改为:
var lineAreaGenerator = d3.area()
.curve(d3.curveMonotoneY)
.x0(function(d){return d[0]-0.5})
.x1(function(d){return d[0]+0.5})
.y0(function(d,i){return d[1]})
.y1(function(d,i){return d[1]});
var lineArea = lineAreaGenerator(points);
svg.append("path")
.attr("d", lineArea)
.attr("id","line")
如果这确实是您选择的方法,那么人们会希望将区域生成器代码分离到一个函数中。我已经在这个 JSFiddle 中展示了如何做到这一点:https://jsfiddle.net/6e03o42f/4/
希望对您有所帮助!