D3.js
Tags: javascript
Published: 2021-01-11 13:18:59

Data-Driven Documents, or D3, is a JavaScript library for producing dynamic, interactive data visualizations in web browsers. D3 uses HTML, SVG, and CSS to accomplish this. D3 is built on the concept using functions to select elements, create SVG objects, style them, and add transitions, dynamic effects or tooltips to them. Large datasets can be bound to SVG objects using D3.js functions to generate text/graphic charts and diagrams. 

##Main Features

####Selections
D3 has two simple functions to select the DOM elements you need: `selectAll` and `select`. Selections methods will accept strings as arguments such as `div` for div elements, `.container` for elements with the class name of “container,” or `#submit` for elements with the id of “submit.”  `selectAll` will return all matches of the specified element, while `select` will only return the first element of the document. For example, to change all paragraph elements to have a red font, use:
```
d3.selectAll(‘p’).style(‘color’, ‘red’);
```
To select only the first paragraph tag and turn it red, use:
```
d3.select(‘p’).style(‘color’, ‘red’);
```
Selections can also be chained to select descendants of elements. For example, to return the first bold element of a paragraph: 
```
d3.select(‘p’).select(‘b’);
```

####Dynamic Properties
Unlike with other DOM frameworks like jQuery, D3 treats things like styles, attributes and other similar properties as functions of data rather than simple constants. For example, to randomly color paragraphs:
```
d3.selectAll(‘p’).style(‘color’, function() {
  return ‘hsl(‘ + Math.random() * 360 + ‘,100%,50%)’;
});
```
Or, alternate colors for even or odd divs:
```
d3.selectAll(‘div’).style(‘background-color’, function(d, i) {
  return i % 2 === 0 ‘#fff’ : ‘#eee’;
});
```
These callback functions often refer to our bound data. We can specify this data as an array with each value passed as the argument `d` to selection functions. The data is then matched to the correct node by matching the index. First node with the first data point, second node with the second data point, and so on. For example, given an array of numbers, we could use these numbers as font size for our paragraphs like so:
```
const fontSizes = [4, 8, 15, 16, 23, 42];
d3.selectAll(‘p’)
  .data(fontSizes)
    .style(‘font-size’, (d) => `${d}px`);
```

####Enter and Exit
Earlier we said that data and nodes match up according to index. But what if there’s more elements of one than the other? The `enter` and `exit` functions handle this for us. Using the previous example, there were 6 numbers in the `fontSizes` array. If only 5 paragraph nodes exist, the last number 42 has nowhere to go. Using `enter` will create a new node which will use the extra data. 
```
d3.selectAll(‘p’)
  .data(fontSizes)
    .enter().append(‘p’)
      .style(‘font-size’, (d) => `${d}px`);
```
`exit` has the opposite effect. It removes unnecessary nodes for which there is no data.

####Transitions
Transitions gradually incorporate styles and attributes over time. For example, to fade the background of the page to black:
```
d3.select(‘body’).transition().
  .style(‘background-color’, ‘black’);
```
Or, to resize circles in a symbol map with a staggered delay:
```
d3.selectAll(‘circle’).transition()
  .duration(750)
  .delay((d, i) => i * 10;
  .attr(‘r’, (d) =>  Math.sqrt(d * scale)});
```
By modifying the attributes that actually change, D3 reduces overhead and allows greater graphical complexity at high frame rates.

##Conclusion
These are just a few of the most used features of D3.js. Others include **timers** for managing when and for how long each animation will take place, **shapes** for creating unique elements used in charts and graphs, and **zoom** for panning and zooming using a mouse or touchpad. You can see plenty of amazing examples using all kinds of techniques [here](https://observablehq.com/@d3/gallery).