Prerequisites: Moderate experience with React and D3.
Why might we want to use both libraries together? Each library has particular strengths which the other doesn’t provide. React has a simple component-based approach to building user interfaces and manipulating the DOM (D3 isn’t really geared towards building UI components) while D3 offers a multitude of data transformation and visualisation functions (React isn’t really geared towards data visualisation).
We’ll look at 3 different approaches to integrating D3 and React by creating a simple bubble chart:
Our 3 approaches are:
- D3 manages the chart (D3-oriented approach)
- React manages the chart while D3 is used as a ‘utility’ library (React-oriented approach)
- React handles element creation/removal while D3 manages style and attributes (hybrid approach)
D3-oriented approach: D3 manages the chart
This is one of the most common approaches to integrating React and D3. In short we:
- create a container element in React for the bubble chart
- add D3 code for creating and updating the bubble chart
- call our D3 code on initial load (
componentDidMount) and updates (
Let’s start by creating our React component and add an SVG element that’ll act as our chart container:
We’ll store our data on the component’s state object and initialise it using
getData() (which is a function that returns a randomised array of data).
Note we’ve used React’s ref feature to allow us to reference the SVG element later on.
We’ll now add a function that manages the chart using D3:
For those experienced with D3 this code should be fairly familiar as it uses the general update pattern.
A key point of contact between React and D3 is the line:
which selects the SVG element.
Our final step is to call
updateChart() when the component is created and updated:
Now any time the state changes,
updateChart() is called and the chart updates.
One of the key benefits of managing the chart using D3 is that we can easily add transitions to the updates:
Here’s the finished code:
React-oriented approach: React manages the chart
We’ll now look at an approach where React is responsible for creating and updating the chart, using D3 for ancillary functions such as
This is the simplest of all the approaches as our chart code can be expressed largely in JSX:
This is probably the most straightforward way of intergrating React and D3, especially if we already have a React application as we can continue working within the React paradigm.
One thing to watch out for are transitions. Whereas in D3 transitions are very easy to add, React doesn’t have transitions built in so a transition plug-in will be required and there’s quite a few of them in existence.
See the finished code on Codepen:
Hybrid approach: React for element creation, D3 for updates
The hybrid approach plays to each library’s strengths: React for specifying the DOM structure, and D3 for updating style (e.g. colour) and attributes (e.g. shape and position) meaning that we can harness D3’s transitions. (If we weren’t bothered about transitions this approach probably isn’t necessary.)
render() function now looks like:
Note that all
render() does is add the circles to the DOM - it isn’t responsible for updating any of the circles’ style or attributes.
The responsibility for updating style and attributes is instead taken by D3. We’ll add a function that makes a selection of the circles, joins the data (
this.state.data) and updates style and attributes:
Here we’ll using D3 just to update style and attributes. (We don’t need to use D3’s
exit() functions because React is taking care of adding and removing elements.)
Finally we’ll call
updateStyleAndAttrs() on component creation and update:
See the finished code on Codepen:
See the Pen React+D3 (D3 updates style and attrs w/transition) by Frontend Charts (@frontendcharts) on CodePen.
We’ve shown 3 approaches to integrating React and D3. The pros and cons of each approach can be quite subtle.
The React-oriented approach is on the surface the most attractive as it leaves the complex job of managing the DOM to React. (This is especially attractive when there’s a lot of element nesting, which is nearly always the case!) However, out-of-the-box React doesn’t support transitions so if we wanted transitions we’d have to use a plug-in such as React Move.
The D3-oriented approach is a common approach as it results in a clean break between the D3 and React code. It’s also an attractive approach if wanting to integrate existing D3 code into a React application.
The hybrid approach seems to be a less explored option, nonetheless it looks a compelling one. Using React to add/remove elements sidesteps D3’s enter/exit paradigm while using D3 to update attributes and style allows us to use D3’s powerful and efficient transitions.
Ultimately the choice of approach depends on the particular use case. Some of the questions you should ask are:
- do you have an existing application build with React?
- how important are transitionsin your application?
- do you already have a visualisation built with D3?
- how experienced with React/D3 are your developers?
I’m frequently working with both React and D3 so do get in touch if you’d like a hand with either!