Yesha
Yesha

Reputation: 678

Add more grouping to grouped bar chart

I am making a grouped bar chart, for which the script is given at this link: https://jsfiddle.net/yL5z1q04/4/

Here I have groups of "salary" and "investment" for rank_buckets. Now, I want to add one more level of "grouping" on X-Axis based on "nation" key given in data.

My data is as follows:

 var data = [
    {group: "investment", height: 84636, rank_bucket: "a", nation: "United States"},
    {group: "salary", height: 76536, rank_bucket: "a", nation: "United States"},
    {group: "investment", height: 84636, rank_bucket: "a", nation: "Australia"},
    {group: "salary", height: 76536, rank_bucket: "a", nation: "Australia"},
    {group: "investment", height: 89626, rank_bucket: "b", nation: "Australia"},
    {group: "salary", height: 98234, rank_bucket: "b", nation: "Australia"},
    {group: "investment", height: 89626, rank_bucket: "b", nation: "United States"},
    {group: "salary", height: 98234, rank_bucket: "b", nation: "United States"}

   ];

The expected output should look somewhat like this:

enter image description here

How do I do this? I want to have "nation" information depicted on X-Axis along with rank_bucket.

Thanks!

Upvotes: 0

Views: 55

Answers (1)

Tom Shanley
Tom Shanley

Reputation: 1787

you can create multiple scaleBands, for rank_bucket, nation and group.

For each scales' range width, use the each bandwidth() of the preceding scale. For example,

var xscale_rank_bucket = d3.scaleBand()
          .rangeRound([0,width])
          .padding(0.2)
          .domain(Array.from(rank_buckets));

var xscale_nation = d3.scaleBand()
          .rangeRound([0,xscale_rank_bucket.bandwidth()])
          .padding(0.1)
          .domain(Array.from(nations));

You had done some of this already, but it just needed extending to the third scale.

Also, you can create multiple x-axes for nation and rank_bucket. For the nation axes, you will need one per rank_bucket, so you can add them based on a rank_bucket data join, for example:

var axisNationG = axes.selectAll(".axis-nation")
        .data(Array.from(rank_buckets))
      .enter()
      .append("g")
      .attr("transform", function(d){
        return "translate(" + xscale_rank_bucket(d) + ",0)"
      })
      .attr("class", "x axis")
      .call(axisNation)

The axes can be translated and styled to look like your mock up.

https://jsfiddle.net/yL5z1q04/5/

PS - The updated fiddle uses Sets to extract the unique values for each scale, and converts the Sets to Arrays for use in the scales and data joins.

Upvotes: 1

Related Questions