D3.js in all its glory

Some techniques to increase the interactivity of an ordinary line chart.

See this article in Russian (Эта статья на русском 🇷🇺).

In this article, we will consider several techniques on how to make an ordinary line chart more informative and interactive using a JavaScript library for data visualization D3.js.

We will take the original data from the Russian open data hub and visualize dynamics of weighted average interest rates on credits extended to businesses and individuals among the regions of the Central Federal district of Russia.

I will try to comment on the most significant parts of the code. However, for a person not familiar with the basic concepts of this library (such as selection, scale, transform, zoom, update pattern) many things may not seem obvious. We will use the last — fifth version of the D3.js library and write code using modern ES6 syntax. If you need to transfer some parts of the code to your own project, working in an environment that does not support any of the ES6 features, do not forget to use the code translator.

Before starting, let’s take a look at the structure of our initial data:

The rows in the csv file are: region ID ( regionId ), region name ( regionName ), date ( date ), and interest rate ( percent ).

Drawing graphs.

We load the data file using the d3.csv method which gets the source url as an argument and returns a promise. After the file is loaded the draw function will be run.

Let us consider the draw function itself. First, define some constants ( margins , width , height ) and three scales that we will need — the scales of the X and Y-axes and the color scale that we will use to set the color of the charts. We will than store an element that will be a container for other elements of our visualization in svg variable.

Update date and percent properties in each element of the source data array by converting their values from a string to a Date object and from a string to a number, respectively.

After that we can set the domain for our scales.

Define the X-axis and Y-axis and add them to the page.

Pay attention, we have set tickSize for the X-axis equal to the width of the graph, and for the Y-axis equal to the height. Due to this, we have the grid in the graph area.

Now we can draw lines on the chart. After some manipulations with the original dataset, we get an object (stored in the regions variable) in this form: keys — regions IDs, values — arrays of data for appropriate regions. We use the array of regions IDs for data binding. Thus we can set the value for the d attribute this way:

.attr('d', regionId => lineGenerator(regions[regionId]))

Now, when the graphs are built, we can see the problems that we have. There are a multitude of lines and they overlap, so it is very difficult for the user to get any useful information from this tangle of lines.

In the following sections of the article, we will try to add maximum opportunities for the user to untangle this and make the chart interactive. The first thing we add is the legend. The chart makes no sense without it.