JavaScript

[Tutorial] How to create a bar chart using D3.js?

Introduction

In this post, we will see a bar chart with D3.js. With the evolution of data science, charts are everywhere. It’s hard to know which chart you have to choose. Which way is the best to show data for your customers?

When do I choose a bar chart with D3.js?

It’s important not to confuse the bar chart and histogram chart. You would like to use bar chart to show data with categories and numerical values.

You can see an example of data to show in the bar chart here: https://docs.google.com/spreadsheets/d/1A3zVHPZhEvvkKmcsvMZjOqbguVnjN-kdHaddhUjHoIo/edit?usp=sharing

You have the first name column and the score column.

Define dimensions of your chart

First of all, you would like to define the dimensions of your chart. With D3.js, it’s always the same way to do that.

  //Define your dimensions
  const margin = { top: 100, right: 0, bottom: 100, left: 100 };
  const color = 'red';
  const height = 600;
  const width = 1200;

Of course, you got your data before. In other posts, I will create tutorials to get data from google spreadsheets, CSV, etc..

I advise you to define it at the top of your function. Because it’s easier to update after.

Define x-axis and y-axis of your chart

After the definition of the dimensions of your charts, you would like to create an x-axis and a y-axis.

  const yAxis = (g) =>
    g
      .attr('transform', `translate(${margin.left},0)`) 
      .call(d3.axisLeft(y).ticks(null, data.format))
      .call((g) =>
        g
          .append('text')
          .attr('x', -margin.left)
          .attr('y', 10)
          .text(data.y)
      );

  const xAxis = (g) =>
    g.attr('transform', `translate(0,${height - margin.bottom})`).call(
      d3
        .axisBottom(x)
        .tickFormat((i) => data[i].name)
    );

You can set an attribute as you want. I start to set the transform attribute of my y-axis.

d3.axisLeft is used to create axis to the left of your chart. After that, you would like to append new text tag for each tick. You can position as you want by setting x and y attributes. To show the text, just call the text method with the text in parameter (data.y here).

It’s exactly the same way for xAxis, just you have to use axisBottom instead of axisLeft.

  const y = d3
    .scaleLinear()
    .domain([0, d3.max(data, (d) => d.value)])
    .nice()
    .range([height - margin.bottom, margin.top]);

  const x = d3
    .scaleBand()
    .domain(d3.range(data.length))
    .range([margin.left, width - margin.right])
    .padding(0.1);

After that, you have to define y and x behaviors. So you would like to define the range, the padding, etc…

scaleLinear() is to define the basic scaling of your axis. It’s very useful when you create a basic chart with numeric values.

scaleBound() is to define scaling with categories. In our example, we would like to define the x-axis with first names.

For more details, and to explore other scale methods, you should read: https://www.d3indepth.com/scales/

Render your chart with D3.js

We would like to create a chart.

 const svg = d3
    .select('svg')
    .attr('width', width)
    .attr('height', height)
    .attr('fill', color);

  svg
    .selectAll('rect')
    .data(data)
    .enter()
    .append('rect')
    .attr('x', (d, i) => x(i))
    .attr('y', (d) => y(d.value))
    .attr('height', (d) => y(0) - y(d.value))
    .attr('width', x.bandwidth());

First of all, we create an SVG variable to have a place to implement our future bar chart. We use d3.select() method to select our SVG tag and add attributes like width, height, and fill.

On our SVG variable, we use selectAll(‘rect’) to create rect tag (rectangle shapes). But rect tags don’t still exist, so we use

  • data(data) to iterate on our data
  • enter() and append() to create rect tag for each item

We created the axis. Right now, we would like to implement it in our HTML.

  svg.append('g').call(xAxis);
  svg.append('g').call(yAxis);

It’s over for this first article on d3.js, you can see this codepen to show all the code : https://codepen.io/pierre_terrat/pen/eYJwmQr

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *