Javascript 有没有办法在d3.js中获取路径的子集/部分?

Javascript 有没有办法在d3.js中获取路径的子集/部分?,javascript,d3.js,svg,Javascript,D3.js,Svg,假设我使用的曲线部分创建了一些任意路径,通过为其提供一组小的x,y点,如下所示: var my_curve = d3.line() .x(function(d) { return d.x; }) .y(function(d) { return d.y; }) .curve(d3.curveCatmullRom.alpha(0.5)); var curve_dat = [{x:10,y:10},{x:110,y:120},{x:160,y:20},{x:400,y:60}

假设我使用的
曲线
部分创建了一些任意路径,通过为其提供一组小的x,y点,如下所示:

var my_curve = d3.line()
    .x(function(d) { return d.x; })
    .y(function(d) { return d.y; })
    .curve(d3.curveCatmullRom.alpha(0.5));

var curve_dat = [{x:10,y:10},{x:110,y:120},{x:160,y:20},{x:400,y:60},{x:200,y:360},{x:40,y:300}];

var svg_main = d3.select("div#svg_cont")
  .append('svg')
  .attr('width', 600)
  .attr('height', 400);

var path_1 = svg_main.append('path')
              .datum(curve_dat)
              .attr('fill', 'none')
              .attr('stroke', 'red')
              .attr('stroke-width', 3)
              .attr('d', my_curve);

svg_main.selectAll('circle')
              .data(curve_dat)
              .enter()
              .append('circle')
              .attr('fill', 'none')
              .attr('stroke', 'black')
              .attr('stroke-width', 3)
              .attr('cx', d => d.x)
              .attr('cy', d => d.y)
              .attr('r', 5);
产生:

(其中黑色圆圈是生成点的位置。)

现在,我想沿路径选择两个点,并从中获取原始路径的截面/子集:

pt1 = path_1.node().getPointAtLength(300);
svg_main.append('circle')
              .attr('fill', 'none')
              .attr('stroke', 'green')
              .attr('stroke-width', 3)
              .attr('cx', pt1.x)
              .attr('cy', pt1.y)
              .attr('r', 5);

pt1 = path_1.node().getPointAtLength(450);
svg_main.append('circle')
              .attr('fill', 'none')
              .attr('stroke', 'green')
              .attr('stroke-width', 3)
              .attr('cx', pt1.x)
              .attr('cy', pt1.y)
              .attr('r', 5);

(其中绿色圆圈是我想要得到的部分的边界)

所以,即使我有这些点的x,y,我也不能只画这两个点产生的曲线,因为它们之间的原始红色曲线不同

有没有一个聪明的方法可以做到这一点?通过一点搜索,它似乎曾经有一个方法被调用,但是它已经被弃用了,而且他们甚至没有提供关于它的文档


还有其他方法吗?

严格地说,正如杰拉尔多所指出的那样,很难获得路径属性数据来完美地复制该曲线。通常我会就此罢休,因为他是一位杰出的权威。但是,我有点逆向,喝了点啤酒,所以让我们看看我们能做些什么

选项一很简单-我们真正需要路径数据做什么?如果只是简单地绘制,那么我们可以使用笔划划线数组。我们使用破折号数组隐藏除路径部分以外的所有内容:

var my_曲线=d3.line()
.x(函数(d){返回d.x;})
.y(函数(d){返回d.y;})
.曲线(d3.曲线A(0.5));
var curve_dat=[{x:10,y:10},{x:110,y:120},{x:160,y:20},{x:400,y:60},{x:200,y:360},{x:40,y:300}];
var svg_main=d3.选择(“主体”)
.append('svg')
.attr('width',600)
.attr('height',400);
var path_1=svg_main.append('path'))
.基准面(曲线数据)
.attr('填充','无')
.attr('笔划','红色')
.attr('stroke-width',3)
.attr('d',my_曲线)
.attr(“笔划数组”,“0 300 150 1000”);
svg_main.selectAll('circle'))
.数据(曲线数据)
.输入()
.append('圆')
.attr('填充','无')
.attr('笔划','黑色')
.attr('stroke-width',3)
.attr('cx',d=>d.x)
.attr('cy',d=>d.y)
.attr('r',5);
pt1=path_1.node().getPointAtLength(300);
svg_main.append('circle'))
.attr('填充','无')
.attr('笔划','绿色')
.attr('stroke-width',3)
.attr('cx',pt1.x)
.attr('cy',pt1.y)
.attr('r',5);
pt1=path_1.node().getPointAtLength(450);
svg_main.append('circle'))
.attr('填充','无')
.attr('笔划','绿色')
.attr('stroke-width',3)
.attr('cx',pt1.x)
.attr('cy',pt1.y)
.attr('r',5);

不可以,这与D3无关,这是
d
属性的工作方式。有趣的是,一个适当的解释,包括控制点和所有东西,将是非常长的,需要很多努力,但尽管如此,它肯定会被否决死亡。所以,让我们说“不,你不能”。投赞成票,但这可能不是OP想要的。我相信OP想要的,也是您面临的挑战,是
d
属性,一个单独的属性,带有
M
Q
a
L
等等,复制该部分。这就是为什么我建议OP,这是不可能的,或者更好的是,这是可能的,但需要付出巨大的努力。不过,解决方案2是一个不错的破解方法。@GerardoFurtado,谢谢-我同意,这是一个相当多的工作(说得委婉一点),但我想不出一个需要这种方法而不是替代方法的用例,但也许我遗漏了更明显的东西。当然。如果OP只需要该部分的一个可视剪辑,那么您的解决方案#1就是最好的选择,因为解决方案#2不太精确(除非使用
every=1
)。第二种方法的更详细实现可以在Aaron Bycoffe的区块中找到。除此之外,我完全同意@GerardoFurtado的观点,即确定子路径的路径定义将是一项艰巨的任务,可能不值得付出努力。