Graphing Data in the HTML5 Canvas Element Part IV Simple Pie Charts

In this post we will create a simple pie chart that is easy to feed data to.

This example is coded for readability and not for optimized operation. All you need is a text editor like notepad and an HTML5 friendly browser (I’m using Firefox 3.6).


<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Canvas Test</title>
</head>
<body>
<section>
<div>
<canvas id="canvas" width="400" height="300">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
</div>

<script type="text/javascript">

var myColor = ["#ECD078","#D95B43","#C02942","#542437","#53777A"];
var myData = [10,30,20,60,40];

function getTotal(){
var myTotal = 0;
for (var j = 0; j < myData.length; j++) {
myTotal += (typeof myData[j] == 'number') ? myData[j] : 0;
}
return myTotal;
}

function plotData() {
var canvas;
var ctx;
var lastend = 0;
var myTotal = getTotal();

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);

for (var i = 0; i < myData.length; i++) {
ctx.fillStyle = myColor[i];
ctx.beginPath();
ctx.moveTo(200,150);
ctx.arc(200,150,150,lastend,lastend+
  (Math.PI*2*(myData[i]/myTotal)),false);
ctx.lineTo(200,150);
ctx.fill();
lastend += Math.PI*2*(myData[i]/myTotal);
}
}

plotData();

</script>
</section>
</body>
</html>

You can copy this code and paste it into a new file called something like simplepie.html and when you open it with an HTML5 friendly browser like Firefox 3.6 it will display the pie chart.

Here is our canvas in action...


This text is displayed if your browser does not support HTML5 Canvas.


The algorithm for making a simple pie chart is something like this...

  1. Get the data that is being represented by the chart (it must be numerical)
  2. Calculate the total by adding all of the data together.
  3. Calculate the amount of pie for each piece of data by dividing it by the total.
  4. Multiply 2*pi radians by the amount of pie to get the length of the arc for that piece of pie.
  5. Draw the resulting arcs at a distance of r (the radius) from the center starting each arc at either 0 (the first arc) or from the end of the last drawn arc.
  6. Each arc has a line from its beginning and its ending to the center of the circle that is of length r

Since the arc() method of the 2d canvas context is based on paths, this is real easy to code.

arc(x, y, radius, startAngle, endAngle, anticlockwise)

This method takes five parameters: x and y are the coordinates of the circle's center. Radius is self explanatory. The startAngle and endAngle parameters define the start and end points of the arc in radians. The starting and closing angle are measured from the x axis. The anticlockwise parameter is a Boolean value which when true draws the arc anticlockwise, otherwise in a clockwise direction.
Note: Angles in the arc function are measured in radians, not degrees. To convert degrees to radians you can use the following JavaScript expression: var radians = (Math.PI/180)*degrees.
https://developer.mozilla.org/en/Canvas_tutorial/Drawing_shapes#Arcs

Step 1 of the algorithm is accomplished by this loop in our plotData() function

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

Where myData[i] represents the data from the hard coded global variable

var myData = [10,30,20,60,40];

This could easily be from a database, table data or from input textboxes filled in by the visitor.

Step 2 of the algorithm is accomplished by our getTotal() function which loops through our data and adds it all together returning our total. It also verifies that our data is numeric giving it a value of zero if it is not.

function getTotal(){
  var myTotal = 0;  
  for (var j = 0; j < myData.length; j++) {
    myTotal += (typeof myData[j] == 'number') ? myData[j] : 0;
  }
  return myTotal;
}      

Step 3 of the algorithm is accomplished by the highlighted part of this line in our plotData() function.

ctx.arc(200,150,150,lastend,lastend+
       (Math.PI*2*(myData[i]/myTotal)),false);

Step 4 of the algorithm is accomplished by the highlighted part of this line in our plotData() function.

ctx.arc(200,150,150,lastend,lastend+
       (Math.PI*2*(myData[i]/myTotal)),false);

Step 5 of the algorithm is accomplished in our plotData() function by using the variable lastend to start at 0 radians and then keep track of where the previous arc ended.

lastend += Math.PI*2*(myData[i]/myTotal);

Step 6 of the algorithm is accomplished in our plotData() function by starting our path at the center of the circle

    ctx.beginPath();
    ctx.moveTo(200,150);

then we draw our arc which extends our path from the center to the start of our arc

    ctx.arc(200,150,150,lastend,lastend+
       (Math.PI*2*(myData[i]/myTotal)),false);

then we extend our path back to the center of our circle and fill in the shape (our pie slice)

    ctx.lineTo(200,150);
    ctx.fill(); 

Since we use an array of color values to make sure that all the pie slices are easy to see,

    var myColor = ["#ECD078","#D95B43","#C02942","#542437","#53777A"]; 

we can create a legend saying what each color represents.

10
30
20
60
40

In our next post, we'll look at making our pie fancy with labels and maybe a few animations.

This is post 4 of a multipart series of posts.

Graphing Data in the HTML5 Canvas Element Part I

Graphing Data in the HTML5 Canvas Element Part II

Graphing Data in the HTML5 Canvas Element Part III

9 Replies to “Graphing Data in the HTML5 Canvas Element Part IV Simple Pie Charts”

  1. Thank you for the very simple code and detailed explanation – quite helpful!

    There is this note at the bottom of the post :
    “In our next post, we’ll look at making our pie fancy with labels and maybe a few animations.”
    Do you have a link to this other article?

  2. Hello
    Nice Article , i really appreciate
    i just have 2 questions ,
    Is it available to fill with images instead of colors?
    Is it available to have hover action on every part of the 5 parts you draw and to change the content on hover on it

  3. Is it available to have hover action on every part of the 5 parts you draw and to change the content on hover on it. Like show the percentage?

Leave a Reply to Nicole Cancel reply

Your email address will not be published. Required fields are marked *