Let's Make a Bar Chart

March 18, 2013 by Alex Coco

A few days ago I started taking a closer look at Michael Bostock’s D3.js. D3 is an amazing JavaScript library for mapping data to HTML elements or SVG nodes. I started off making some bar charts with HTML elements and then moved onto SVG nodes and transitions.

Generally, to make simple charts, all you need to do is follow these steps:

  1. Select the place you want to put your chart
  2. Select all the chart components
  3. Apply the data to this selection
  4. Add a new compononent for each piece of data that wasn’t applied
  5. Position the new components
  6. Apply any other attributes or styles

Here’s an example of a bar chart and the code that will create it below:

var data = [ 1, 2, 3, 4, 5, 4, 3, 4, 3, 2, 1 ];

var svg1 = d3.select('#barchart1')
             .append('svg')
             .attr('width', 240)
             .attr('height', 100);
            
svg1.selectAll('rect')
    .data(data)
    .enter()
    .append('rect')
      .attr('x', function(d, i) { return i * 22; })
      .attr('y', function(d) { return 100 - d * 20; })
      .attr('width', 20)
      .attr('height', function(d) { return d * 20; });

When setting an attribute, the second argument can be a literal, variable, or a function. The function can take up to two arguments: the value of the current piece of data and its index in the selection being operated on. With functions, it’s possible to return a value based on what position the data holds. This can be useful when setting a position where every subsequent element will be offset by a larger value than the last. Using functions is also the only way to get a hold of a variable containing the value of the data.

D3 also lets you apply transitions to selections. For example, the bars in the bar chart can start off with a height of 0 and grow upwards.

var svg2 = d3.select('#barchart2')
             .append('svg')
             .attr('width', 240)
             .attr('height', 100);
            
svg2.selectAll('rect')
    .data(data)
    .enter()
    .append('rect')
      .attr('x', function(d, i) { return i * 22; })
      .attr('y', 100)
      .attr('width', 20)
      .attr('height', 0)
    .transition()
      .delay(function(d, i) { return i * 100; })
      .duration(200)
      .attr('y', function(d) { return 100 - d * 20; })
      .attr('height', function(d) { return d * 20; });

Transitions are simple: append a call to transition() and set the delay and/or duration with calls to delay and duration. Then, any attributes changed after the call to transition() will transition to their new values.

D3 can do so much more than just displaying bar charts or line graphs. Here’s an amazing show reel with loads of great transitions and here’s a bunch D3 examples.

Note that I’ve applied some default styles for SVG and rect in my stylesheet so that they appear centered and have a nice color. The default fill for SVG nodes is black.