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.
Top comments (0)