Creating a simple pie chart with HTML5 Canvas Part 2

Last week we created a pie chart using HTML5’s Canvas element. This week we will utilize jQuery to add some simple functionality.  For this exercise, we want to be able to visualize the exact values of each slice of the pie when the user positions the mouse over them. To do this, we will use the .mousemove event from jQuery to update text on the page.

The first step is to include jQuery.



Next, we will need to refactor the script from last week a bit in order to reference it from the mousemove event. To do this, we will create an array to store the data for each slice.

var pieData = [];

for(var i in data) {

pieData[i] = [];

pieData[i]['value'] = data[i];

pieData[i]['startAngle'] = 2 * Math.PI * lastPosition;

pieData[i]['endAngle'] = 2 * Math.PI * (lastPosition + (data[i]/total));

lastPosition += data[i]/total;

}

Now that the data is stored a bit differently than last week, we will need to update the script that renders the pie chart. Specifically, we will change the ctx.arc call to reference the data we just stored in the pieData array.

for(var i = 0; i < data.length; i++)

{

ctx.beginPath();

ctx.moveTo(center[0],center[1]);

ctx.arc(center[0],center[1],radius,pieData[i]['startAngle'],pieData[i]['endAngle'],false);

ctx.lineTo(center[0],center[1]);

ctx.closePath();

ctx.fillStyle = colors[i];

ctx.fill();

}

Next we will add some text to the page that will be used to display the value of the pie chart that the user is currently hovering over with the mouse.



Hover over a slice



Now that we have a placeholder for the text, we can add the mousemove event that will first evaluate whether the user is within the radius of the chart and then do a bit of math to determine which slice the mouse is over.

$("#canvas").mousemove(function(e) {

var x = Math.floor((e.pageX-$("#canvas").offset().left));

var y = Math.floor((e.pageY-$("#canvas").offset().top));

var fromCenterX = x - center[0];

var fromCenterY = y - center[1];

var fromCenter = Math.sqrt(Math.pow(Math.abs(fromCenterX), 2) + Math.pow(Math.abs(fromCenterY), 2 ));

if (fromCenter <= radius) {

var angle = Math.atan2(fromCenterY, fromCenterX);

if (angle < 0) angle = 2 * Math.PI + angle; // normalize

for (var slice in pieData) {

if (angle >= pieData[slice]['startAngle'] && angle <= pieData[slice]['endAngle']) {

$("div.sliceValue").text("The value for the slice is " + pieData[slice]['value']);

return;

}

}

}

});

If all went well, you should now have a working demo. If not, you can view the source of the working demo linked below.

[http://yojimbocorp.com/demos/pieChart2.html](http://yojimbocorp.com/demos/pieChart2.html)