rgraph-rails 1.0.8 → 4.62

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 +4 -4
  2. data/README.md +3 -3
  3. data/lib/rgraph-rails/version.rb +1 -1
  4. data/vendor/assets/javascripts/RGraph.bar.js +16 -8
  5. data/vendor/assets/javascripts/RGraph.bipolar.js +1 -1
  6. data/vendor/assets/javascripts/RGraph.common.annotate.js +1 -1
  7. data/vendor/assets/javascripts/RGraph.common.context.js +1 -1
  8. data/vendor/assets/javascripts/RGraph.common.core.js +84 -7
  9. data/vendor/assets/javascripts/RGraph.common.csv.js +1 -1
  10. data/vendor/assets/javascripts/RGraph.common.deprecated.js +1 -1
  11. data/vendor/assets/javascripts/RGraph.common.dynamic.js +1 -1
  12. data/vendor/assets/javascripts/RGraph.common.effects.js +1 -1
  13. data/vendor/assets/javascripts/RGraph.common.key.js +3 -3
  14. data/vendor/assets/javascripts/RGraph.common.resizing.js +1 -1
  15. data/vendor/assets/javascripts/RGraph.common.sheets.js +1 -1
  16. data/vendor/assets/javascripts/RGraph.common.tooltips.js +1 -1
  17. data/vendor/assets/javascripts/RGraph.common.zoom.js +1 -1
  18. data/vendor/assets/javascripts/RGraph.drawing.background.js +1 -1
  19. data/vendor/assets/javascripts/RGraph.drawing.circle.js +1 -1
  20. data/vendor/assets/javascripts/RGraph.drawing.image.js +1 -1
  21. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +1 -1
  22. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +1 -1
  23. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +1 -1
  24. data/vendor/assets/javascripts/RGraph.drawing.poly.js +1 -1
  25. data/vendor/assets/javascripts/RGraph.drawing.rect.js +1 -1
  26. data/vendor/assets/javascripts/RGraph.drawing.text.js +1 -1
  27. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +1 -1
  28. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +1 -1
  29. data/vendor/assets/javascripts/RGraph.fuel.js +1 -1
  30. data/vendor/assets/javascripts/RGraph.funnel.js +1 -1
  31. data/vendor/assets/javascripts/RGraph.gantt.js +1 -1
  32. data/vendor/assets/javascripts/RGraph.gauge.js +1 -1
  33. data/vendor/assets/javascripts/RGraph.hbar.js +228 -2
  34. data/vendor/assets/javascripts/RGraph.hprogress.js +1 -1
  35. data/vendor/assets/javascripts/RGraph.line.js +27 -5
  36. data/vendor/assets/javascripts/RGraph.meter.js +1 -1
  37. data/vendor/assets/javascripts/RGraph.modaldialog.js +1 -1
  38. data/vendor/assets/javascripts/RGraph.odo.js +1 -1
  39. data/vendor/assets/javascripts/RGraph.pie.js +1 -1
  40. data/vendor/assets/javascripts/RGraph.radar.js +1 -1
  41. data/vendor/assets/javascripts/RGraph.rose.js +1 -1
  42. data/vendor/assets/javascripts/RGraph.rscatter.js +1 -1
  43. data/vendor/assets/javascripts/RGraph.scatter.js +161 -34
  44. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +1 -1
  45. data/vendor/assets/javascripts/RGraph.svg.bar.js +772 -103
  46. data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +1 -1
  47. data/vendor/assets/javascripts/RGraph.svg.common.core.js +806 -231
  48. data/vendor/assets/javascripts/RGraph.svg.common.csv.js +1 -1
  49. data/vendor/assets/javascripts/RGraph.svg.common.fx.js +24 -24
  50. data/vendor/assets/javascripts/RGraph.svg.common.key.js +206 -0
  51. data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +1 -1
  52. data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +63 -22
  53. data/vendor/assets/javascripts/RGraph.svg.hbar.js +351 -91
  54. data/vendor/assets/javascripts/RGraph.svg.line.js +159 -64
  55. data/vendor/assets/javascripts/RGraph.svg.pie.js +402 -51
  56. data/vendor/assets/javascripts/RGraph.svg.radar.js +320 -143
  57. data/vendor/assets/javascripts/RGraph.svg.rose.js +1818 -0
  58. data/vendor/assets/javascripts/RGraph.svg.scatter.js +1262 -0
  59. data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +106 -57
  60. data/vendor/assets/javascripts/RGraph.svg.waterfall.js +1253 -0
  61. data/vendor/assets/javascripts/RGraph.thermometer.js +7 -6
  62. data/vendor/assets/javascripts/RGraph.vprogress.js +1 -1
  63. data/vendor/assets/javascripts/RGraph.waterfall.js +1 -1
  64. data/vendor/assets/javascripts/financial-data.js +1067 -0
  65. metadata +8 -5
  66. data/vendor/assets/javascripts/RGraph.cornergauge.js +0 -71
  67. data/vendor/assets/javascripts/RGraph.thermometer.old.js +0 -68
