rgraph-rails 1.0.7 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/lib/rgraph-rails/version.rb +1 -1
  4. data/license.txt +4 -16
  5. data/vendor/assets/javascripts/RGraph.bar.js +3734 -241
  6. data/vendor/assets/javascripts/RGraph.bipolar.js +2005 -115
  7. data/vendor/assets/javascripts/RGraph.common.annotate.js +395 -35
  8. data/vendor/assets/javascripts/RGraph.common.context.js +595 -30
  9. data/vendor/assets/javascripts/RGraph.common.core.js +5282 -405
  10. data/vendor/assets/javascripts/RGraph.common.csv.js +276 -19
  11. data/vendor/assets/javascripts/RGraph.common.deprecated.js +450 -35
  12. data/vendor/assets/javascripts/RGraph.common.dynamic.js +1395 -86
  13. data/vendor/assets/javascripts/RGraph.common.effects.js +1545 -90
  14. data/vendor/assets/javascripts/RGraph.common.key.js +753 -54
  15. data/vendor/assets/javascripts/RGraph.common.resizing.js +563 -37
  16. data/vendor/assets/javascripts/RGraph.common.sheets.js +352 -29
  17. data/vendor/assets/javascripts/RGraph.common.tooltips.js +450 -32
  18. data/vendor/assets/javascripts/RGraph.common.zoom.js +219 -14
  19. data/vendor/assets/javascripts/RGraph.drawing.background.js +570 -35
  20. data/vendor/assets/javascripts/RGraph.drawing.circle.js +544 -35
  21. data/vendor/assets/javascripts/RGraph.drawing.image.js +755 -52
  22. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +645 -41
  23. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +633 -37
  24. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +514 -36
  25. data/vendor/assets/javascripts/RGraph.drawing.poly.js +559 -39
  26. data/vendor/assets/javascripts/RGraph.drawing.rect.js +548 -35
  27. data/vendor/assets/javascripts/RGraph.drawing.text.js +664 -36
  28. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +812 -50
  29. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +856 -51
  30. data/vendor/assets/javascripts/RGraph.fuel.js +964 -58
  31. data/vendor/assets/javascripts/RGraph.funnel.js +984 -55
  32. data/vendor/assets/javascripts/RGraph.gantt.js +1354 -77
  33. data/vendor/assets/javascripts/RGraph.gauge.js +1421 -87
  34. data/vendor/assets/javascripts/RGraph.hbar.js +2562 -146
  35. data/vendor/assets/javascripts/RGraph.hprogress.js +1401 -80
  36. data/vendor/assets/javascripts/RGraph.line.js +4226 -244
  37. data/vendor/assets/javascripts/RGraph.meter.js +1280 -74
  38. data/vendor/assets/javascripts/RGraph.modaldialog.js +301 -19
  39. data/vendor/assets/javascripts/RGraph.odo.js +1264 -71
  40. data/vendor/assets/javascripts/RGraph.pie.js +2288 -137
  41. data/vendor/assets/javascripts/RGraph.radar.js +1847 -110
  42. data/vendor/assets/javascripts/RGraph.rose.js +1977 -108
  43. data/vendor/assets/javascripts/RGraph.rscatter.js +1432 -80
  44. data/vendor/assets/javascripts/RGraph.scatter.js +3036 -168
  45. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +1120 -60
  46. data/vendor/assets/javascripts/RGraph.svg.bar.js +1067 -0
  47. data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +247 -0
  48. data/vendor/assets/javascripts/RGraph.svg.common.core.js +3363 -0
  49. data/vendor/assets/javascripts/RGraph.svg.common.csv.js +277 -0
  50. data/vendor/assets/javascripts/RGraph.svg.common.fx.js +1304 -0
  51. data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +353 -0
  52. data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +233 -0
  53. data/vendor/assets/javascripts/RGraph.svg.hbar.js +1141 -0
  54. data/vendor/assets/javascripts/RGraph.svg.line.js +1486 -0
  55. data/vendor/assets/javascripts/RGraph.svg.pie.js +781 -0
  56. data/vendor/assets/javascripts/RGraph.svg.radar.js +1326 -0
  57. data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +817 -0
  58. data/vendor/assets/javascripts/RGraph.thermometer.js +1135 -62
  59. data/vendor/assets/javascripts/RGraph.vprogress.js +1470 -83
  60. data/vendor/assets/javascripts/RGraph.waterfall.js +1347 -80
  61. metadata +15 -3
