Added more updates
[soho-sigint.git] / client-freqwatch / Chart.js / src / Chart.PolarArea.js
1 (function(){
2         "use strict";
3
4         var root = this,
5                 Chart = root.Chart,
6                 //Cache a local reference to Chart.helpers
7                 helpers = Chart.helpers;
8
9         var defaultConfig = {
10                 //Boolean - Show a backdrop to the scale label
11                 scaleShowLabelBackdrop : true,
12
13                 //String - The colour of the label backdrop
14                 scaleBackdropColor : "rgba(255,255,255,0.75)",
15
16                 // Boolean - Whether the scale should begin at zero
17                 scaleBeginAtZero : true,
18
19                 //Number - The backdrop padding above & below the label in pixels
20                 scaleBackdropPaddingY : 2,
21
22                 //Number - The backdrop padding to the side of the label in pixels
23                 scaleBackdropPaddingX : 2,
24
25                 //Boolean - Show line for each value in the scale
26                 scaleShowLine : true,
27
28                 //Boolean - Stroke a line around each segment in the chart
29                 segmentShowStroke : true,
30
31                 //String - The colour of the stroke on each segment.
32                 segmentStrokeColor : "#fff",
33
34                 //Number - The width of the stroke value in pixels
35                 segmentStrokeWidth : 2,
36
37                 //Number - Amount of animation steps
38                 animationSteps : 100,
39
40                 //String - Animation easing effect.
41                 animationEasing : "easeOutBounce",
42
43                 //Boolean - Whether to animate the rotation of the chart
44                 animateRotate : true,
45
46                 //Boolean - Whether to animate scaling the chart from the centre
47                 animateScale : false,
48
49                 //String - A legend template
50                 legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"><%if(segments[i].label){%><%=segments[i].label%><%}%></span></li><%}%></ul>"
51         };
52
53
54         Chart.Type.extend({
55                 //Passing in a name registers this chart in the Chart namespace
56                 name: "PolarArea",
57                 //Providing a defaults will also register the deafults in the chart namespace
58                 defaults : defaultConfig,
59                 //Initialize is fired when the chart is initialized - Data is passed in as a parameter
60                 //Config is automatically merged by the core of Chart.js, and is available at this.options
61                 initialize:  function(data){
62                         this.segments = [];
63                         //Declare segment class as a chart instance specific class, so it can share props for this instance
64                         this.SegmentArc = Chart.Arc.extend({
65                                 showStroke : this.options.segmentShowStroke,
66                                 strokeWidth : this.options.segmentStrokeWidth,
67                                 strokeColor : this.options.segmentStrokeColor,
68                                 ctx : this.chart.ctx,
69                                 innerRadius : 0,
70                                 x : this.chart.width/2,
71                                 y : this.chart.height/2
72                         });
73                         this.scale = new Chart.RadialScale({
74                                 display: this.options.showScale,
75                                 fontStyle: this.options.scaleFontStyle,
76                                 fontSize: this.options.scaleFontSize,
77                                 fontFamily: this.options.scaleFontFamily,
78                                 fontColor: this.options.scaleFontColor,
79                                 showLabels: this.options.scaleShowLabels,
80                                 showLabelBackdrop: this.options.scaleShowLabelBackdrop,
81                                 backdropColor: this.options.scaleBackdropColor,
82                                 backdropPaddingY : this.options.scaleBackdropPaddingY,
83                                 backdropPaddingX: this.options.scaleBackdropPaddingX,
84                                 lineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,
85                                 lineColor: this.options.scaleLineColor,
86                                 lineArc: true,
87                                 width: this.chart.width,
88                                 height: this.chart.height,
89                                 xCenter: this.chart.width/2,
90                                 yCenter: this.chart.height/2,
91                                 ctx : this.chart.ctx,
92                                 templateString: this.options.scaleLabel,
93                                 valuesCount: data.length
94                         });
95
96                         this.updateScaleRange(data);
97
98                         this.scale.update();
99
100                         helpers.each(data,function(segment,index){
101                                 this.addData(segment,index,true);
102                         },this);
103
104                         //Set up tooltip events on the chart
105                         if (this.options.showTooltips){
106                                 helpers.bindEvents(this, this.options.tooltipEvents, function(evt){
107                                         var activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];
108                                         helpers.each(this.segments,function(segment){
109                                                 segment.restore(["fillColor"]);
110                                         });
111                                         helpers.each(activeSegments,function(activeSegment){
112                                                 activeSegment.fillColor = activeSegment.highlightColor;
113                                         });
114                                         this.showTooltip(activeSegments);
115                                 });
116                         }
117
118                         this.render();
119                 },
120                 getSegmentsAtEvent : function(e){
121                         var segmentsArray = [];
122
123                         var location = helpers.getRelativePosition(e);
124
125                         helpers.each(this.segments,function(segment){
126                                 if (segment.inRange(location.x,location.y)) segmentsArray.push(segment);
127                         },this);
128                         return segmentsArray;
129                 },
130                 addData : function(segment, atIndex, silent){
131                         var index = atIndex || this.segments.length;
132
133                         this.segments.splice(index, 0, new this.SegmentArc({
134                                 fillColor: segment.color,
135                                 highlightColor: segment.highlight || segment.color,
136                                 label: segment.label,
137                                 value: segment.value,
138                                 outerRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),
139                                 circumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),
140                                 startAngle: Math.PI * 1.5
141                         }));
142                         if (!silent){
143                                 this.reflow();
144                                 this.update();
145                         }
146                 },
147                 removeData: function(atIndex){
148                         var indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;
149                         this.segments.splice(indexToDelete, 1);
150                         this.reflow();
151                         this.update();
152                 },
153                 calculateTotal: function(data){
154                         this.total = 0;
155                         helpers.each(data,function(segment){
156                                 this.total += segment.value;
157                         },this);
158                         this.scale.valuesCount = this.segments.length;
159                 },
160                 updateScaleRange: function(datapoints){
161                         var valuesArray = [];
162                         helpers.each(datapoints,function(segment){
163                                 valuesArray.push(segment.value);
164                         });
165
166                         var scaleSizes = (this.options.scaleOverride) ?
167                                 {
168                                         steps: this.options.scaleSteps,
169                                         stepValue: this.options.scaleStepWidth,
170                                         min: this.options.scaleStartValue,
171                                         max: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)
172                                 } :
173                                 helpers.calculateScaleRange(
174                                         valuesArray,
175                                         helpers.min([this.chart.width, this.chart.height])/2,
176                                         this.options.scaleFontSize,
177                                         this.options.scaleBeginAtZero,
178                                         this.options.scaleIntegersOnly
179                                 );
180
181                         helpers.extend(
182                                 this.scale,
183                                 scaleSizes,
184                                 {
185                                         size: helpers.min([this.chart.width, this.chart.height]),
186                                         xCenter: this.chart.width/2,
187                                         yCenter: this.chart.height/2
188                                 }
189                         );
190
191                 },
192                 update : function(){
193                         this.calculateTotal(this.segments);
194
195                         helpers.each(this.segments,function(segment){
196                                 segment.save();
197                         });
198                         
199                         this.reflow();
200                         this.render();
201                 },
202                 reflow : function(){
203                         helpers.extend(this.SegmentArc.prototype,{
204                                 x : this.chart.width/2,
205                                 y : this.chart.height/2
206                         });
207                         this.updateScaleRange(this.segments);
208                         this.scale.update();
209
210                         helpers.extend(this.scale,{
211                                 xCenter: this.chart.width/2,
212                                 yCenter: this.chart.height/2
213                         });
214
215                         helpers.each(this.segments, function(segment){
216                                 segment.update({
217                                         outerRadius : this.scale.calculateCenterOffset(segment.value)
218                                 });
219                         }, this);
220
221                 },
222                 draw : function(ease){
223                         var easingDecimal = ease || 1;
224                         //Clear & draw the canvas
225                         this.clear();
226                         helpers.each(this.segments,function(segment, index){
227                                 segment.transition({
228                                         circumference : this.scale.getCircumference(),
229                                         outerRadius : this.scale.calculateCenterOffset(segment.value)
230                                 },easingDecimal);
231
232                                 segment.endAngle = segment.startAngle + segment.circumference;
233
234                                 // If we've removed the first segment we need to set the first one to
235                                 // start at the top.
236                                 if (index === 0){
237                                         segment.startAngle = Math.PI * 1.5;
238                                 }
239
240                                 //Check to see if it's the last segment, if not get the next and update the start angle
241                                 if (index < this.segments.length - 1){
242                                         this.segments[index+1].startAngle = segment.endAngle;
243                                 }
244                                 segment.draw();
245                         }, this);
246                         this.scale.draw();
247                 }
248         });
249
250 }).call(this);