Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags

javascript

How to create stacked bar chart using D3

Shahpar Khan

A bit about D3

D3 is an interactive JavaScript library for data visualization. It uses Scalar Vector Graphics (SVG) coupled with HTML and CSS to display charts and figures that illustrate the numeric data. You can also use D3 to make stacked bar charts. Here is a step-by-step guide on how to make a stacked bar chart using D3.

Step 1: Dataset

Before even starting to code, we need a data set to base our chart on. For this example, we will take an array of objects where each object has five attributes: year, alex, mindy, sean, and karen. We will then take an array of colors associated with each of our stacked bars. Next, we will combine them and create layers with year assigned to x and the bars (values of alex, mindy, sean, and karen) assigned to y:

    var data = [
      { year: "2006", alex: "104", mindy: "152", sean: "90", karen: "162" },
      { year: "2007", alex: "122", mindy: "184", sean: "99", karen: "143" },
      { year: "2008", alex: "50", mindy: "201", sean: "127", karen: "114" },
      { year: "2009", alex: "150", mindy: "134", sean: "139", karen: "80" }
      ];
    
    var colors = ["#C9D6DF", "#F7EECF", "#E3E1B2", "#F9CAC8"];
    
    var dataset = d3.layout.stack()(["alex", "mindy", "sean", "karen"].map(function(fruit) {
      return data.map(function(d) {
        return {x: d3.time.format("%Y").parse(d.year), y: +d[fruit]};
      });
    }));

Step 2: Set dimensions

We make an svg variable and define its constraints keeping in mind the height, width, and margin:

var margin = 50;
    var width = 600;
        height = 300;
    
    var svg = d3.select("body")
      .append("svg")
      .attr("width", width + margin + 40 )
      .attr("height", height + margin + 20)
      .append("g")
      .attr("transform", "translate(" + (margin+30)/2 +  "," + margin/2 + ")")

Step 3: Set scales

For discrete data visualization on the x-axis, we need to construct an ordinal scale. The ordinal scale makes discrete bands for our values on the x-axis and then induces padding to separate the bars in the bar chart.

For our y-axis, we use a linear scale to show the sales:

    var xScale = d3.scale.ordinal()
      .domain(dataset[0].map(function(d) { return d.x; }))
      .rangeRoundBands([0, width], 0.5);
    
    var yScale = d3.scale.linear()
      .domain([0, 600])
      .range([height, 0]);

Step 4: Draw axes

After setting scales, we need to draw axes. For each axes, we supply the corresponding scale (xScale or yScale) and then specify the ticks. After that, we call our defined xAxis and yAxis and translate where necessary:

    var yAxis = d3.svg.axis()
      .scale(yScale)
      .orient("left")
      .ticks(6)
      .tickSize(-width, 0, 0)
      .tickFormat( function(d) { return "$" + d } );
    
    var xAxis = d3.svg.axis()
      .scale(xScale)
      .orient("bottom")
      .tickFormat(d3.time.format("%Y"));
    
    svg.append("g")
      .attr("class", "y axis")
      .call(yAxis);
    
    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

Step 5: Add labels

We need to add the x-axis label and y-axis label to our plot. For this purpose, we first append text to our svg, and then set the position, style, and actual text attribute. To rotate our text for the y-axis, we use transform and specify the angle of rotation:

// X label
    svg.append('text')
        .attr('x', width/2)
        .attr('y', height + 30)
        .attr('text-anchor', 'middle')
        .style('font-family', 'Helvetica')
        .style('font-size', 12)
        .text('Year');
            
    // Y label
    svg.append('text')
        .attr('text-anchor', 'middle')
        .attr('transform', 'translate(-30,' + height/2 + ')rotate(-90)')
        .style('font-family', 'Helvetica')
        .style('font-size', 12)
        .text('Sale');

Step 6: Draw bars

Finally, we need to plot the stacked bars. To do that, we first make subgroups of each bar for the associated x value and assign them to their appropriate color. Then, we need to specify the x position, y position, height, and width of each stacked bar. The x position and width can be found out using the xScale – it’s finding out the y position and height for each bar is the tricky part.

To find the y position of the sub-bar of one year, we add the previous bar’s height to the current bar. To find out the height of the sub-bar of one year, we first calculate the total height of the current bar and the previous bar, and then we subtract the previous bar’s height.

    var groups = svg.selectAll("g.bars")
      .data(dataset)
      .enter().append("g")
      .attr("class", "bars")
      .style("fill", function(d, i) { return colors[i]; })
      .style("stroke", "#000");
    
    var rect = groups.selectAll("rect")
      .data(function(d) { return d; })
      .enter()
      .append("rect")
      .attr("x", function(d) { return xScale(d.x); })
      .attr("y", function(d) { return yScale(d.y0 + d.y); })
      .attr("height", function(d) { return yScale(d.y0) - yScale(d.y0 + d.y); })
      .attr("width", xScale.rangeBand())

RELATED TAGS

javascript

CONTRIBUTOR

Shahpar Khan
Copyright ©2022 Educative, Inc. All rights reserved
RELATED COURSES

View all Courses

Keep Exploring