Barbarian Meets Coding
barbarianmeetscoding

WebDev, UX & a Pinch of Fantasy

5 minutes readvisualization

D3.js: Data-Driven Documents

This article is part of my personal wiki where I write personal notes while I am learning new technologies. You are welcome to use it for your own learning! It’s been updated to d3.js v5.

D3js(Data Driven Documents) is a JavaScript library that lets you create beautiful and interactive visualizations by transforming data into HTML (oftentimes SVG).

You can see D3.js as composed of two parts:

  • A DOM manipulation API which includes a way to bind data to the DOM (that’s where the Data Drive Document comes from)
  • A ton of utilities to make it easy to operate and create charts and visualizations: from scales that let you transform between the data domain and the visualization domain, to axes, facades over svg, force charts, and more.

A great wait to get started experimenting with d3.js is using the Block Builder online d3.js playground.

D3js As a DOM Manipulation Library

D3js comes with a humongous amount of utilities to create amazing visualizations but at its core lays a DOM manipulation API that helps you transform the DOM with ease in a declarative fashion.

The entry point to D3.js is its select function. Using d3.select you can select one or several DOM elements and take advantage of the d3 API to work with them in different ways.

For example, imagine that you have this super simple HTML:

<div></div>

Using d3.js you can change the styles of this div element like so:

d3.select('div')
  .style('width', '100px')
  .style('height', '100px')
  .style('background', 'black');

The style function can be used to set or retrieve a style value. Using the style function passing only the name of a CSS property will return the value of that CSS property:

const myDiv = d3.select('div')
  .style('width', '100px')
  .style('height', '100px')
  .style('background', 'black');

const color = myDiv.style('background')
console.log(color); // => black;

If we add two more divs:

<div></div>
<div></div>
<div></div>

You’ll discover that the D3 transformation only applies to the first div element. You can have D3 affect all div elements by using the selectAll function:

d3.selectAll('div')
  .style('width', '100px')
  .style('height', '100px')
  .style('background', 'black');

The result of using the d3.select and d3.selectAll functions is referred to as a selection in D3 and it is a cornerstone concept in working with D3. Selections are DOM elements wrapped in D3 DOM manipulation API, a simplified declarative way to work with the DOM.

We’ve seen how you can use D3’s selection API to select stuff and change its style, but you can do pretty much anything you can do with the actual DOM with less code and in a declarative fashion:

  • Manipulate DOM attributes with the attr function
  • Manipulate DOM classes with the classed function
  • Manipulate DOM properties such as checked, value with the property function
  • Manipulate text or innerHTML content with the text and html functions
  • Handling DOM events with the on functions
  • And more…

You aren’t limited to operating only on existing DOM elements. You can create new ones with the append function:

d3.select('body')
  .append('div')
    .style('width', '100px')
    .style('height', '100px')
    .style('background', 'black');

As you can see from what you’ve learned thus far, you can use D3 to operate on normal HTML elements but the most common type of DOM elements you’ll work with when building visualizations are svg elements so that’s what we’ll focus on from here onwards.

// paint a cookie

Enter Some Data! Creating a Simple Bar Chart

Let’s say that we want to create a simple bar chart to represent some data, like the amount of cookies I’ve eaten this week:

const cookiesEatenThisWeek = [100, 200, 150, 10, 50, 200, 250];

Would look like this:

    d3.append('body').append('svg')
        .append('rect')
        .attr('width', 50)
        .attr('height', 200)
        .style('fill', 'blue');
<svg>
    <rect width="50" height="200" style="fill:blue;"/>
</svg>

// then show binding to the actual data // from imperative to declarative

References and Resources


Jaime González García

Written by Jaime González García , dad, husband, software engineer, ux designer, amateur pixel artist, tinkerer and master of the arcane arts. You can also find him on Twitter jabbering about random stuff.Jaime González García