code everywhere
technology, web services and applications

easy SVG donut charts

posted on March 1, 2015, 12:00 am in

the code

var donutChart = function(options) {
    
    var 
backgroundColor options['backgroundColor'] || "#fff";
    var 
lineWidth options['lineWidth'] || .40;
    var 
values options['values'] || [0,1];
    var 
colors options['colors'];
    var 
size options['circleSize'];

    var 
svgns "http://www.w3.org/2000/svg";
    var 
chart document.createElementNS(svgns"svg:svg");
    
chart.setAttribute("width"size);
    
chart.setAttribute("height"size);
    
chart.setAttribute("viewBox""0 0 " size " " size);

    
//calculate sum
    
var sum 0;
    for( var 
x=0x<values.lengthx++) sum += values[x];
    
    
//calculate percentages
    
var slices = [];
    for( var 
x=0x<values.lengthx++) {
        
slices.push({
            
name     'x',
            
value     values[x],
            
color     colors[x],
            
perc     values[x]/sum 100,
            
draw     : -1
        
});
    }
    
    
//create array to draw
    
sum 0;
    for( var 
x=slices.length-1x>=0x--) {
        for( var 
y=0y<=xy++)
            
sum += slices[y].perc;
       
slices[x].draw sum;       
       
sum 0;
    }

    
//fix 100+ problem
    
slices[slices.length-1].draw 100;

    for( var 
x=slices.length-1x>=0x--) {
        var 
percentage slices[x].draw;
        var 
color slices[x].color;
                
        var 
path document.createElementNS(svgns"path");
        var 
unit = (Math.PI 2) / 100;
        var 
startangle 0;
        var 
endangle percentage unit 0.001;
        var 
x1 = (size 2) + (size 2) * Math.sin(startangle);
        var 
y1 = (size 2) - (size 2) * Math.cos(startangle);
        var 
x2 = (size 2) + (size 2) * Math.sin(endangle);
        var 
y2 = (size 2) - (size 2) * Math.cos(endangle);
        var 
big 0;
        if(
endangle startangle Math.PIbig 1;

        var 
"M " + (size 2) + "," + (size 2) +  // Start at circle center
            
" L " x1 "," y1 +                     // Draw line to (x1,y1)
            
" A " + (size 2) + "," + (size 2) +     // Draw an arc of radius r
            
" 0 " big " 1 " +                       // Arc details...
            
x2 "," y2 +                             // Arc goes to to (x2,y2)
            
" Z";                                       // Close path back to (cx,cy)

        
path.setAttribute("d"d); // Set this path 
        
path.setAttribute("fill"color);

        var 
title document.createElementNS(svgns"title");
        
title.appendChild(document.createTextNode(slices[x].name " (" + (Math.floor(slices[x].perc 100) / 100 ) + "%)"));
        
path.appendChild(title);

        
path.setAttribute("onmouseout""evt.target.setAttribute('fill', '"+color+"');");
        
//path.setAttribute("onmouseover", "evt.target.setAttribute('fill', '#fafafa');");

        
chart.appendChild(path);
        
        var 
front document.createElementNS(svgns"circle");
        
front.setAttributeNS(null"cx", (size 2));
        
front.setAttributeNS(null"cy", (size 2));
        
front.setAttributeNS(null"r",  (size lineWidth));         // 0.0 to 0.5
        
front.setAttributeNS(null"fill"backgroundColor);
        
chart.appendChild(front);        
    }
                
                
    
document.getElementByIdoptions['divId'] ).appendChild(chart);
    return 
chart;
}

usage

var options = {
    
divId "donutChart",
    
values : [2575150],
    
colors : [ 'red',  'blue''yellow'],
    
circleSize 100,
    
backgroundColor "#fff",
    
lineWidth .35
};
donutChart(options);

var 
options = {
    
divId "donutChart2",
    
values : [45,90],
    
colors : [ 'green''grey'],
    
circleSize 100,
    
backgroundColor "#fff",
    
lineWidth .35
};
donutChart(options);

recent posts

< back