rgraph-rails 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/.travis.yml +0 -1
- data/README.md +3 -3
- data/lib/rgraph-rails/version.rb +1 -1
- data/vendor/assets/javascripts/RGraph.bar.js +239 -3764
- data/vendor/assets/javascripts/RGraph.bipolar.js +115 -1986
- data/vendor/assets/javascripts/RGraph.common.annotate.js +35 -399
- data/vendor/assets/javascripts/RGraph.common.context.js +30 -600
- data/vendor/assets/javascripts/RGraph.common.core.js +403 -5187
- data/vendor/assets/javascripts/RGraph.common.csv.js +19 -275
- data/vendor/assets/javascripts/RGraph.common.deprecated.js +35 -454
- data/vendor/assets/javascripts/RGraph.common.dynamic.js +84 -1189
- data/vendor/assets/javascripts/RGraph.common.effects.js +90 -1548
- data/vendor/assets/javascripts/RGraph.common.key.js +54 -755
- data/vendor/assets/javascripts/RGraph.common.resizing.js +37 -567
- data/vendor/assets/javascripts/RGraph.common.sheets.js +29 -356
- data/vendor/assets/javascripts/RGraph.common.tooltips.js +32 -614
- data/vendor/assets/javascripts/RGraph.common.zoom.js +14 -223
- data/vendor/assets/javascripts/RGraph.cornergauge.js +71 -0
- data/vendor/assets/javascripts/RGraph.drawing.background.js +35 -620
- data/vendor/assets/javascripts/RGraph.drawing.circle.js +35 -576
- data/vendor/assets/javascripts/RGraph.drawing.image.js +52 -807
- data/vendor/assets/javascripts/RGraph.drawing.marker1.js +41 -717
- data/vendor/assets/javascripts/RGraph.drawing.marker2.js +37 -668
- data/vendor/assets/javascripts/RGraph.drawing.marker3.js +36 -563
- data/vendor/assets/javascripts/RGraph.drawing.poly.js +40 -608
- data/vendor/assets/javascripts/RGraph.drawing.rect.js +35 -597
- data/vendor/assets/javascripts/RGraph.drawing.text.js +34 -642
- data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +50 -809
- data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +51 -856
- data/vendor/assets/javascripts/RGraph.fuel.js +58 -964
- data/vendor/assets/javascripts/RGraph.funnel.js +55 -984
- data/vendor/assets/javascripts/RGraph.gantt.js +75 -1241
- data/vendor/assets/javascripts/RGraph.gauge.js +87 -1397
- data/vendor/assets/javascripts/RGraph.hbar.js +143 -2376
- data/vendor/assets/javascripts/RGraph.hprogress.js +80 -1397
- data/vendor/assets/javascripts/RGraph.line.js +241 -4162
- data/vendor/assets/javascripts/RGraph.meter.js +74 -1278
- metadata +3 -30
- data/vendor/assets/images/bg.png +0 -0
- data/vendor/assets/images/bullet.png +0 -0
- data/vendor/assets/images/facebook-large.png +0 -0
- data/vendor/assets/images/google-plus-large.png +0 -0
- data/vendor/assets/images/logo.png +0 -0
- data/vendor/assets/images/meter-image-sd-needle.png +0 -0
- data/vendor/assets/images/meter-image-sd.png +0 -0
- data/vendor/assets/images/meter-sketch-needle.png +0 -0
- data/vendor/assets/images/meter-sketch.png +0 -0
- data/vendor/assets/images/odometer-background.png +0 -0
- data/vendor/assets/images/rgraph.jpg +0 -0
- data/vendor/assets/images/title.png +0 -0
- data/vendor/assets/images/twitter-large.png +0 -0
- data/vendor/assets/javascripts/RGraph.modaldialog.js +0 -301
- data/vendor/assets/javascripts/RGraph.odo.js +0 -1265
- data/vendor/assets/javascripts/RGraph.pie.js +0 -2272
- data/vendor/assets/javascripts/RGraph.radar.js +0 -1847
- data/vendor/assets/javascripts/RGraph.rose.js +0 -1877
- data/vendor/assets/javascripts/RGraph.rscatter.js +0 -1425
- data/vendor/assets/javascripts/RGraph.scatter.js +0 -2970
- data/vendor/assets/javascripts/RGraph.semicircularprogress.js +0 -1015
- data/vendor/assets/javascripts/RGraph.thermometer.js +0 -1129
- data/vendor/assets/javascripts/RGraph.vprogress.js +0 -1452
- data/vendor/assets/javascripts/RGraph.waterfall.js +0 -1252
- data/vendor/assets/javascripts/financial-data.js +0 -1067
- data/vendor/assets/stylesheets/ModalDialog.css +0 -90
- data/vendor/assets/stylesheets/animations.css +0 -3347
- data/vendor/assets/stylesheets/website.css +0 -446
@@ -1,2272 +0,0 @@
|
|
1
|
-
// version: 2016-06-04
|
2
|
-
/**
|
3
|
-
* o--------------------------------------------------------------------------------o
|
4
|
-
* | This file is part of the RGraph package - you can learn more at: |
|
5
|
-
* | |
|
6
|
-
* | http://www.rgraph.net |
|
7
|
-
* | |
|
8
|
-
* | RGraph is dual licensed under the Open Source GPL (General Public License) |
|
9
|
-
* | v2.0 license and a commercial license which means that you're not bound by |
|
10
|
-
* | the terms of the GPL. The commercial license is just 99 GBP and you can |
|
11
|
-
* | read about it here: |
|
12
|
-
* | http://www.rgraph.net/license |
|
13
|
-
* o--------------------------------------------------------------------------------o
|
14
|
-
*/
|
15
|
-
|
16
|
-
RGraph = window.RGraph || {isRGraph: true};
|
17
|
-
|
18
|
-
/**
|
19
|
-
* The pie chart constructor
|
20
|
-
*
|
21
|
-
* @param data array The data to be represented on the Pie chart
|
22
|
-
*/
|
23
|
-
RGraph.Pie = function (conf)
|
24
|
-
{
|
25
|
-
/**
|
26
|
-
* Allow for object config style
|
27
|
-
*/
|
28
|
-
if ( typeof conf === 'object'
|
29
|
-
&& typeof conf.data === 'object'
|
30
|
-
&& typeof conf.id === 'string') {
|
31
|
-
|
32
|
-
var id = conf.id,
|
33
|
-
canvas = document.getElementById(id),
|
34
|
-
data = conf.data,
|
35
|
-
parseConfObjectForOptions = true; // Set this so the config is parsed (at the end of the constructor
|
36
|
-
|
37
|
-
} else {
|
38
|
-
|
39
|
-
var id = conf,
|
40
|
-
canvas = document.getElementById(id),
|
41
|
-
data = arguments[1];
|
42
|
-
}
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
// Get the canvas and context objects
|
48
|
-
this.id = id;
|
49
|
-
this.canvas = canvas;
|
50
|
-
this.context = this.canvas.getContext ? this.canvas.getContext("2d", {alpha: (typeof id === 'object' && id.alpha === false) ? false : true}) : null;
|
51
|
-
this.canvas.__object__ = this;
|
52
|
-
this.total = 0;
|
53
|
-
this.subTotal = 0;
|
54
|
-
this.angles = [];
|
55
|
-
this.data = data;
|
56
|
-
this.properties = [];
|
57
|
-
this.type = 'pie';
|
58
|
-
this.isRGraph = true;
|
59
|
-
this.coords = [];
|
60
|
-
this.coords.key = [];
|
61
|
-
this.coordsSticks = [];
|
62
|
-
this.coordsText = [];
|
63
|
-
this.uid = RGraph.CreateUID();
|
64
|
-
this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.CreateUID();
|
65
|
-
this.colorsParsed = false;
|
66
|
-
this.original_colors = [];
|
67
|
-
this.firstDraw = true; // After the first draw this will be false
|
68
|
-
|
69
|
-
|
70
|
-
//
|
71
|
-
// Go through the data and convert strings to numbers
|
72
|
-
//
|
73
|
-
for (var i=0; i<this.data.length; ++i) {
|
74
|
-
if (typeof this.data[i] === 'string') {
|
75
|
-
this.data[i] = parseFloat(this.data[i]);
|
76
|
-
}
|
77
|
-
}
|
78
|
-
|
79
|
-
this.properties =
|
80
|
-
{
|
81
|
-
'chart.centerx.adjust': 0,
|
82
|
-
'chart.centery.adjust': 0,
|
83
|
-
'chart.colors': ['red', '#ccc', '#cfc', 'blue', 'pink', 'yellow', 'black', 'orange', 'cyan', 'purple', '#78CAEA', '#E284E9', 'white', 'blue', '#9E7BF6'],
|
84
|
-
'chart.strokestyle': 'white',
|
85
|
-
'chart.linewidth': 3,
|
86
|
-
'chart.labels': [],
|
87
|
-
'chart.labels.sticks': false,
|
88
|
-
'chart.labels.sticks.length': 7,
|
89
|
-
'chart.labels.sticks.colors': null,
|
90
|
-
'chart.labels.sticks.usecolors': true,
|
91
|
-
'chart.labels.sticks.linewidth': 1,
|
92
|
-
'chart.labels.sticks.hlength': 5,
|
93
|
-
'chart.labels.sticks.list': false,
|
94
|
-
'chart.labels.ingraph': null,
|
95
|
-
'chart.labels.ingraph.color': null,
|
96
|
-
'chart.labels.ingraph.font': null,
|
97
|
-
'chart.labels.ingraph.size': null,
|
98
|
-
'chart.labels.ingraph.bounding':true,
|
99
|
-
'chart.labels.ingraph.bounding.fill':'white',
|
100
|
-
'chart.labels.ingraph.specific':null,
|
101
|
-
'chart.labels.ingraph.units.pre':'',
|
102
|
-
'chart.labels.ingraph.units.post':'',
|
103
|
-
'chart.labels.ingraph.radius': null,
|
104
|
-
'chart.labels.center': null,
|
105
|
-
'chart.labels.center.size': 26,
|
106
|
-
'chart.labels.center.font': 'Segoe UI, Arial, Verdana, sans-serif',
|
107
|
-
'chart.labels.center.color': 'black',
|
108
|
-
'chart.labels.center.italic': false,
|
109
|
-
'chart.labels.center.bold': false,
|
110
|
-
'chart.labels.center.units.pre': '',
|
111
|
-
'chart.labels.center.units.post': '',
|
112
|
-
'chart.gutter.left': 25,
|
113
|
-
'chart.gutter.right': 25,
|
114
|
-
'chart.gutter.top': 25,
|
115
|
-
'chart.gutter.bottom': 25,
|
116
|
-
'chart.title': '',
|
117
|
-
'chart.title.background': null,
|
118
|
-
'chart.title.hpos': null,
|
119
|
-
'chart.title.vpos': 0.5,
|
120
|
-
'chart.title.bold': true,
|
121
|
-
'chart.title.font': null,
|
122
|
-
'chart.title.x': null,
|
123
|
-
'chart.title.y': null,
|
124
|
-
'chart.title.halign': null,
|
125
|
-
'chart.title.valign': null,
|
126
|
-
'chart.shadow': true,
|
127
|
-
'chart.shadow.color': '#aaa',
|
128
|
-
'chart.shadow.offsetx': 0,
|
129
|
-
'chart.shadow.offsety': 0,
|
130
|
-
'chart.shadow.blur': 15,
|
131
|
-
'chart.text.size': 12,
|
132
|
-
'chart.text.color': 'black',
|
133
|
-
'chart.text.font': 'Segoe UI, Arial, Verdana, sans-serif',
|
134
|
-
'chart.text.accessible': true,
|
135
|
-
'chart.text.accessible.overflow': 'visible',
|
136
|
-
'chart.text.accessible.pointerevents': false,
|
137
|
-
'chart.contextmenu': null,
|
138
|
-
'chart.tooltips': null,
|
139
|
-
'chart.tooltips.event': 'onclick',
|
140
|
-
'chart.tooltips.effect': 'fade',
|
141
|
-
'chart.tooltips.css.class': 'RGraph_tooltip',
|
142
|
-
'chart.tooltips.highlight': true,
|
143
|
-
'chart.highlight.style': '2d',
|
144
|
-
'chart.highlight.style.twod.fill': 'rgba(255,255,255,0.7)',
|
145
|
-
'chart.highlight.style.twod.stroke': 'rgba(255,255,255,0.7)',
|
146
|
-
'chart.highlight.style.outline.width': null,
|
147
|
-
'chart.centerx': null,
|
148
|
-
'chart.centery': null,
|
149
|
-
'chart.radius': null,
|
150
|
-
'chart.border': false,
|
151
|
-
'chart.border.color': 'rgba(255,255,255,0.5)',
|
152
|
-
'chart.key': null,
|
153
|
-
'chart.key.background': 'white',
|
154
|
-
'chart.key.position': 'graph',
|
155
|
-
'chart.key.halign': 'right',
|
156
|
-
'chart.key.shadow': false,
|
157
|
-
'chart.key.shadow.color': '#666',
|
158
|
-
'chart.key.shadow.blur': 3,
|
159
|
-
'chart.key.shadow.offsetx': 2,
|
160
|
-
'chart.key.shadow.offsety': 2,
|
161
|
-
'chart.key.position.gutter.boxed': false,
|
162
|
-
'chart.key.position.x': null,
|
163
|
-
'chart.key.position.y': null,
|
164
|
-
'chart.key.color.shape': 'square',
|
165
|
-
'chart.key.rounded': true,
|
166
|
-
'chart.key.linewidth': 1,
|
167
|
-
'chart.key.colors': null,
|
168
|
-
'chart.key.interactive': false,
|
169
|
-
'chart.key.interactive.highlight.chart.stroke': 'black',
|
170
|
-
'chart.key.interactive.highlight.chart.fill': 'rgba(255,255,255,0.7)',
|
171
|
-
'chart.key.interactive.highlight.label': 'rgba(255,0,0,0.2)',
|
172
|
-
'chart.key.text.color': 'black',
|
173
|
-
'chart.annotatable': false,
|
174
|
-
'chart.annotate.color': 'black',
|
175
|
-
'chart.zoom.factor': 1.5,
|
176
|
-
'chart.zoom.fade.in': true,
|
177
|
-
'chart.zoom.fade.out': true,
|
178
|
-
'chart.zoom.hdir': 'right',
|
179
|
-
'chart.zoom.vdir': 'down',
|
180
|
-
'chart.zoom.frames': 25,
|
181
|
-
'chart.zoom.delay': 16.666,
|
182
|
-
'chart.zoom.shadow': true,
|
183
|
-
'chart.zoom.background': true,
|
184
|
-
'chart.zoom.action': 'zoom',
|
185
|
-
'chart.resizable': false,
|
186
|
-
'chart.resize.handle.adjust': [0,0],
|
187
|
-
'chart.resize.handle.background': null,
|
188
|
-
'chart.variant': 'pie',
|
189
|
-
'chart.variant.donut.width': null,
|
190
|
-
'chart.variant.threed.depth': 20,
|
191
|
-
'chart.exploded': [],
|
192
|
-
'chart.effect.roundrobin.multiplier': 1,
|
193
|
-
'chart.events.click': null,
|
194
|
-
'chart.events.mousemove': null,
|
195
|
-
'chart.centerpin': null,
|
196
|
-
'chart.centerpin.fill': 'gray',
|
197
|
-
'chart.centerpin.stroke': 'white',
|
198
|
-
'chart.origin': 0 - (Math.PI / 2),
|
199
|
-
'chart.events': true,
|
200
|
-
'chart.labels.colors': [],
|
201
|
-
'chart.clearto': 'rgba(0,0,0,0)'
|
202
|
-
}
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
/**
|
207
|
-
* Calculate the total
|
208
|
-
*/
|
209
|
-
for (var i=0,len=data.length; i<len; i++) {
|
210
|
-
this.total += data[i];
|
211
|
-
|
212
|
-
// This loop also creates the $xxx objects - this isn't related to
|
213
|
-
// the code above but just saves doing another loop through the data
|
214
|
-
this['$' + i] = {};
|
215
|
-
}
|
216
|
-
|
217
|
-
|
218
|
-
/**
|
219
|
-
* Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
|
220
|
-
* done already
|
221
|
-
*/
|
222
|
-
if (!this.canvas.__rgraph_aa_translated__) {
|
223
|
-
this.context.translate(0.5,0.5);
|
224
|
-
|
225
|
-
this.canvas.__rgraph_aa_translated__ = true;
|
226
|
-
}
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
// Short variable names
|
232
|
-
var RG = RGraph,
|
233
|
-
ca = this.canvas,
|
234
|
-
co = ca.getContext('2d'),
|
235
|
-
prop = this.properties,
|
236
|
-
pa2 = RG.path2,
|
237
|
-
win = window,
|
238
|
-
doc = document,
|
239
|
-
ma = Math
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
/**
|
244
|
-
* "Decorate" the object with the generic effects if the effects library has been included
|
245
|
-
*/
|
246
|
-
if (RG.Effects && typeof RG.Effects.decorate === 'function') {
|
247
|
-
RG.Effects.decorate(this);
|
248
|
-
}
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
/**
|
254
|
-
* A generic setter
|
255
|
-
*/
|
256
|
-
this.set =
|
257
|
-
this.Set = function (name)
|
258
|
-
{
|
259
|
-
var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
|
260
|
-
|
261
|
-
/**
|
262
|
-
* the number of arguments is only one and it's an
|
263
|
-
* object - parse it for configuration data and return.
|
264
|
-
*/
|
265
|
-
if (arguments.length === 1 && typeof name === 'object') {
|
266
|
-
RG.parseObjectStyleConfig(this, name);
|
267
|
-
return this;
|
268
|
-
}
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
/**
|
275
|
-
* This should be done first - prepend the property name with "chart." if necessary
|
276
|
-
*/
|
277
|
-
if (name.substr(0,6) != 'chart.') {
|
278
|
-
name = 'chart.' + name;
|
279
|
-
}
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
// Convert uppercase letters to dot+lower case letter
|
285
|
-
while(name.match(/([A-Z])/)) {
|
286
|
-
name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
|
287
|
-
}
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
if (name == 'chart.highlight.style.twod.color') {
|
292
|
-
name = 'chart.highlight.style.twod.fill';
|
293
|
-
}
|
294
|
-
|
295
|
-
|
296
|
-
if (name == 'chart.labels.spaced') {
|
297
|
-
name = 'chart.labels.sticks.list';
|
298
|
-
}
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
prop[name] = value;
|
306
|
-
|
307
|
-
return this;
|
308
|
-
};
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
/**
|
314
|
-
* A generic getter
|
315
|
-
*/
|
316
|
-
this.get =
|
317
|
-
this.Get = function (name)
|
318
|
-
{
|
319
|
-
/**
|
320
|
-
* This should be done first - prepend the property name with "chart." if necessary
|
321
|
-
*/
|
322
|
-
if (name.substr(0,6) != 'chart.') {
|
323
|
-
name = 'chart.' + name;
|
324
|
-
}
|
325
|
-
|
326
|
-
// Convert uppercase letters to dot+lower case letter
|
327
|
-
name = name.replace(/([A-Z])/g, function (str)
|
328
|
-
{
|
329
|
-
return '.' + String(RegExp.$1).toLowerCase()
|
330
|
-
});
|
331
|
-
|
332
|
-
if (name == 'chart.highlight.style.twod.color') {
|
333
|
-
name = 'chart.highlight.style.twod.fill';
|
334
|
-
}
|
335
|
-
|
336
|
-
return prop[name];
|
337
|
-
};
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
/**
|
343
|
-
* This draws the pie chart
|
344
|
-
*/
|
345
|
-
this.draw =
|
346
|
-
this.Draw = function ()
|
347
|
-
{
|
348
|
-
/**
|
349
|
-
* Fire the onbeforedraw event
|
350
|
-
*/
|
351
|
-
RG.FireCustomEvent(this, 'onbeforedraw');
|
352
|
-
|
353
|
-
// NB: Colors are parsed further down so that the center X/Y can be used
|
354
|
-
|
355
|
-
|
356
|
-
/**
|
357
|
-
* This is new in May 2011 and facilitates indiviual gutter settings,
|
358
|
-
* eg chart.gutter.left
|
359
|
-
*/
|
360
|
-
this.gutterLeft = prop['chart.gutter.left'];
|
361
|
-
this.gutterRight = prop['chart.gutter.right'];
|
362
|
-
this.gutterTop = prop['chart.gutter.top'];
|
363
|
-
this.gutterBottom = prop['chart.gutter.bottom'];
|
364
|
-
|
365
|
-
this.radius = this.getRadius();// MUST be first
|
366
|
-
this.centerx = (this.graph.width / 2) + this.gutterLeft + prop['chart.centerx.adjust'];
|
367
|
-
this.centery = (this.graph.height / 2) + this.gutterTop + prop['chart.centery.adjust'];
|
368
|
-
this.subTotal = this.properties['chart.origin'];
|
369
|
-
this.angles = [];
|
370
|
-
this.coordsText = [];
|
371
|
-
|
372
|
-
/**
|
373
|
-
* Allow specification of a custom radius & center X/Y
|
374
|
-
*/
|
375
|
-
if (typeof prop['chart.radius'] === 'number') this.radius = prop['chart.radius'];
|
376
|
-
if (typeof prop['chart.centerx'] === 'number') this.centerx = prop['chart.centerx'];
|
377
|
-
if (typeof prop['chart.centery'] === 'number') this.centery = prop['chart.centery'];
|
378
|
-
|
379
|
-
|
380
|
-
if (this.radius <= 0) {
|
381
|
-
return;
|
382
|
-
}
|
383
|
-
|
384
|
-
/**
|
385
|
-
* Parse the colors for gradients. Its down here so that the center X/Y can be used
|
386
|
-
*/
|
387
|
-
if (!this.colorsParsed) {
|
388
|
-
|
389
|
-
this.parseColors();
|
390
|
-
|
391
|
-
// Don't want to do this again
|
392
|
-
this.colorsParsed = true;
|
393
|
-
}
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
/**
|
399
|
-
* This sets the label colors. Doing it here saves lots of if() conditions in the draw method
|
400
|
-
*/
|
401
|
-
if (prop['chart.labels.colors'].length < prop['chart.labels'].length) {
|
402
|
-
while (prop['chart.labels.colors'].length < prop['chart.labels'].length) {
|
403
|
-
prop['chart.labels.colors'].push(prop['chart.labels.colors'][prop['chart.labels.colors'].length - 1]);
|
404
|
-
}
|
405
|
-
} else {
|
406
|
-
if (typeof prop['chart.labels.colors'] === 'undefined') {
|
407
|
-
prop['chart.labels.colors'] = [];
|
408
|
-
}
|
409
|
-
|
410
|
-
while (prop['chart.labels.colors'].length < prop['chart.labels'].length) {
|
411
|
-
prop['chart.labels.colors'].push(prop['chart.text.color']);
|
412
|
-
}
|
413
|
-
}
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
if (prop['chart.variant'].indexOf('3d') > 0) {
|
419
|
-
return this.draw3d();
|
420
|
-
}
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
/**
|
426
|
-
* Draw the title
|
427
|
-
*/
|
428
|
-
RG.DrawTitle(
|
429
|
-
this,
|
430
|
-
prop['chart.title'],
|
431
|
-
(ca.height / 2) - this.radius - 5,
|
432
|
-
this.centerx,
|
433
|
-
prop['chart.title.size'] ? prop['chart.title.size'] : prop['chart.text.size'] + 2
|
434
|
-
);
|
435
|
-
|
436
|
-
/**
|
437
|
-
* Draw the shadow if required
|
438
|
-
*
|
439
|
-
* ???
|
440
|
-
*/
|
441
|
-
//if (prop['chart.shadow'] && false) {
|
442
|
-
//
|
443
|
-
// var offsetx = doc.all ? prop['chart.shadow.offsetx'] : 0;
|
444
|
-
// var offsety = doc.all ? prop['chart.shadow.offsety'] : 0;
|
445
|
-
//
|
446
|
-
// co.beginPath();
|
447
|
-
// co.fillStyle = prop['chart.shadow.color'];
|
448
|
-
//
|
449
|
-
// co.shadowColor = prop['chart.shadow.color'];
|
450
|
-
// co.shadowBlur = prop['chart.shadow.blur'];
|
451
|
-
// co.shadowOffsetX = prop['chart.shadow.offsetx'];
|
452
|
-
// co.shadowOffsetY = prop['chart.shadow.offsety'];
|
453
|
-
//
|
454
|
-
// co.arc(this.centerx + offsetx, this.centery + offsety, this.radius, 0, TWOPI, 0);
|
455
|
-
//
|
456
|
-
// co.fill();
|
457
|
-
//
|
458
|
-
// // Now turn off the shadow
|
459
|
-
// RG.NoShadow(this);
|
460
|
-
//}
|
461
|
-
|
462
|
-
/**
|
463
|
-
* The total of the array of values
|
464
|
-
*/
|
465
|
-
this.total = RG.array_sum(this.data);
|
466
|
-
var tot = this.total;
|
467
|
-
var data = this.data;
|
468
|
-
|
469
|
-
for (var i=0,len=this.data.length; i<len; i++) {
|
470
|
-
|
471
|
-
var angle = ((data[i] / tot) * RG.TWOPI);
|
472
|
-
|
473
|
-
// Draw the segment
|
474
|
-
this.DrawSegment(angle,prop['chart.colors'][i],i == (len - 1), i);
|
475
|
-
}
|
476
|
-
|
477
|
-
RG.NoShadow(this);
|
478
|
-
|
479
|
-
/**
|
480
|
-
* Redraw the seperating lines
|
481
|
-
*/
|
482
|
-
if (prop['chart.linewidth'] > 0) {
|
483
|
-
this.DrawBorders();
|
484
|
-
}
|
485
|
-
|
486
|
-
/**
|
487
|
-
* Now draw the segments again with shadow turned off. This is always performed,
|
488
|
-
* not just if the shadow is on.
|
489
|
-
*/
|
490
|
-
var len = this.angles.length;
|
491
|
-
var r = this.radius;
|
492
|
-
|
493
|
-
|
494
|
-
for (var action=0; action<2; action+=1) {
|
495
|
-
for (var i=0; i<len; i++) {
|
496
|
-
|
497
|
-
co.beginPath();
|
498
|
-
|
499
|
-
var segment = this.angles[i];
|
500
|
-
|
501
|
-
if (action === 1) {
|
502
|
-
co.strokeStyle = typeof(prop['chart.strokestyle']) == 'object' ? prop['chart.strokestyle'][i] : prop['chart.strokestyle'];
|
503
|
-
}
|
504
|
-
prop['chart.colors'][i] ? co.fillStyle = prop['chart.colors'][i] : null;
|
505
|
-
co.lineJoin = 'round';
|
506
|
-
|
507
|
-
co.arc(segment[2],
|
508
|
-
segment[3],
|
509
|
-
r,
|
510
|
-
(segment[0]),
|
511
|
-
(segment[1]),
|
512
|
-
false);
|
513
|
-
if (prop['chart.variant'] == 'donut') {
|
514
|
-
|
515
|
-
co.arc(
|
516
|
-
segment[2],
|
517
|
-
segment[3],
|
518
|
-
typeof(prop['chart.variant.donut.width']) == 'number' ? r - prop['chart.variant.donut.width'] : r / 2,
|
519
|
-
(segment[1]),
|
520
|
-
(segment[0]),
|
521
|
-
true
|
522
|
-
);
|
523
|
-
|
524
|
-
} else {
|
525
|
-
co.lineTo(segment[2], segment[3]);
|
526
|
-
}
|
527
|
-
co.closePath();
|
528
|
-
action === 0 ? co.fill() : co.stroke();
|
529
|
-
}
|
530
|
-
}
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
/**
|
536
|
-
* Draw label sticks
|
537
|
-
*/
|
538
|
-
if (prop['chart.labels.sticks']) {
|
539
|
-
|
540
|
-
this.DrawSticks();
|
541
|
-
|
542
|
-
// Redraw the border going around the Pie chart if the stroke style is NOT white
|
543
|
-
var strokeStyle = prop['chart.strokestyle'];
|
544
|
-
}
|
545
|
-
|
546
|
-
/**
|
547
|
-
* Draw the labels
|
548
|
-
*/
|
549
|
-
if (prop['chart.labels']) {
|
550
|
-
this.DrawLabels();
|
551
|
-
}
|
552
|
-
|
553
|
-
|
554
|
-
/**
|
555
|
-
* Draw centerpin if requested
|
556
|
-
*/
|
557
|
-
if (prop['chart.centerpin']) {
|
558
|
-
this.DrawCenterpin();
|
559
|
-
}
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
/**
|
565
|
-
* Draw ingraph labels
|
566
|
-
*/
|
567
|
-
if (prop['chart.labels.ingraph']) {
|
568
|
-
this.DrawInGraphLabels();
|
569
|
-
}
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
/**
|
575
|
-
* Draw the center label if requested
|
576
|
-
*/
|
577
|
-
if (!RG.isNull(prop['chart.labels.center'])) {
|
578
|
-
this.drawCenterLabel(prop['chart.labels.center']);
|
579
|
-
}
|
580
|
-
|
581
|
-
|
582
|
-
/**
|
583
|
-
* Setup the context menu if required
|
584
|
-
*/
|
585
|
-
if (prop['chart.contextmenu']) {
|
586
|
-
RG.ShowContext(this);
|
587
|
-
}
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
/**
|
592
|
-
* If a border is pecified, draw it
|
593
|
-
*/
|
594
|
-
if (prop['chart.border']) {
|
595
|
-
co.beginPath();
|
596
|
-
co.lineWidth = 5;
|
597
|
-
co.strokeStyle = prop['chart.border.color'];
|
598
|
-
|
599
|
-
co.arc(this.centerx,
|
600
|
-
this.centery,
|
601
|
-
this.radius - 2,
|
602
|
-
0,
|
603
|
-
RG.TWOPI,
|
604
|
-
0);
|
605
|
-
|
606
|
-
co.stroke();
|
607
|
-
}
|
608
|
-
|
609
|
-
/**
|
610
|
-
* Draw the kay if desired
|
611
|
-
*/
|
612
|
-
if (prop['chart.key'] && prop['chart.key'].length) {
|
613
|
-
RG.DrawKey(this, prop['chart.key'], prop['chart.colors']);
|
614
|
-
}
|
615
|
-
|
616
|
-
RG.NoShadow(this);
|
617
|
-
|
618
|
-
|
619
|
-
/**
|
620
|
-
* This function enables resizing
|
621
|
-
*/
|
622
|
-
if (prop['chart.resizable']) {
|
623
|
-
RG.AllowResizing(this);
|
624
|
-
}
|
625
|
-
|
626
|
-
|
627
|
-
/**
|
628
|
-
* This installs the event listeners
|
629
|
-
*/
|
630
|
-
if (prop['chart.events'] == true) {
|
631
|
-
RG.InstallEventListeners(this);
|
632
|
-
}
|
633
|
-
|
634
|
-
|
635
|
-
/**
|
636
|
-
* Fire the onfirstdraw event
|
637
|
-
*/
|
638
|
-
if (this.firstDraw) {
|
639
|
-
RG.fireCustomEvent(this, 'onfirstdraw');
|
640
|
-
this.firstDraw = false;
|
641
|
-
this.firstDrawFunc();
|
642
|
-
}
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
/**
|
648
|
-
* Fire the RGraph ondraw event
|
649
|
-
*/
|
650
|
-
RG.FireCustomEvent(this, 'ondraw');
|
651
|
-
|
652
|
-
return this;
|
653
|
-
};
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
/**
|
658
|
-
* Used in chaining. Runs a function there and then - not waiting for
|
659
|
-
* the events to fire (eg the onbeforedraw event)
|
660
|
-
*
|
661
|
-
* @param function func The function to execute
|
662
|
-
*/
|
663
|
-
this.exec = function (func)
|
664
|
-
{
|
665
|
-
func(this);
|
666
|
-
|
667
|
-
return this;
|
668
|
-
};
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
/**
|
674
|
-
* Draws a single segment of the pie chart
|
675
|
-
*
|
676
|
-
* @param int degrees The number of degrees for this segment
|
677
|
-
*/
|
678
|
-
this.drawSegment =
|
679
|
-
this.DrawSegment = function (radians, color, last, index)
|
680
|
-
{
|
681
|
-
// IE7/8/ExCanvas fix (when there's only one segment the Pie chart doesn't display
|
682
|
-
if (RGraph.ISOLD && radians == RG.TWOPI) {
|
683
|
-
radians -= 0.0001;
|
684
|
-
} else if (RGraph.ISOLD && radians == 0) {
|
685
|
-
radians = 0.001;
|
686
|
-
}
|
687
|
-
|
688
|
-
var subTotal = this.subTotal;
|
689
|
-
radians = radians * prop['chart.effect.roundrobin.multiplier'];
|
690
|
-
|
691
|
-
co.beginPath();
|
692
|
-
|
693
|
-
color ? co.fillStyle = color : null;
|
694
|
-
co.strokeStyle = prop['chart.strokestyle'];
|
695
|
-
co.lineWidth = 0;
|
696
|
-
|
697
|
-
if (prop['chart.shadow']) {
|
698
|
-
RG.setShadow(
|
699
|
-
this,
|
700
|
-
prop['chart.shadow.color'],
|
701
|
-
prop['chart.shadow.offsetx'],
|
702
|
-
prop['chart.shadow.offsety'],
|
703
|
-
prop['chart.shadow.blur']
|
704
|
-
);
|
705
|
-
}
|
706
|
-
|
707
|
-
/**
|
708
|
-
* Exploded segments
|
709
|
-
*/
|
710
|
-
if ( (typeof(prop['chart.exploded']) == 'object' && prop['chart.exploded'][index] > 0) || typeof(prop['chart.exploded']) == 'number') {
|
711
|
-
|
712
|
-
var explosion = typeof(prop['chart.exploded']) == 'number' ? prop['chart.exploded'] : prop['chart.exploded'][index];
|
713
|
-
var x = 0;
|
714
|
-
var y = 0;
|
715
|
-
var h = explosion;
|
716
|
-
var t = subTotal + (radians / 2);
|
717
|
-
var x = (Math.cos(t) * explosion);
|
718
|
-
var y = (Math.sin(t) * explosion);
|
719
|
-
var r = this.radius;
|
720
|
-
|
721
|
-
co.moveTo(this.centerx + x, this.centery + y);
|
722
|
-
} else {
|
723
|
-
var x = 0;
|
724
|
-
var y = 0;
|
725
|
-
var r = this.radius;
|
726
|
-
}
|
727
|
-
|
728
|
-
/**
|
729
|
-
* Calculate the angles
|
730
|
-
*/
|
731
|
-
var startAngle = subTotal;
|
732
|
-
var endAngle = ((subTotal + radians));
|
733
|
-
|
734
|
-
co.arc(this.centerx + x,
|
735
|
-
this.centery + y,
|
736
|
-
r,
|
737
|
-
startAngle,
|
738
|
-
endAngle,
|
739
|
-
0);
|
740
|
-
|
741
|
-
if (prop['chart.variant'] == 'donut') {
|
742
|
-
|
743
|
-
co.arc(this.centerx + x,
|
744
|
-
this.centery + y,
|
745
|
-
typeof(prop['chart.variant.donut.width']) == 'number' ? r - prop['chart.variant.donut.width'] : r / 2,
|
746
|
-
endAngle,
|
747
|
-
startAngle,
|
748
|
-
true);
|
749
|
-
} else {
|
750
|
-
co.lineTo(this.centerx + x, this.centery + y);
|
751
|
-
}
|
752
|
-
|
753
|
-
co.closePath();
|
754
|
-
|
755
|
-
|
756
|
-
// Keep hold of the angles
|
757
|
-
this.angles.push([subTotal, subTotal + radians, this.centerx + x, this.centery + y]);
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
//co.stroke();
|
762
|
-
co.fill();
|
763
|
-
|
764
|
-
/**
|
765
|
-
* Calculate the segment angle
|
766
|
-
*/
|
767
|
-
this.subTotal += radians;
|
768
|
-
};
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
/**
|
774
|
-
* Draws the graphs labels
|
775
|
-
*/
|
776
|
-
this.drawLabels =
|
777
|
-
this.DrawLabels = function ()
|
778
|
-
{
|
779
|
-
// New way of spacing labels out
|
780
|
-
if (prop['chart.labels'].length && prop['chart.labels.sticks.list']) {
|
781
|
-
return this.drawLabelsList();
|
782
|
-
}
|
783
|
-
|
784
|
-
var hAlignment = 'left';
|
785
|
-
var vAlignment = 'center';
|
786
|
-
var labels = prop['chart.labels'];
|
787
|
-
var context = co;
|
788
|
-
var font = prop['chart.text.font'];
|
789
|
-
var text_size = prop['chart.text.size'];
|
790
|
-
var cx = this.centerx;
|
791
|
-
var cy = this.centery;
|
792
|
-
var r = this.radius;
|
793
|
-
|
794
|
-
/**
|
795
|
-
* Turn the shadow off
|
796
|
-
*/
|
797
|
-
RG.NoShadow(this);
|
798
|
-
|
799
|
-
co.fillStyle = 'black';
|
800
|
-
co.beginPath();
|
801
|
-
|
802
|
-
/**
|
803
|
-
* Draw the labels
|
804
|
-
*/
|
805
|
-
if (labels && labels.length) {
|
806
|
-
|
807
|
-
for (i=0; i<this.angles.length; ++i) {
|
808
|
-
|
809
|
-
var segment = this.angles[i];
|
810
|
-
|
811
|
-
if (typeof(labels[i]) != 'string' && typeof(labels[i]) != 'number') {
|
812
|
-
continue;
|
813
|
-
}
|
814
|
-
|
815
|
-
// Move to the centre
|
816
|
-
co.moveTo(cx,cy);
|
817
|
-
|
818
|
-
var a = segment[0] + ((segment[1] - segment[0]) / 2);
|
819
|
-
var angle = ((segment[1] - segment[0]) / 2) + segment[0];
|
820
|
-
|
821
|
-
/**
|
822
|
-
* Handle the additional "explosion" offset
|
823
|
-
*/
|
824
|
-
if (typeof prop['chart.exploded'] === 'object' && prop['chart.exploded'][i] || typeof(prop['chart.exploded']) == 'number') {
|
825
|
-
|
826
|
-
var t = ((segment[1] - segment[0]) / 2);
|
827
|
-
var seperation = typeof(prop['chart.exploded']) == 'number' ? prop['chart.exploded'] : prop['chart.exploded'][i];
|
828
|
-
|
829
|
-
// Adjust the angles
|
830
|
-
var explosion_offsetx = (Math.cos(angle) * seperation);
|
831
|
-
var explosion_offsety = (Math.sin(angle) * seperation);
|
832
|
-
} else {
|
833
|
-
var explosion_offsetx = 0;
|
834
|
-
var explosion_offsety = 0;
|
835
|
-
}
|
836
|
-
|
837
|
-
/**
|
838
|
-
* Allow for the label sticks
|
839
|
-
*/
|
840
|
-
if (prop['chart.labels.sticks']) {
|
841
|
-
explosion_offsetx += (ma.cos(angle) * (typeof prop['chart.labels.sticks.length'] === 'object' ? prop['chart.labels.sticks.length'][i] : prop['chart.labels.sticks.length']) );
|
842
|
-
explosion_offsety += (ma.sin(angle) * (typeof prop['chart.labels.sticks.length'] === 'object' ? prop['chart.labels.sticks.length'][i] : prop['chart.labels.sticks.length']) );
|
843
|
-
}
|
844
|
-
|
845
|
-
/**
|
846
|
-
* Coords for the text
|
847
|
-
*/
|
848
|
-
var x = cx + explosion_offsetx + ((r + 10)* Math.cos(a)) + (prop['chart.labels.sticks'] ? (a < RG.HALFPI || a > (RG.TWOPI + RG.HALFPI) ? 2 : -2) : 0)
|
849
|
-
var y = cy + explosion_offsety + (((r + 10) * Math.sin(a)));
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
/**
|
855
|
-
* If sticks are enabled use the endpoints that have been saved
|
856
|
-
*/
|
857
|
-
if (this.coordsSticks && this.coordsSticks[i]) {
|
858
|
-
var x = this.coordsSticks[i][4][0] + (x < cx ? -5 : 5);
|
859
|
-
var y = this.coordsSticks[i][4][1];
|
860
|
-
}
|
861
|
-
|
862
|
-
|
863
|
-
/**
|
864
|
-
* Alignment
|
865
|
-
*/
|
866
|
-
//vAlignment = y < cy ? 'center' : 'center';
|
867
|
-
vAlignment = 'center';
|
868
|
-
hAlignment = x < cx ? 'right' : 'left';
|
869
|
-
|
870
|
-
co.fillStyle = prop['chart.text.color'];
|
871
|
-
if ( typeof(prop['chart.labels.colors']) == 'object' && prop['chart.labels.colors'] && prop['chart.labels.colors'][i]) {
|
872
|
-
co.fillStyle = prop['chart.labels.colors'][i];
|
873
|
-
}
|
874
|
-
|
875
|
-
|
876
|
-
RG.text2(this, {
|
877
|
-
'font':font,
|
878
|
-
'size':text_size,
|
879
|
-
'x':x,
|
880
|
-
'y':y,
|
881
|
-
'text':labels[i],
|
882
|
-
'valign':vAlignment,
|
883
|
-
'halign':hAlignment,
|
884
|
-
'tag': 'labels',
|
885
|
-
color: prop['chart.labels.sticks.usecolors'] ? prop['chart.colors'][i] : 'black'
|
886
|
-
});
|
887
|
-
}
|
888
|
-
|
889
|
-
co.fill();
|
890
|
-
}
|
891
|
-
};
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
//
|
897
|
-
// A new way of spacing out labels
|
898
|
-
//
|
899
|
-
this.drawLabelsList = function ()
|
900
|
-
{
|
901
|
-
var segment = this.angles[i],
|
902
|
-
labels = prop['chart.labels'],
|
903
|
-
labels_right = [],
|
904
|
-
labels_left = [],
|
905
|
-
text_font = prop['chart.text.font'],
|
906
|
-
text_size = prop['chart.text.size'],
|
907
|
-
text_color = prop['chart.text.color'],
|
908
|
-
left = [],
|
909
|
-
right = [],
|
910
|
-
centerx = this.centerx,
|
911
|
-
centery = this.centery,
|
912
|
-
radius = this.radius,
|
913
|
-
offset = 50
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
//
|
923
|
-
// Draw the right hand side labels first
|
924
|
-
//
|
925
|
-
for (var i=0; i<this.angles.length; ++i) {
|
926
|
-
|
927
|
-
var angle = this.angles[i][0] + ((this.angles[i][1] - this.angles[i][0]) / 2), // Midpoint
|
928
|
-
endpoint_inner = RG.getRadiusEndPoint(centerx, centery, angle, radius + 5),
|
929
|
-
endpoint_outer = RG.getRadiusEndPoint(centerx, centery, angle, radius + 10),
|
930
|
-
explosion = [
|
931
|
-
(typeof prop['chart.exploded'] === 'number' ? prop['chart.exploded'] : prop['chart.exploded'][i]),
|
932
|
-
(ma.cos(angle) * (typeof prop['chart.exploded'] === 'number' ? prop['chart.exploded'] : prop['chart.exploded'][i])),
|
933
|
-
(ma.sin(angle) * (typeof prop['chart.exploded'] === 'number' ? prop['chart.exploded'] : prop['chart.exploded'][i]))
|
934
|
-
]
|
935
|
-
|
936
|
-
|
937
|
-
//
|
938
|
-
// Work out the color
|
939
|
-
//
|
940
|
-
if ( typeof prop['chart.labels.sticks.colors'] === 'object' && prop['chart.labels.sticks.colors'] && prop['chart.labels.sticks.colors'][i] ) {
|
941
|
-
var color = prop['chart.labels.sticks.colors'][i];
|
942
|
-
} else if ( prop['chart.labels.sticks.usecolors'] && prop['chart.colors'][i] ) {
|
943
|
-
var color = prop['chart.colors'][i];
|
944
|
-
} else {
|
945
|
-
var color = prop['chart.text.color'];
|
946
|
-
}
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
if (angle > (-1 * RG.HALFPI) && angle < RG.HALFPI) {
|
952
|
-
labels_right.push([
|
953
|
-
i,
|
954
|
-
angle,
|
955
|
-
labels[i] ? labels[i] : '',
|
956
|
-
endpoint_inner,
|
957
|
-
endpoint_outer,
|
958
|
-
color,
|
959
|
-
RG.arrayClone(explosion)
|
960
|
-
]);
|
961
|
-
} else {
|
962
|
-
labels_left.push([
|
963
|
-
i,
|
964
|
-
angle,
|
965
|
-
labels[i] ? labels[i] : '',
|
966
|
-
endpoint_inner,
|
967
|
-
endpoint_outer,
|
968
|
-
color,
|
969
|
-
RG.arrayClone(explosion)
|
970
|
-
]);
|
971
|
-
}
|
972
|
-
}
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
//
|
978
|
-
// Draw the right hand side labels first
|
979
|
-
//
|
980
|
-
|
981
|
-
|
982
|
-
// Calculate how much space there is for each label
|
983
|
-
var vspace_right = (ca.height - prop['chart.gutter.top'] - prop['chart.gutter.bottom']) / labels_right.length
|
984
|
-
|
985
|
-
for (var i=0,y=(prop['chart.gutter.top'] + (vspace_right / 2)); i<labels_right.length; y+=vspace_right,i++) {
|
986
|
-
|
987
|
-
if (labels_right[i][2]) {
|
988
|
-
|
989
|
-
var x = this.centerx + this.radius + offset,
|
990
|
-
idx = labels_right[i][0],
|
991
|
-
explosionX = labels_right[i][6][0] ? labels_right[i][6][1] : 0,
|
992
|
-
explosionY = labels_right[i][6][0] ? labels_right[i][6][2] : 0
|
993
|
-
|
994
|
-
var ret = RG.text2(this, {
|
995
|
-
font: text_font,
|
996
|
-
size: text_size,
|
997
|
-
x: x + explosionX,
|
998
|
-
y: y + explosionY,
|
999
|
-
text: labels_right[i][2],
|
1000
|
-
valign: 'center',
|
1001
|
-
halign: 'left',
|
1002
|
-
tag: 'labels',
|
1003
|
-
color: labels_right[i][5]
|
1004
|
-
});
|
1005
|
-
|
1006
|
-
if (ret && ret.node) {
|
1007
|
-
ret.node.__index__ = labels_right[i][0];
|
1008
|
-
}
|
1009
|
-
|
1010
|
-
|
1011
|
-
pa2(co, 'lc round lw % b m % % l % % l % % l % % s %',
|
1012
|
-
|
1013
|
-
prop['chart.labels.sticks.linewidth'],
|
1014
|
-
|
1015
|
-
labels_right[i][3][0] + explosionX,
|
1016
|
-
labels_right[i][3][1] + explosionY,
|
1017
|
-
|
1018
|
-
labels_right[i][4][0] + explosionX,
|
1019
|
-
labels_right[i][4][1] + explosionY,
|
1020
|
-
|
1021
|
-
this.centerx + this.radius + 25 + explosionX,
|
1022
|
-
ma.round(labels_right[i][4][1] + explosionY),
|
1023
|
-
|
1024
|
-
ret.x - 5 ,
|
1025
|
-
ret.y + (ret.height / 2),
|
1026
|
-
|
1027
|
-
labels_right[i][5]
|
1028
|
-
);
|
1029
|
-
}
|
1030
|
-
}
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
//
|
1041
|
-
// Draw the left hand side labels
|
1042
|
-
//
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
// Calculate how much space there is for each label
|
1049
|
-
var vspace_left = (ca.height - prop['chart.gutter.top'] - prop['chart.gutter.bottom']) / labels_left.length
|
1050
|
-
|
1051
|
-
for (var i=(labels_left.length - 1),y=(prop['chart.gutter.top'] + (vspace_left / 2)); i>=0; y+=vspace_left,i--) {
|
1052
|
-
|
1053
|
-
if (labels_left[i][2]) {
|
1054
|
-
|
1055
|
-
var x = this.centerx - this.radius - offset,
|
1056
|
-
idx = labels_left[i][0],
|
1057
|
-
explosionX = labels_left[i][6][0] ? labels_left[i][6][1] : 0,
|
1058
|
-
explosionY = labels_left[i][6][0] ? labels_left[i][6][2] : 0
|
1059
|
-
|
1060
|
-
var ret = RG.text2(this, {
|
1061
|
-
font: text_font,
|
1062
|
-
size: text_size,
|
1063
|
-
x: x + explosionX,
|
1064
|
-
y: y + explosionY,
|
1065
|
-
text: labels_left[i][2],
|
1066
|
-
valign: 'center',
|
1067
|
-
halign: 'right',
|
1068
|
-
tag: 'labels',
|
1069
|
-
color: labels_left[i][5]
|
1070
|
-
});
|
1071
|
-
|
1072
|
-
if (ret && ret.node) {
|
1073
|
-
ret.node.__index__ = labels_left[i][0];
|
1074
|
-
}
|
1075
|
-
|
1076
|
-
pa2(co,
|
1077
|
-
'lw % b m % % l % % l % % l % % s %',
|
1078
|
-
|
1079
|
-
prop['chart.labels.sticks.linewidth'],
|
1080
|
-
|
1081
|
-
labels_left[i][3][0] + explosionX,
|
1082
|
-
labels_left[i][3][1] + explosionY,
|
1083
|
-
|
1084
|
-
labels_left[i][4][0] + explosionX,
|
1085
|
-
labels_left[i][4][1] + explosionY,
|
1086
|
-
|
1087
|
-
this.centerx - this.radius - 25 + explosionX,
|
1088
|
-
ma.round(labels_left[i][4][1] + explosionY),
|
1089
|
-
|
1090
|
-
ret.x + 5 + ret.width,
|
1091
|
-
ret.y + (ret.height / 2),
|
1092
|
-
|
1093
|
-
labels_left[i][5]
|
1094
|
-
);
|
1095
|
-
}
|
1096
|
-
}
|
1097
|
-
};
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
/**
|
1118
|
-
* This function draws the pie chart sticks (for the labels)
|
1119
|
-
*/
|
1120
|
-
this.drawSticks =
|
1121
|
-
this.DrawSticks = function ()
|
1122
|
-
{
|
1123
|
-
var offset = prop['chart.linewidth'] / 2,
|
1124
|
-
exploded = prop['chart.exploded'],
|
1125
|
-
sticks = prop['chart.labels.sticks'],
|
1126
|
-
colors = prop['chart.colors'],
|
1127
|
-
cx = this.centerx,
|
1128
|
-
cy = this.centery,
|
1129
|
-
radius = this.radius,
|
1130
|
-
points = [],
|
1131
|
-
linewidth = prop['chart.labels.sticks.linewidth']
|
1132
|
-
|
1133
|
-
for (var i=0,len=this.angles.length; i<len; ++i) {
|
1134
|
-
|
1135
|
-
var segment = this.angles[i];
|
1136
|
-
|
1137
|
-
// This allows the chart.labels.sticks to be an array as well as a boolean
|
1138
|
-
if (typeof sticks === 'object' && !sticks[i]) {
|
1139
|
-
continue;
|
1140
|
-
}
|
1141
|
-
|
1142
|
-
var radians = segment[1] - segment[0];
|
1143
|
-
|
1144
|
-
co.beginPath();
|
1145
|
-
co.strokeStyle = typeof prop['chart.labels.sticks.colors'] === 'string' ? prop['chart.labels.sticks.colors'] : (!RG.isNull(prop['chart.labels.sticks.colors']) ? prop['chart.labels.sticks.colors'][0] : 'gray');
|
1146
|
-
co.lineWidth = linewidth;
|
1147
|
-
|
1148
|
-
if (typeof prop['chart.labels.sticks.color'] === 'string') {
|
1149
|
-
co.strokeStyle = prop['chart.labels.sticks.color'];
|
1150
|
-
}
|
1151
|
-
|
1152
|
-
//
|
1153
|
-
// Allow for labelsSticksUseColors
|
1154
|
-
//
|
1155
|
-
if (prop['chart.labels.sticks.usecolors']) {
|
1156
|
-
co.strokeStyle = prop['chart.colors'][i];
|
1157
|
-
}
|
1158
|
-
|
1159
|
-
var midpoint = (segment[0] + (radians / 2));
|
1160
|
-
|
1161
|
-
if (typeof exploded === 'object' && exploded[i]) {
|
1162
|
-
var extra = exploded[i];
|
1163
|
-
} else if (typeof exploded === 'number') {
|
1164
|
-
var extra = exploded;
|
1165
|
-
} else {
|
1166
|
-
var extra = 0;
|
1167
|
-
}
|
1168
|
-
|
1169
|
-
/**
|
1170
|
-
* Determine the stick length
|
1171
|
-
*/
|
1172
|
-
var stickLength = typeof prop['chart.labels.sticks.length'] === 'object' ? prop['chart.labels.sticks.length'][i] : prop['chart.labels.sticks.length'];
|
1173
|
-
|
1174
|
-
|
1175
|
-
points[0] = RG.getRadiusEndPoint(cx, cy, midpoint, radius + extra + offset);
|
1176
|
-
points[1] = RG.getRadiusEndPoint(cx, cy, midpoint, radius + stickLength + extra - 5);
|
1177
|
-
|
1178
|
-
points[2] = RG.getRadiusEndPoint(cx, cy, midpoint, radius + stickLength + extra);
|
1179
|
-
|
1180
|
-
points[3] = RG.getRadiusEndPoint(cx, cy, midpoint, radius + stickLength + extra);
|
1181
|
-
points[3][0] += (points[3][0] > cx ? 5 : -5);
|
1182
|
-
|
1183
|
-
points[4] = [
|
1184
|
-
points[2][0] + (points[2][0] > cx ? 5 + prop['chart.labels.sticks.hlength'] : -5 - prop['chart.labels.sticks.hlength']),
|
1185
|
-
points[2][1]
|
1186
|
-
];
|
1187
|
-
|
1188
|
-
|
1189
|
-
co.moveTo(points[0][0], points[0][1]);
|
1190
|
-
co.quadraticCurveTo(points[2][0], points[2][1], points[4][0], points[4][1]);
|
1191
|
-
|
1192
|
-
co.stroke();
|
1193
|
-
|
1194
|
-
/**
|
1195
|
-
* Save the stick end coords
|
1196
|
-
*/
|
1197
|
-
this.coordsSticks[i] = [points[0],points[1], points[2], points[3], points[4]];
|
1198
|
-
}
|
1199
|
-
};
|
1200
|
-
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1204
|
-
/**
|
1205
|
-
* The (now Pie chart specific) getSegment function
|
1206
|
-
*
|
1207
|
-
* @param object e The event object
|
1208
|
-
*/
|
1209
|
-
this.getShape =
|
1210
|
-
this.getSegment = function (e)
|
1211
|
-
{
|
1212
|
-
RG.FixEventObject(e);
|
1213
|
-
|
1214
|
-
// The optional arg provides a way of allowing some accuracy (pixels)
|
1215
|
-
var accuracy = arguments[1] ? arguments[1] : 0;
|
1216
|
-
|
1217
|
-
var canvas = ca;
|
1218
|
-
var context = co;
|
1219
|
-
var mouseCoords = RG.getMouseXY(e);
|
1220
|
-
var mouseX = mouseCoords[0];
|
1221
|
-
var mouseY = mouseCoords[1];
|
1222
|
-
var r = this.radius;
|
1223
|
-
var angles = this.angles;
|
1224
|
-
var ret = [];
|
1225
|
-
|
1226
|
-
for (var i=0,len=angles.length; i<len; ++i) {
|
1227
|
-
|
1228
|
-
// DRAW THE SEGMENT AGAIN SO IT CAN BE TESTED //////////////////////////
|
1229
|
-
co.beginPath();
|
1230
|
-
co.strokeStyle = 'rgba(0,0,0,0)';
|
1231
|
-
co.arc(angles[i][2], angles[i][3], this.radius, angles[i][0], angles[i][1], false);
|
1232
|
-
|
1233
|
-
if (this.type == 'pie' && prop['chart.variant'] == 'donut') {
|
1234
|
-
co.arc(angles[i][2], angles[i][3], (typeof(prop['chart.variant.donut.width']) == 'number' ? this.radius - prop['chart.variant.donut.width'] : this.radius / 2), angles[i][1], angles[i][0], true);
|
1235
|
-
} else {
|
1236
|
-
co.lineTo(angles[i][2], angles[i][3]);
|
1237
|
-
}
|
1238
|
-
co.closePath();
|
1239
|
-
|
1240
|
-
if (!co.isPointInPath(mouseX, mouseY)) {
|
1241
|
-
continue;
|
1242
|
-
}
|
1243
|
-
|
1244
|
-
////////////////////////////////////////////////////////////////////////
|
1245
|
-
|
1246
|
-
ret[0] = angles[i][2];
|
1247
|
-
ret[1] = angles[i][3];
|
1248
|
-
ret[2] = this.radius;
|
1249
|
-
ret[3] = angles[i][0] - RG.TWOPI;
|
1250
|
-
ret[4] = angles[i][1];
|
1251
|
-
ret[5] = i;
|
1252
|
-
|
1253
|
-
|
1254
|
-
|
1255
|
-
if (ret[3] < 0) ret[3] += RG.TWOPI;
|
1256
|
-
if (ret[4] > RG.TWOPI) ret[4] -= RG.TWOPI;
|
1257
|
-
|
1258
|
-
/**
|
1259
|
-
* Add the tooltip to the returned shape
|
1260
|
-
*/
|
1261
|
-
var tooltip = RG.parseTooltipText ? RG.parseTooltipText(prop['chart.tooltips'], ret[5]) : null;
|
1262
|
-
|
1263
|
-
/**
|
1264
|
-
* Now return textual keys as well as numerics
|
1265
|
-
*/
|
1266
|
-
ret['object'] = this;
|
1267
|
-
ret['x'] = ret[0];
|
1268
|
-
ret['y'] = ret[1];
|
1269
|
-
ret['radius'] = ret[2];
|
1270
|
-
ret['angle.start'] = ret[3];
|
1271
|
-
ret['angle.end'] = ret[4];
|
1272
|
-
ret['index'] = ret[5];
|
1273
|
-
ret['tooltip'] = tooltip;
|
1274
|
-
|
1275
|
-
return ret;
|
1276
|
-
}
|
1277
|
-
|
1278
|
-
return null;
|
1279
|
-
};
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
this.drawBorders =
|
1285
|
-
this.DrawBorders = function ()
|
1286
|
-
{
|
1287
|
-
if (prop['chart.linewidth'] > 0) {
|
1288
|
-
|
1289
|
-
co.lineWidth = prop['chart.linewidth'];
|
1290
|
-
co.strokeStyle = prop['chart.strokestyle'];
|
1291
|
-
|
1292
|
-
var r = this.radius;
|
1293
|
-
|
1294
|
-
for (var i=0,len=this.angles.length; i<len; ++i) {
|
1295
|
-
|
1296
|
-
var segment = this.angles[i];
|
1297
|
-
|
1298
|
-
co.beginPath();
|
1299
|
-
co.arc(segment[2],
|
1300
|
-
segment[3],
|
1301
|
-
r,
|
1302
|
-
(segment[0]),
|
1303
|
-
(segment[0] + 0.001),
|
1304
|
-
0);
|
1305
|
-
co.arc(segment[2],
|
1306
|
-
segment[3],
|
1307
|
-
prop['chart.variant'] == 'donut' ? (typeof(prop['chart.variant.donut.width']) == 'number' ? this.radius - prop['chart.variant.donut.width'] : r / 2): r,
|
1308
|
-
segment[0],
|
1309
|
-
segment[0] + 0.0001,
|
1310
|
-
0);
|
1311
|
-
co.closePath();
|
1312
|
-
co.stroke();
|
1313
|
-
}
|
1314
|
-
}
|
1315
|
-
};
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
/**
|
1321
|
-
* Returns the radius of the pie chart
|
1322
|
-
*
|
1323
|
-
* [06-02-2012] Maintained for compatibility ONLY.
|
1324
|
-
*/
|
1325
|
-
this.getRadius = function ()
|
1326
|
-
{
|
1327
|
-
this.graph = {width: ca.width - prop['chart.gutter.left'] - prop['chart.gutter.right'], height: ca.height - prop['chart.gutter.top'] - prop['chart.gutter.bottom']}
|
1328
|
-
|
1329
|
-
if (typeof(prop['chart.radius']) == 'number') {
|
1330
|
-
this.radius = prop['chart.radius'];
|
1331
|
-
} else {
|
1332
|
-
this.radius = Math.min(this.graph.width, this.graph.height) / 2;
|
1333
|
-
}
|
1334
|
-
|
1335
|
-
return this.radius;
|
1336
|
-
};
|
1337
|
-
|
1338
|
-
|
1339
|
-
|
1340
|
-
|
1341
|
-
/**
|
1342
|
-
* A programmatic explode function
|
1343
|
-
*
|
1344
|
-
* @param object obj The chart object
|
1345
|
-
* @param number index The zero-indexed number of the segment
|
1346
|
-
* @param number size The size (in pixels) of the explosion
|
1347
|
-
*/
|
1348
|
-
this.explodeSegment =
|
1349
|
-
this.Explode = function (index, size)
|
1350
|
-
{
|
1351
|
-
//this.Set('chart.exploded', []);
|
1352
|
-
if (!prop['chart.exploded']) {
|
1353
|
-
prop['chart.exploded'] = [];
|
1354
|
-
}
|
1355
|
-
|
1356
|
-
// If chart.exploded is a number - convert it to an array
|
1357
|
-
if (typeof(prop['chart.exploded']) == 'number') {
|
1358
|
-
|
1359
|
-
var original_explode = prop['chart.exploded'];
|
1360
|
-
var exploded = prop['chart.exploded'];
|
1361
|
-
|
1362
|
-
prop['chart.exploded'] = [];
|
1363
|
-
|
1364
|
-
for (var i=0,len=this.data.length; i<len; ++i) {
|
1365
|
-
prop['chart.exploded'][i] = exploded;
|
1366
|
-
}
|
1367
|
-
}
|
1368
|
-
|
1369
|
-
prop['chart.exploded'][index] = typeof(original_explode) == 'number' ? original_explode : 0;
|
1370
|
-
|
1371
|
-
for (var o=0; o<size; ++o) {
|
1372
|
-
|
1373
|
-
setTimeout(
|
1374
|
-
function ()
|
1375
|
-
{
|
1376
|
-
prop['chart.exploded'][index] += 1;
|
1377
|
-
RG.Clear(ca);
|
1378
|
-
RG.RedrawCanvas(ca);
|
1379
|
-
}, o * (RGraph.ISIE && !RGraph.ISIE10 ? 25 : 16.666));
|
1380
|
-
}
|
1381
|
-
};
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
/**
|
1387
|
-
* This function highlights a segment
|
1388
|
-
*
|
1389
|
-
* @param array segment The segment information that is returned by the pie.getSegment(e) function
|
1390
|
-
*/
|
1391
|
-
this.highlight_segment = function (segment)
|
1392
|
-
{
|
1393
|
-
co.beginPath();
|
1394
|
-
co.strokeStyle = prop['chart.highlight.style.twod.stroke'];
|
1395
|
-
co.fillStyle = prop['chart.highlight.style.twod.fill'];
|
1396
|
-
co.moveTo(segment[0], segment[1]);
|
1397
|
-
co.arc(segment[0], segment[1], segment[2], this.angles[segment[5]][0], this.angles[segment[5]][1], 0);
|
1398
|
-
co.lineTo(segment[0], segment[1]);
|
1399
|
-
co.closePath();
|
1400
|
-
|
1401
|
-
co.stroke();
|
1402
|
-
co.fill();
|
1403
|
-
};
|
1404
|
-
|
1405
|
-
|
1406
|
-
|
1407
|
-
|
1408
|
-
/**
|
1409
|
-
* Each object type has its own Highlight() function which highlights
|
1410
|
-
* the appropriate shape
|
1411
|
-
*
|
1412
|
-
* @param object shape The shape to highlight
|
1413
|
-
*/
|
1414
|
-
this.highlight =
|
1415
|
-
this.Highlight = function (shape)
|
1416
|
-
{
|
1417
|
-
if (prop['chart.tooltips.highlight']) {
|
1418
|
-
|
1419
|
-
if (typeof prop['chart.highlight.style'] === 'function') {
|
1420
|
-
(prop['chart.highlight.style'])(shape);
|
1421
|
-
|
1422
|
-
/**
|
1423
|
-
* 3D style of highlighting
|
1424
|
-
*/
|
1425
|
-
} else if (prop['chart.highlight.style'] == '3d') {
|
1426
|
-
|
1427
|
-
co.lineWidth = 1;
|
1428
|
-
|
1429
|
-
// This is the extent of the 2D effect. Bigger values will give the appearance of a larger "protusion"
|
1430
|
-
var extent = 2;
|
1431
|
-
|
1432
|
-
// Draw a white-out where the segment is
|
1433
|
-
co.beginPath();
|
1434
|
-
RG.NoShadow(this);
|
1435
|
-
co.fillStyle = 'rgba(0,0,0,0)';
|
1436
|
-
co.arc(shape['x'], shape['y'], shape['radius'], shape['angle.start'], shape['angle.end'], false);
|
1437
|
-
if (prop['chart.variant'] == 'donut') {
|
1438
|
-
co.arc(shape['x'], shape['y'], shape['radius'] / 5, shape['angle.end'], shape['angle.start'], true);
|
1439
|
-
} else {
|
1440
|
-
co.lineTo(shape['x'], shape['y']);
|
1441
|
-
}
|
1442
|
-
co.closePath();
|
1443
|
-
co.fill();
|
1444
|
-
|
1445
|
-
// Draw the new segment
|
1446
|
-
co.beginPath();
|
1447
|
-
|
1448
|
-
co.shadowColor = '#666';
|
1449
|
-
co.shadowBlur = 3;
|
1450
|
-
co.shadowOffsetX = 3;
|
1451
|
-
co.shadowOffsetY = 3;
|
1452
|
-
|
1453
|
-
co.fillStyle = prop['chart.colors'][shape['index']];
|
1454
|
-
co.strokeStyle = prop['chart.strokestyle'];
|
1455
|
-
co.arc(shape['x'] - extent, shape['y'] - extent, shape['radius'], shape['angle.start'], shape['angle.end'], false);
|
1456
|
-
if (prop['chart.variant'] == 'donut') {
|
1457
|
-
co.arc(shape['x'] - extent, shape['y'] - extent, shape['radius'] / 2, shape['angle.end'], shape['angle.start'], true)
|
1458
|
-
} else {
|
1459
|
-
co.lineTo(shape['x'] - extent, shape['y'] - extent);
|
1460
|
-
}
|
1461
|
-
co.closePath();
|
1462
|
-
|
1463
|
-
co.stroke();
|
1464
|
-
co.fill();
|
1465
|
-
|
1466
|
-
// Turn off the shadow
|
1467
|
-
RG.NoShadow(this);
|
1468
|
-
|
1469
|
-
/**
|
1470
|
-
* If a border is defined, redraw that
|
1471
|
-
*/
|
1472
|
-
if (prop['chart.border']) {
|
1473
|
-
co.beginPath();
|
1474
|
-
co.strokeStyle = prop['chart.border.color'];
|
1475
|
-
co.lineWidth = 5;
|
1476
|
-
co.arc(shape['x'] - extent, shape['y'] - extent, shape['radius'] - 2, shape['angle.start'], shape['angle.end'], false);
|
1477
|
-
co.stroke();
|
1478
|
-
}
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
// Outline style of highlighting
|
1484
|
-
} else if (prop['chart.highlight.style'] === 'outline') {
|
1485
|
-
|
1486
|
-
var tooltip = RG.Registry.get('chart.tooltip'),
|
1487
|
-
index = tooltip.__index__,
|
1488
|
-
coords = this.angles[index],
|
1489
|
-
color = this.get('colors')[index]
|
1490
|
-
width = this.radius / 12.5;
|
1491
|
-
|
1492
|
-
// Allow custom setting of outline
|
1493
|
-
if (typeof prop['chart.highlight.style.outline.width'] === 'number') {
|
1494
|
-
width = prop['chart.highlight.style.outline.width'];
|
1495
|
-
}
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
RGraph.path2(
|
1500
|
-
co,
|
1501
|
-
'ga 0.25 b a % % % % % false a % % % % % true c f % ga 1',
|
1502
|
-
coords[2],
|
1503
|
-
coords[3],
|
1504
|
-
this.radius + 2 + width,
|
1505
|
-
coords[0],
|
1506
|
-
coords[1],
|
1507
|
-
|
1508
|
-
coords[2],
|
1509
|
-
coords[3],
|
1510
|
-
this.radius + 2,
|
1511
|
-
coords[1],
|
1512
|
-
coords[0],
|
1513
|
-
color
|
1514
|
-
);
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
// Default 2D style of highlighting
|
1522
|
-
} else {
|
1523
|
-
|
1524
|
-
co.beginPath();
|
1525
|
-
|
1526
|
-
co.strokeStyle = prop['chart.highlight.style.twod.stroke'];
|
1527
|
-
co.fillStyle = prop['chart.highlight.style.twod.fill'];
|
1528
|
-
|
1529
|
-
if (prop['chart.variant'].indexOf('donut') > -1) {
|
1530
|
-
co.arc(shape['x'], shape['y'], shape['radius'], shape['angle.start'], shape['angle.end'], false);
|
1531
|
-
co.arc(shape['x'], shape['y'], typeof(prop['chart.variant.donut.width']) == 'number' ? this.radius - prop['chart.variant.donut.width'] : shape['radius'] / 2, shape['angle.end'], shape['angle.start'], true);
|
1532
|
-
} else {
|
1533
|
-
co.arc(shape['x'], shape['y'], shape['radius'] + 1, shape['angle.start'], shape['angle.end'], false);
|
1534
|
-
co.lineTo(shape['x'], shape['y']);
|
1535
|
-
}
|
1536
|
-
co.closePath();
|
1537
|
-
|
1538
|
-
co.stroke();
|
1539
|
-
co.fill();
|
1540
|
-
}
|
1541
|
-
}
|
1542
|
-
};
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
/**
|
1548
|
-
* The getObjectByXY() worker method. The Pie chart is able to use the
|
1549
|
-
* getShape() method - so it does.
|
1550
|
-
*/
|
1551
|
-
this.getObjectByXY = function (e)
|
1552
|
-
{
|
1553
|
-
if (this.getShape(e)) {
|
1554
|
-
return this;
|
1555
|
-
}
|
1556
|
-
};
|
1557
|
-
|
1558
|
-
|
1559
|
-
|
1560
|
-
|
1561
|
-
/**
|
1562
|
-
* Draws the centerpin if requested
|
1563
|
-
*/
|
1564
|
-
this.drawCenterpin =
|
1565
|
-
this.DrawCenterpin = function ()
|
1566
|
-
{
|
1567
|
-
if (typeof(prop['chart.centerpin']) == 'number' && prop['chart.centerpin'] > 0) {
|
1568
|
-
|
1569
|
-
var cx = this.centerx;
|
1570
|
-
var cy = this.centery;
|
1571
|
-
|
1572
|
-
co.beginPath();
|
1573
|
-
co.strokeStyle = prop['chart.centerpin.stroke'] ? prop['chart.centerpin.stroke'] : prop['chart.strokestyle'];
|
1574
|
-
co.fillStyle = prop['chart.centerpin.fill'] ? prop['chart.centerpin.fill'] : prop['chart.strokestyle'];
|
1575
|
-
co.moveTo(cx, cy);
|
1576
|
-
co.arc(cx, cy, prop['chart.centerpin'], 0, RG.TWOPI, false);
|
1577
|
-
co.stroke();
|
1578
|
-
co.fill();
|
1579
|
-
}
|
1580
|
-
};
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
/**
|
1586
|
-
* This function positions a tooltip when it is displayed
|
1587
|
-
*
|
1588
|
-
* @param obj object The chart object
|
1589
|
-
* @param int x The X coordinate specified for the tooltip
|
1590
|
-
* @param int y The Y coordinate specified for the tooltip
|
1591
|
-
* @param objec tooltip The tooltips DIV element
|
1592
|
-
*/
|
1593
|
-
this.positionTooltip = function (obj, x, y, tooltip, idx)
|
1594
|
-
{
|
1595
|
-
var coordX = obj.angles[idx][2];
|
1596
|
-
var coordY = obj.angles[idx][3];
|
1597
|
-
var mouseXY = RG.getMouseXY(window.event);
|
1598
|
-
var angleStart = obj.angles[idx][0];
|
1599
|
-
var angleEnd = obj.angles[idx][1];
|
1600
|
-
var angleCenter = ((angleEnd - angleStart) / 2) + angleStart;
|
1601
|
-
var canvasXY = RGraph.getCanvasXY(obj.canvas);
|
1602
|
-
var gutterLeft = prop['chart.gutter.left'];
|
1603
|
-
var gutterTop = prop['chart.gutter.top'];
|
1604
|
-
var width = tooltip.offsetWidth;
|
1605
|
-
var height = tooltip.offsetHeight;
|
1606
|
-
var x = canvasXY[0] + this.angles[idx][2] + (Math.cos(angleCenter) * (prop['chart.variant'] == 'donut' && typeof(prop['chart.variant.donut.width']) == 'number' ? ((this.radius - prop['chart.variant.donut.width']) + (prop['chart.variant.donut.width'] / 2)) : (this.radius * 0.5)));
|
1607
|
-
var y = canvasXY[1] + this.angles[idx][3] + (Math.sin(angleCenter) * (prop['chart.variant'] == 'donut' && typeof(prop['chart.variant.donut.width']) == 'number' ? ((this.radius - prop['chart.variant.donut.width']) + (prop['chart.variant.donut.width'] / 2)) : (this.radius * 0.5)));
|
1608
|
-
|
1609
|
-
|
1610
|
-
// By default any overflow is hidden
|
1611
|
-
tooltip.style.overflow = '';
|
1612
|
-
|
1613
|
-
// Set the top position
|
1614
|
-
tooltip.style.left = 0;
|
1615
|
-
tooltip.style.top = window.event.pageY - height - 5 + 'px';
|
1616
|
-
|
1617
|
-
|
1618
|
-
// Reposition the tooltip if at the edges:
|
1619
|
-
|
1620
|
-
// LEFT edge
|
1621
|
-
if (canvasXY[0] + mouseXY[0] - (width / 2) < 0) {
|
1622
|
-
tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.1) + 'px';
|
1623
|
-
|
1624
|
-
// RIGHT edge
|
1625
|
-
} else if (canvasXY[0] + mouseXY[0] + (width / 2) > doc.body.offsetWidth) {
|
1626
|
-
tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.9) + 'px';
|
1627
|
-
|
1628
|
-
// Default positioning - CENTERED
|
1629
|
-
} else {
|
1630
|
-
tooltip.style.left = canvasXY[0] + mouseXY[0] - (width / 2) + 'px';
|
1631
|
-
}
|
1632
|
-
};
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1637
|
-
/**
|
1638
|
-
* This draws Ingraph labels
|
1639
|
-
*/
|
1640
|
-
this.drawInGraphLabels =
|
1641
|
-
this.DrawInGraphLabels = function ()
|
1642
|
-
{
|
1643
|
-
var context = co;
|
1644
|
-
var cx = this.centerx;
|
1645
|
-
var cy = this.centery;
|
1646
|
-
var radius = prop['chart.labels.ingraph.radius'];
|
1647
|
-
|
1648
|
-
//
|
1649
|
-
// Is the radius less than 2? If so then it's a factor and not n exact point
|
1650
|
-
//
|
1651
|
-
if (radius <= 2 && radius > 0) {
|
1652
|
-
radiusFactor = radius;
|
1653
|
-
} else {
|
1654
|
-
radiusFactor = 0.5;
|
1655
|
-
}
|
1656
|
-
|
1657
|
-
if (prop['chart.variant'] == 'donut') {
|
1658
|
-
var r = this.radius * (0.5 + (radiusFactor * 0.5));
|
1659
|
-
|
1660
|
-
if (typeof(prop['chart.variant.donut.width']) == 'number') {
|
1661
|
-
var r = (this.radius - prop['chart.variant.donut.width']) + (prop['chart.variant.donut.width'] / 2);
|
1662
|
-
}
|
1663
|
-
} else {
|
1664
|
-
var r = this.radius * radiusFactor;
|
1665
|
-
}
|
1666
|
-
|
1667
|
-
if (radius > 2) {
|
1668
|
-
r = radius;
|
1669
|
-
}
|
1670
|
-
|
1671
|
-
for (var i=0,len=this.angles.length; i<len; ++i) {
|
1672
|
-
|
1673
|
-
// This handles any explosion that the segment may have
|
1674
|
-
if (typeof(prop['chart.exploded']) == 'object' && typeof(prop['chart.exploded'][i]) == 'number') {
|
1675
|
-
var explosion = prop['chart.exploded'][i];
|
1676
|
-
} else if (typeof(prop['chart.exploded']) == 'number') {
|
1677
|
-
var explosion = parseInt(prop['chart.exploded']);
|
1678
|
-
} else {
|
1679
|
-
var explosion = 0;
|
1680
|
-
}
|
1681
|
-
|
1682
|
-
var angleStart = this.angles[i][0];
|
1683
|
-
var angleEnd = this.angles[i][1];
|
1684
|
-
var angleCenter = ((angleEnd - angleStart) / 2) + angleStart;
|
1685
|
-
var coords = RG.getRadiusEndPoint(
|
1686
|
-
this.centerx,
|
1687
|
-
this.centery,
|
1688
|
-
angleCenter,
|
1689
|
-
r + (explosion ? explosion : 0)
|
1690
|
-
);
|
1691
|
-
|
1692
|
-
var x = coords[0];
|
1693
|
-
var y = coords[1];
|
1694
|
-
|
1695
|
-
var text = prop['chart.labels.ingraph.specific'] && typeof(prop['chart.labels.ingraph.specific'][i]) == 'string' ? prop['chart.labels.ingraph.specific'][i] : RG.number_format(this, this.data[i], prop['chart.labels.ingraph.units.pre'] , prop['chart.labels.ingraph.units.post']);
|
1696
|
-
|
1697
|
-
if (text) {
|
1698
|
-
co.beginPath();
|
1699
|
-
|
1700
|
-
var font = typeof prop['chart.labels.ingraph.font'] === 'string' ? prop['chart.labels.ingraph.font'] : prop['chart.text.font'];
|
1701
|
-
var size = typeof prop['chart.labels.ingraph.size'] === 'number' ? prop['chart.labels.ingraph.size'] : prop['chart.text.size'] + 2;
|
1702
|
-
|
1703
|
-
//
|
1704
|
-
// Set the colors
|
1705
|
-
//
|
1706
|
-
co.fillStyle = prop['chart.labels.ingraph.color'] ? prop['chart.labels.ingraph.color'] : 'black';
|
1707
|
-
|
1708
|
-
RG.Text2(this, {
|
1709
|
-
'font':font,
|
1710
|
-
'size':size,
|
1711
|
-
'x':x,
|
1712
|
-
'y':y,
|
1713
|
-
'text':text,
|
1714
|
-
'valign':'center',
|
1715
|
-
'halign':'center',
|
1716
|
-
'bounding': prop['chart.labels.ingraph.bounding'],
|
1717
|
-
'bounding.fill': prop['chart.labels.ingraph.bounding.fill'],
|
1718
|
-
'tag':'labels.ingraph'
|
1719
|
-
});
|
1720
|
-
co.stroke();
|
1721
|
-
}
|
1722
|
-
}
|
1723
|
-
};
|
1724
|
-
|
1725
|
-
|
1726
|
-
|
1727
|
-
|
1728
|
-
//
|
1729
|
-
// Draws the center label if required
|
1730
|
-
//
|
1731
|
-
this.drawCenterLabel = function (label)
|
1732
|
-
{
|
1733
|
-
var font = prop['chart.labels.center.font'],
|
1734
|
-
size = prop['chart.labels.center.size'],
|
1735
|
-
color = prop['chart.labels.center.color'],
|
1736
|
-
unitsPre = prop['chart.labels.center.units.pre'],
|
1737
|
-
unitsPost = prop['chart.labels.center.units.post'],
|
1738
|
-
bold = prop['chart.labels.center.bold'],
|
1739
|
-
italic = prop['chart.labels.center.italic'];
|
1740
|
-
|
1741
|
-
|
1742
|
-
RG.text2(this, {
|
1743
|
-
color: color,
|
1744
|
-
bold: bold,
|
1745
|
-
italic: italic,
|
1746
|
-
font: font,
|
1747
|
-
size: size,
|
1748
|
-
x: this.centerx,
|
1749
|
-
y: this.centery,
|
1750
|
-
halign: 'center',
|
1751
|
-
valign: 'center',
|
1752
|
-
text: RG.numberFormat(this, label,unitsPre, unitsPost)
|
1753
|
-
});
|
1754
|
-
}
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
/**
|
1760
|
-
* This returns the angle for a value based around the maximum number
|
1761
|
-
*
|
1762
|
-
* @param number value The value to get the angle for
|
1763
|
-
*/
|
1764
|
-
this.getAngle = function (value)
|
1765
|
-
{
|
1766
|
-
if (value > this.total) {
|
1767
|
-
return null;
|
1768
|
-
}
|
1769
|
-
|
1770
|
-
var angle = (value / this.total) * RG.TWOPI;
|
1771
|
-
|
1772
|
-
// Handle the origin (it can br -HALFPI or 0)
|
1773
|
-
angle += prop['chart.origin'];
|
1774
|
-
|
1775
|
-
return angle;
|
1776
|
-
};
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
/**
|
1782
|
-
* This allows for easy specification of gradients
|
1783
|
-
*/
|
1784
|
-
this.parseColors = function ()
|
1785
|
-
{
|
1786
|
-
// Save the original colors so that they can be restored when the canvas is reset
|
1787
|
-
if (this.original_colors.length === 0) {
|
1788
|
-
this.original_colors['chart.colors'] = RG.arrayClone(prop['chart.colors']);
|
1789
|
-
this.original_colors['chart.key.colors'] = RG.arrayClone(prop['chart.key.colors']);
|
1790
|
-
this.original_colors['chart.strokestyle'] = RG.arrayClone(prop['chart.strokestyle']);
|
1791
|
-
this.original_colors['chart.highlight.stroke'] = RG.arrayClone(prop['chart.highlight.stroke']);
|
1792
|
-
this.original_colors['chart.highlight.style.twod.fill'] = RG.arrayClone(prop['chart.highlight.style.twod.fill']);
|
1793
|
-
this.original_colors['chart.highlight.style.twod.stroke'] = RG.arrayClone(prop['chart.highlight.style.twod.stroke']);
|
1794
|
-
this.original_colors['chart.ingraph.bounding.fill'] = RG.arrayClone(prop['chart.ingraph.bounding.fill']);
|
1795
|
-
this.original_colors['chart.ingraph.color'] = RG.arrayClone(prop['chart.ingraph.color']);
|
1796
|
-
}
|
1797
|
-
|
1798
|
-
for (var i=0; i<prop['chart.colors'].length; ++i) {
|
1799
|
-
prop['chart.colors'][i] = this.parseSingleColorForGradient(prop['chart.colors'][i]);
|
1800
|
-
}
|
1801
|
-
|
1802
|
-
var keyColors = prop['chart.key.colors'];
|
1803
|
-
if (keyColors) {
|
1804
|
-
for (var i=0; i<keyColors.length; ++i) {
|
1805
|
-
keyColors[i] = this.parseSingleColorForGradient(keyColors[i]);
|
1806
|
-
}
|
1807
|
-
}
|
1808
|
-
|
1809
|
-
prop['chart.strokestyle'] = this.parseSingleColorForGradient(prop['chart.strokestyle']);
|
1810
|
-
prop['chart.highlight.stroke'] = this.parseSingleColorForGradient(prop['chart.highlight.stroke']);
|
1811
|
-
prop['chart.highlight.style.twod.fill'] = this.parseSingleColorForGradient(prop['chart.highlight.style.twod.fill']);
|
1812
|
-
prop['chart.highlight.style.twod.stroke'] = this.parseSingleColorForGradient(prop['chart.highlight.style.twod.stroke']);
|
1813
|
-
prop['chart.labels.ingraph.bounding.fill'] = this.parseSingleColorForGradient(prop['chart.labels.ingraph.bounding.fill']);
|
1814
|
-
prop['chart.labels.ingraph.color'] = this.parseSingleColorForGradient(prop['chart.labels.ingraph.color']);
|
1815
|
-
};
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
/**
|
1821
|
-
* Use this function to reset the object to the post-constructor state. Eg reset colors if
|
1822
|
-
* need be etc
|
1823
|
-
*/
|
1824
|
-
this.reset = function ()
|
1825
|
-
{
|
1826
|
-
};
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
/**
|
1832
|
-
* This parses a single color value
|
1833
|
-
*/
|
1834
|
-
this.parseSingleColorForGradient = function (color)
|
1835
|
-
{
|
1836
|
-
|
1837
|
-
if (!color || typeof(color) != 'string') {
|
1838
|
-
return color;
|
1839
|
-
}
|
1840
|
-
|
1841
|
-
if (color.match(/^gradient\((.*)\)$/i)) {
|
1842
|
-
|
1843
|
-
var parts = RegExp.$1.split(':');
|
1844
|
-
|
1845
|
-
// If the chart is a donut - the first width should half the total radius
|
1846
|
-
if (prop['chart.variant'] == 'donut') {
|
1847
|
-
var radius_start = typeof(prop['chart.variant.donut.width']) == 'number' ? this.radius - prop['chart.variant.donut.width'] : this.radius / 2;
|
1848
|
-
} else {
|
1849
|
-
var radius_start = 0;
|
1850
|
-
}
|
1851
|
-
|
1852
|
-
// Create the gradient
|
1853
|
-
var grad = co.createRadialGradient(this.centerx, this.centery, radius_start, this.centerx, this.centery, Math.min(ca.width - prop['chart.gutter.left'] - prop['chart.gutter.right'], ca.height - prop['chart.gutter.top'] - prop['chart.gutter.bottom']) / 2);
|
1854
|
-
|
1855
|
-
|
1856
|
-
var diff = 1 / (parts.length - 1);
|
1857
|
-
|
1858
|
-
grad.addColorStop(0, RG.trim(parts[0]));
|
1859
|
-
|
1860
|
-
for (var j=1; j<parts.length; ++j) {
|
1861
|
-
grad.addColorStop(j * diff, RG.trim(parts[j]));
|
1862
|
-
}
|
1863
|
-
}
|
1864
|
-
|
1865
|
-
return grad ? grad : color;
|
1866
|
-
};
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1871
|
-
/**
|
1872
|
-
* This function handles highlighting an entire data-series for the interactive
|
1873
|
-
* key
|
1874
|
-
*
|
1875
|
-
* @param int index The index of the data series to be highlighted
|
1876
|
-
*/
|
1877
|
-
this.interactiveKeyHighlight = function (index)
|
1878
|
-
{
|
1879
|
-
if (this.angles && this.angles[index]) {
|
1880
|
-
|
1881
|
-
var segment = this.angles[index];
|
1882
|
-
var x = segment[2];
|
1883
|
-
var y = segment[3];
|
1884
|
-
var start = segment[0];
|
1885
|
-
var end = segment[1];
|
1886
|
-
|
1887
|
-
co.strokeStyle = prop['chart.key.interactive.highlight.chart.stroke'];
|
1888
|
-
co.fillStyle = prop['chart.key.interactive.highlight.chart.fill'];
|
1889
|
-
co.lineWidth = 2;
|
1890
|
-
co.lineJoin = 'bevel';
|
1891
|
-
|
1892
|
-
co.beginPath();
|
1893
|
-
co.moveTo(x, y);
|
1894
|
-
co.arc(x, y, this.radius, start, end, false);
|
1895
|
-
co.closePath();
|
1896
|
-
co.fill();
|
1897
|
-
co.stroke();
|
1898
|
-
}
|
1899
|
-
};
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1903
|
-
|
1904
|
-
/**
|
1905
|
-
* Using a function to add events makes it easier to facilitate method chaining
|
1906
|
-
*
|
1907
|
-
* @param string type The type of even to add
|
1908
|
-
* @param function func
|
1909
|
-
*/
|
1910
|
-
this.on = function (type, func)
|
1911
|
-
{
|
1912
|
-
if (type.substr(0,2) !== 'on') {
|
1913
|
-
type = 'on' + type;
|
1914
|
-
}
|
1915
|
-
|
1916
|
-
this[type] = func;
|
1917
|
-
|
1918
|
-
return this;
|
1919
|
-
};
|
1920
|
-
|
1921
|
-
|
1922
|
-
|
1923
|
-
|
1924
|
-
/**
|
1925
|
-
* This function runs once only
|
1926
|
-
* (put at the end of the file (before any effects))
|
1927
|
-
*/
|
1928
|
-
this.firstDrawFunc = function ()
|
1929
|
-
{
|
1930
|
-
};
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
//
|
1936
|
-
// Draw a 3D Pie/Donut chart
|
1937
|
-
//
|
1938
|
-
this.draw3d = function ()
|
1939
|
-
{
|
1940
|
-
var scaleX = 1.5,
|
1941
|
-
depth = prop['chart.variant.threed.depth'],
|
1942
|
-
prop_shadow = prop['chart.shadow'],
|
1943
|
-
prop_labels = prop['chart.labels'],
|
1944
|
-
prop_labelsSticks = prop['chart.labels.sticks']
|
1945
|
-
|
1946
|
-
this.set({
|
1947
|
-
labels: [],
|
1948
|
-
labelsSticks: false,
|
1949
|
-
strokestyle: 'rgba(0,0,0,0)'
|
1950
|
-
});
|
1951
|
-
|
1952
|
-
//
|
1953
|
-
// Change the variant so that the draw function doesn't keep
|
1954
|
-
// coming in here
|
1955
|
-
//
|
1956
|
-
this.set({
|
1957
|
-
variant: this.get('variant').replace(/3d/, '')
|
1958
|
-
});
|
1959
|
-
|
1960
|
-
this.context.setTransform(scaleX, 0, 0, 1, (ca.width * (scaleX) - ca.width) * -0.5, 0);
|
1961
|
-
|
1962
|
-
for (var i=depth; i>0; i-=1) {
|
1963
|
-
|
1964
|
-
this.set({
|
1965
|
-
centeryAdjust: i
|
1966
|
-
});
|
1967
|
-
|
1968
|
-
if (i === parseInt(depth / 2) ) {
|
1969
|
-
this.set({
|
1970
|
-
labels: prop_labels,
|
1971
|
-
labelsSticks: prop_labelsSticks
|
1972
|
-
});
|
1973
|
-
}
|
1974
|
-
|
1975
|
-
if (i === 0) {
|
1976
|
-
this.set({
|
1977
|
-
shadow: prop_shadow
|
1978
|
-
});
|
1979
|
-
}
|
1980
|
-
|
1981
|
-
this.draw();
|
1982
|
-
|
1983
|
-
// Turn off the shadow after the bottom pie/donut has
|
1984
|
-
// been drawn
|
1985
|
-
this.set('shadow', false);
|
1986
|
-
|
1987
|
-
//
|
1988
|
-
// If on the middle pie/donut turn the labels and sticks off
|
1989
|
-
//
|
1990
|
-
if (i <= parseInt(depth / 2) ) {
|
1991
|
-
this.set({
|
1992
|
-
labels: [],
|
1993
|
-
labelsSticks: false
|
1994
|
-
});
|
1995
|
-
}
|
1996
|
-
|
1997
|
-
//
|
1998
|
-
// Make what we're drawng darker by going over
|
1999
|
-
// it in a semi-transparent dark color
|
2000
|
-
//
|
2001
|
-
if (i > 1) {
|
2002
|
-
if (prop['chart.variant'].indexOf('donut') !== -1) {
|
2003
|
-
|
2004
|
-
for (var j=0; j<this.angles.length; ++j) {
|
2005
|
-
pa2(co,[
|
2006
|
-
'b',
|
2007
|
-
'a', this.angles[j][2], this.angles[j][3], this.radius + 1, this.angles[j][0], this.angles[j][1] * prop['chart.effect.roundrobin.multiplier'], false,
|
2008
|
-
'a', this.angles[j][2], this.angles[j][3], this.radius / 2, this.angles[j][1] * prop['chart.effect.roundrobin.multiplier'], this.angles[j][0], true,
|
2009
|
-
'f', 'rgba(0,0,0,0.15)'
|
2010
|
-
]);
|
2011
|
-
}
|
2012
|
-
|
2013
|
-
// Draw the pie chart darkened segments
|
2014
|
-
} else {
|
2015
|
-
|
2016
|
-
for (var j=0; j<this.angles.length; ++j) {
|
2017
|
-
|
2018
|
-
pa2(co,[
|
2019
|
-
'b',
|
2020
|
-
'm', this.angles[j][2], this.angles[j][3],
|
2021
|
-
'a', this.angles[j][2],
|
2022
|
-
this.angles[j][3],
|
2023
|
-
this.radius + 1,
|
2024
|
-
this.angles[j][0],
|
2025
|
-
this.angles[j][1] * prop['chart.effect.roundrobin.multiplier'],
|
2026
|
-
false,
|
2027
|
-
'c',
|
2028
|
-
'f', 'rgba(0,0,0,0.15)'
|
2029
|
-
]);
|
2030
|
-
}
|
2031
|
-
}
|
2032
|
-
}
|
2033
|
-
}
|
2034
|
-
|
2035
|
-
//
|
2036
|
-
// Reset the variant by adding the 3d back on
|
2037
|
-
//
|
2038
|
-
this.set({
|
2039
|
-
variant: this.get('variant') + '3d',
|
2040
|
-
shadow: prop_shadow,
|
2041
|
-
labels: prop_labels,
|
2042
|
-
labelsSticks: prop_labelsSticks
|
2043
|
-
});
|
2044
|
-
|
2045
|
-
// Necessary to allow method chaining
|
2046
|
-
return this;
|
2047
|
-
};
|
2048
|
-
|
2049
|
-
|
2050
|
-
|
2051
|
-
|
2052
|
-
/**
|
2053
|
-
* Pie chart explode
|
2054
|
-
*
|
2055
|
-
* Explodes the Pie chart - gradually incrementing the size of the chart.explode property
|
2056
|
-
*
|
2057
|
-
* @param object Options for the effect
|
2058
|
-
* @param function An optional callback function to call when the animation completes
|
2059
|
-
*/
|
2060
|
-
this.explode = function ()
|
2061
|
-
{
|
2062
|
-
var obj = this;
|
2063
|
-
var opt = arguments[0] ? arguments[0] : {};
|
2064
|
-
var callback = arguments[1] ? arguments[1] : function () {};
|
2065
|
-
var frames = opt.frames ? opt.frames : 30;
|
2066
|
-
var frame = 0;
|
2067
|
-
var maxExplode = Number(typeof opt.radius === 'number' ? opt.radius : ma.max(ca.width, ca.height));
|
2068
|
-
var currentExplode = Number(obj.get('exploded')) || 0;
|
2069
|
-
var step = (maxExplode - currentExplode) / frames;
|
2070
|
-
|
2071
|
-
// chart.exploded
|
2072
|
-
var iterator = function ()
|
2073
|
-
{
|
2074
|
-
obj.set('exploded', currentExplode + (step * frame) );
|
2075
|
-
|
2076
|
-
RGraph.clear(obj.canvas);
|
2077
|
-
RGraph.redrawCanvas(obj.canvas);
|
2078
|
-
|
2079
|
-
if (frame++ < frames) {
|
2080
|
-
RGraph.Effects.updateCanvas(iterator);
|
2081
|
-
} else {
|
2082
|
-
callback(obj);
|
2083
|
-
}
|
2084
|
-
}
|
2085
|
-
|
2086
|
-
iterator();
|
2087
|
-
|
2088
|
-
return this;
|
2089
|
-
};
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
/**
|
2095
|
-
* Pie chart grow
|
2096
|
-
*
|
2097
|
-
* Gradually increases the pie chart radius
|
2098
|
-
*
|
2099
|
-
* @param object OPTIONAL An object of options
|
2100
|
-
* @param function OPTIONAL A callback function
|
2101
|
-
*/
|
2102
|
-
this.grow = function ()
|
2103
|
-
{
|
2104
|
-
var obj = this;
|
2105
|
-
var canvas = obj.canvas;
|
2106
|
-
var opt = arguments[0] ? arguments[0] : {};
|
2107
|
-
var frames = opt.frames || 30;
|
2108
|
-
var frame = 0;
|
2109
|
-
var callback = arguments[1] ? arguments[1] : function () {};
|
2110
|
-
var radius = obj.getRadius();
|
2111
|
-
|
2112
|
-
|
2113
|
-
prop['chart.radius'] = 0;
|
2114
|
-
|
2115
|
-
var iterator = function ()
|
2116
|
-
{
|
2117
|
-
obj.set('chart.radius', (frame / frames) * radius);
|
2118
|
-
|
2119
|
-
RG.redrawCanvas(ca);
|
2120
|
-
|
2121
|
-
if (frame++ < frames) {
|
2122
|
-
RG.Effects.updateCanvas(iterator);
|
2123
|
-
|
2124
|
-
} else {
|
2125
|
-
|
2126
|
-
RG.redrawCanvas(obj.canvas);
|
2127
|
-
|
2128
|
-
|
2129
|
-
callback(obj);
|
2130
|
-
}
|
2131
|
-
};
|
2132
|
-
|
2133
|
-
iterator();
|
2134
|
-
|
2135
|
-
return this;
|
2136
|
-
};
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2140
|
-
|
2141
|
-
|
2142
|
-
/**
|
2143
|
-
* RoundRobin
|
2144
|
-
*
|
2145
|
-
* This effect does two things:
|
2146
|
-
* 1. Gradually increases the size of each segment
|
2147
|
-
* 2. Gradually increases the size of the radius from 0
|
2148
|
-
*
|
2149
|
-
* @param object OPTIONAL Options for the effect
|
2150
|
-
* @param function OPTIONAL A callback function
|
2151
|
-
*/
|
2152
|
-
this.roundrobin =
|
2153
|
-
this.roundRobin = function ()
|
2154
|
-
{
|
2155
|
-
var obj = this,
|
2156
|
-
opt = arguments[0] || {},
|
2157
|
-
callback = arguments[1] || function () {},
|
2158
|
-
frame = 0,
|
2159
|
-
frames = opt.frames || 30,
|
2160
|
-
radius = obj.getRadius(),
|
2161
|
-
labels = obj.get('labels')
|
2162
|
-
|
2163
|
-
obj.Set('chart.events', false);
|
2164
|
-
obj.Set('chart.labels', []);
|
2165
|
-
|
2166
|
-
var iterator = function ()
|
2167
|
-
{
|
2168
|
-
obj.set(
|
2169
|
-
'effect.roundrobin.multiplier',
|
2170
|
-
RG.Effects.getEasingMultiplier(frames, frame)
|
2171
|
-
);
|
2172
|
-
|
2173
|
-
RGraph.redrawCanvas(ca);
|
2174
|
-
|
2175
|
-
if (frame++ < frames) {
|
2176
|
-
RGraph.Effects.updateCanvas(iterator);
|
2177
|
-
|
2178
|
-
} else {
|
2179
|
-
|
2180
|
-
obj.set({
|
2181
|
-
events: true,
|
2182
|
-
labels: labels
|
2183
|
-
});
|
2184
|
-
|
2185
|
-
RG.redrawCanvas(obj.canvas);
|
2186
|
-
callback(obj);
|
2187
|
-
}
|
2188
|
-
};
|
2189
|
-
|
2190
|
-
iterator();
|
2191
|
-
|
2192
|
-
return this;
|
2193
|
-
};
|
2194
|
-
|
2195
|
-
|
2196
|
-
|
2197
|
-
|
2198
|
-
RG.att(ca);
|
2199
|
-
|
2200
|
-
|
2201
|
-
|
2202
|
-
|
2203
|
-
|
2204
|
-
|
2205
|
-
|
2206
|
-
|
2207
|
-
|
2208
|
-
/**
|
2209
|
-
* Pie chart implode
|
2210
|
-
*
|
2211
|
-
* Implodes the Pie chart - gradually decreasing the size of the chart.explode property. It starts at the largest of
|
2212
|
-
* the canvas width./height
|
2213
|
-
*
|
2214
|
-
* @param object Optional options for the effect. You can pass in frames here - such as:
|
2215
|
-
* myPie.implode({frames: 60}; function () {alert('Done!');})
|
2216
|
-
* @param function A callback function which is called when the effect is finished
|
2217
|
-
*/
|
2218
|
-
this.implode = function ()
|
2219
|
-
{
|
2220
|
-
var obj = this,
|
2221
|
-
opt = arguments[0] || {},
|
2222
|
-
callback = arguments[1] || function (){},
|
2223
|
-
frames = opt.frames || 30,
|
2224
|
-
frame = 0,
|
2225
|
-
explodedMax = ma.max(ca.width, ca.height),
|
2226
|
-
exploded = explodedMax;
|
2227
|
-
|
2228
|
-
|
2229
|
-
|
2230
|
-
function iterator ()
|
2231
|
-
{
|
2232
|
-
exploded = explodedMax - ((frame / frames) * explodedMax);
|
2233
|
-
|
2234
|
-
// Set the new value
|
2235
|
-
obj.Set('exploded', exploded);
|
2236
|
-
|
2237
|
-
RG.clear(ca);
|
2238
|
-
RG.redrawCanvas(ca);
|
2239
|
-
|
2240
|
-
if (frame++ < frames) {
|
2241
|
-
RG.Effects.updateCanvas(iterator);
|
2242
|
-
} else {
|
2243
|
-
RG.clear(obj.canvas);
|
2244
|
-
RG.redrawCanvas(obj.canvas);
|
2245
|
-
callback(obj);
|
2246
|
-
}
|
2247
|
-
}
|
2248
|
-
|
2249
|
-
iterator();
|
2250
|
-
|
2251
|
-
return this;
|
2252
|
-
};
|
2253
|
-
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2257
|
-
/**
|
2258
|
-
* Now need to register all chart types. MUST be after the setters/getters are defined
|
2259
|
-
*/
|
2260
|
-
RG.register(this);
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
2264
|
-
|
2265
|
-
/**
|
2266
|
-
* This is the 'end' of the constructor so if the first argument
|
2267
|
-
* contains configuration data - handle that.
|
2268
|
-
*/
|
2269
|
-
if (parseConfObjectForOptions) {
|
2270
|
-
RG.parseObjectStyleConfig(this, conf.options);
|
2271
|
-
}
|
2272
|
-
};
|