d3js更新重绘堆积条形图

时间:2016-07-04 14:06:34

标签: d3.js

我正在尝试通过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); 

1 个答案:

答案 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();