mirror of
https://github.com/JonnyBro/JaBa.git
synced 2024-11-29 00:24:58 +05:00
250 lines
7.5 KiB
JavaScript
250 lines
7.5 KiB
JavaScript
|
(function(){
|
||
|
"use strict";
|
||
|
|
||
|
var root = this,
|
||
|
Chart = root.Chart,
|
||
|
//Cache a local reference to Chart.helpers
|
||
|
helpers = Chart.helpers;
|
||
|
|
||
|
var defaultConfig = {
|
||
|
//Boolean - Show a backdrop to the scale label
|
||
|
scaleShowLabelBackdrop : true,
|
||
|
|
||
|
//String - The colour of the label backdrop
|
||
|
scaleBackdropColor : "rgba(255,255,255,0.75)",
|
||
|
|
||
|
// Boolean - Whether the scale should begin at zero
|
||
|
scaleBeginAtZero : true,
|
||
|
|
||
|
//Number - The backdrop padding above & below the label in pixels
|
||
|
scaleBackdropPaddingY : 2,
|
||
|
|
||
|
//Number - The backdrop padding to the side of the label in pixels
|
||
|
scaleBackdropPaddingX : 2,
|
||
|
|
||
|
//Boolean - Show line for each value in the scale
|
||
|
scaleShowLine : true,
|
||
|
|
||
|
//Boolean - Stroke a line around each segment in the chart
|
||
|
segmentShowStroke : true,
|
||
|
|
||
|
//String - The colour of the stroke on each segement.
|
||
|
segmentStrokeColor : "#fff",
|
||
|
|
||
|
//Number - The width of the stroke value in pixels
|
||
|
segmentStrokeWidth : 2,
|
||
|
|
||
|
//Number - Amount of animation steps
|
||
|
animationSteps : 100,
|
||
|
|
||
|
//String - Animation easing effect.
|
||
|
animationEasing : "easeOutBounce",
|
||
|
|
||
|
//Boolean - Whether to animate the rotation of the chart
|
||
|
animateRotate : true,
|
||
|
|
||
|
//Boolean - Whether to animate scaling the chart 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: "PolarArea",
|
||
|
//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){
|
||
|
this.segments = [];
|
||
|
//Declare segment class as a chart instance specific class, so it can share props for this instance
|
||
|
this.SegmentArc = Chart.Arc.extend({
|
||
|
showStroke : this.options.segmentShowStroke,
|
||
|
strokeWidth : this.options.segmentStrokeWidth,
|
||
|
strokeColor : this.options.segmentStrokeColor,
|
||
|
ctx : this.chart.ctx,
|
||
|
innerRadius : 0,
|
||
|
x : this.chart.width/2,
|
||
|
y : this.chart.height/2
|
||
|
});
|
||
|
this.scale = new Chart.RadialScale({
|
||
|
display: this.options.showScale,
|
||
|
fontStyle: this.options.scaleFontStyle,
|
||
|
fontSize: this.options.scaleFontSize,
|
||
|
fontFamily: this.options.scaleFontFamily,
|
||
|
fontColor: this.options.scaleFontColor,
|
||
|
showLabels: this.options.scaleShowLabels,
|
||
|
showLabelBackdrop: this.options.scaleShowLabelBackdrop,
|
||
|
backdropColor: this.options.scaleBackdropColor,
|
||
|
backdropPaddingY : this.options.scaleBackdropPaddingY,
|
||
|
backdropPaddingX: this.options.scaleBackdropPaddingX,
|
||
|
lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
|
||
|
lineColor: this.options.scaleLineColor,
|
||
|
lineArc: true,
|
||
|
width: this.chart.width,
|
||
|
height: this.chart.height,
|
||
|
xCenter: this.chart.width/2,
|
||
|
yCenter: this.chart.height/2,
|
||
|
ctx : this.chart.ctx,
|
||
|
templateString: this.options.scaleLabel,
|
||
|
valuesCount: data.length
|
||
|
});
|
||
|
|
||
|
this.updateScaleRange(data);
|
||
|
|
||
|
this.scale.update();
|
||
|
|
||
|
helpers.each(data,function(segment,index){
|
||
|
this.addData(segment,index,true);
|
||
|
},this);
|
||
|
|
||
|
//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.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({
|
||
|
fillColor: segment.color,
|
||
|
highlightColor: segment.highlight || segment.color,
|
||
|
label: segment.label,
|
||
|
value: segment.value,
|
||
|
outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),
|
||
|
circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),
|
||
|
startAngle: Math.PI * 1.5
|
||
|
}));
|
||
|
if (!silent){
|
||
|
this.reflow();
|
||
|
this.update();
|
||
|
}
|
||
|
},
|
||
|
removeData: function(atIndex){
|
||
|
var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
|
||
|
this.segments.splice(indexToDelete, 1);
|
||
|
this.reflow();
|
||
|
this.update();
|
||
|
},
|
||
|
calculateTotal: function(data){
|
||
|
this.total = 0;
|
||
|
helpers.each(data,function(segment){
|
||
|
this.total += segment.value;
|
||
|
},this);
|
||
|
this.scale.valuesCount = this.segments.length;
|
||
|
},
|
||
|
updateScaleRange: function(datapoints){
|
||
|
var valuesArray = [];
|
||
|
helpers.each(datapoints,function(segment){
|
||
|
valuesArray.push(segment.value);
|
||
|
});
|
||
|
|
||
|
var scaleSizes = (this.options.scaleOverride) ?
|
||
|
{
|
||
|
steps: this.options.scaleSteps,
|
||
|
stepValue: this.options.scaleStepWidth,
|
||
|
min: this.options.scaleStartValue,
|
||
|
max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
|
||
|
} :
|
||
|
helpers.calculateScaleRange(
|
||
|
valuesArray,
|
||
|
helpers.min([this.chart.width, this.chart.height])/2,
|
||
|
this.options.scaleFontSize,
|
||
|
this.options.scaleBeginAtZero,
|
||
|
this.options.scaleIntegersOnly
|
||
|
);
|
||
|
|
||
|
helpers.extend(
|
||
|
this.scale,
|
||
|
scaleSizes,
|
||
|
{
|
||
|
size: helpers.min([this.chart.width, this.chart.height]),
|
||
|
xCenter: this.chart.width/2,
|
||
|
yCenter: this.chart.height/2
|
||
|
}
|
||
|
);
|
||
|
|
||
|
},
|
||
|
update : function(){
|
||
|
this.calculateTotal(this.segments);
|
||
|
|
||
|
helpers.each(this.segments,function(segment){
|
||
|
segment.save();
|
||
|
});
|
||
|
|
||
|
this.reflow();
|
||
|
this.render();
|
||
|
},
|
||
|
reflow : function(){
|
||
|
helpers.extend(this.SegmentArc.prototype,{
|
||
|
x : this.chart.width/2,
|
||
|
y : this.chart.height/2
|
||
|
});
|
||
|
this.updateScaleRange(this.segments);
|
||
|
this.scale.update();
|
||
|
|
||
|
helpers.extend(this.scale,{
|
||
|
xCenter: this.chart.width/2,
|
||
|
yCenter: this.chart.height/2
|
||
|
});
|
||
|
|
||
|
helpers.each(this.segments, function(segment){
|
||
|
segment.update({
|
||
|
outerRadius : this.scale.calculateCenterOffset(segment.value)
|
||
|
});
|
||
|
}, this);
|
||
|
|
||
|
},
|
||
|
draw : function(ease){
|
||
|
var easingDecimal = ease || 1;
|
||
|
//Clear & draw the canvas
|
||
|
this.clear();
|
||
|
helpers.each(this.segments,function(segment, index){
|
||
|
segment.transition({
|
||
|
circumference : this.scale.getCircumference(),
|
||
|
outerRadius : this.scale.calculateCenterOffset(segment.value)
|
||
|
},easingDecimal);
|
||
|
|
||
|
segment.endAngle = segment.startAngle + segment.circumference;
|
||
|
|
||
|
// If we've removed the first segment we need to set the first one to
|
||
|
// start at the top.
|
||
|
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;
|
||
|
}
|
||
|
segment.draw();
|
||
|
}, this);
|
||
|
this.scale.draw();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
}).call(this);
|