Subscribe via RSS Feed

Pie Chart using HTML5 canvas

August 17, 2013 0 Comments

In current post, we will see how to create pie chart using html5 canvas.

What is pie chart?

A pie chart (or a circle graph) is a circular chart divided into sectors, illustrating numerical proportion. In a pie chart, the arc length of each sector (and consequently its central angle and area), is proportional to the quantity it represents.

To build this we will use javascript with html5 canvas.

In the body section just create a canvas element with hight, width & style mentioning.

<canvas id="myCanvas" width="600" height="300" style="border:1px solid black;">
</canvas> 

Lets discuss the JavaScript functions.

window.onload = function(){ 
    var data = [{
        label: "Sci-Fi", 
        value: 4, 
        color: "red"
     }, 
     { 
        label: "Drama", 
        value: 2, 
        color: "blue"
     }, { 
        label: "Comedy", 
        value: 5, 
        color: "green"
     }, { 
        label: "Romance", 
        value: 4, 
        color: "yellow"
     }, { 
        label: "Action", 
        value: 6, 
        color: "violet"
     }
];

This function will be called when the web page is loading. Where the lables, its colour & its corresponding values are initiated.

Next is the piechart constructor -


function PieChart(canvasId, data){ 
	// user defined properties
 	this.canvas = document.getElementById(canvasId); 
 	this.data = data;
	// constants
 	this.padding = 10; 
 	this.legendBorder = 2; 
 	this.pieBorder = 5; 
 	this.colorLabelSize = 20; 
 	this.borderColor = "#555"; 
 	this.shadowColor = "#777"; 
 	this.shadowBlur = 10;
 	this.shadowX = 2;
 	this.shadowY = 2; 
 	this.font = "16pt Calibri";
	// relationships
	this.context = this.canvas.getContext("2d"); 
	this.legendWidth = this.getLegendWidth(); 
	this.legendX = this.canvas.width - this.legendWidth; 
	this.legendY = this.padding; 
	this.pieAreaWidth = (this.canvas.width - this.legendWidth); 
	this.pieAreaHeight = this.canvas.height; 
	this.pieX = this.pieAreaWidth / 2; 
	this.pieY = this.pieAreaHeight / 2; 
	this.pieRadius = (Math.min(this.pieAreaWidth, this.pieAreaHeight) / 2) - (this.padding);
	// draw pie chart
	this.drawPieBorder();
	this.drawSlices();
	this.drawLegend();
}

In the constructor class of piechart which draws the pie chart.

Next is getLegendWidth() where the width of legend is set by taking into account the text length of the longest label.

 
PieChart.prototype.getLegendWidth = function(){
    this.context.font = this.font;
    var labelWidth = 0;
    for (var n = 0; n <this.data.length; n++) {
        var label = this.data[n].label;
        labelWidth = Math.max(labelWidth, this.context.measureText(label).width);
    }
    return labelWidth + (this.padding * 2) + this.legendBorder + this.colorLabelSize; 
};

Define the drawPieBorder() method which draws a border around the pie chart,

PieChart.prototype.drawPieBorder = function(){ 
    var context = this.context; 
    context.save(); 
    context.fillStyle = "white"; 
    context.shadowColor = this.shadowColor; 
    context.shadowBlur = this.shadowBlur; 
    context.shadowOffsetX = this.shadowX; 
    context.shadowOffsetY = this.shadowY; 
    context.beginPath(); 
    context.arc(this.pieX, this.pieY, this.pieRadius + this.pieBorder, 0, Math.PI * 2, false); 
    context.fill();
    context.closePath(); 
    context.restore();
};

Define the drawPieBorder() method which draws a border around the pie chart,

PieChart.prototype.drawPieBorder = function(){ 
    var context = this.context; 
    context.save(); 
    context.fillStyle = "white"; 
    context.shadowColor = this.shadowColor; 
    context.shadowBlur = this.shadowBlur; 
    context.shadowOffsetX = this.shadowX; 
    context.shadowOffsetY = this.shadowY; 
    context.beginPath(); 
    context.arc(this.pieX, this.pieY, this.pieRadius + this.pieBorder, 0, Math.PI * 2, false); 
    context.fill();
    context.closePath(); 
    context.restore();
};

Define the drawSlices() method which loops over the data and draws a slice of the pie for each data element,

 
PieChart.prototype.drawSlices = function(){ 
    var context = this.context; context.save(); 
    var total = this.getTotalValue();
    var startAngle = 0; 
    for (var n = 0; n < this.data.length; n++) {
        var slice = this.data[n];
        // draw slice
        var sliceAngle = 2 * Math.PI * slice.value / total; 
        var endAngle = startAngle + sliceAngle;
        context.beginPath(); 
        context.moveTo(this.pieX, this.pieY); 
        context.arc(this.pieX, this.pieY, this.pieRadius,startAngle, endAngle, false); 
        context.fillStyle = slice.color;
        context.fill(); 
        context.closePath(); 
        startAngle = endAngle;
   } 
   context.restore();
};

Define the getTotalValue() method which is used to get the sum of the data values -

PieChart.prototype.getTotalValue = function(){ 
    var data = this.data; 
    var total = 0;
    for (var n = 0; n < data.length; n++) 
        { 
            total += data[n].value;    //gets the total value of the labels by looping through the data and adding                                        //up each value
        } 
    return total;
};

Here the total value of labels have been calculated by looping through the data.

Next is drawLegend(), for drawing the legends of pie chart.

 
PieChart.prototype.drawLegend = function(){ 
    var context = this.context; 
    context.save(); 
    var labelX = this.legendX;
    var labelY = this.legendY;
    context.strokeStyle = "black"; 
    context.lineWidth = this.legendBorder; 
    context.font = this.font; 
    context.textBaseline = "middle";

    for (var n = 0; n < this.data.length; n++) { 
        var slice = this.data[n];
        // draw legend label
        context.beginPath(); 
        context.rect(labelX, labelY, this.colorLabelSize, this.colorLabelSize); 
        context.closePath();
        context.fillStyle = slice.color; 
        context.fill(); 
        context.stroke();
        context.fillStyle = "black";
        context.fillText(slice.label,labelX + this.colorLabelSize + this.padding,labelY + this.colorLabelSize / 2);
        labelY += this.colorLabelSize + this.padding; context.restore();
   }
};

So, in short we have created a canvas element in the body section.

With window.onload function we have initiated some values of pie-chart.

Also, we have created class to draw the the legends, the pie-chart borders, the slices.

A default constructor is used, in which we have called other javascript functions to draw the pie chart.

 Pie Chart

Before diving into how the code works, let’s first take a step back and think about what a PieChart object should do. As a developer, we would need to pass in the canvas ID so the object knows where to draw, and also an array of data elements so it knows what to draw.

The PieChart element is rendered with the drawSlices() and drawPieBorder() methods. The drawSlices() method performs these steps:

1. Loops through the data elements.

2. Calculates the angle of each data value by multiplying 2π by the value fraction of the total value.

3. Draws an arc using the arc() method for each slice.

4. Fills each slice with the data element color.

Once the pie chart is rendered, we can draw the legend with the drawLegend() method.

This method performs these steps:

1. Loops through the data elements.

2. Draws a box using rect() for each element.

3. Strokes and fills each box with the data element color using stroke() and fill().

4. Writes the corresponding label using fillText() for each element.

Once the page loads, we can create an array of data elements that identify our daily activities

with the corresponding number of hours for each activity and then instantiate a new PieChart

object by passing in the data array.

If you find this article helpful, you can connect us in Google+ and Twitter.

Enter your email address:

Delivered by FeedBurner

Sign Up to read the rest of the content

Email will be used only for updates of our site

No Thanks

Filed in: HTML5, Open Source Technologies • Tags: ,