D3.js tutorial - Part 8 - Bar chart

If you read the previous parts of this tutorial, you should have all the tools to create you first bar chart, that should look like this awesome chart:

Step 1: dataset

Let's create a set of data for our bar chart:

// Set of data
var dataset = [31, 64, 42, 28, 16, 32, 64, 10];

Step 2: SVG container

Let's create a SVG container (200 x 100 pixels) with a grey background (see part 5 for more details):

// Create our SVG container with grey background
var svg = d3.select("body")
            .append("svg")
            .attr("width", 200)
            .attr("height", 100)
            .style('background-color', 'lightgrey');

Step 4: display bars

We'll now bind our dataset in order to display the bars.

// Bind data to chart, and create bars
svg.selectAll('.bar')
    .data(dataset)
    .enter()
    .append('rect')
    .attr('x', (d,i) => i*25 )
    .attr('y', 0)
    .attr('width', 20)
    .attr('height', (d) => d);

The first four lines are for dataset binding. It creates as many bars as there are row in our datase. See Part 7. for more details.

The next line is more intesting:

.attr('x', (d,i) => i*25 )

It sets the x-coordinate for each rectangle. The anonymous function accepts two parameters :

Since we want our rectangle to be spread across the width of our container, each rectangle must be spaced with 25 pixels (200 pixels / 8 rows in dataset). We multiply i by 25.

The last line set the rectangle height to the value of our data:

.attr('height', (d) => d);

Upside down

You probably noticed our chart was upside down. By shifting the y-coordinate of each rectangle we'll can reverse the chart:

.attr('y', (d) => 100-d)

Note in passing that:

It may seems unatural to mathematicians, but classics for developers used to works with graphics.

Container in a division

We created our chart from scratch in the body document. In practice, the chart is usualy inserted in the document with text, images... Let's create a the <div> tag in the page body, and creating the SVG container inside:

<h1>My first bar chart with D3.js</h1>
<div id="bar-chart"></div>

We no longer need to append the SVG container in the body. Instead, we'll append our container in the div:

// Create our SVG container with grey background
var svg = d3.select("#bar-chart")
            .append("svg")
            .attr("width", 200)
            .attr("height", 100)
            .style('background-color', 'lightgrey');

The result is the same as previously:

Group

It's a best practice to groups elements in the SVG container. Until now, we put our stuff in the container as it is. If we look at our SVG source code, it should look like:

<svg width="200" height="100" style="background-color: lightgrey;">
    <rect x="0" y="69" width="20" height="31"></rect>
    <rect x="25" y="36" width="20" height="64"></rect>
    <rect x="50" y="58" width="20" height="42"></rect>
    <rect x="75" y="72" width="20" height="28"></rect>
    ...
</svg>

Since all our rectangle forms the bars, it's a better idea to group them in a group entity:

<svg width="200" height="100" style="background-color: lightgrey;">
    <g class="bars">
        <rect x="0" y="69" width="20" height="31"></rect>
        <rect x="25" y="36" width="20" height="64"></rect>
        <rect x="50" y="58" width="20" height="42"></rect>
        <rect x="75" y="72" width="20" height="28"></rect>
        <rect x="100" y="84" width="20" height="16"></rect>
        ...
    </g>
</svg>

This is done by adding the following line in our JavaScript code:

var bars = svg.append('g')
            .attr('class', 'bars');

CSS styling

Until now, we added styles in our JS source code, but it is a best practice to separate styles from source code. You probably noticed at the previous step we added the bars class to our group. We now may create an independant CSS style:

#bar-chart svg { background-color: Gainsboro; }
#bar-chart .bars { fill: LightSkyBlue; }

Here is the result online:

Congrat's, you made your first bar chart with D3.js!

See also


Last update : 10/12/2021