rgraph-rails 1.0.8 → 4.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +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);