2015-11-19 63 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选择中。