UPDATE: Translation in Brazilian Portuguese here, thanks Maujor!
OK, so you have an HTML table. Let's turn it into a pie chart with a bit of javascript.
We'll be using the canvas tag, so the browser has to support it. For IE - well, you still have the table. That's why we'll call it progressive enhancement. Unobtrusive too. Here's a screenshot:
» The demo is here (refresh for new colors)
Here are the ingredients to the recipe:
- One
<canvas>
tag - One
<table>
full of data - javascript to get the data from the table
- javascript to plot the data on the canvas
One canvas tag
<canvas id="canvas" width="300" height="300"></canvas>
One table full of data
This is a bare bone unstyled old school table.
<table id="mydata"> <tr> <th>Lang</th><th>Value</th> </tr> <tr><td>JavaScript</td> <td>100</td> </tr> <tr><td> CSS</td> <td>200</td> </tr> <tr><td> HTML</td> <td>300</td> </tr> <tr><td> PHP</td> <td> 50</td> </tr> <tr><td> MySQL</td> <td> 30</td> </tr> <tr><td> Apache</td> <td> 10</td> </tr> <tr><td> Linux</td> <td> 30</td> </tr> </table>
javascript to get the data from the table
First, some setup. Let's tell the script which is the ID of the data table, the ID of the canvas tag and which column contains the data:
// source data table and canvas tag var data_table = document.getElementById('mydata'); var canvas = document.getElementById('canvas'); var td_index = 1; // which TD contains the data
Next, select all table rows, then loop through the rows, selecting all TDs. Add the data we need to a data
array. While at it, run a total
of the data in the column and also create an array of random colors
. Paint each row with the selected color. (we'll see the actual getColor() in a bit.)
var tds, data = [], color, colors = [], value = 0, total = 0; var trs = data_table.getElementsByTagName('tr'); // all TRs for (var i = 0; i < trs.length; i++) { tds = trs[i].getElementsByTagName('td'); // all TDs if (tds.length === 0) continue; // no TDs here, move on // get the value, update total value = parseFloat(tds[td_index].innerHTML); data[data.length] = value; total += value; // random color color = getColor(); colors[colors.length] = color; // save for later trs[i].style.backgroundColor = color; // color this TR }
javascript to plot the data on the canvas
Time for the fun part, the drawing! First, we need to create a context object. Then figure out the raduis of the pie and the center, all based on the width/height pf the canvas tag:
// get canvas context, determine radius and center var ctx = canvas.getContext('2d'); var canvas_size = [canvas.width, canvas.height]; var radius = Math.min(canvas_size[0], canvas_size[1]) / 2; var center = [canvas_size[0]/2, canvas_size[1]/2];
Next, let's loop through data
and paint pieces of the pie. To draw a piece of pie, you basically need to call these methods of the context object:
beginPath()
- to start the piece of the piemoveTo()
- to set the pencil in the centerarc()
- draw a piece of a circlelineTo()
- finish the circle piece with a line back to the centerclosePath()
andfill()
but set the fill color first.
Here's the actual code for this part, hopefully the comments help:
var sofar = 0; // keep track of progress // loop the data[] for (var piece in data) { var thisvalue = data[piece] / total; ctx.beginPath(); ctx.moveTo(center[0], center[1]); // center of the pie ctx.arc( // draw next arc center[0], center[1], radius, Math.PI * (- 0.5 + 2 * sofar), // -0.5 sets set the start to be top Math.PI * (- 0.5 + 2 * (sofar + thisvalue)), false ); ctx.lineTo(center[0], center[1]); // line back to the center ctx.closePath(); ctx.fillStyle = colors[piece]; // color ctx.fill(); sofar += thisvalue; // increment progress tracker }
utility
Here's the function that gives a random color:
// utility - generates random color function getColor() { var rgb = []; for (var i = 0; i < 3; i++) { rgb[i] = Math.round(100 * Math.random() + 155) ; // [155-255] = lighter colors } return 'rgb(' + rgb.join(',') + ')'; }
C'est tout! Enjoy your pie 😀
UPDATE: Comment by Zoltan below, if you use Explorer Canvas, you can make this work in IE with only this:
<!--[if IE]><script type="text/javascript"
src="/path/to/excanvas.js"></script><![endif]-->
Comments? Find me on BlueSky, Mastodon, LinkedIn, Threads, Twitter