2015-11-19 42 views
0

我試圖建立一個互動人口金字塔。我想更新酒吧的寬度。D3條形圖更新選擇只返回一個數據

雖然有些東西不適合我的選擇。女性和男性酒吧的圖表更新爲相同的寬度,因爲他們收到相同的數據。我懷疑它與我選擇或加入數據的方式有關。我嘗試了幾種組合,現在我堅持在select和selectAll上閱讀文檔。

對這裏出了什麼問題的任何意見都非常感謝。

代碼(here is the fiddle):

var pyramidCanvas = d3.select("body") 
    .append("svg") 
    .attr("width",200) 
    .attr("height",100); 

var pyramidHeight = 100; 
var pyramidWidth = 100; 
var pyramidBarsRight, pyramidBarsLeft; 

function setupPyramid(){ 

    var data = [300,20,40,50,10]; 

    var pyramidHeight = 100; 
    var pyramidWidth = 100; 

    var xScale = d3.scale.linear() 
     .domain([0,d3.max(data,function(d){return d;})]) 
     .range([0,pyramidWidth]); 

    var barHeight = pyramidHeight/data.length; 

    console.log(barHeight); 

    pyramidBarsLeft = pyramidCanvas.selectAll("g-female") 
     .data(data) 
     .enter() 
     .append("g") 
     .attr("transform",function(d,i){return "translate(0,"+ (i * 10)+ ")" ;}); 

    pyramidBarsLeft.append("rect") 
     .attr("class","female-bar") 
     .attr("x",function(d){return pyramidWidth-xScale(d);}) 
     .attr("y",function(d,i){ 
      return i*10; 
     }) 
     .attr("width",function(d){console.log(d);return xScale(d);}) 
     .attr("height",10) 
     .style("fill","pink"); 

    pyramidBarsRight = pyramidCanvas.selectAll("g-male") 
     .data(data) 
     .enter() 
     .append("g") 
     .attr("transform",function(d,i){return "translate(0,"+ (i * 10)+ ")" ;}); 

    pyramidBarsRight.append("rect") 
     .attr("class","male-bar") 
     .attr("x",pyramidWidth) 
     .attr("y",function(d,i){ 
      return i*10; 
     }) 
     .attr("width",function(d){console.log(d);return xScale(d);}) 
     .attr("height",10) 
     .style("fill","steelblue"); 

} 


function updatePyramid(data){ 

    var femData = data.slice(0,5); 
    var malData = data.slice(5,9); 

    console.log(femData); 
    console.log(malData); 

    console.log(pyramidBarsRight.selectAll("rect")); 

    var xScale = d3.scale.linear() 
     .domain([0,d3.max(data,function(d){return d;})]) 
     .range([0,pyramidWidth]); 

    pyramidBarsLeft 
     .selectAll(".female-bar") 
     .data(femData) 
     .transition() 
     .duration(500) 
     .attr("x",function(d){return pyramidWidth-xScale(d);}) 
     .attr("width",function(d){console.log(d);return xScale(d);}) 

    pyramidBarsRight 
     .selectAll(".male-bar") 
     .data(malData) 
     .transition() 
     .duration(500) 
     .attr("width",function(d){console.log(d);return xScale(d);}); 


} 

setupPyramid(); 
updatePyramid([20,10,50,100,600,30,22,54,91,19,10]); 
+1

你不應該保存'enter'選擇的結果並像那樣使用它。它可以很好地從畫布中選擇:https://jsfiddle.net/mozyt6td/2/ –

+0

謝謝,@LarsKotthoff!解決了這個問題。如果你把它寫成答案,我會接受它。 tbh,現在我更加困惑了。爲什麼當我從畫布中選擇時會起作用?當我從欄中選擇時,選擇內容也包含正確數量的元素。 如果需要太多時間,則無需回答。我回到閱讀https://github.com/mbostock/d3/wiki/Selections ;-)。 – seb

回答

1

你不應該保存enter選擇的結果,並用它這樣的。它可以很好地從畫布中選擇,請參閱here。原因在於一旦添加了DOM元素,enter選擇中的元素就會合併到update選擇中。