@@ -1,4 +1,4 @@
1
- // version: 2017-01-02
1
+ // version: 2017-05-08
2
2
  /**
3
3
  * o--------------------------------------------------------------------------------o
4
4
  * | This file is part of the RGraph package - you can learn more at: |
@@ -26,6 +26,56 @@
26
26
 
27
27
  RG.SVG.SemiCircularProgress = function (conf)
28
28
  {
29
+ //
30
+ // A setter that the constructor uses (at the end)
31
+ // to set all of the properties
32
+ //
33
+ // @param string name The name of the property to set
34
+ // @param string value The value to set the property to
35
+ //
36
+ this.set = function (name, value)
37
+ {
38
+ if (arguments.length === 1 && typeof name === 'object') {
39
+ for (i in arguments[0]) {
40
+ if (typeof i === 'string') {
41
+
42
+ var ret = RG.SVG.commonSetter({
43
+ object: this,
44
+ name: i,
45
+ value: arguments[0][i]
46
+ });
47
+
48
+ name = ret.name;
49
+ value = ret.value;
50
+
51
+ this.set(name, value);
52
+ }
53
+ }
54
+ } else {
55
+
56
+
57
+ var ret = RG.SVG.commonSetter({
58
+ object: this,
59
+ name: name,
60
+ value: value
61
+ });
62
+
63
+ name = ret.name;
64
+ value = ret.value;
65
+
66
+ this.properties[name] = value;
67
+ }
68
+
69
+ return this;
70
+ };
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
29
79
  this.min = RG.SVG.stringsToNumbers(conf.min);
30
80
  this.max = RG.SVG.stringsToNumbers(conf.max);
31
81
  this.value = RG.SVG.stringsToNumbers(conf.value);
@@ -143,7 +193,7 @@
143
193
  titleX: null,
144
194
  titleY: null,
145
195
  titleHalign: 'center',
146
- titleValign: 'bottom',
196
+ titleValign: null,
147
197
  titleColor: 'black',
148
198
  titleFont: null,
149
199
  titleBold: false,
@@ -154,7 +204,7 @@
154
204
  titleSubtitleX: null,
155
205
  titleSubtitleY: null,
156
206
  titleSubtitleHalign: 'center',
157
- titleSubtitleValign: 'top',
207
+ titleSubtitleValign: null,
158
208
  titleSubtitleColor: '#aaa',
159
209
  titleSubtitleFont: null,
160
210
  titleSubtitleBold: false,
@@ -163,10 +213,10 @@
163
213
  attribution: true,
164
214
  attributionX: null,
165
215
  attributionY: null,
166
- attributionHref: 'http://www.rgraph.net/svg/index.html',
216
+ attributionHref: null,// Default is set in RGraph.svg.common.core.js
167
217
  attributionHalign: 'right',
168
218
  attributionValign: 'bottom',
169
- attributionSize: 8,
219
+ attributionSize: 7,
170
220
  attributionColor: 'gray',
171
221
  attributionFont: 'sans-serif',
172
222
  attributionItalic: false,
@@ -198,31 +248,6 @@
198
248
 
199
249
 
200
250
 
201
- //
202
- // A setter that the constructor uses (at the end)
203
- // to set all of the properties
204
- //
205
- // @param string name The name of the property to set
206
- // @param string value The value to set the property to
207
- //
208
- this.set = function (name, value)
209
- {
210
- if (arguments.length === 1 && typeof name === 'object') {
211
- for (i in arguments[0]) {
212
- if (typeof i === 'string') {
213
- this.set(i, arguments[0][i]);
214
- }
215
- }
216
- } else {
217
- this.properties[name] = value;
218
- }
219
-
220
- return this;
221
- };
222
-
223
-
224
-
225
-
226
251
 
227
252
 
228
253
 
@@ -270,19 +295,12 @@
270
295
 
271
296
  // Set the width of the meter
272
297
  this.progressWidth = prop.width || (this.radius / 3);
273
-
274
-
275
- /**
276
- * Parse the colors. This allows for simple gradient syntax
277
- *
278
- * ** must be after the cx/cy/r has been calcuated **
279
- */
280
- if (!this.colorsParsed) {
281
- this.parseColors();
282
-
283
- // Don't want to do this again
284
- this.colorsParsed = true;
285
- }
298
+
299
+
300
+
301
+ // Parse the colors for gradients
302
+ RG.SVG.resetColorsToOriginalValues({object:this});
303
+ this.parseColors();
286
304
 
287
305
 
288
306
 
@@ -320,8 +338,10 @@
320
338
  //
321
339
  // Add tooltip event listeners
322
340
  //
323
- this.path['on' + prop.tooltipsEvent] = function (e)
341
+ this.path.addEventListener(prop.tooltipsEvent, function (e)
324
342
  {
343
+ obj.removeHighlight();
344
+
325
345
  // Show the tooltip
326
346
  RG.SVG.tooltip({
327
347
  object: obj,
@@ -334,24 +354,22 @@
334
354
 
335
355
  // Highlight the rect that has been clicked on
336
356
  obj.highlight(e.target);
337
-
338
- };
357
+ }, false);
339
358
 
340
- this.path.onmousemove = function (e)
359
+ this.path.addEventListener('mousemove', function (e)
341
360
  {
342
361
  e.target.style.cursor = 'pointer'
343
- };
362
+ }, false);
344
363
  }
345
364
 
346
365
 
347
366
  // Add the event listener that clears the highlight if
348
367
  // there is any. Must be MOUSEDOWN (ie before the click event)
349
- RG.SVG.SSP_window_mousedown_listener = function (e)
350
- {
351
- RG.SVG.removeHighlight(obj);
352
- }
353
368
  var obj = this;
354
- doc.body.addEventListener('mousedown', RG.SVG.SSP_body_mousedown_listener, false);
369
+ doc.body.addEventListener('mousedown', function (e)
370
+ {
371
+ obj.removeHighlight();
372
+ }, false);
355
373
 
356
374
 
357
375
 
@@ -400,6 +418,7 @@
400
418
  RG.SVG.create({
401
419
  svg: this.svg,
402
420
  type: 'path',
421
+ parent: this.svg.all,
403
422
  attr: {
404
423
  d: path + " L " + (this.centerx + this.radius - this.progressWidth) + " " + this.centery + path2 + " L " + (this.centerx - this.radius) + " " + this.centery,
405
424
  fill: prop.backgroundFill || prop.colors[0],
@@ -455,6 +474,7 @@
455
474
  var path = RG.SVG.create({
456
475
  svg: this.svg,
457
476
  type: 'path',
477
+ parent: this.svg.all,
458
478
  attr: {
459
479
  d: path + " L{1} {2} ".format(
460
480
  path2[1],
@@ -496,6 +516,7 @@
496
516
 
497
517
  RG.SVG.text({
498
518
  object: this,
519
+ parent: this.svg.all,
499
520
  text: typeof prop.labelsMinSpecific === 'string' ? prop.labelsMinSpecific : min,
500
521
  x: this.centerx - this.radius + (this.progressWidth / 2),
501
522
  y: this.height - prop.gutterBottom + 5,
@@ -531,6 +552,7 @@
531
552
 
532
553
  RG.SVG.text({
533
554
  object: this,
555
+ parent: this.svg.all,
534
556
  text: typeof prop.labelsMaxSpecific === 'string' ? prop.labelsMaxSpecific : max,
535
557
  x: this.centerx + this.radius - (this.progressWidth / 2),
536
558
  y: this.height - prop.gutterBottom + 5,
@@ -565,6 +587,7 @@
565
587
 
566
588
  RG.SVG.text({
567
589
  object: this,
590
+ parent: this.svg.all,
568
591
  text: typeof prop.labelsCenterSpecific === 'string' ? prop.labelsCenterSpecific : center,
569
592
  x: this.centerx,
570
593
  y: this.centery,
@@ -597,9 +620,10 @@
597
620
  // installed
598
621
  this.removeHighlight();
599
622
 
600
- this.highlightNode = RG.SVG.create({
623
+ var highlight = RG.SVG.create({
601
624
  svg: this.svg,
602
625
  type: 'path',
626
+ parent: this.svg.all,
603
627
  attr: {
604
628
  d: this.path.getAttribute('d'),
605
629
  fill: prop.highlightFill,
@@ -607,6 +631,9 @@
607
631
  'stroke-width': prop.highlightLinewidth
608
632
  }
609
633
  });
634
+
635
+ // Store the highlight node in the registry
636
+ RG.SVG.REG.set('highlight', highlight);
610
637
 
611
638
  // Add the event listener that clears the highlight path if
612
639
  // there is any. Must be MOUSEDOWN (ie before the click event)
@@ -631,9 +658,11 @@
631
658
  */
632
659
  this.removeHighlight = function ()
633
660
  {
634
- if (this.highlightNode) {
635
- this.highlightNode.parentNode.removeChild(this.highlightNode);
636
- this.highlightNode = null;
661
+ var highlight = RG.SVG.REG.get('highlight');
662
+
663
+ if (highlight) {
664
+ highlight.parentNode.removeChild(highlight);
665
+ highlight = null;
637
666
  }
638
667
  };
639
668
 
@@ -796,6 +825,26 @@
796
825
 
797
826
 
798
827
 
828
+ //
829
+ // Remove highlight from the chart (tooltips)
830
+ //
831
+ this.removeHighlight = function ()
832
+ {
833
+ var highlight = RG.SVG.REG.get('highlight');
834
+ if (highlight && highlight.parentNode) {
835
+ highlight.parentNode.removeChild(highlight);
836
+ }
837
+
838
+ RG.SVG.REG.set('highlight', null);
839
+ };
840
+
841
+
842
+
843
+
844
+
845
+
846
+
847
+
799
848
  //
800
849
  // Set the options that the user has provided
801
850
  //
@@ -0,0 +1,1253 @@
1
+ // version: 2017-05-08
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.Waterfall = function (conf)
28
+ {
29
+ //
30
+ // A setter that the constructor uses (at the end)
31
+ // to set all of the properties
32
+ //
33
+ // @param string name The name of the property to set
34
+ // @param string value The value to set the property to
35
+ //
36
+ this.set = function (name, value)
37
+ {
38
+ if (arguments.length === 1 && typeof name === 'object') {
39
+ for (i in arguments[0]) {
40
+ if (typeof i === 'string') {
41
+
42
+ var ret = RG.SVG.commonSetter({
43
+ object: this,
44
+ name: i,
45
+ value: arguments[0][i]
46
+ });
47
+
48
+ name = ret.name;
49
+ value = ret.value;
50
+
51
+ this.set(name, value);
52
+ }
53
+ }
54
+ } else {
55
+
56
+ var ret = RG.SVG.commonSetter({
57
+ object: this,
58
+ name: name,
59
+ value: value
60
+ });
61
+
62
+ name = ret.name;
63
+ value = ret.value;
64
+
65
+ this.properties[name] = value;
66
+ }
67
+
68
+ return this;
69
+ };
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+ this.id = conf.id;
79
+ this.uid = RG.SVG.createUID();
80
+ this.container = document.getElementById(this.id);
81
+ this.svg = RG.SVG.createSVG({container: this.container});
82
+ this.isRGraph = true;
83
+ this.width = Number(this.svg.getAttribute('width'));
84
+ this.height = Number(this.svg.getAttribute('height'));
85
+ this.data = conf.data;
86
+ this.type = 'waterfall';
87
+ this.coords = [];
88
+ this.colorsParsed = false;
89
+ this.originalColors = {};
90
+ this.gradientCounter = 1;
91
+
92
+ // Add this object to the ObjectRegistry
93
+ RG.SVG.OR.add(this);
94
+
95
+ this.container.style.display = 'inline-block';
96
+
97
+ this.properties =
98
+ {
99
+ gutterLeft: 35,
100
+ gutterRight: 35,
101
+ gutterTop: 35,
102
+ gutterBottom: 35,
103
+
104
+ backgroundColor: null,
105
+ backgroundImage: null,
106
+ backgroundImageAspect: 'none',
107
+ backgroundImageStretch: true,
108
+ backgroundImageOpacity: null,
109
+ backgroundImageX: null,
110
+ backgroundImageY: null,
111
+ backgroundImageW: null,
112
+ backgroundImageH: null,
113
+ backgroundGrid: true,
114
+ backgroundGridColor: '#ddd',
115
+ backgroundGridLinewidth: 1,
116
+ backgroundGridHlines: true,
117
+ backgroundGridHlinesCount: null,
118
+ backgroundGridVlines: true,
119
+ backgroundGridVlinesCount: null,
120
+ backgroundGridBorder: true,
121
+
122
+ // 20 colors. If you need more you need to set the colors property
123
+ colors: ['black', 'red', 'blue'],
124
+ colorsSequential: false,
125
+ strokestyle: '#aaa',
126
+ strokestyleConnector: null,
127
+
128
+ total: true,
129
+ hmargin: 5,
130
+ linewidth: 1,
131
+
132
+ yaxis: true,
133
+ yaxisTickmarks: true,
134
+ yaxisTickmarksLength: 5,
135
+ yaxisColor: 'black',
136
+ yaxisScale: true,
137
+ yaxisLabels: null,
138
+ yaxisLabelsOffsetx: 0,
139
+ yaxisLabelsOffsety: 0,
140
+ yaxisLabelsCount: 5,
141
+ yaxisUnitsPre: '',
142
+ yaxisUnitsPost: '',
143
+ yaxisStrict: false,
144
+ yaxisDecimals: 0,
145
+ yaxisPoint: '.',
146
+ yaxisThousand: ',',
147
+ yaxisRound: false,
148
+ yaxisMax: null,
149
+ yaxisMin: 0,
150
+ yaxisFormatter: null,
151
+ yaxisTextColor: null,
152
+ yaxisTextBold: null,
153
+ yaxisTextItalic: null,
154
+ yaxisTextFont: null,
155
+ yaxisTextSize: null,
156
+
157
+ xaxis: true,
158
+ xaxisTickmarks: true,
159
+ xaxisTickmarksLength: 5,
160
+ xaxisLabels: null,
161
+ xaxisLabelsPosition: 'section',
162
+ xaxisLabelsPositionEdgeTickmarksCount: null,
163
+ xaxisColor: 'black',
164
+ xaxisLabelsOffsetx: 0,
165
+ xaxisLabelsOffsety: 0,
166
+
167
+ labelsAbove: false,
168
+ labelsAboveFont: null,
169
+ labelsAboveSize: null,
170
+ labelsAboveBold: null,
171
+ labelsAboveItalic: null,
172
+ labelsAboveColor: null,
173
+ labelsAboveBackground: 'rgba(255,255,255,0.5)',
174
+ labelsAboveBackgroundPadding: 2,
175
+ labelsAboveUnitsPre: null,
176
+ labelsAboveUnitsPost: null,
177
+ labelsAbovePoint: null,
178
+ labelsAboveThousand: null,
179
+ labelsAboveFormatter: null,
180
+ labelsAboveDecimals: null,
181
+ labelsAboveOffsetx: 0,
182
+ labelsAboveOffsety: 0,
183
+ labelsAboveHalign: 'center',
184
+ labelsAboveValign: 'bottom',
185
+ labelsAboveSpecific: null,
186
+
187
+ textColor: 'black',
188
+ textFont: 'sans-serif',
189
+ textSize: 12,
190
+ textBold: false,
191
+ textItalic: false,
192
+
193
+
194
+ tooltips: null,
195
+ tooltipsOverride: null,
196
+ tooltipsEffect: 'fade',
197
+ tooltipsCssClass: 'RGraph_tooltip',
198
+ tooltipsEvent: 'click',
199
+
200
+ highlightStroke: 'rgba(0,0,0,0)',
201
+ highlightFill: 'rgba(255,255,255,0.7)',
202
+ highlightLinewidth: 1,
203
+
204
+ title: '',
205
+ titleSize: 16,
206
+ titleX: null,
207
+ titleY: null,
208
+ titleHalign: 'center',
209
+ titleValign: null,
210
+ titleColor: 'black',
211
+ titleFont: null,
212
+ titleBold: false,
213
+ titleItalic: false,
214
+
215
+ titleSubtitle: '',
216
+ titleSubtitleSize: 10,
217
+ titleSubtitleX: null,
218
+ titleSubtitleY: null,
219
+ titleSubtitleHalign: 'center',
220
+ titleSubtitleValign: null,
221
+ titleSubtitleColor: '#aaa',
222
+ titleSubtitleFont: null,
223
+ titleSubtitleBold: false,
224
+ titleSubtitleItalic: false,
225
+
226
+ //shadow: false,
227
+ //shadowOffsetx: 2,
228
+ //shadowOffsety: 2,
229
+ //shadowBlur: 2,
230
+ //shadowOpacity: 0.25,
231
+
232
+
233
+
234
+ key: null,
235
+ keyColors: null,
236
+ keyOffsetx: 0,
237
+ keyOffsety: 0,
238
+ keyTextOffsetx: 0,
239
+ keyTextOffsety: -1,
240
+ keyTextSize: null,
241
+ keyTextBold: null,
242
+ keyTextItalic: null,
243
+
244
+ attribution: true,
245
+ attributionX: null,
246
+ attributionY: null,
247
+ attributionHref: null,// Default is set in RGraph.svg.common.core.js
248
+ attributionHalign: 'right',
249
+ attributionValign: 'bottom',
250
+ attributionSize: 7,
251
+ attributionColor: 'gray',
252
+ attributionFont: 'sans-serif',
253
+ attributionItalic: false,
254
+ attributionBold: false
255
+ };
256
+
257
+
258
+
259
+
260
+
261
+ /**
262
+ * "Decorate" the object with the generic effects if the effects library has been included
263
+ */
264
+ if (RG.SVG.FX && typeof RG.SVG.FX.decorate === 'function') {
265
+ RG.SVG.FX.decorate(this);
266
+ }
267
+
268
+
269
+
270
+
271
+ var prop = this.properties;
272
+
273
+
274
+
275
+
276
+
277
+
278
+
279
+
280
+ //
281
+ // The draw method draws the Bar chart
282
+ //
283
+ this.draw = function ()
284
+ {
285
+ // Fire the beforedraw event
286
+ RG.SVG.fireCustomEvent(this, 'onbeforedraw');
287
+
288
+
289
+
290
+
291
+ // Create the defs tag if necessary
292
+ RG.SVG.createDefs(this);
293
+
294
+
295
+
296
+
297
+
298
+ this.graphWidth = this.width - prop.gutterLeft - prop.gutterRight;
299
+ this.graphHeight = this.height - prop.gutterTop - prop.gutterBottom;
300
+
301
+
302
+
303
+ // Parse the colors for gradients
304
+ RG.SVG.resetColorsToOriginalValues({object:this});
305
+ this.parseColors();
306
+
307
+
308
+
309
+
310
+ // Work out the sum of the data and add it to the data
311
+ if (prop.total) {
312
+ var sum = RG.SVG.arraySum(this.data);
313
+
314
+ // Now append the sum to the data
315
+ this.data.push(sum);
316
+
317
+ // May need to append something to the labels array if prop.total
318
+ // is enabled, so that the labels line up
319
+
320
+ if (prop.xaxisLabels && prop.xaxisLabels.length === (this.data.length - 1)) {
321
+ prop.xaxisLabels.push('');
322
+ }
323
+ }
324
+
325
+
326
+
327
+
328
+ for (var i=0,max=0,runningTotal=0; i<this.data.length - (prop.total ? 1 : 0); ++i) {
329
+ runningTotal += this.data[i]
330
+ max = ma.max(max, runningTotal);
331
+ }
332
+
333
+ // A custom, user-specified maximum value
334
+ if (typeof prop.yaxisMax === 'number') {
335
+ max = prop.yaxisMax;
336
+ }
337
+
338
+ // Set the ymin to zero if it's set mirror
339
+ if (prop.yaxisMin === 'mirror' || prop.yaxisMin === 'middle' || prop.yaxisMin === 'center') {
340
+ var mirrorScale = true;
341
+ prop.yaxisMin = 0;
342
+ }
343
+
344
+
345
+ //
346
+ // Generate an appropiate scale
347
+ //
348
+ this.scale = RG.SVG.getScale({
349
+ object: this,
350
+ numlabels: prop.yaxisLabelsCount,
351
+ unitsPre: prop.yaxisUnitsPre,
352
+ unitsPost: prop.yaxisUnitsPost,
353
+ max: max,
354
+ min: prop.yaxisMin,
355
+ point: prop.yaxisPoint,
356
+ round: prop.yaxisRound,
357
+ thousand: prop.yaxisThousand,
358
+ decimals: prop.yaxisDecimals,
359
+ strict: typeof prop.yaxisMax === 'number',
360
+ formatter: prop.yaxisFormatter
361
+ });
362
+
363
+
364
+
365
+ //
366
+ // Get the scale a second time if the ymin should be mirored
367
+ //
368
+ // Set the ymin to zero if it's set mirror
369
+ if (mirrorScale) {
370
+ this.scale = RG.SVG.getScale({
371
+ object: this,
372
+ numlabels: prop.yaxisLabelsCount,
373
+ unitsPre: prop.yaxisUnitsPre,
374
+ unitsPost: prop.yaxisUnitsPost,
375
+ max: this.scale.max,
376
+ min: this.scale.max * -1,
377
+ point: prop.yaxisPoint,
378
+ round: false,
379
+ thousand: prop.yaxisThousand,
380
+ decimals: prop.yaxisDecimals,
381
+ strict: typeof prop.yaxisMax === 'number',
382
+ formatter: prop.yaxisFormatter
383
+ });
384
+ }
385
+
386
+ // Now the scale has been generated adopt its max value
387
+ this.max = this.scale.max;
388
+ this.min = this.scale.min;
389
+ prop.yaxisMax = this.scale.max;
390
+ prop.yaxisMin = this.scale.min;
391
+
392
+
393
+
394
+
395
+ // Draw the background first
396
+ RG.SVG.drawBackground(this);
397
+
398
+
399
+
400
+ // Draw the axes BEFORE the bars
401
+ RG.SVG.drawXAxis(this);
402
+ RG.SVG.drawYAxis(this);
403
+
404
+
405
+ // Draw the bars
406
+ this.drawBars();
407
+
408
+
409
+ // Draw the labelsAbove labels
410
+ this.drawLabelsAbove();
411
+
412
+
413
+
414
+
415
+
416
+
417
+
418
+
419
+
420
+
421
+ // Draw the key
422
+ if (typeof prop.key !== null && RG.SVG.drawKey) {
423
+ RG.SVG.drawKey(this);
424
+ } else if (!RGraph.SVG.isNull(prop.key)) {
425
+ alert('The drawKey() function does not exist - have you forgotten to include the key library?');
426
+ }
427
+
428
+
429
+
430
+
431
+
432
+
433
+
434
+ // Add the attribution link. If you're adding this elsewhere on your page/site
435
+ // and you don't want it displayed then there are options available to not
436
+ // show it.
437
+ RG.SVG.attribution(this);
438
+
439
+
440
+
441
+
442
+ // Add the event listener that clears the highlight rect if
443
+ // there is any. Must be MOUSEDOWN (ie before the click event)
444
+ //var obj = this;
445
+ //document.body.addEventListener('mousedown', function (e)
446
+ //{
447
+ // //RG.SVG.removeHighlight(obj);
448
+ //
449
+ //}, false);
450
+
451
+
452
+
453
+ // Fire the draw event
454
+ RG.SVG.fireCustomEvent(this, 'ondraw');
455
+
456
+
457
+
458
+
459
+ return this;
460
+ };
461
+
462
+
463
+
464
+
465
+
466
+
467
+
468
+
469
+ //
470
+ // Draws the bars
471
+ //
472
+ this.drawBars = function ()
473
+ {
474
+ this.graphWidth = this.width - prop.gutterLeft - prop.gutterRight;
475
+ this.graphHeight = this.height - prop.gutterTop - prop.gutterBottom;
476
+
477
+ // The width of the bars
478
+ var innerWidth = (this.graphWidth / this.data.length) - (2 * prop.hmargin),
479
+ outerWidth = (this.graphWidth / this.data.length);
480
+
481
+
482
+ // The starting Y coordinate
483
+ var y = this.getYCoord(0),
484
+ total = 0;
485
+
486
+
487
+
488
+ // Loop thru the data drawing the bars
489
+ for (var i=0; i<(this.data.length); ++i) {
490
+
491
+ var prevValue = this.data[i - 1],
492
+ nextValue = this.data[i + 1],
493
+ currentValue = this.data[i],
494
+ prevTotal = total;
495
+
496
+ total += parseFloat(this.data[i]) || 0;
497
+
498
+ // Figure out the height
499
+ var height = ma.abs((this.data[i] / (this.scale.max - this.scale.min) ) * this.graphHeight);
500
+
501
+
502
+
503
+
504
+
505
+
506
+
507
+
508
+
509
+
510
+ // Work out the starting coord
511
+ if (prevValue === null) {
512
+
513
+ if (currentValue > 0) {
514
+ y = this.getYCoord(prevTotal) - height;
515
+ } else {
516
+ y = this.getYCoord(prevTotal);
517
+ }
518
+
519
+ } else {
520
+ if (i == 0 && this.data[i] > 0) {
521
+ y = y - height;
522
+
523
+ } else if (this.data[i] > 0 && this.data[i - 1] > 0) {
524
+ y = y - height;
525
+
526
+ } else if (this.data[i] > 0 && this.data[i - 1] < 0) {
527
+ y = y + prevHeight - height;
528
+
529
+ } else if (this.data[i] < 0 && this.data[i - 1] > 0) {
530
+ // Nada
531
+
532
+ } else if (this.data[i] < 0 && this.data[i - 1] < 0) {
533
+ y = y + prevHeight;
534
+ }
535
+ }
536
+
537
+ //
538
+ // Determine the color
539
+ //
540
+ var fill = this.data[i] > 0 ? prop.colors[0] : prop.colors[1];
541
+
542
+ if (prop.colorsSequential) {
543
+ fill = prop.colors[i];
544
+ }
545
+
546
+
547
+
548
+
549
+
550
+ // The last (the total) value if required
551
+ if (i === (this.data.length - 1) && this.data[this.data.length - 1] >= 0) {
552
+ y = this.getYCoord(0) - height;
553
+
554
+ if (!prop.colorsSequential) {
555
+ fill = prop.colors[2];
556
+ }
557
+ } else if (i === (this.data.length - 1) && this.data[this.data.length - 1] < 0) {
558
+ y = this.getYCoord(0);
559
+
560
+ if (!prop.colorsSequential) {
561
+ fill = prop.colors[2];
562
+ }
563
+ }
564
+
565
+
566
+
567
+
568
+
569
+
570
+ // Calculate the X coordinate
571
+ var x = prop.gutterLeft + (outerWidth * i) + prop.hmargin;
572
+
573
+
574
+
575
+
576
+
577
+ // This handles an intermediate total
578
+ if (this.data[i] === null || typeof this.data[i] === 'undefined') {
579
+
580
+ var axisY = this.getYCoord(0);
581
+
582
+ if (prevValue < 0) {
583
+ y = prevY + prevHeight;
584
+ } else {
585
+ y = prevY;
586
+ }
587
+
588
+ height = this.getYCoord(0) - this.getYCoord(total);
589
+
590
+ // Do this if not sequential colors
591
+ if (!prop.colorsSequential) {
592
+ fill = prop.colors[3] || prop.colors[2];
593
+ }
594
+
595
+ if (height < 0) {
596
+ y += height;
597
+ height *= -1;
598
+ }
599
+ }
600
+
601
+
602
+
603
+
604
+
605
+
606
+ // Create the rect object
607
+ var rect = RG.SVG.create({
608
+ svg: this.svg,
609
+ type: 'rect',
610
+ parent: this.svg.all,
611
+ attr: {
612
+ x: x,
613
+ y: y,
614
+ width: innerWidth,
615
+ height: height,
616
+ stroke: prop.strokestyle,
617
+ fill: fill,
618
+ 'stroke-width': prop.linewidth,
619
+ 'shape-rendering': 'crispEdges',
620
+ 'data-index': i,
621
+ 'data-original-x': x,
622
+ 'data-original-y': y,
623
+ 'data-original-width': innerWidth,
624
+ 'data-original-height': height,
625
+ 'data-original-stroke': prop.strokestyle,
626
+ 'data-original-fill': fill,
627
+ 'data-value': String(this.data[i])
628
+ }
629
+ });
630
+
631
+ // Store the coordinates
632
+ this.coords[i] = {
633
+ object: rect,
634
+ x: x,
635
+ y: y,
636
+ width: innerWidth,
637
+ height: height
638
+ };
639
+
640
+
641
+
642
+
643
+
644
+
645
+
646
+
647
+ // Add the tooltips
648
+ if (!RG.SVG.isNull(prop.tooltips) && prop.tooltips[i]) {
649
+
650
+ var obj = this;
651
+
652
+ //
653
+ // Add tooltip event listeners
654
+ //
655
+ (function (idx)
656
+ {
657
+ rect.addEventListener(prop.tooltipsEvent.replace(/^on/, ''), function (e)
658
+ {
659
+ obj.removeHighlight();
660
+
661
+ // Show the tooltip
662
+ RG.SVG.tooltip({
663
+ object: obj,
664
+ index: idx,
665
+ text: prop.tooltips[idx],
666
+ event: e
667
+ });
668
+
669
+ // Highlight the rect that has been clicked on
670
+ obj.highlight(e.target);
671
+ }, false);
672
+
673
+ rect.addEventListener('mousemove', function (e)
674
+ {
675
+ e.target.style.cursor = 'pointer'
676
+ }, false);
677
+ })(i);
678
+ }
679
+
680
+
681
+
682
+
683
+
684
+
685
+
686
+
687
+
688
+
689
+ // Store these for the next iteration of the loop
690
+ var prevX = x,
691
+ prevY = y,
692
+ prevWidth = innerWidth,
693
+ prevHeight = height,
694
+ prevValue = this.data[i];
695
+ }
696
+
697
+
698
+
699
+
700
+
701
+
702
+
703
+
704
+
705
+
706
+
707
+
708
+
709
+
710
+
711
+
712
+
713
+
714
+
715
+
716
+ // Now draw the connecting lines
717
+ for (var i=0; i<this.coords.length; ++i) {
718
+
719
+ if (this.coords[i+1] && this.coords[i+1].object) {
720
+
721
+ var x1 = Number(this.coords[i].object.getAttribute('x')) + Number(this.coords[i].object.getAttribute('width')),
722
+ y1 = parseInt(this.coords[i].object.getAttribute('y')) + (this.data[i] > 0 ? 0 : parseInt(this.coords[i].object.getAttribute('height')) ),
723
+ x2 = x1 + (2 * prop.hmargin),
724
+ y2 = parseInt(this.coords[i].object.getAttribute('y')) + (this.data[i] > 0 ? 0 : parseInt(this.coords[i].object.getAttribute('height')) );
725
+
726
+ // Handle total columns
727
+ if(this.coords[i].object.getAttribute('data-value') === 'null') {
728
+ y1 = parseFloat(this.coords[i].object.getAttribute('y'));
729
+ y2 = parseFloat(y1);
730
+ }
731
+
732
+ var line = RG.SVG.create({
733
+ svg: this.svg,
734
+ type: 'line',
735
+ parent: this.svg.all,
736
+ attr: {
737
+ x1: x1,
738
+ y1: y1 + 0.5,
739
+ x2: x2,
740
+ y2: y2 + 0.5,
741
+ stroke: prop.strokestyleConnector || prop.strokestyle,
742
+ 'stroke-width': prop.linewidth,
743
+ 'data-index': i,
744
+ 'data-original-x1': x1,
745
+ 'data-original-y1': y1 + 0.5,
746
+ 'data-original-x2': x2,
747
+ 'data-original-y2': y2 + 0.5
748
+ }
749
+ });
750
+ }
751
+ }
752
+ };
753
+
754
+
755
+
756
+
757
+
758
+
759
+
760
+
761
+ /**
762
+ * This function can be used to retrieve the relevant Y coordinate for a
763
+ * particular value.
764
+ *
765
+ * @param int value The value to get the Y coordinate for
766
+ */
767
+ this.getYCoord = function (value)
768
+ {
769
+ var prop = this.properties;
770
+
771
+ if (value > this.scale.max) {
772
+ return null;
773
+ }
774
+
775
+ var y, xaxispos = prop.xaxispos;
776
+
777
+ if (value < this.scale.min) {
778
+ return null;
779
+ }
780
+
781
+ y = ((value - this.scale.min) / (this.scale.max - this.scale.min));
782
+ y *= (this.height - prop.gutterTop - prop.gutterBottom);
783
+
784
+ y = this.height - prop.gutterBottom - y;
785
+
786
+ return y;
787
+ };
788
+
789
+
790
+
791
+
792
+
793
+
794
+
795
+
796
+ /**
797
+ * This function can be used to highlight a bar on the chart
798
+ *
799
+ * @param object rect The rectangle to highlight
800
+ */
801
+ this.highlight = function (rect)
802
+ {
803
+ var x = rect.getAttribute('x'),
804
+ y = rect.getAttribute('y'),
805
+ width = rect.getAttribute('width'),
806
+ height = rect.getAttribute('height');
807
+
808
+ var highlight = RG.SVG.create({
809
+ svg: this.svg,
810
+ type: 'rect',
811
+ parent: this.svg.all,
812
+ attr: {
813
+ stroke: prop.highlightStroke,
814
+ fill: prop.highlightFill,
815
+ x: x,
816
+ y: y,
817
+ width: width,
818
+ height: height,
819
+ 'stroke-width': prop.highlightLinewidth
820
+ }
821
+ });
822
+
823
+
824
+ //if (prop.tooltipsEvent === 'mousemove') {
825
+
826
+ //var obj = this;
827
+
828
+ //highlight.addEventListener('mouseout', function (e)
829
+ //{
830
+ // obj.removeHighlight();
831
+ // RG.SVG.hideTooltip();
832
+ // RG.SVG.REG.set('highlight', null);
833
+ //}, false);
834
+ //}
835
+
836
+
837
+ // Store the highlight rect in the rebistry so
838
+ // it can be cleared later
839
+ RG.SVG.REG.set('highlight', highlight);
840
+ };
841
+
842
+
843
+
844
+
845
+
846
+
847
+
848
+
849
+ /**
850
+ * This allows for easy specification of gradients
851
+ */
852
+ this.parseColors = function ()
853
+ {
854
+ // Save the original colors so that they can be restored when
855
+ // the canvas is cleared
856
+ if (!Object.keys(this.originalColors).length) {
857
+ this.originalColors = {
858
+ colors: RG.SVG.arrayClone(prop.colors),
859
+ backgroundGridColor: RG.SVG.arrayClone(prop.backgroundGridColor),
860
+ highlightFill: RG.SVG.arrayClone(prop.highlightFill),
861
+ backgroundColor: RG.SVG.arrayClone(prop.backgroundColor)
862
+ }
863
+ }
864
+
865
+
866
+ // colors
867
+ var colors = prop.colors;
868
+
869
+ if (colors) {
870
+ for (var i=0; i<colors.length; ++i) {
871
+ colors[i] = RG.SVG.parseColorLinear({
872
+ object: this,
873
+ color: colors[i]
874
+ });
875
+ }
876
+ }
877
+
878
+ prop.backgroundGridColor = RG.SVG.parseColorLinear({object: this, color: prop.backgroundGridColor});
879
+ prop.highlightFill = RG.SVG.parseColorLinear({object: this, color: prop.highlightFill});
880
+ prop.backgroundColor = RG.SVG.parseColorLinear({object: this, color: prop.backgroundColor});
881
+ };
882
+
883
+
884
+
885
+
886
+
887
+
888
+
889
+
890
+ //
891
+ // Draws the labelsAbove
892
+ //
893
+ this.drawLabelsAbove = function ()
894
+ {
895
+ // Go through the above labels
896
+ if (prop.labelsAbove) {
897
+
898
+ var total = 0;
899
+
900
+ for (var i=0; i<this.coords.length; ++i) {
901
+
902
+ var num = this.data[i],
903
+ total = total + num;
904
+
905
+ if (typeof num === 'number' || RG.SVG.isNull(num)) {
906
+
907
+ if (RG.SVG.isNull(num)) {
908
+ num = total;
909
+ }
910
+
911
+ var str = RG.SVG.numberFormat({
912
+ object: this,
913
+ num: num.toFixed(prop.labelsAboveDecimals),
914
+ prepend: typeof prop.labelsAboveUnitsPre === 'string' ? prop.labelsAboveUnitsPre : null,
915
+ append: typeof prop.labelsAboveUnitsPost === 'string' ? prop.labelsAboveUnitsPost : null,
916
+ point: typeof prop.labelsAbovePoint === 'string' ? prop.labelsAbovePoint : null,
917
+ thousand: typeof prop.labelsAboveThousand === 'string' ? prop.labelsAboveThousand : null,
918
+ formatter: typeof prop.labelsAboveFormatter === 'function' ? prop.labelsAboveFormatter : null
919
+ });
920
+
921
+ // Facilitate labelsAboveSpecific
922
+ if (prop.labelsAboveSpecific && prop.labelsAboveSpecific.length && (typeof prop.labelsAboveSpecific[i] === 'string' || typeof prop.labelsAboveSpecific[i] === 'number') ) {
923
+ str = prop.labelsAboveSpecific[i];
924
+ } else if ( prop.labelsAboveSpecific && prop.labelsAboveSpecific.length && typeof prop.labelsAboveSpecific[i] !== 'string' && typeof prop.labelsAboveSpecific[i] !== 'number') {
925
+ continue;
926
+ }
927
+
928
+ var x = parseFloat(this.coords[i].object.getAttribute('x')) + parseFloat(this.coords[i].object.getAttribute('width') / 2) + prop.labelsAboveOffsetx;
929
+
930
+ if (this.data[i] >= 0) {
931
+ var y = parseFloat(this.coords[i].object.getAttribute('y')) - 7 + prop.labelsAboveOffsety;
932
+ var valign = prop.labelsAboveValign;
933
+ } else {
934
+ var y = parseFloat(this.coords[i].object.getAttribute('y')) + parseFloat(this.coords[i].object.getAttribute('height')) + 7 - prop.labelsAboveOffsety;
935
+ var valign = prop.labelsAboveValign === 'top' ? 'bottom' : 'top';
936
+ }
937
+
938
+ RG.SVG.text({
939
+ object: this,
940
+ parent: this.svg.all,
941
+ text: str,
942
+ x: x,
943
+ y: y,
944
+ halign: prop.labelsAboveHalign,
945
+ valign: valign,
946
+ font: prop.labelsAboveFont || prop.textFont,
947
+ size: prop.labelsAboveSize || prop.textSize,
948
+ bold: prop.labelsAboveBold || prop.textBold,
949
+ italic: prop.labelsAboveItalic || prop.textItalic,
950
+ color: prop.labelsAboveColor || prop.textColor,
951
+ background: prop.labelsAboveBackground || null,
952
+ padding: prop.labelsAboveBackgroundPadding || 0
953
+ });
954
+ }
955
+ }
956
+ }
957
+ };
958
+
959
+
960
+
961
+
962
+
963
+
964
+
965
+
966
+ /**
967
+ * Using a function to add events makes it easier to facilitate method
968
+ * chaining
969
+ *
970
+ * @param string type The type of even to add
971
+ * @param function func
972
+ */
973
+ this.on = function (type, func)
974
+ {
975
+ if (type.substr(0,2) !== 'on') {
976
+ type = 'on' + type;
977
+ }
978
+
979
+ RG.SVG.addCustomEventListener(this, type, func);
980
+
981
+ return this;
982
+ };
983
+
984
+
985
+
986
+
987
+
988
+
989
+
990
+
991
+ //
992
+ // Used in chaining. Runs a function there and then - not waiting for
993
+ // the events to fire (eg the onbeforedraw event)
994
+ //
995
+ // @param function func The function to execute
996
+ //
997
+ this.exec = function (func)
998
+ {
999
+ func(this);
1000
+
1001
+ return this;
1002
+ };
1003
+
1004
+
1005
+
1006
+
1007
+
1008
+
1009
+
1010
+
1011
+ //
1012
+ // Remove highlight from the chart (tooltips)
1013
+ //
1014
+ this.removeHighlight = function ()
1015
+ {
1016
+ var highlight = RG.SVG.REG.get('highlight');
1017
+ if (highlight && highlight.parentNode) {
1018
+ highlight.parentNode.removeChild(highlight);
1019
+ }
1020
+
1021
+ RG.SVG.REG.set('highlight', null);
1022
+ };
1023
+
1024
+
1025
+
1026
+
1027
+
1028
+
1029
+
1030
+
1031
+ //
1032
+ // The Bar chart grow effect
1033
+ //
1034
+ this.grow = function ()
1035
+ {
1036
+ var opt = arguments[0] || {},
1037
+ frames = opt.frames || 30,
1038
+ frame = 0,
1039
+ obj = this,
1040
+ data = [],
1041
+ height = null,
1042
+ seq = 0;
1043
+ /*
1044
+ //
1045
+ // Copy the data
1046
+ //
1047
+ data = RG.SVG.arrayClone(this.data);
1048
+
1049
+ this.draw();
1050
+
1051
+ var iterate = function ()
1052
+ {
1053
+
1054
+ for (var i=0,seq=0,len=obj.coords.length; i<len; ++i, ++seq) {
1055
+
1056
+ var multiplier = (frame / frames)
1057
+ * RG.SVG.FX.getEasingMultiplier(frames, frame)
1058
+ * RG.SVG.FX.getEasingMultiplier(frames, frame);
1059
+
1060
+
1061
+
1062
+
1063
+ // TODO Go through the data and update the value according to
1064
+ // the frame number
1065
+ if (typeof data[i] === 'number') {
1066
+
1067
+ height = ma.abs(obj.getYCoord(data[i]) - obj.getYCoord(0));
1068
+ obj.data[i] = data[i] * multiplier;
1069
+ height = multiplier * height;
1070
+
1071
+ // Set the new height on the rect
1072
+ obj.coords[seq].object.setAttribute(
1073
+ 'height',
1074
+ height
1075
+ );
1076
+
1077
+ // Set the correct Y coord on the object
1078
+ obj.coords[seq].object.setAttribute(
1079
+ 'y',
1080
+ data[i] < 0 ? obj.getYCoord(0) : obj.getYCoord(0) - height
1081
+ );
1082
+
1083
+ } else if (typeof data[i] === 'object') {
1084
+
1085
+ var accumulativeHeight = 0;
1086
+
1087
+ for (var j=0,len2=data[i].length; j<len2; ++j, ++seq) {
1088
+
1089
+ height = ma.abs(obj.getYCoord(data[i][j]) - obj.getYCoord(0));
1090
+ height = multiplier * height;
1091
+ obj.data[i][j] = data[i][j] * multiplier;
1092
+
1093
+ obj.coords[seq].object.setAttribute(
1094
+ 'height',
1095
+ height
1096
+ );
1097
+
1098
+ obj.coords[seq].object.setAttribute(
1099
+ 'y',
1100
+ data[i][j] < 0 ? (obj.getYCoord(0) + accumulativeHeight) : (obj.getYCoord(0) - height - accumulativeHeight)
1101
+ );
1102
+
1103
+ accumulativeHeight += (prop.grouping === 'stacked' ? height : 0);
1104
+ }
1105
+
1106
+ //
1107
+ // Set the height and Y cooord of the backfaces if necessary
1108
+ //
1109
+ if (obj.stackedBackfaces[i]) {
1110
+ obj.stackedBackfaces[i].setAttribute(
1111
+ 'height',
1112
+ accumulativeHeight
1113
+ );
1114
+
1115
+ obj.stackedBackfaces[i].setAttribute(
1116
+ 'y',
1117
+ obj.height - prop.gutterBottom - accumulativeHeight
1118
+ );
1119
+ }
1120
+
1121
+ // Decrease seq by one so that it's not incremented twice
1122
+ --seq;
1123
+ }
1124
+ }
1125
+
1126
+ if (frame++ < frames) {
1127
+ //setTimeout(iterate, frame > 1 ? opt.delay : 200);
1128
+ RG.SVG.FX.update(iterate);
1129
+ } else if (opt.callback) {
1130
+ (opt.callback)(obj);
1131
+ }
1132
+ };
1133
+
1134
+ iterate();
1135
+ */
1136
+ return this;
1137
+ };
1138
+
1139
+
1140
+
1141
+
1142
+
1143
+
1144
+
1145
+
1146
+ /**
1147
+ * HBar chart Wave effect.
1148
+ *
1149
+ * @param object OPTIONAL An object map of options. You specify 'frames'
1150
+ * here to give the number of frames in the effect
1151
+ * and also callback to specify a callback function
1152
+ * thats called at the end of the effect
1153
+ */
1154
+ this.wave = function ()
1155
+ {
1156
+ /*
1157
+ // First draw the chart
1158
+ this.draw();
1159
+
1160
+
1161
+ var obj = this,
1162
+ opt = arguments[0] || {};
1163
+
1164
+ opt.frames = opt.frames || 60;
1165
+ opt.startFrames = [];
1166
+ opt.counters = [];
1167
+
1168
+ var framesperbar = opt.frames / 3,
1169
+ frame = -1,
1170
+ callback = opt.callback || function () {};
1171
+
1172
+ for (var i=0,len=this.coords.length; i<len; i+=1) {
1173
+ opt.startFrames[i] = ((opt.frames / 2) / (obj.coords.length - 1)) * i;
1174
+ opt.counters[i] = 0;
1175
+
1176
+ // Now zero the width of the bar
1177
+ this.coords[i].object.setAttribute('height', 0);
1178
+ }
1179
+
1180
+
1181
+ function iterator ()
1182
+ {
1183
+ ++frame;
1184
+
1185
+ for (var i=0,len=obj.coords.length; i<len; i+=1) {
1186
+ if (frame > opt.startFrames[i]) {
1187
+
1188
+ var originalHeight = obj.coords[i].object.getAttribute('data-original-height'),
1189
+ height,
1190
+ value = parseFloat(obj.coords[i].object.getAttribute('data-value'));
1191
+
1192
+ obj.coords[i].object.setAttribute(
1193
+ 'height',
1194
+ height = ma.min(
1195
+ ((frame - opt.startFrames[i]) / framesperbar) * originalHeight,
1196
+ originalHeight
1197
+ )
1198
+ );
1199
+
1200
+ obj.coords[i].object.setAttribute(
1201
+ 'y',
1202
+ value >=0 ? obj.getYCoord(0) - height : obj.getYCoord(0)
1203
+ );
1204
+
1205
+ if (prop.grouping === 'stacked') {
1206
+ var seq = obj.coords[i].object.getAttribute('data-sequential-index');
1207
+
1208
+ var indexes = RG.SVG.sequentialIndexToGrouped(seq, obj.data);
1209
+
1210
+ if (indexes[1] > 0) {
1211
+ obj.coords[i].object.setAttribute(
1212
+ 'y',
1213
+ parseInt(obj.coords[i - 1].object.getAttribute('y')) - height
1214
+ );
1215
+ }
1216
+ }
1217
+ }
1218
+ }
1219
+
1220
+
1221
+ if (frame >= opt.frames) {
1222
+ callback(obj);
1223
+ } else {
1224
+ RG.SVG.FX.update(iterator);
1225
+ }
1226
+ }
1227
+
1228
+ iterator();
1229
+ */
1230
+ return this;
1231
+ };
1232
+
1233
+
1234
+
1235
+
1236
+
1237
+
1238
+
1239
+
1240
+ //
1241
+ // Set the options that the user has provided
1242
+ //
1243
+ for (i in conf.options) {
1244
+ if (typeof i === 'string') {
1245
+ this.set(i, conf.options[i]);
1246
+ }
1247
+ }
1248
+ };
1249
+
1250
+ return this;
1251
+
1252
+ // End module pattern
1253
+ })(window, document);