Search code examples
javascriptd3.jsstacked-chartstackedbarseries

D3.js stacked bar chart growing to negative direction


I am new to D3 and javascripts. I am trying to build an animated vertical stacked bar chart. I found an example here for a horizontal stacked bar chart. After tweaking it, I got a vertical stacked bar chart, however, growing downwards. Here is my edited fiddle.

Update: after making several tweaks, including the ones suggested by below, this finally works:final working upward growing stacked bar chart I feel the place(s) that I need to change should be within this code chunk

rects = groups.selectAll('.stackedBar')
        .data(function(d,i) {console.log("data", d,i); return d; })
        .enter()
        .append('rect').attr('class','stackedBar')
        .attr('y', function(d) { return yScale(d.y0); })
        .attr('x', function(d, i) {return xScale(d.x); })
        .attr('height',0)
        .attr('width', xScale.rangeBand());

        console.log(document.querySelectorAll(".stacked"));
        var abc=document.querySelectorAll(".stackedBar");

     rects
        .transition()
        .delay(function(d,i,j){console.log("pre",j); return j*500;})
        .attr("y", function(d) { return yScale(d.y0); })
        .attr("height", function(d) { return yScale(d.y); } )
        .duration(1000);

But I searched around and tried to revert the yScale range, the initial position of y, and none of them worked. I also noticed that no matter what, my yAxis is always below my X axis going doward.


Solution

  • First you must change the orientation of your y-scale:

    yScale = d3.scale.linear().domain([0,yMax]).range([height,0])
    

    And the x-axis must be transformed as well so it start at "height". In svg the top has height=0 so the bottom of your svg equals "height":

    svg.append('g')
       .attr('class', 'axis')
       .call(xAxis)
       .attr("transform", "translate(0," + height + ")");
    

    Last but not least, you have to change the building orientation of your stacked bar chart like:

    rects
       .transition()
       .delay(function(d,i,j){console.log("pre",j); return j*500;})
       .attr("y", function(d) { return yScale(d.y + d.y0); })
       .attr("height", function (d) { return yScale(d.y0) - yScale(d.y + d.y0); } )
       .duration(1000);
    

    Here is an updated fiddle.