我想删除单击的栏,但由于某种原因,它总是删除最后一个栏。我认为答案可能在下面的文章(http://pothibo.com/2013/09/d3-js-how-to-handle-dynamic-json-data/)中,但我不确定是否有必要手动为每个元素分配一个键。我花了好几个小时试图让它发挥作用,所以我希望有人可以指出我正确的方向。提前谢谢。
<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>
答案 0 :(得分:2)
在此处查看我的解决方案:http://fiddle.jshell.net/sydvpsfp/
主要问题是你没有在drawChart函数开头删除所有旧条。 我添加了这个:
// remove any old bars var oldBars=chart.selectAll("g"); if (oldBars.size()>0) oldBars.remove();
答案 1 :(得分:1)
以下是您需要进行的更改,并附有评论:
// 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元素。
此外,同样重要的是,处理分组与非分组元素的更新之间存在一些细微差别(使用select
与selectAll
)。因此,我修改了代码以更适当地处理分组元素。
您可以找到有关正确处理分组元素here和here的更多信息。但这是承诺的改进:
<强> UPDATED FIDDLE 强>