我正在尝试通过d3js制作堆积条形图,并在新数据通过更新功能时进行更新。我称这个更新函数最初调用图形,它工作正常。但是,当我更改数据并再次调用它时,它会删除所有" rect"图中的元素(当我控制台记录数据时,它似乎正在通过)。如何正确地重新绘制图形?我已经尝试在开始时尝试使用.remove()语句,但是如果没有它,则在重绘条形图时数据不会通过。
function update(my_data) {
svg.selectAll(".year").remove();
var year = svg.selectAll(".year")
.data(my_data)
.enter().append("g")
.attr("class", "year")
.attr("transform", function(d) { return "translate(" + x0(d.Year) + ",0)"; });
var bar = year.selectAll(".bar")
.data( function(d){ return d.locations; });
bar
.enter().append("rect")
.attr("class", "bar")
.attr("width", x0.rangeBand())
.attr("y", function(d) { return y(d.y1); })
.attr("height", function(d) { return y(d.y0) - y(d.y1); })
.style("fill", function(d) { return color(d.name); });
}
update(data);
答案 0 :(得分:0)
很难准确说出您正在做什么,因为您的问题不包含数据或DOM。如果你包含一个正在进行中的工作jsFiddle的链接会有所帮助。
如果我不得不猜测出了什么问题,看起来您正在进行嵌套连接,其中每年都绑定到ag元素,然后每个位置都绑定到每个g元素内的rect。
问题可能是您只指定了输入行为,而不是更新行为或退出行为。因此,当您尝试重绘时,没有任何更新,也没有任何退出 - 但会添加新的数据元素。
这似乎就是为什么你必须添加selectAll()。remove()来获取重绘的东西。通过删除所有内容,所有数据元素都将触发输入条件并再次添加。
看一下这些教程,以便更好地理解输入/更新/退出模式的工作原理以及嵌套连接的工作原理。
常规更新模式: https://bl.ocks.org/mbostock/3808218
嵌套选择: https://bost.ocks.org/mike/nest/
此外,我前面写了一篇 jsFiddle 来演示如何一起使用嵌套选择和一般更新模式:
https://jsfiddle.net/reblace/bWp8L/
var series = svg.selectAll("g.row").data(data, function(d) { return d.key; });
/*
* This section handles the "enter" for each row
*/
// Adding a g element to wrap the svg elements of each row
var seriesEnter = series.enter().append("g");
seriesEnter
.attr("class", "row")
.attr("transform", function(d, i){
return "translate(" + margin.left + "," + (margin.top + (span*i)) + ")";
})
.attr("opacity", 0).transition().duration(200).attr("opacity", 1);
// Adding a text label for each series
seriesEnter.append("text")
.style("text-anchor", "end")
.attr("x", -6)
.attr("y", boxMargin + (boxDim/2))
.attr("dy", ".32em")
.text(function(d){ return d.key; });
// nested selection for the rects associated with each row
var seriesEnterRect = seriesEnter.selectAll("rect").data(function(d){ return d.values; });
// rect enter. don't need to worry about updates/exit when a row is added
seriesEnterRect.enter().append("rect")
.attr("fill", function(d){ return colorScale(d)})
.attr("x", function(d, i){ return i*span + boxMargin; })
.attr("y", boxMargin)
.attr("height", boxDim)
.attr("width", boxDim);
/*
* This section handles updates to each row
*/
var seriesUpdateRect = series.selectAll("rect").data(function(d){ return d.values});
// rect update (Will handle updates after enter)
// rect enter
seriesUpdateRect.enter().append("rect")
.attr("x", function(d, i){ return i*span + boxMargin; })
.attr("y", boxMargin)
.attr("height", boxDim)
.attr("width", boxDim);
// rect enter + update
seriesUpdateRect
.attr("fill", function(d){ return colorScale(d)});
// Exit
seriesUpdateRect.exit();
/*
* This section handles row exit
*/
series.exit()
.attr("opacity", 1)
.transition().duration(200).attr("opacity", 0)
.remove();