Kunal Sharma
Kunal Sharma

Reputation: 369

D3 JS: Transforming the vertically grouped bar chart to horizontally grouped bar chart

I am new to D3's world. I am facing a complicated situation when trying to transform this example to horizontally grouped bar chart. I was following the points described in this post for the transformation. This is my version of code.

I have converted all the domains and ranges for horizontal group charts, but could not possibly succeed.

var xScale = d3.scale.linear().range([innerHeight, 0]);
var yScale = d3.scale.ordinal().rangeBands([innerWidth, 0], barPadding);

bars.attr("y", function(d, i, j) {
    return yScale(d[yColumn]) + barWidth * j;
  })
  .attr("x", 0)
  .attr("height", barWidth)
  .attr("width", function(d) {
    return xScale(d.y);
  })

Any help would be greatly appreciated!

Upvotes: 1

Views: 1349

Answers (1)

Rafael
Rafael

Reputation: 454

This conversion is a bit trickier than you might assume at first. In the snippet you shared, yScale range is [innerWidth, 0] when it should be [0, innerHeight]. Below are the relevant parts. You can see it running live here.

Note that I use stack's layout d.x as input for the y axis, and d.y as input for the x axis. That's because d3.layout.stack doesn't have orientation as a parameter.

var yColumn = "country";
var xColumn = "population";

var xScale = d3.scale.linear().range([0, innerWidth]);
var yScale = d3.scale.ordinal().rangeBands([0, innerHeight], barPadding);
var colorScale = d3.scale.category10();

var xAxis = d3.svg.axis().scale(xScale).orient("bottom")
  .ticks(5)
  .tickFormat(d3.format("s"))
  .outerTickSize(0);
var yAxis = d3.svg.axis().scale(yScale).orient("left")
  .outerTickSize(0);

function render(data) {

  var nested = d3.nest()
    .key(function(d) {
      return d[layerColumn];
    })
    .entries(data);

  var stack = d3.layout.stack()
    .y(function(d) { return d[xColumn];})
    .values(function(d) {return d.values;});

  var layers = stack(nested);

  yScale.domain(layers[0].values.map(function(d) {
    return d[yColumn];
  }));

  xScale.domain([
    0,
    d3.max(layers, function(layer) {
      return d3.max(layer.values, function(d) {
        return d.y;
      });
    })
  ]);

  colorScale.domain(layers.map(function(layer) {
    return layer.key;
  }));

  xAxisG.call(xAxis);
  yAxisG.call(yAxis);

  var layers = g.selectAll(".layer").data(layers);
  layers.enter().append("g").attr("class", "layer");
  layers.exit().remove();
  layers.style("fill", function(d) {
    return colorScale(d.key);
  });

  var bars = layers.selectAll("rect").data(function(d) {
    return d.values;
  });
  var barWidth = yScale.rangeBand() / colorScale.domain().length;
  bars.enter().append("rect")
  bars.exit().remove();
  bars
    .attr("y", function(d, i, j) {
      return yScale(d[yColumn]) + barWidth * j;
    })
    .attr("x", function(d) {
      return xScale(d.x);
    })
    .attr("height", barWidth)
    .attr("width", function(d) {
      return xScale(d.y);
    })

  colorLegendG.call(colorLegend);
}

Upvotes: 1

Related Questions