2016-07-04 200 views
0

我试图通过d3js使堆积条形图和具有当新数据通过一个更新功能通过它更新。我称这个更新函数为最初调用图,它工作正常。但是,当我更改数据并再次调用它时,它会从图中清除所有“rect”元素(当我控制台记录数据时,它似乎正在通过)。我怎样才能使图形适当重绘?我曾尝试过使用.remove()语句进行实验,但没有它,当重新绘制条形图时,数据不会通过。d3js更新重绘堆积条形图

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

很难确切地说出你在做什么,因为你的问题不包括数据或DOM。如果你包含一个到正在进行中的jsFiddle或其他东西的链接,这将有所帮助。

如果我猜什么错,它看起来像你正在做一个嵌套加入其中,每年被绑定到g组件,然后将每个位置被绑定到每个G元素内一个矩形。

的问题很可能你只是指定进入的行为,而不是更新的行为或退出行为。因此,当您尝试重新绘制时,没有任何更新,也没有任何结果 - 但新的数据元素将被添加。

这似乎这就是为什么你必须添加全选()。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(); 
+0

感谢您的回复。我改变了更新功能,基本上试图复制和粘贴你的代码,但我仍然有什么似乎是同样的问题。如果我在开头添加remove()语句,代码第11行(translate属性)中的任何console.log语句都会正确打印,但所有元素都会在图形上消失而不会重绘。如果我不添加这个remove()语句,那么第11行中的console.log将不返回任何内容,并且旧图保持与更新前一样。你知道这可能是为什么吗? –

+0

如果没有发布实际的代码,我真的不能提供更多的帮助,对不起。你应该尝试获得一个基于jsFiddle的例子。 – reblace