Javascript 使用D3.js嵌套数据

Javascript 使用D3.js嵌套数据,javascript,d3.js,svg,nested,Javascript,D3.js,Svg,Nested,我试图使用父数据和嵌套数据生成SVG元素,但在显示内容时遇到问题。这与非常类似,非常有帮助,但没有完全解决我的问题 对于本例,我正在绘制由多个点组成的SVG路径。我想画一条与每条路径的线段相切的线。它基本上是有效的,但我不能为切线路径创建组,相反,它们最终位于SVG的根。我希望结构像这样: 但是,所有切线路径都被附加到svg中,我无法创建“切线组”svg组: 这是我目前的代码。我也愿意接受关于如何在其他方面改进它的建议 //测试数据 变量行=[{ id:0, 坐标:[[0,0],[10,

我试图使用父数据和嵌套数据生成SVG元素,但在显示内容时遇到问题。这与非常类似,非常有帮助,但没有完全解决我的问题

对于本例,我正在绘制由多个点组成的SVG路径。我想画一条与每条路径的线段相切的线。它基本上是有效的,但我不能为切线路径创建组,相反,它们最终位于SVG的根。我希望结构像这样:


但是,所有切线路径都被附加到svg中,我无法创建“切线组”svg组:


这是我目前的代码。我也愿意接受关于如何在其他方面改进它的建议

//测试数据
变量行=[{
id:0,
坐标:[[0,0],[10,10],[20,20]},
{
id:1,
坐标:[[30,30],[40,40],[50,50]]
}];
var直径=100;
var d3line=d3.svg.line();
var svg=d3.选择(“正文”).追加(“svg”)
.attr(“宽度”,直径)
.attr(“高度”,直径);
//为每条直线及其切线创建组
var linegroups=svg.selectAll(“.linegroup”)
.数据(行)
.enter().append('g')
.attr('class','linegroup')
.attr('id',函数(d){返回d.id;});
//添加行路径
linegroups.append('g')
.attr('class','linepath')
.append('路径')
.attr(“d”,函数(d){返回d3line(d坐标);});
///////问题部分////////
//为直线段的切线创建一个组,
//并为每个线段创建切线路径
线组。每个(功能(线,i){
d3.选择全部(此)
//“切向组”组从未出现过
.append('g')
.attr('类','组')
.数据(线段(直线坐标))
//“tan”路径附加到父svg,而不是“linegroup”。
.enter().append('path')
.attr('class','tan')
.attr('d',函数(d){
返回D3线(与中点(d)相切);
});
});
////////////////////////////////
//返回由点对组成的线段
功能线段(坐标){
返回d3.range(坐标.length-1).map(函数(i){
返回[坐标[i],坐标[i+1];
});
}
//返回从原始直线中点开始的切线
函数切线自中点(直线){
变量p1=第[0]行;
变量p2=第[1]行;
var中点=[(p1[0]+p2[0])/2,(p1[1]+p2[1])/2];
var tv=切向矢量(p1,p2)[0];
返回[中点[tv[0]+中点[0],tv[1]+中点[1]];
}
//返回直线的两个切线向量(不是单位向量)
函数切线向量(p1,p2){
//如果我们定义dx=x2-x1和dy=y2-y1,
//然后法线是(-dy,dx)和(dy,-dx)
var dx=p2[0]-p1[0];
var dy=p2[1]-p1[1];
返回[-dy,dx,dy,-dx]];
}

问题是您在调用
.data()
时没有使用
。请先选择all()
,然后操作
.enter()
选项。代码应该是

linegroups.each(function(line, i) {
  d3.select(this)
  .append('g')
    .attr('class', 'tangentgroup')
  .selectAll("path")
  .data(lineSegments(line.coordinates))
  .enter().append('path')
    .attr('class', 'tan')
    .attr('d', function (d) {
      return d3line(tangentFromMidpoint(d));
    });
});
完成演示。您甚至不需要
.each()
,但是:

linegroups.append('g')
   .attr('class', 'tangentgroup')
   .selectAll("path")
   .data(function(line) { return lineSegments(line.coordinates); })
   .enter().append('path')
   .attr('class', 'tan')
   .attr('d', function (d) {
     return d3line(tangentFromMidpoint(d));
   });

完成演示。

有趣的是,我没有意识到
d3。selectAll(这个)
也会导致问题。显然,我必须重新阅读选择API的详细信息。感谢您通过删除
.each()
而进行的改进!如果使用
d3.selectAll()
它必须是一个节点列表,例如
[this]