mirror of
https://github.com/JonnyBro/JaBa.git
synced 2024-11-22 21:24:59 +05:00
184 lines
No EOL
5.7 KiB
JavaScript
184 lines
No EOL
5.7 KiB
JavaScript
(function(){
|
|
"use strict";
|
|
|
|
var root = this,
|
|
Chart = root.Chart,
|
|
//Cache a local reference to Chart.helpers
|
|
helpers = Chart.helpers;
|
|
|
|
var defaultConfig = {
|
|
//Boolean - Whether we should show a stroke on each segment
|
|
segmentShowStroke : true,
|
|
|
|
//String - The colour of each segment stroke
|
|
segmentStrokeColor : "#fff",
|
|
|
|
//Number - The width of each segment stroke
|
|
segmentStrokeWidth : 2,
|
|
|
|
//The percentage of the chart that we cut out of the middle.
|
|
percentageInnerCutout : 50,
|
|
|
|
//Number - Amount of animation steps
|
|
animationSteps : 100,
|
|
|
|
//String - Animation easing effect
|
|
animationEasing : "easeOutBounce",
|
|
|
|
//Boolean - Whether we animate the rotation of the Doughnut
|
|
animateRotate : true,
|
|
|
|
//Boolean - Whether we animate scaling the Doughnut from the centre
|
|
animateScale : false,
|
|
|
|
//String - A legend template
|
|
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
|
|
|
|
};
|
|
|
|
|
|
Chart.Type.extend({
|
|
//Passing in a name registers this chart in the Chart namespace
|
|
name: "Doughnut",
|
|
//Providing a defaults will also register the deafults in the chart namespace
|
|
defaults : defaultConfig,
|
|
//Initialize is fired when the chart is initialized - Data is passed in as a parameter
|
|
//Config is automatically merged by the core of Chart.js, and is available at this.options
|
|
initialize: function(data){
|
|
|
|
//Declare segments as a static property to prevent inheriting across the Chart type prototype
|
|
this.segments = [];
|
|
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
|
|
|
|
this.SegmentArc = Chart.Arc.extend({
|
|
ctx : this.chart.ctx,
|
|
x : this.chart.width/2,
|
|
y : this.chart.height/2
|
|
});
|
|
|
|
//Set up tooltip events on the chart
|
|
if (this.options.showTooltips){
|
|
helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
|
|
var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
|
|
|
|
helpers.each(this.segments,function(segment){
|
|
segment.restore(["fillColor"]);
|
|
});
|
|
helpers.each(activeSegments,function(activeSegment){
|
|
activeSegment.fillColor = activeSegment.highlightColor;
|
|
});
|
|
this.showTooltip(activeSegments);
|
|
});
|
|
}
|
|
this.calculateTotal(data);
|
|
|
|
helpers.each(data,function(datapoint, index){
|
|
this.addData(datapoint, index, true);
|
|
},this);
|
|
|
|
this.render();
|
|
},
|
|
getSegmentsAtEvent : function(e){
|
|
var segmentsArray = [];
|
|
|
|
var location = helpers.getRelativePosition(e);
|
|
|
|
helpers.each(this.segments,function(segment){
|
|
if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
|
|
},this);
|
|
return segmentsArray;
|
|
},
|
|
addData : function(segment, atIndex, silent){
|
|
var index = atIndex || this.segments.length;
|
|
this.segments.splice(index, 0, new this.SegmentArc({
|
|
value : segment.value,
|
|
outerRadius : (this.options.animateScale) ? 0 : this.outerRadius,
|
|
innerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout,
|
|
fillColor : segment.color,
|
|
highlightColor : segment.highlight || segment.color,
|
|
showStroke : this.options.segmentShowStroke,
|
|
strokeWidth : this.options.segmentStrokeWidth,
|
|
strokeColor : this.options.segmentStrokeColor,
|
|
startAngle : Math.PI * 1.5,
|
|
circumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value),
|
|
label : segment.label
|
|
}));
|
|
if (!silent){
|
|
this.reflow();
|
|
this.update();
|
|
}
|
|
},
|
|
calculateCircumference : function(value){
|
|
return (Math.PI*2)*(Math.abs(value) / this.total);
|
|
},
|
|
calculateTotal : function(data){
|
|
this.total = 0;
|
|
helpers.each(data,function(segment){
|
|
this.total += Math.abs(segment.value);
|
|
},this);
|
|
},
|
|
update : function(){
|
|
this.calculateTotal(this.segments);
|
|
|
|
// Reset any highlight colours before updating.
|
|
helpers.each(this.activeElements, function(activeElement){
|
|
activeElement.restore(['fillColor']);
|
|
});
|
|
|
|
helpers.each(this.segments,function(segment){
|
|
segment.save();
|
|
});
|
|
this.render();
|
|
},
|
|
|
|
removeData: function(atIndex){
|
|
var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
|
|
this.segments.splice(indexToDelete, 1);
|
|
this.reflow();
|
|
this.update();
|
|
},
|
|
|
|
reflow : function(){
|
|
helpers.extend(this.SegmentArc.prototype,{
|
|
x : this.chart.width/2,
|
|
y : this.chart.height/2
|
|
});
|
|
this.outerRadius = (helpers.min([this.chart.width,this.chart.height]) - this.options.segmentStrokeWidth/2)/2;
|
|
helpers.each(this.segments, function(segment){
|
|
segment.update({
|
|
outerRadius : this.outerRadius,
|
|
innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
|
|
});
|
|
}, this);
|
|
},
|
|
draw : function(easeDecimal){
|
|
var animDecimal = (easeDecimal) ? easeDecimal : 1;
|
|
this.clear();
|
|
helpers.each(this.segments,function(segment,index){
|
|
segment.transition({
|
|
circumference : this.calculateCircumference(segment.value),
|
|
outerRadius : this.outerRadius,
|
|
innerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout
|
|
},animDecimal);
|
|
|
|
segment.endAngle = segment.startAngle + segment.circumference;
|
|
|
|
segment.draw();
|
|
if (index === 0){
|
|
segment.startAngle = Math.PI * 1.5;
|
|
}
|
|
//Check to see if it's the last segment, if not get the next and update the start angle
|
|
if (index < this.segments.length-1){
|
|
this.segments[index+1].startAngle = segment.endAngle;
|
|
}
|
|
},this);
|
|
|
|
}
|
|
});
|
|
|
|
Chart.types.Doughnut.extend({
|
|
name : "Pie",
|
|
defaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0})
|
|
});
|
|
|
|
}).call(this); |