Dynamic and Interactive Content
Thus far we've looked at building static content, but the backbone of D3.js are it's beautiful transitions and dynamic updating capabilities.
Intervals
We need some way of repeatedly running code to change something the chart reacts to. The easiest way to do this in d3 is using an interval.
const myInterval = d3.interval(() -> {
// code to loop
}, 500) //runs every 500ms
clearInterval(myInterval) // stop loop
The D3 Update Pattern
Let's debug the following code to observe how D3 objects work:
// Joining data to create d3 virtual selectors
const rects = g.selectAll("rect")
.data(data)
console.log(rects)
// Remove Old Elements
rects.exit().remove();
// Entering new elements onto the page
rects.enter().append("rect")
.attr("y", d => y(d.revenue))
.attr("x", (d) => x(d.month))
.attr("width", x.bandwidth)
.attr("height", d => HEIGHT - y(d.revenue))
.attr("fill", "grey")
// Update as needed
rects.attr("fill", "blue")
console.log(rects)
We now have an object with _enter, _exit, _groups and _parents. _enter contains elements in our data array that don't exist on the page (the shapes that need to be 'entered' on the screen). _exit is elements that are on the page but not in our data array (elements to be removed from the screen). _groups represents all elements that exist on the screen.
We always want to use the same update pattern when our data changes:
- Data Join - select all matching elements on the screen with selectAll() and update the data we're using
- Exit - Use the exit() selector to remove the elements that don't exist in our new array of data
- Update - set attributes for existing elements on screen
- Enter - use the enter() selector to set attributes for new items in our data array