Reputation: 298
I'm looking for a way to generate pie charts using SVG.
The numbers I have are simple enough - just percentages, an array of numbers that obviously add up to 100.
I have a basic understanding of SVG, but I can't think how to translate these numbers into meaningful coordinates to use in the path tag
Can anyone point me to a useful utility or library, or give any hints as to how I could use percentages to draw a pie chart - in JavaScript?
Upvotes: 8
Views: 16886
Reputation: 21318
Credits to https://stackoverflow.com/a/3642265/309483 and http://jbkflex.wordpress.com/2011/07/28/creating-a-svg-pie-chart-html5/ (note that the last one has a bug, fixed here)
function makeSVG(tag, attrs) {
var el= document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]);
return el;
}
function drawArcs(paper, pieData){
var total = pieData.reduce(function (accu, that) { return that + accu; }, 0);
var sectorAngleArr = pieData.map(function (v) { return 360 * v / total; });
var startAngle = 0;
var endAngle = 0;
for (var i=0; i<sectorAngleArr.length; i++){
startAngle = endAngle;
endAngle = startAngle + sectorAngleArr[i];
var x1,x2,y1,y2 ;
x1 = parseInt(Math.round(200 + 195*Math.cos(Math.PI*startAngle/180)));
y1 = parseInt(Math.round(200 + 195*Math.sin(Math.PI*startAngle/180)));
x2 = parseInt(Math.round(200 + 195*Math.cos(Math.PI*endAngle/180)));
y2 = parseInt(Math.round(200 + 195*Math.sin(Math.PI*endAngle/180)));
var d = "M200,200 L" + x1 + "," + y1 + " A195,195 0 " +
((endAngle-startAngle > 180) ? 1 : 0) + ",1 " + x2 + "," + y2 + " z";
//alert(d); // enable to see coords as they are displayed
var c = parseInt(i / sectorAngleArr.length * 360);
var arc = makeSVG("path", {d: d, fill: "hsl(" + c + ", 66%, 50%)"});
paper.appendChild(arc);
arc.onclick = (function (originalData) {
return function(event) {
alert("Associated pie piece data: " + originalData);
}
})(pieData[i]);
}
}
var svgdoc = document.getElementById("s");
drawArcs(svgdoc, [52,15,20,80]); // here is the pie chart data
// You can attach additional content (from e.g. AJAX) like this:
var parser = new DOMParser();
var docToEmbed = parser.parseFromString(
"<svg xmlns='http://www.w3.org/2000/svg'><text x='50' y='50' fill='black'>hi</text></svg>",
"image/svg+xml");
Array.prototype.slice.call(docToEmbed.documentElement.childNodes).forEach(function(elem) {
svgdoc.appendChild(document.importNode(elem, true));
});
#con {
resize:both;
overflow:hidden;
display:inline-block;
width:20em;
height:20em;
padding:0.5em;
}
<div id="con">
<!-- the div container is of course optional. It is used with
{width,height}="100%" below to make the chart resizable. -->
<svg width="100%" height="100%" id="s"
xmlns="http://www.w3.org/2000/svg" viewbox="0 0 400 400">
<style type="text/css">
path:hover {
opacity: 0.8;
}
</style>
</svg>
</div>
Upvotes: 17
Reputation: 168853
Raphael is a very good SVG drawing library -- in particular, it beats the others because in older versions of IE, it automatically falls back to using VML, and therefore it works in IE from version 6 and up, as well as in all other mainstream browsers.
It has a separate graphing library, called gRaphael. This does all the usual graph types (pies, lines, bars, etc), and can animate them too.
If those aren't enough, it's easy enough to use the main Raphael library to roll your own - it's very easy to use.
Upvotes: 3
Reputation: 61046
Here are a few more:
I try to collect links to all svg graphing libraries here.
Upvotes: 7