@@ -0,0 +1,781 @@
1
+ // version: 2017-01-02
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 licensed under the Open Source MIT license. That means that it's |
9
+ * | totally free to use! |
10
+ * o--------------------------------------------------------------------------------o
11
+ */
12
+
13
+ RGraph = window.RGraph || {isRGraph: true};
14
+ RGraph.SVG = RGraph.SVG || {};
15
+
16
+ // Module pattern
17
+ (function (win, doc, undefined)
18
+ {
19
+ var RG = RGraph,
20
+ ua = navigator.userAgent,
21
+ ma = Math,
22
+ win = window,
23
+ doc = document;
24
+
25
+
26
+
27
+ RG.SVG.Pie = function (conf)
28
+ {
29
+ this.id = conf.id;
30
+ this.uid = RG.SVG.createUID();
31
+ this.container = document.getElementById(this.id);
32
+ this.svg = RG.SVG.createSVG({container: this.container});
33
+ this.isRGraph = true;
34
+ this.width = Number(this.svg.getAttribute('width'));
35
+ this.height = Number(this.svg.getAttribute('height'));
36
+ this.data = conf.data;
37
+ this.type = 'pie';
38
+ this.angles = [];
39
+ this.colorsParsed = false;
40
+ this.originalColors = {};
41
+ this.gradientCounter = 1;
42
+ this.nodes = [];
43
+ this.shadowNodes = [];
44
+
45
+ // Add this object to the ObjectRegistry
46
+ RG.SVG.OR.add(this);
47
+
48
+ // Set the DIV container to be inline-block
49
+ this.container.style.display = 'inline-block';
50
+
51
+ this.properties =
52
+ {
53
+ centerx: null,
54
+ centery: null,
55
+ radius: null,
56
+
57
+ gutterLeft: 35,
58
+ gutterRight: 35,
59
+ gutterTop: 35,
60
+ gutterBottom: 35,
61
+
62
+ colors: [
63
+ '#f66', '#6f6', '#66f', '#ff6', '#6ff', '#ccc',
64
+ 'pink', 'orange', 'cyan', 'maroon', 'olive', 'teal'
65
+ ],
66
+ strokestyle: 'rgba(0,0,0,0)',
67
+
68
+ margin: 3,
69
+
70
+ textColor: 'black',
71
+ textFont: 'sans-serif',
72
+ textSize: 12,
73
+ textBold: false,
74
+ textItalic: false,
75
+ labels: [],
76
+
77
+ linewidth: 1,
78
+
79
+ tooltips: null,
80
+ tooltipsOverride: null,
81
+ tooltipsEffect: 'fade',
82
+ tooltipsCssClass: 'RGraph_tooltip',
83
+ tooltipsEvent: 'click',
84
+
85
+ highlightStroke: 'rgba(0,0,0,0)',
86
+ highlightFill: 'rgba(255,255,255,0.7)',
87
+ highlightLinewidth: 1,
88
+
89
+ title: '',
90
+ titleSize: 16,
91
+ titleX: null,
92
+ titleY: null,
93
+ titleHalign: 'center',
94
+ titleValign: 'bottom',
95
+ titleColor: 'black',
96
+ titleFont: null,
97
+ titleBold: false,
98
+ titleItalic: false,
99
+
100
+ titleSubtitle: '',
101
+ titleSubtitleSize: 10,
102
+ titleSubtitleX: null,
103
+ titleSubtitleY: null,
104
+ titleSubtitleHalign: 'center',
105
+ titleSubtitleValign: 'top',
106
+ titleSubtitleColor: '#aaa',
107
+ titleSubtitleFont: null,
108
+ titleSubtitleBold: false,
109
+ titleSubtitleItalic: false,
110
+
111
+ shadow: false,
112
+ shadowOffsetx: 2,
113
+ shadowOffsety: 2,
114
+ shadowBlur: 2,
115
+ shadowOpacity: 0.25,
116
+
117
+ exploded: 0,
118
+ roundRobinMultiplier: 1,
119
+
120
+ attribution: true,
121
+ attributionX: null,
122
+ attributionY: null,
123
+ attributionHref: 'http://www.rgraph.net/svg/index.html',
124
+ attributionHalign: 'right',
125
+ attributionValign: 'bottom',
126
+ attributionSize: 8,
127
+ attributionColor: 'gray',
128
+ attributionFont: 'sans-serif',
129
+ attributionItalic: false,
130
+ attributionBold: false
131
+ };
132
+
133
+
134
+
135
+
136
+
137
+ /**
138
+ * "Decorate" the object with the generic effects if the effects library has been included
139
+ */
140
+ if (RG.SVG.FX && typeof RG.SVG.FX.decorate === 'function') {
141
+ RG.SVG.FX.decorate(this);
142
+ }
143
+
144
+
145
+
146
+
147
+ var prop = this.properties;
148
+
149
+
150
+
151
+
152
+ //
153
+ // A setter that the constructor uses (at the end)
154
+ // to set all of the properties
155
+ //
156
+ // @param string name The name of the property to set
157
+ // @param string value The value to set the property to
158
+ //
159
+ this.set = function (name, value)
160
+ {
161
+ if (arguments.length === 1 && typeof name === 'object') {
162
+ for (i in arguments[0]) {
163
+ if (typeof i === 'string') {
164
+ this.set(i, arguments[0][i]);
165
+ }
166
+ }
167
+ } else {
168
+ this.properties[name] = value;
169
+ }
170
+
171
+ return this;
172
+ };
173
+
174
+
175
+
176
+
177
+
178
+
179
+
180
+
181
+ //
182
+ // The draw method draws the Bar chart
183
+ //
184
+ this.draw = function ()
185
+ {
186
+ // Fire the beforedraw event
187
+ RG.SVG.fireCustomEvent(this, 'onbeforedraw');
188
+
189
+
190
+
191
+
192
+ // Create the defs tag if necessary
193
+ RG.SVG.createDefs(this);
194
+
195
+
196
+
197
+
198
+ this.graphWidth = this.width - prop.gutterLeft - prop.gutterRight;
199
+ this.graphHeight = this.height - prop.gutterTop - prop.gutterBottom;
200
+
201
+
202
+
203
+ // Work out the center point
204
+ this.centerx = (this.graphWidth / 2) + prop.gutterLeft;
205
+ this.centery = (this.graphHeight / 2) + prop.gutterTop;
206
+ this.radius = ma.min(this.graphWidth, this.graphHeight) / 2;
207
+
208
+
209
+
210
+ // Allow the user to override the calculated centerx/y/radius
211
+ this.centerx = typeof prop.centerx === 'number' ? prop.centerx : this.centerx;
212
+ this.centery = typeof prop.centery === 'number' ? prop.centery : this.centery;
213
+ this.radius = typeof prop.radius === 'number' ? prop.radius : this.radius;
214
+
215
+ //
216
+ // Allow the centerx/centery/radius to be a plus/minus
217
+ //
218
+ if (typeof prop.radius === 'string' && prop.radius.match(/^\+|-\d+$/) ) this.radius += parseFloat(prop.radius);
219
+ if (typeof prop.centerx === 'string' && prop.centerx.match(/^\+|-\d+$/) ) this.centery += parseFloat(prop.centerx);
220
+ if (typeof prop.centery === 'string' && prop.centery.match(/^\+|-\d+$/) ) this.centerx += parseFloat(prop.centery);
221
+
222
+
223
+ /**
224
+ * Parse the colors. This allows for simple gradient syntax
225
+ *
226
+ * ** must be after the cx/cy/r has been calcuated **
227
+ */
228
+ if (!this.colorsParsed) {
229
+ this.parseColors();
230
+
231
+ // Don't want to do this again
232
+ this.colorsParsed = true;
233
+ }
234
+
235
+
236
+ // Go through the data and work out the maximum value
237
+ this.max = RG.SVG.arrayMax(this.data);
238
+ this.total = RG.SVG.arraySum(this.data);
239
+
240
+ // Set the explosion to be an array if it's a number
241
+ if (typeof prop.exploded === 'number' && prop.exploded > 0) {
242
+ var val = prop.exploded;
243
+
244
+ prop.exploded = [];
245
+
246
+ for (var i=0; i<this.data.length; ++i) {
247
+ prop.exploded[i] = val;
248
+ }
249
+ }
250
+
251
+
252
+
253
+ // Draw the segments
254
+ this.drawSegments({shadow: true});
255
+
256
+
257
+
258
+ // Draw the title and subtitle
259
+ RG.SVG.drawTitle(this);
260
+
261
+
262
+
263
+ // Draw the labels
264
+ this.drawLabels();
265
+
266
+
267
+ // Add the attribution link. If you're adding this elsewhere on your page/site
268
+ // and you don't want it displayed then there are options available to not
269
+ // show it.
270
+ RG.SVG.attribution(this);
271
+
272
+
273
+ // Add the event listener that clears the highlight if
274
+ // there is any. Must be MOUSEDOWN (ie before the click event)
275
+ var obj = this;
276
+ document.body.addEventListener('mousedown', function (e)
277
+ {
278
+ RG.SVG.removeHighlight(obj);
279
+ }, false);
280
+
281
+
282
+
283
+ // Fire the draw event
284
+ RG.SVG.fireCustomEvent(this, 'ondraw');
285
+
286
+
287
+
288
+ return this;
289
+ };
290
+
291
+
292
+
293
+
294
+
295
+
296
+
297
+
298
+ //
299
+ // Draws the segments
300
+ //
301
+ // @param bool Whether or not this is a redraw. If this is a redraw
302
+ // shadows are omitted
303
+ //
304
+ this.drawSegments = function (opt)
305
+ {
306
+ var start = 0,
307
+ end = 0,
308
+ angle = 0,
309
+ sum = RG.SVG.arraySum(this.data),
310
+ segment = 0;
311
+
312
+
313
+
314
+
315
+ // Work out the start and end angles for the data
316
+ for (var i=0,len=this.data.length; i<len; ++i) {
317
+
318
+ var value = this.data[i] * prop.roundRobinMultiplier;
319
+
320
+ start = angle;
321
+ segment = ((value / sum) * RG.SVG.TRIG.TWOPI);
322
+ end = start + segment;
323
+
324
+ var explosion = RG.SVG.TRIG.getRadiusEndPoint({
325
+ angle: start + (segment / 2),
326
+ r: prop.exploded[i]
327
+ });
328
+
329
+ var explosionX = explosion[1],
330
+ explosionY = explosion[0];
331
+
332
+
333
+ this.angles[i] = {
334
+ start: start,
335
+ end: end,
336
+ angle: end - start,
337
+ halfway: ((end - start) / 2) + start,
338
+ cx: this.centerx + (parseFloat(explosionX) || 0),
339
+ cy: this.centery - (parseFloat(explosionY) || 0),
340
+ radius: this.radius
341
+ };
342
+
343
+ // Increase the angle at which we start drawing the next segment at
344
+ angle += (end - start);
345
+ }
346
+
347
+
348
+
349
+ if (opt.shadow) {
350
+ RG.SVG.setShadow({
351
+ object: this,
352
+ offsetx: prop.shadowOffsetx,
353
+ offsety: prop.shadowOffsety,
354
+ blur: prop.shadowBlur,
355
+ opacity: prop.shadowOpacity,
356
+ id: 'dropShadow'
357
+ });
358
+ }
359
+
360
+
361
+ //
362
+ // This loop goes thru the angles that were
363
+ // generated above and adds them to the
364
+ // scene
365
+ //
366
+ for (var i=0; i<this.angles.length; ++i) {
367
+
368
+ var path = RG.SVG.TRIG.getArcPath({
369
+ cx: this.angles[i].cx,
370
+ cy: this.angles[i].cy,
371
+ r: this.radius,
372
+ start: this.angles[i].start,
373
+ end: this.angles[i].end
374
+ });
375
+
376
+
377
+ var arc = RG.SVG.create({
378
+ svg: this.svg,
379
+ type: 'path',
380
+ attr: {
381
+ d: path + " L {1} {2} Z".format(
382
+ this.angles[i].cx,
383
+ this.angles[i].cy
384
+ ),
385
+ fill: prop.colors[i],
386
+ stroke: prop.strokestyle,
387
+ 'stroke-width': prop.linewidth,
388
+ 'data-tooltip': (!RG.SVG.isNull(prop.tooltips) && prop.tooltips.length) ? prop.tooltips[i] : '',
389
+ 'data-index': i,
390
+ 'data-value': value,
391
+ 'data-start-angle': this.angles[i].start,
392
+ 'data-end-angle': this.angles[i].end,
393
+ 'data-radius': this.radius,
394
+ filter: (prop.shadow && opt.shadow) ? 'url(#dropShadow)' : ''
395
+ }
396
+ });
397
+
398
+ // Store a reference to the node
399
+ if (prop.shadow && opt.shadow) {
400
+ this.shadowNodes[i] = arc;
401
+ } else {
402
+ this.nodes[i] = arc;
403
+ }
404
+
405
+ if (prop.tooltips && prop.tooltips[i] && (!opt.shadow || !prop.shadow)) {
406
+
407
+ // Make the tooltipsEvent default to click
408
+ if (prop.tooltipsEvent !== 'mousemove') {
409
+ prop.tooltipsEvent = 'click';
410
+ }
411
+
412
+ (function (index, obj)
413
+ {
414
+ arc.addEventListener(prop.tooltipsEvent, function (e)
415
+ {
416
+ // Show the tooltip
417
+ RG.SVG.tooltip({
418
+ object: obj,
419
+ index: index,
420
+ sequentialIndex: index,
421
+ text: prop.tooltips[index],
422
+ event: e
423
+ });
424
+
425
+ // Highlight the rect that has been clicked on
426
+ obj.highlight(e.target);
427
+
428
+ var highlight = RG.SVG.REG.get('highlight');
429
+
430
+ if (prop.tooltipsEvent === 'mousemove') {
431
+ highlight.style.cursor = 'pointer';
432
+ }
433
+
434
+ }, false);
435
+
436
+ // Install the event listener that changes the
437
+ // cursor if necessary
438
+ if (prop.tooltipsEvent === 'click') {
439
+ arc.addEventListener('mousemove', function (e)
440
+ {
441
+ e.target.style.cursor = 'pointer';
442
+ }, false);
443
+ }
444
+
445
+ }(i, this));
446
+ }
447
+ }
448
+
449
+ //
450
+ // Redraw the segments if necessary so that they're on
451
+ // top of any shadow
452
+ //
453
+ if (prop.shadow && opt.shadow) {
454
+ this.redrawSegments();
455
+ }
456
+ };
457
+
458
+
459
+
460
+
461
+
462
+
463
+
464
+
465
+ //
466
+ // Redraw the Bars o that the bars appear above any shadow
467
+ //
468
+ this.redrawSegments = function ()
469
+ {
470
+ this.drawSegments({shadow: false});
471
+ };
472
+
473
+
474
+
475
+
476
+
477
+
478
+
479
+
480
+ //
481
+ // Draw the labels
482
+ //
483
+ this.drawLabels = function ()
484
+ {
485
+ var angles = this.angles,
486
+ prop = this.properties,
487
+ labels = prop.labels;
488
+
489
+ for (var i=0; i<angles.length; ++i) {
490
+
491
+ var endpoint = RG.SVG.TRIG.getRadiusEndPoint({
492
+ angle: angles[i].halfway - RG.SVG.TRIG.HALFPI,
493
+ r: angles[i].radius + 15
494
+ });
495
+
496
+ var x = endpoint[0] + angles[i].cx,
497
+ y = endpoint[1] + angles[i].cy,
498
+ valign,
499
+ halign;
500
+
501
+ // Figure out the valign and halign based on the quadrant
502
+ // the the center of the sgement is in.
503
+ if (angles[i].halfway > 0 && angles[i].halfway < RG.SVG.TRIG.HALFPI) {
504
+ halign = 'left';
505
+ valign = 'bottom';
506
+ } else if (angles[i].halfway > RG.SVG.TRIG.HALFPI && angles[i].halfway < RG.SVG.TRIG.PI) {
507
+ halign = 'left';
508
+ valign = 'top';
509
+ } else if (angles[i].halfway > RG.SVG.TRIG.PI && angles[i].halfway < (RG.SVG.TRIG.HALFPI + RG.SVG.TRIG.PI)) {
510
+ halign = 'right';
511
+ valign = 'top';
512
+ } else if (angles[i].halfway > (RG.SVG.TRIG.HALFPI + RG.SVG.TRIG.PI) && angles[i].halfway < RG.SVG.TRIG.TWOPI) {
513
+ halign = 'right';
514
+ valign = 'top';
515
+ }
516
+
517
+ RG.SVG.text({
518
+ object: this,
519
+ text: typeof labels[i] === 'string' ? labels[i] : '',
520
+ font: prop.textFont,
521
+ size: prop.textSize,
522
+ x: x,
523
+ y: y,
524
+ valign: valign,
525
+ halign: halign,
526
+ bold: prop.textBold,
527
+ italic: prop.textItalic,
528
+ color: prop.textColor
529
+ });
530
+ }
531
+ };
532
+
533
+
534
+
535
+
536
+
537
+
538
+
539
+
540
+ /**
541
+ * This function can be used to highlight a segment on the chart
542
+ *
543
+ * @param object segment The segment to highlight
544
+ */
545
+ this.highlight = function (segment)
546
+ {
547
+ var highlight = RG.SVG.create({
548
+ svg: this.svg,
549
+ type: 'path',
550
+ attr: {
551
+ d: segment.getAttribute('d'),
552
+ fill: prop.highlightFill,
553
+ stroke: prop.highlightStroke,
554
+ 'stroke-width': prop.highlightLinewidth
555
+ }
556
+ });
557
+
558
+ if (prop.tooltipsEvent === 'mousemove') {
559
+ highlight.addEventListener('mouseout', function (e)
560
+ {
561
+ highlight.parentNode.removeChild(highlight);
562
+ RG.SVG.hideTooltip();
563
+
564
+ RG.SVG.REG.set('highlight', null);
565
+ }, false);
566
+ }
567
+
568
+
569
+ // Store the highlight rect in the registry so
570
+ // it can be cleared later
571
+ RG.SVG.REG.set('highlight', highlight);
572
+ };
573
+
574
+
575
+
576
+
577
+
578
+
579
+
580
+
581
+ /**
582
+ * This allows for easy specification of gradients
583
+ */
584
+ this.parseColors = function ()
585
+ {
586
+ // Save the original colors so that they can be restored when the canvas is reset
587
+ if (!Object.keys(this.originalColors).length) {
588
+ this.originalColors = {
589
+ colors: RG.SVG.arrayClone(prop.colors),
590
+ highlightFill: RG.SVG.arrayClone(prop.highlightFill)
591
+ }
592
+ }
593
+
594
+
595
+ // colors
596
+ var colors = prop.colors;
597
+
598
+ if (colors) {
599
+ for (var i=0; i<colors.length; ++i) {
600
+ colors[i] = RG.SVG.parseColorRadial({
601
+ object: this,
602
+ color: colors[i]
603
+ });
604
+ }
605
+ }
606
+
607
+ // Highlight fill
608
+ prop.highlightFill = RG.SVG.parseColorRadial({
609
+ object: this,
610
+ color: prop.highlightFill
611
+ });
612
+ };
613
+
614
+
615
+
616
+
617
+
618
+
619
+
620
+
621
+ //
622
+ // A roundRobin effect for the Pie chart
623
+ //
624
+ // @param object Options for the effect
625
+ // @param function An optional callback function to call when
626
+ // the effect is complete
627
+ //
628
+ this.roundRobin = function ()
629
+ {
630
+ var obj = this,
631
+ opt = arguments[0] || {},
632
+ data = RG.SVG.arrayClone(this.data),
633
+ prop = this.properties,
634
+ frame = 1,
635
+ frames = opt.frames || 30,
636
+ callback = typeof opt.callback === 'function' ? opt.callback : function () {},
637
+ dataSum = RG.SVG.arraySum(this.data),
638
+ textColor = prop.textColor;
639
+
640
+ // Set the text color to transparent
641
+ this.properties.textColor = 'rgba(0,0,0,0)';
642
+
643
+
644
+ // Draw the chart first
645
+ obj.draw();
646
+
647
+ // Now get the resulting angles
648
+ angles = RG.SVG.arrayClone(obj.angles);
649
+
650
+
651
+ function iterator ()
652
+ {
653
+ prop.roundRobinMultiplier = 1 / frames * frame++;
654
+
655
+ for (var i=0; i<obj.angles.length; ++i) {
656
+
657
+ var value = obj.data[i];
658
+
659
+
660
+
661
+ // NB This was an absolute git to work out for some reason.
662
+
663
+
664
+
665
+ obj.angles[i].start = angles[i].start * prop.roundRobinMultiplier;
666
+ obj.angles[i].end = angles[i].end * prop.roundRobinMultiplier;
667
+
668
+ //var segment = (((value * prop.roundRobinMultiplier) / dataSum) * RG.SVG.TRIG.TWOPI);
669
+ var segment = ((obj.angles[i].end - obj.angles[i].start) / 2);
670
+ var explodedX = ma.cos(obj.angles[i].start + segment - RG.SVG.TRIG.HALFPI) * (prop.exploded[i] || 0);
671
+ var explodedY = ma.sin(obj.angles[i].start + segment - RG.SVG.TRIG.HALFPI) * (prop.exploded[i] || 0);
672
+
673
+
674
+
675
+ var path = RG.SVG.TRIG.getArcPath({
676
+ cx: obj.centerx + explodedX,
677
+ cy: obj.centery + explodedY,
678
+ r: obj.radius,// * prop.roundRobinMultiplier,
679
+ start: obj.angles[i].start,
680
+ end: obj.angles[i].end
681
+ });
682
+
683
+ path = path + " L {1} {2} Z".format(
684
+ obj.centerx + explodedX,
685
+ obj.centery + explodedY
686
+ );
687
+
688
+ if (obj.shadowNodes && obj.shadowNodes[i]) {
689
+ obj.shadowNodes[i].setAttribute('d', path);
690
+ }
691
+ obj.nodes[i].setAttribute('d', path);
692
+ }
693
+
694
+
695
+ if (frame <= frames) {
696
+ RG.SVG.FX.update(iterator);
697
+ } else {
698
+ prop.textColor = textColor;
699
+
700
+ RG.SVG.redraw(obj.svg);
701
+
702
+ callback(obj);
703
+ }
704
+ }
705
+
706
+ iterator();
707
+
708
+ return this;
709
+ };
710
+
711
+
712
+
713
+
714
+
715
+
716
+
717
+
718
+ /**
719
+ * Using a function to add events makes it easier to facilitate method
720
+ * chaining
721
+ *
722
+ * @param string type The type of even to add
723
+ * @param function func
724
+ */
725
+ this.on = function (type, func)
726
+ {
727
+ if (type.substr(0,2) !== 'on') {
728
+ type = 'on' + type;
729
+ }
730
+
731
+ RG.SVG.addCustomEventListener(this, type, func);
732
+
733
+ return this;
734
+ };
735
+
736
+
737
+
738
+
739
+
740
+
741
+
742
+
743
+ //
744
+ // Used in chaining. Runs a function there and then - not waiting for
745
+ // the events to fire (eg the onbeforedraw event)
746
+ //
747
+ // @param function func The function to execute
748
+ //
749
+ this.exec = function (func)
750
+ {
751
+ func(this);
752
+
753
+ return this;
754
+ };
755
+
756
+
757
+
758
+
759
+
760
+
761
+
762
+
763
+ //
764
+ // Set the options that the user has provided
765
+ //
766
+ for (i in conf.options) {
767
+ if (typeof i === 'string') {
768
+ this.set(i, conf.options[i]);
769
+ }
770
+ }
771
+ };
772
+
773
+
774
+
775
+ return this;
776
+
777
+
778
+
779
+
780
+ // End module pattern
781
+ })(window, document);