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...
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();
The algorithm for making a simple pie chart is something like this...
-
Get the data that is being represented by the chart (it must be numerical)
-
Calculate the total by adding all of the data together.
-
Calculate the amount of pie for each piece of data by dividing it by the total.
-
Multiply 2*pi radians by the amount of pie to get the length of the arc for that piece of pie.
-
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.
-
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
Thank you for your easy-to-follow code sample on using the new canvas element.
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?
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
Great! example
Thanks for share.
Great work ! But it seems not supported on ie 10 or 11 or any version. How can get support on ie 11
Oh yes ! Supporting ie versions. Many thanks.
Well written and displayed nicely. Thank you!!!
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?