rgraph-rails 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
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
- };