我正在构建一个交互式散点图,我无法更新圆圈的选择(数据点SEEM工作正常,但我不能确定,因为行为有些不稳定)。当我创建初始绘图时,点和线显示正常,但在单击节点并将其删除后,我无法重置选择。更具体地说,变量“i”(在我的理解中给出了选择中对象的索引)仍然与初始选择绑定。代码如下:
function mousedownCircle(d, i) {
console.log(i);
circles[0][i].remove();
dataset.splice(i, 1);
circles = svg.selectAll("circle").data(dataset);
line_obj.attr("d", valueline(dataset));
d3.event.stopPropagation();
}
// Create Circles
var circles = svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle") // Add circle svg
.attr("cx", function(d) {
return xScale(d[0]); // Circle's X
})
.attr("cy", function(d) { // Circle's Y
return yScale(d[1]);
})
.attr("r", radius) // radius
.on("click", mousedownCircle); // click callback
主要思想是能够删除圆圈和数据点。我做错了什么?
谢谢你的时间!
答案 0 :(得分:0)
d3
的关键是遵循正确的enter
,update
,exit
模式。我通常将它包装成一个我可以调用的函数,而不管“重绘”我的可视化的动作。从查看代码片段开始,正确的函数将如下所示:
function update() {
// Create Circles
var circles = svg.selectAll("circle")
.data(dataset);
circles.exit().remove(); // remove the ones exiting
circles = circles
.enter() // Add circle to svg
.append("circle")
.merge(circles); // this is the update + enter selection
circles // update circles
.attr("cx", function(d) {
return xScale(d[0]); // Circle's X
})
.attr("cy", function(d) { // Circle's Y
return yScale(d[1]);
})
.attr("r", 40) // radius
.style("fill", "steelblue")
.on("click", mousedownCircle); // click callback
}
您的mousedownCircle
功能变得如此简单:
function mousedownCircle(d, i) {
dataset.splice(i, 1);
update();
}
运行示例:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
function mousedownCircle(d, i) {
dataset.splice(i, 1);
update();
}
var w = 400,
h = 400;
var svg = d3.select('body')
.append('svg')
.attr('width', w)
.attr('height', h);
var dataset = [
[Math.random() * w, Math.random() * h],
[Math.random() * w, Math.random() * h],
[Math.random() * w, Math.random() * h],
[Math.random() * w, Math.random() * h],
[Math.random() * w, Math.random() * h],
[Math.random() * w, Math.random() * h]
];
update();
function update() {
// Create Circles
var circles = svg.selectAll("circle")
.data(dataset);
circles.exit().remove();
circles = circles
.enter()
.append("circle")
.merge(circles); // Add circle svg
circles
.attr("cx", function(d) {
return d[0]; // Circle's X
})
.attr("cy", function(d) { // Circle's Y
return d[1];
})
.attr("r", 40) // radius
.style("fill", "steelblue")
.on("click", mousedownCircle); // click callback
}
</script>
</body>
</html>
对评论的回应
最直接的做法是:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
function mousedownCircle(d, i) {
d3.select(this).remove();
}
var w = 400,
h = 400;
var svg = d3.select('body')
.append('svg')
.attr('width', w)
.attr('height', h);
var dataset = [
[Math.random() * w, Math.random() * h],
[Math.random() * w, Math.random() * h],
[Math.random() * w, Math.random() * h],
[Math.random() * w, Math.random() * h],
[Math.random() * w, Math.random() * h],
[Math.random() * w, Math.random() * h]
];
// Create Circles
var circles = svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
.attr("cx", function(d) {
return d[0]; // Circle's X
})
.attr("cy", function(d) { // Circle's Y
return d[1];
})
.attr("r", 40) // radius
.style("fill", "steelblue")
.on("click", mousedownCircle); // click callback
</script>
</body>
</html>