2016-07-04 186 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