Alan W. Smith
Alan W. Smith

Reputation: 25475

Flip the x-axis of a D3 Stacked Bar Chart

Chapter 11 of "Interactive Data Visualization for the Web" shows how to create stacked bar charts with the D3.js library. The example produces an upside down chart with the bars attached to the top of the x-axis.

D3 Stacked Bar Chart with bars attached to the top.

Flipping the chart and attaching them to the bottom is left as an exercise for the reader.

Given this starting point:

<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript">
  var w = 500;
  var h = 300;

  var dataset = [[ { x: 0, y: 5 }, { x: 1, y: 4 }, { x: 2, y: 2 }, { x: 3, y: 7 }, { x: 4, y: 23 }],
    [ { x: 0, y: 10 }, { x: 1, y: 12 }, { x: 2, y: 19 }, { x: 3, y: 23 }, { x: 4, y: 17 } ],
    [ { x: 0, y: 22 }, { x: 1, y: 28 }, { x: 2, y: 32 }, { x: 3, y: 35 }, { x: 4, y: 43 } ]];

  var stack = d3.layout.stack();
  stack(dataset);

  var xScale = d3.scale.ordinal()
      .domain(d3.range(dataset[0].length)).rangeRoundBands([0, w], 0.05);

  var yScale = d3.scale.linear()
      .domain([0, d3.max(dataset, function(d) {
        return d3.max(d, function(d) { return d.y0 + d.y; });
      })])
      .range([0, h]);

  var colors = d3.scale.category10();

  var svg = d3.select("body").append("svg").attr("width", w).attr("height", h);

  var groups = svg.selectAll("g").data(dataset).enter().append("g")
      .style("fill", function(d, i) { return colors(i); });

  var rects = groups.selectAll("rect")
      .data(function(d) { return d; })
      .enter()
      .append("rect")
      .attr("x", function(d, i) { return xScale(i); })
      .attr("y", function(d) { return yScale(d.y0); })
      .attr("height", function(d) { return yScale(d.y); })
      .attr("width", xScale.rangeBand());
</script>

What needs to be done to flip the chart?

Upvotes: 2

Views: 2017

Answers (1)

Alan W. Smith
Alan W. Smith

Reputation: 25475

The solution I came up with involves three changes:

  1. Change the yScale .range from:

    .range([0, h]);
    

    to:

    .range([h, 0]);
    
  2. Change the rect "y" .attr from:

    .attr("y", function(d) { return yScale(d.y0); })
    

    to:

    .attr("y", function(d) { return yScale(d.y0) + yScale(d.y) - h; })
    
  3. Change the rect "height" .attr from:

    .attr("height", function(d) { return yScale(d.y); })
    

    to:

    .attr("height", function(d) { return h - yScale(d.y); })
    

With those changes applied, the stacks attach to the bottom and still maintain their relative sizes.

D3 Stacked Bar Chart with bars attached to the bottom.

Upvotes: 4

Related Questions