删除了不正确的SVG组 [英] Incorrect SVG group being deleted
问题描述
我想删除单击的栏,但是由于某些原因,它总是删除最后一个栏.我认为答案可能在以下文章中( http://pothibo.com/2013/09/d3-js-how-to-handle-dynamic-json-data/),但是我不确定是否为每个元素手动分配键是必要的.我已经花了数小时试图使它正常工作,所以我希望有人可以指出正确的方向.预先感谢.
I want to remove the bar that is clicked, but for some reason it is always removing the last bar instead. I think the answer may be in the following article (http://pothibo.com/2013/09/d3-js-how-to-handle-dynamic-json-data/), but I'm not sure if manually assigning a key to each element is necessary. I have spent hours trying to get this to work, so I'm hoping someone can point me in the right direction. Thanks in advance.
<html>
<head>
<title>Interactive Div-based Bar Chart</title>
<style type="text/css">
.chart rect {
fill: teal;
}
.chart text {
fill: white;
font: 30px sans-serif;
text-anchor: end;
}
</style>
<script src="Scripts/d3.min.js"></script>
</head>
<body>
<div id="data-field"></div>
<button id="add-btn">Add Data</button>
<p>Click on a bar to remove it</p>
<script>
var barHeight = 75, margin = 3, padding = 3;
var chartData = [6,12,15,21,29,41];
var chart = d3.select("body").append("svg").attr("class","chart");
drawChart();
function drawChart() {
var selection = chart.selectAll("g")
.data(chartData);
// Remove extra bars
selection.exit()
.remove();
// Add more bars
var groups = selection.enter()
.append("g");
var bars = groups
.append("rect");
var labels = groups
.append("text");
// Update existing bars
groups
.attr("transform", function (d, i) { return "translate(0," + i * (barHeight + margin) + ")"; })
.on("click", function (d, i) { chartData.splice(i, 1); drawChart(); });
bars
.attr("width", function (d) { return d * 10 + "px"; })
.attr("height", barHeight);
labels
.attr("x", function (d) { return d * 10 - padding + "px"; })
.attr("y", barHeight / 3 + padding + "px")
.text(function (d) { return d; });
// update list of numbers
d3.select("#data-field").text("numbers: [" + chartData.join(", ") + "]");
}
// add more data
d3.select("#add-btn")
.on("click", function(d) { chartData.push(Math.round(Math.random() * 100)); drawChart(); });
</script>
</body>
</html>
推荐答案
以下是您需要进行的更改,并带有注释:
Here are the changes you need to make, with comments:
// Update existing bars; do not use groups here since it represents
// only the ENTER selection, and not ALL g elements
selection
.attr("transform", function (d, i) { return "translate(0," + i * (barHeight + margin) + ")"; })
.on("click", function (d, i) {
d3.select(this).remove(); // remove appropriate DOM element
chartData.splice(i, 1);
drawChart();
});
这是 FIDDLE .
重要
@loucatsfan问我为什么不简单地摆脱selection.exit().remove();
,因为这没什么不同,所以我意识到使我的回答更习惯化的重要性.因此,我创建了一个更新的小提琴,该小提琴利用了exit
选择并消除了手动删除DOM元素的需要.
After @loucatsfan asked me why not simply getting rid of selection.exit().remove();
since it made no difference, I realized the importance of making my answer more idiomatic. So, I created an updated fiddle that leverages the exit
selection and removes the need to manually delete the DOM element.
同样重要的是,在处理分组和非分组元素的更新之间存在一些细微的差异(使用select
与selectAll
).因此,我修改了代码以更适当地处理分组的元素.
Also, and just as important, there are some subtle differences between handling updates for grouped vs. non-grouped elements (use of select
vs. selectAll
). So, I revised the code to more appropriately handle grouped elements.
您可以找到有关正确处理分组元素的更多信息此处.但是,这是有望实现的改进:
You can find more info on the proper handling of grouped elements here and here. But here is the promised improvement:
更新字段 .
UPDATED FIDDLE.
这篇关于删除了不正确的SVG组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!