这应该是一个多线图 我有一个这样的数组作为数据:
data = [[point:{x: 0, y: 1},point:{x: 0, y: 3}], [point:{x: 3, y: 1},point:{x: 3, y: 3}], [point:{x: 0, y: 6},point:{x: 1, y: 9}], [point:{x: 2, y: 6},point:{x: 3, y: 2}]]
代码:
gr.line = d3.line()
.x((d) => d.point.x)
.y((d) => d.point.y)
let allGroup = gr.g.selectAll(".pathGroup").data(data)
allGroup.exit().remove()
let g = allGroup.enter()
.append("g")
.attr("class", "pathGroup")
g.append("path")
.attr("class", "line")
.attr("stroke", (d) => {
return 'red'
})
.attr("d", (d) => gr.line(d))
我想在路径中添加圆圈。如果我想将圆圈附加到组(在这种情况下是变量g),我得到整个数组。但我只需要数组中的每个项目来附加圆圈。我想用数据绑定来做,因为我想在数据更改时删除项目。我用forEach循环完成它,但我认为这不是一个好的解决方案。有人知道如何通过数据绑定完成它吗?
答案 0 :(得分:2)
您的data
无效。根据你的行生成器判断,你应该有一个对象数组,如下所示:
var data = [[{point:{x: 10, y: 10}}, {point:{x: 100, y: 30}}],
[{point:{x: 30, y: 100}},{point:{x: 230, y: 30}}]
];
回到问题:你是对的,做任何类型的循环(如forEach
)在D3代码中追加元素通常是个坏主意。
只需在内部选择中使用外部选择的单个数据(这是一个数组本身):
g.selectAll(null)
.data(d=>d)
.enter()
.append("circle")
//etc...
值得一提的是我在这里使用selectAll(null)
因为输入/更新/退出选择似乎在外部选择中运行,而不是在内部选择中。如果不正确则相应地更改该行。
这是一个演示,我正在更改数据值以更好地查看路径和圆圈:
var data = [
[{
point: {
x: 10,
y: 10
}
}, {
point: {
x: 100,
y: 30
}
}],
[{
point: {
x: 30,
y: 100
}
}, {
point: {
x: 230,
y: 30
}
}]
];
var svg = d3.select("svg");
var line = d3.line()
.x((d) => d.point.x)
.y((d) => d.point.y);
var allGroup = svg.selectAll(".pathGroup").data(data);
var g = allGroup.enter()
.append("g")
.attr("class", "pathGroup")
g.append("path")
.attr("class", "line")
.attr("stroke", "red")
.attr("stroke-width", "1px")
.attr("d", line);
g.selectAll(null)
.data(d => d)
.enter()
.append("circle")
.attr("r", 4)
.attr("fill", "teal")
.attr("cx", d => d.point.x)
.attr("cy", d => d.point.y);
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>