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.
Files changed (67) hide show
  1. checksums.yaml +8 -8
  2. data/.travis.yml +0 -1
  3. data/README.md +3 -3
  4. data/lib/rgraph-rails/version.rb +1 -1
  5. data/vendor/assets/javascripts/RGraph.bar.js +239 -3764
  6. data/vendor/assets/javascripts/RGraph.bipolar.js +115 -1986
  7. data/vendor/assets/javascripts/RGraph.common.annotate.js +35 -399
  8. data/vendor/assets/javascripts/RGraph.common.context.js +30 -600
  9. data/vendor/assets/javascripts/RGraph.common.core.js +403 -5187
  10. data/vendor/assets/javascripts/RGraph.common.csv.js +19 -275
  11. data/vendor/assets/javascripts/RGraph.common.deprecated.js +35 -454
  12. data/vendor/assets/javascripts/RGraph.common.dynamic.js +84 -1189
  13. data/vendor/assets/javascripts/RGraph.common.effects.js +90 -1548
  14. data/vendor/assets/javascripts/RGraph.common.key.js +54 -755
  15. data/vendor/assets/javascripts/RGraph.common.resizing.js +37 -567
  16. data/vendor/assets/javascripts/RGraph.common.sheets.js +29 -356
  17. data/vendor/assets/javascripts/RGraph.common.tooltips.js +32 -614
  18. data/vendor/assets/javascripts/RGraph.common.zoom.js +14 -223
  19. data/vendor/assets/javascripts/RGraph.cornergauge.js +71 -0
  20. data/vendor/assets/javascripts/RGraph.drawing.background.js +35 -620
  21. data/vendor/assets/javascripts/RGraph.drawing.circle.js +35 -576
  22. data/vendor/assets/javascripts/RGraph.drawing.image.js +52 -807
  23. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +41 -717
  24. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +37 -668
  25. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +36 -563
  26. data/vendor/assets/javascripts/RGraph.drawing.poly.js +40 -608
  27. data/vendor/assets/javascripts/RGraph.drawing.rect.js +35 -597
  28. data/vendor/assets/javascripts/RGraph.drawing.text.js +34 -642
  29. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +50 -809
  30. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +51 -856
  31. data/vendor/assets/javascripts/RGraph.fuel.js +58 -964
  32. data/vendor/assets/javascripts/RGraph.funnel.js +55 -984
  33. data/vendor/assets/javascripts/RGraph.gantt.js +75 -1241
  34. data/vendor/assets/javascripts/RGraph.gauge.js +87 -1397
  35. data/vendor/assets/javascripts/RGraph.hbar.js +143 -2376
  36. data/vendor/assets/javascripts/RGraph.hprogress.js +80 -1397
  37. data/vendor/assets/javascripts/RGraph.line.js +241 -4162
  38. data/vendor/assets/javascripts/RGraph.meter.js +74 -1278
  39. metadata +3 -30
  40. data/vendor/assets/images/bg.png +0 -0
  41. data/vendor/assets/images/bullet.png +0 -0
  42. data/vendor/assets/images/facebook-large.png +0 -0
  43. data/vendor/assets/images/google-plus-large.png +0 -0
  44. data/vendor/assets/images/logo.png +0 -0
  45. data/vendor/assets/images/meter-image-sd-needle.png +0 -0
  46. data/vendor/assets/images/meter-image-sd.png +0 -0
  47. data/vendor/assets/images/meter-sketch-needle.png +0 -0
  48. data/vendor/assets/images/meter-sketch.png +0 -0
  49. data/vendor/assets/images/odometer-background.png +0 -0
  50. data/vendor/assets/images/rgraph.jpg +0 -0
  51. data/vendor/assets/images/title.png +0 -0
  52. data/vendor/assets/images/twitter-large.png +0 -0
  53. data/vendor/assets/javascripts/RGraph.modaldialog.js +0 -301
  54. data/vendor/assets/javascripts/RGraph.odo.js +0 -1265
  55. data/vendor/assets/javascripts/RGraph.pie.js +0 -2272
  56. data/vendor/assets/javascripts/RGraph.radar.js +0 -1847
  57. data/vendor/assets/javascripts/RGraph.rose.js +0 -1877
  58. data/vendor/assets/javascripts/RGraph.rscatter.js +0 -1425
  59. data/vendor/assets/javascripts/RGraph.scatter.js +0 -2970
  60. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +0 -1015
  61. data/vendor/assets/javascripts/RGraph.thermometer.js +0 -1129
  62. data/vendor/assets/javascripts/RGraph.vprogress.js +0 -1452
  63. data/vendor/assets/javascripts/RGraph.waterfall.js +0 -1252
  64. data/vendor/assets/javascripts/financial-data.js +0 -1067
  65. data/vendor/assets/stylesheets/ModalDialog.css +0 -90
  66. data/vendor/assets/stylesheets/animations.css +0 -3347
  67. 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
- };