Let’s Make a Pie Chart with D3.js

Hey, so this post is broken. I moved platforms and some of my old tutorials don’t play nicely with WordPress. I’m working on fixing them, but in the meantime you can view the old version here: https://cagrimmett-jekyll.s3.amazonaws.com/til/2016/08/19/d3-pie-chart.html

Part 1: Let’s Make a Pie Chart with D3.js (this post)

Part 2: Let’s Update a Pie Chart in Realtime with D3.js

Part 3: Smooth Pie Chart Transitions with D3.js

This is part of my ongoing effort to relearn D3.js. This short tutorial applies what I’ve learned about data joins, arcs, and labels. It varies slightly from other examples like Mike Bostock’s Pie Chart block because I’m using D3.js version 4 and the API for arcs and pies is different from version 3, which most tutorials are based on. I figured this out through some trial and error. Always read the documentation!

I’m eventually going to use this pie chart as a base to learn how to update charts in real time based on interactions like button pushes or clicks.

Getting Started

Always include the library:

Make a div to hold the chart:

D3 stands for Data-Driven Documents. So what do we always start with when creating something with D3? Data!

Since I’m eventually going to figure out how to update this chart in real time based on button presses, I’m going to start with some dummy data for three easy-to-press buttons: q, w, and e. As always, I log it to the console for quick debugging:

var data = [{"letter":"q","presses":1},{"letter":"w","presses":5},{"letter":"e","presses":2}]; console.log(data);

We’ll also need some basics like width, height, and radius since we are dealing with a circle here. Make them variables so your code is reusable later:

var width = 300, height = 300, // Think back to 5th grade. Radius is 1/2 of the diameter. What is the limiting factor on the diameter? Width or height, whichever is smaller radius = Math.min(width, height) / 2;

Next we need a color scheme. Be referring to the API, we learn that we should use .scaleOrdinal() for this:

var color = d3.scaleOrdinal() .range(["#2C93E8","#838690","#F56C4E"]);

Setting up the pie and arcs

We need to set up the pie based on our data. According to the documentation, d3.pie() computes the necessary angles based on data to generate a pie or doughnut chart, but does not make shapes directly. We need to use an arc generator for that.

var pie = d3.pie() .value(function(d) { return d.presses; })(data);

Before we create the SVG and join data with shapes, let’s define some arguments for the two arcs we want: The main arc (for the chart) and the arc to hold the labels. We need an inner and outer radius for each. If you change the inner radius to any number greater than 0 on the main arc you’ll get a doughnut.

var arc = d3.arc() .outerRadius(radius - 10) .innerRadius(0); var labelArc = d3.arc() .outerRadius(radius - 40) .innerRadius(radius - 40);

Making the shapes

We always start with an SVG. Select the div we created to hold the chart, append an SVG, give the SVG the attributes defined above, and create a group to hold the arcs. Don’t forget to move the center points, or else the chart will be centered in the upper right corner:

var svg = d3.select("#pie") .append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width/2 + "," + height/2 +")"); // Moving the center point. 1/2 the width and 1/2 the height

Now let’s join the data generated by .pie() with the arcs to generate the necessary groups to hold the upcoming paths. Give them the class “arc”.

var g = svg.selectAll("arc") .data(pie) .enter().append("g") .attr("class", "arc");

Now we can append the paths created by the .arc() functions with the variables we defined above. We’re using the color variable we defined above to get the colors we want for the various arcs:

g.append("path") .attr("d", arc) .style("fill", function(d) { return color(d.data.letter);});

Once you save, you should see a chart. Now we’re cooking with data!

Labels

Let’s put some labels on it now. We’ll need to append some text tags in each arc, set the position with a transform defined by the labelArc variable we defined earlier, then access the correct letter to add to the label. Then we’ll make it white so it shows up a little better:

g.append("text") .attr("transform", function(d) { return "translate(" + labelArc.centroid(d) + ")"; }) .text(function(d) { return d.data.letter;}) .style("fill", "#fff");

There you have it! A basic pie chart. Play around with the variables so you understand better what is going on.