;(function () {
'use strict';
/**
* Draw simple pie chart using svg.
* @namespace
*/
db.libs.pieChart = (function($){
var name = 'pieChart';
/**
* Animates chart to values to in series.
* @public
* @memberof db.libs.pieChart
* @param {external:jQuery|string} id Selector or jQuery element
* @return {external:jQuery} jQuery element
*/
function update(id){
var $id = $(id);
var options = $id.data('options');
var slices = $id.get(0).querySelectorAll('.slice');
var animate, animateTransform;
for(var i = 0; i < slices.length; i++){
animate = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
animate.setAttribute('attributeName', 'd');
animate.setAttribute('from', slices[i].getAttribute('d'));
animate.setAttribute('to', options.slices[i].path);
animate.setAttribute('dur', '0.3s');
animate.setAttribute('begin', 'click');
animate.setAttribute('fill', 'freeze');
animate.setAttribute('keySplines', '0 0.75 0.25 1');
animate.setAttribute('calcMode','spline');
animate.setAttribute('keyTimes','0;1');
animateTransform = document.createElementNS('http://www.w3.org/2000/svg', 'animateTransform');
animateTransform.setAttribute('attributeName', 'transform');
animateTransform.setAttribute('type', 'rotate');
animateTransform.setAttribute('from', slices[i].getAttribute('transform').replace('rotate(','').replace(')',''));
animateTransform.setAttribute('to', options.slices[i].rotation + ' 200 200');
animateTransform.setAttribute('dur', '0.3s');
animateTransform.setAttribute('begin', 'click');
animateTransform.setAttribute('fill', 'freeze');
animateTransform.setAttribute('keySplines', '0 0.75 0.25 1');
animateTransform.setAttribute('calcMode','spline');
animateTransform.setAttribute('keyTimes','0;1');
slices[i].appendChild(animate);
slices[i].appendChild(animateTransform);
slices[i].dispatchEvent( new Event('click', {'bubbles':true, 'cancelable':false}) );
}
// Clean up the once the animation is complete.
setTimeout(function(){
for(var s = 0; s < slices.length; s++){
slices[s].setAttribute('d', options.slices[s].path);
slices[s].setAttribute('transform', 'rotate(' + options.slices[s].rotation + ' 200 200)');
slices[s].innerHTML = '';
}
}, 300);
return $id;
}
/**
* Updates data series.
* @public
* @memberof db.libs.pieChart
* @param {external:jQuery|string} id Selector or jQuery element
* @param {array|string} data Series data. Accepts array or string that can be parsed to array using JSON.parse
* @return {external:jQuery} jQuery element
*/
function series(id, data){
var $id = $(id);
var options = $id.data('options');
var rotation = 0;
options.slices = [];
options.series = db.libs.chart.parse(data);
options.total = db.libs.chart.sum(options.series);
for(var i=0; i < options.series.length; i++){
options.slices.push( slice(options.series[i], options.total, rotation) );
rotation += options.slices[options.slices.length - 1].degrees;
}
$id.data('options', options);
return $id;
}
/**
* Returns values for a slice
* @private
* @memberof db.libs.pieChart
* @param {number} value The value for the slice
* @param {number} total The total value for the chart
* @param {number} rotation The rotation for the slice
* @return {object} object containing data needed to draw the slice
*/
function slice(value, total, rotation){
var degrees = (value * 360) / total;
var x1 = 200 + 180 * Math.cos( Math.PI * 0 / 180);
var y1 = 200 + 180 * Math.sin( Math.PI * 0 / 180);
var x2 = 200 + 180 * Math.cos( Math.PI * degrees / 180);
var y2 = 200 + 180 * Math.sin( Math.PI * degrees / 180);
return {
degrees: degrees,
rotation: rotation,
path: "M 200 200 L " + x1 + " " + y1 + " A 180 180 0 0 1 " + x2 + " " + y2 + " Z"
};
}
/**
* Render the chart
* @public
* @memberof db.libs.pieChart
* @param {external:jQuery|string} id Selector or jQuery element
* @fires rendered
* @return {external:jQuery} jQuery element
*/
function render(id){
var $id = $(id);
var options = $id.data('options');
options.donut = ((options.width / 2) / 100) * options.donut;
$id.html( Mustache.render(db.templates['chart-pie'], options) );
$id.get(0).dispatchEvent( new Event('rendered') );
return $id;
}
/**
* Initialize the component
* @public
* @example <caption>Initializing can be done with or without jQuery</caption>
* db.libs.pieChart(document.getElementById('pieChartDemo'), { series: [113,100,50,28,27,44,68,52] });
* $('#pieChartDemo').pieChart({ series: [113,100,50,28,27,44,68,52] });
* @memberof db.libs.pieChart
* @param {external:jQuery|string} [id] Selector or jQuery element
* @param {object} [options] Options can be passed to init or read from the data-options attribute on the element
* @param {number} [options.width=400] Width given as pixels
* @param {number} [options.height=400] Height given as pixels
* @param {number} [options.donut=0] Size of donut given as a percentage size of the chart
* @param {array} [options.series] Values used to create the chart
* @return {array} Returns array of all targeted elements
*/
function init(id, options){
var $targets;
if(id !== undefined){
$targets = $(id);
} else {
$targets = $('.pie[data-options]');
}
$targets.each(function(i, el){
if( !db.utils.isInitialized(el, name) ){
var $el = $(el);
var defaults = {
width: 400,
height: 400,
donut: 50,
series: [],
angles: [],
paths: [],
slices: [],
total: 0
};
if(id === undefined){
options = Foundation.utils.data_options($el);
}
options = $.extend({}, defaults, options);
$el.data('options', options);
series($el, options.series);
render($el);
db.utils.initialized(el, name);
}
});
return $targets;
}
return {
init: init,
reflow: function(){},
series: series,
render: render,
update: update
};
})(jQuery);
})();