From circle to pie chart, with JavaScript and Canvas

Browsers market share in pie chart

Example of pie chart in Canvas

To draw a circle in Canvas we manipulate arcs and PI parts, then drawing a pie and pieces is the next step.

To draw a simple circle, we use the canvas arc method with a 2 * PI length.

<script>
function circle()
{
var canvas = document.getElementById("canvas1");
var context = canvas.getContext("2d");
context.beginPath();
context.lineWidth="2";
context.arc(100, 100, 90, 0, 2 * Math.PI);
context.stroke();
}
circle();
</script>


The canvas has a size of 200 x 200 pixels. The center of the circle is at x = 100, y = 100, given by x and y arguments of the function arc.

The radius of 90 pixels is the third argument. The third and fourth arguments give the starting angle, 0 and the final angle, twice PI.

We can ignore the argument about the direction of rotation that is superfluous here.

The circle may be filled with the fill method

We add a fill statement to the previous code, but we must also assign the attribute fillStyle to set the color .
Then the stroke() statement may be removed if we do not want to draw a border.

function fillCircle()
{
  var canvas = document.getElementById("canvas2");
  var context = canvas.getContext("2d");
  context.beginPath();
  context.fillStyle="#FF4422"
  context.arc(80, 80, 70, 0, 2 * Math.PI);
  context.fill();
}

fillCircle(); 

To imitate the fillRect method, we define a fillCircle function.

Creating a pie chart

To create a chart consisting of circular sectors or "pie chart ", we creating these sectors with the arc, lineTo and fill methods.

  1. To distribute the value on the chart, we first calculate the sum of the values. Each arc is proportional to a statistical value as a percentage of PI * 2, which is the circumference of the circle.
  2. Each arc is delimited by a first position that is the end of the previous arc, to a new position which corresponds to 2 * PI * value / total.
    The pie is made by these arcs, we do not draw a circle at start.
  3. We must add a correction if we want the first sector on top, then we deduce PI / 2 which corresponds to a quarter of the circumference.
  4. A line is drawn following radius from the center to the latter position. As the arc it is actually invisible on the chart because it has the same color as the sector.
    In fact, as we have just drawn the arc, a moveTo function is useless, we just continue the line from the circumference to the center of the circle with lineTo.
  5. The sector is filled of the color assigned to it, with the fill method. We choose the colors in an indexed list.

Example:

Source code

function pie(ctx, w, h, datalist)
{
var radius = h / 2 - 5;
var centerx = w / 2;
var centery = h / 2;
var total = 0;
for(x=0; x < datalist.length; x++) { total += datalist[x]; };
var lastend=0;
var offset = Math.PI / 2;
for(x=0; x < datalist.length; x++)
{
var thispart = datalist[x];
ctx.beginPath();
ctx.fillStyle = colist[x];
ctx.moveTo(centerx,centery);
var arcsector = Math.PI * (2 * thispart / total);
ctx.arc(centerx, centery, radius, lastend - offset, lastend + arcsector - offset, false);
ctx.lineTo(centerx, centery);
ctx.fill();
ctx.closePath();
lastend += arcsector;
}
}
var datalist= new Array(35, 25, 20, 12, 7, 1);
var colist = new Array('blue', 'red', 'green', 'orange', 'gray', 'yellow');
var canvas = document.getElementById("canvas3");
var ctx = canvas.getContext('2d');
pie(ctx, canvas.width, canvas.height, datalist);

Values ​​are stored in the datalist array and colors in colist. The two array are scanned together in the function pie() to create successive sectors according to the successive values ​​and colors. Note: Do not use the function for (x in array), it does not work.

It is possible to flatten the graph to create a 3D effect, with the scale function, see the article on ellipse.

The code has been tested with all browsers supporting Canvas.

See also