Last week we made a pie chart with D3.js. Today we are going to update it in realtime when buttons are clicked.

Here is the basic pie chart again, slightly modified from the original (I only changed the letters):

The key to making this work is D3’s object constancy. We already baked that into the original design by specifying a key function for the underlying presses count data.

Setting Up

First, we need to copy the pie chart we made last week. Make a few updates: change all the presses in data to 1 and change the letters to A, B, and C.

Next, we need something to click so we can increment the count and update the chart. Three buttons will do nicely:

<div class="buttons" style="width: 300px; text-align: center;">
	<button id="a" style="width:50px;">A</button>
	<button id="b" style="width:50px;">B</button>
	<button id="c" style="width:50px;">C</button>
</div>

Recomputing the angles

We ultimately want to call a specific update function when we click each button, so let’s write one. We need to consider what the most critical parts of making the original pie chart were so that we can recreate only the necessary steps:

  • Defining the value function for d3.pie
  • Computing the angles based on that data
  • Putting that information in a path so it can be displayed

Remember that we have two arcs: The main pie and the one holding the labels. We need to update both!

function change() {
	var pie = d3.pie()
		.value(function(d) { return d.presses; })(data);
	path = d3.select("#pie").selectAll("path").data(pie); // Compute the new angles
	path.attr("d", arc); // redrawing the path
	d3.selectAll("text").data(pie).attr("transform", function(d) { return "translate(" + labelArc.centroid(d) + ")"; }); // recomputing the centroid and translating the text accordingly.
}

Updating the data and chart on click

Now we need to update the underlying data and the whole chart on click:

d3.select("button#a")
	.on("click", function() {
		data[0].presses++;
		change();
	})
d3.select("button#b")
	.on("click", function() {
		data[1].presses++;
		change();
	})
d3.select("button#c")
	.on("click", function() {
		data[2].presses++;
		change();
	})

Here is the result. Click the buttons and watch the chart change!


Up next: Smooth transitions with d3.interpolate.

View more TIL posts
See more of my D3.js work