Add an interactive chart to your React app using D3 (v6)
Learning d3.js can be a bit daunting. Let’s break the process down, and get you up and running with your first chart in short order.
Follow along with the repl linked above as we use d3 and react to make a simple donut chart capable of rendering multiple data sets. I will break the example down into easy to digest chunks. Note that this example is using react, react-dom, @babel/standalone and d3 (v6).
(script.js lines 1–18) Let’s start with setting up some sample data. While d3 has the ability to load in data from multiple formats like CSV, we’ll start with some hard coded data. Each of the four charts in this example will need an array of objects. Each object in that array will need a name and a value key. These objects will become the arcs in our donut chart. In summary, our “data” object will contain four datasets.
(script.js lines 104–116) Next, let’s take a quick look at our JSX at the bottom of the file. On line 108, we create the div that d3 will insert our chart into, and give it an id of chartContainer. In our CSS file, we have given chartContainer a height and width of 400px, as well as a gray border (so that we can visualize the chart margins). We then add a select element with the four corresponding chart keys from our hard coded data, and an onChange event listener which will call our changeSelection function.
(script.js lines 44–48) Ok, now let’s start working with d3. Inside our createDonutChart function, on line 44, we’ll start by getting the data from our selected dataset. Next, we’ll declare variables for the height, width and margin of our chart. Let’s match the height and width to that of our chartContainer div (400), and set our margin to taste.
(script.js lines 50–56) Now we will declare a variable named svg, which will represent an actual <svg></svg> element appended to our chartCointainer div. If you are unfamiliar with svg, g, and path elements, you can quickly brush up with these articles: https://www.w3schools.com/html/html5_svg.asp https://developer.mozilla.org/en-US/docs/Web/SVG/Element/g https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path
Let’s work through each of the subsequent lines of method chaining:
50: We use d3.select() to select our chartContainer div
51: We append an svg element to our chartContainer div
52/53: We set width and height attributes of said svg, using our width and height variables
54: We give said svg an id attribute of “donutChart” (this will come in handy later on)
Lastly for this section, we will define the size of our radius on line 56. The Math.min(width, height) would be beneficial in the event that our dimensions are rectangular.
(script.js lines 58–62) Our g variable represents a group element appended to our svg element. This group element will eventually contain child group elements, which will then become the arcs that we see in our donut chart. Our g variable also centers our chart within the svg element. Next we’ll set up a simple color palette. While there are a large variety of color palettes that can be loaded into d3, for simplicity’s sake, we’ll hard code a simple array of four colors on line 62.
(script.js lines 64–68) The pie variable will be used to extract the values from our data set and bind them with additional data required for the donut chart rendering process, (properties of startAngle and endAngle). On line 68, our path variable will determine the thickness of our arcs. An innerRadius of 0 would render a traditional pie chart. Feel free to experiment with this value!
(script.js lines 70–80) The label variable will determine how far our text labels are positioned from the center of the chart. If you change the thickness of your arcs, or switch to a traditional pie chart, you can adjust the inner and or outer radius within the label variable to ensure that your text labels are nicely positioned. Next, our pies variable will represent newly appended group elements, within our previously declared group element. In this case, pies will represent four child group elements, one for each object within our dataset. The pies variable will also iteratively bind the data from our dataset to each group element. These four group elements will become the arcs we see on our chart.
(script.js lines 82–85) Now we will append a path element to each of the four group elements we just made. On line 85, we add color to each of the four group elements. The first parameter “d”, contains the information that is bound to each of our four group elements, including the data from our dataset, as well as startAngle, endAngle etc. The second parameter “i”, will be the index of the object from our dataset that each group element is bound to. This function will set the first object in our dataset, to the first color in our colors array, the second object in our dataset, to the second color in our colors array and so on. It is at this point we will finally be able to see a graph on our screen.
(script.js lines 87–94) Now that we can see our arcs, let’s add text labels to them so that we know what we’re looking at! You can easily adjust the font size of the labels on line 93. Line 94 will extract the name value from each object in our dataset and give it to .text().
(script.js lines 96–101) Finally, let’s add a nice text label in the center of our chart so that we can easily see which dataset we are viewing. Note: unlike the arc labels that were appended to each child group element, this center label is appended to our parent group element.
Now that we have our createDonutChart function completed, let’s quickly summarize the progression of our component before we finish with the changeSelection function.
Our state.selection has been initialized with “Ice Cream”, and our componentDidMount calls our createDonutChart function. createDonutChart uses state.selection to know which dataset it should use, so once our react component mounts, the “Ice Cream” chart will automatically render. But what about selecting a different chart?
(script.js lines 34–40) When we select a new chart with our select box, our changeSelection function will fire. Remember line 54, when we gave our appended svg an id? On line 36, we will use that id to remove our chart entirely. We must remove our current chart before we render a new one, otherwise the new chart would render below the current one. After we remove the current chart, we can set state.selection the select value from the event object. All that’s left to do now is call our createDonutChart function again.
That’s all for this simple little chart! Spend some time playing around with the code and becoming familiar with it. Before you know it, you’ll be making bar charts, line charts and beyond.