D3 根据条形图更新选择 returns 只有一个数据

D3 upon bar chart update selections returns only one datum

我正在尝试构建交互式人口金字塔。我想更新条形的宽度。

不过我的 selection 有问题。女性和男性条形图更新为相同的宽度,因为它们接收相同的数据。我怀疑这与我 select 或加入数据的方式有关。我尝试了几种组合,现在我一直在阅读 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]);

您不应该保存 enter selection 的结果并像那样使用它。 canvas 中的 select,请参阅 here,它工作正常。原因是 enter selection 中的元素在添加 DOM 元素后合并到 update selection 中。