rgraph-rails 4.62 → 4.64

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 +5 -5
  2. data/README.md +3 -4
  3. data/lib/rgraph-rails/version.rb +1 -1
  4. data/vendor/assets/javascripts/RGraph.bar.js +240 -3742
  5. data/vendor/assets/javascripts/RGraph.bipolar.js +165 -2005
  6. data/vendor/assets/javascripts/RGraph.common.annotate.js +35 -395
  7. data/vendor/assets/javascripts/RGraph.common.context.js +30 -595
  8. data/vendor/assets/javascripts/RGraph.common.core.js +418 -5359
  9. data/vendor/assets/javascripts/RGraph.common.csv.js +20 -276
  10. data/vendor/assets/javascripts/RGraph.common.deprecated.js +35 -450
  11. data/vendor/assets/javascripts/RGraph.common.dynamic.js +88 -1395
  12. data/vendor/assets/javascripts/RGraph.common.effects.js +90 -1545
  13. data/vendor/assets/javascripts/RGraph.common.key.js +52 -753
  14. data/vendor/assets/javascripts/RGraph.common.resizing.js +37 -563
  15. data/vendor/assets/javascripts/RGraph.common.sheets.js +29 -352
  16. data/vendor/assets/javascripts/RGraph.common.tooltips.js +32 -450
  17. data/vendor/assets/javascripts/RGraph.common.zoom.js +14 -219
  18. data/vendor/assets/javascripts/RGraph.cornergauge.js +71 -0
  19. data/vendor/assets/javascripts/RGraph.drawing.background.js +34 -570
  20. data/vendor/assets/javascripts/RGraph.drawing.circle.js +33 -544
  21. data/vendor/assets/javascripts/RGraph.drawing.image.js +51 -755
  22. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +37 -645
  23. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +36 -633
  24. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +35 -514
  25. data/vendor/assets/javascripts/RGraph.drawing.poly.js +37 -559
  26. data/vendor/assets/javascripts/RGraph.drawing.rect.js +33 -548
  27. data/vendor/assets/javascripts/RGraph.drawing.text.js +36 -664
  28. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +50 -812
  29. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +51 -856
  30. data/vendor/assets/javascripts/RGraph.fuel.js +58 -964
  31. data/vendor/assets/javascripts/RGraph.funnel.js +55 -984
  32. data/vendor/assets/javascripts/RGraph.gantt.js +77 -1354
  33. data/vendor/assets/javascripts/RGraph.gauge.js +85 -1421
  34. data/vendor/assets/javascripts/RGraph.hbar.js +162 -2788
  35. data/vendor/assets/javascripts/RGraph.hprogress.js +80 -1401
  36. data/vendor/assets/javascripts/RGraph.line.js +249 -4248
  37. data/vendor/assets/javascripts/RGraph.meter.js +74 -1280
  38. data/vendor/assets/javascripts/RGraph.modaldialog.js +19 -301
  39. data/vendor/assets/javascripts/RGraph.odo.js +71 -1264
  40. data/vendor/assets/javascripts/RGraph.pie.js +137 -2288
  41. data/vendor/assets/javascripts/RGraph.radar.js +110 -1847
  42. data/vendor/assets/javascripts/RGraph.rose.js +108 -1977
  43. data/vendor/assets/javascripts/RGraph.rscatter.js +80 -1432
  44. data/vendor/assets/javascripts/RGraph.scatter.js +172 -3163
  45. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +60 -1120
  46. data/vendor/assets/javascripts/RGraph.svg.bar.js +66 -1735
  47. data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +21 -246
  48. data/vendor/assets/javascripts/RGraph.svg.common.core.js +255 -3937
  49. data/vendor/assets/javascripts/RGraph.svg.common.csv.js +20 -276
  50. data/vendor/assets/javascripts/RGraph.svg.common.fx.js +68 -1303
  51. data/vendor/assets/javascripts/RGraph.svg.common.key.js +19 -205
  52. data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +29 -352
  53. data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +22 -273
  54. data/vendor/assets/javascripts/RGraph.svg.funnel.js +32 -0
  55. data/vendor/assets/javascripts/RGraph.svg.hbar.js +59 -1400
  56. data/vendor/assets/javascripts/RGraph.svg.line.js +70 -1580
  57. data/vendor/assets/javascripts/RGraph.svg.pie.js +55 -1131
  58. data/vendor/assets/javascripts/RGraph.svg.radar.js +57 -1502
  59. data/vendor/assets/javascripts/RGraph.svg.rose.js +66 -1817
  60. data/vendor/assets/javascripts/RGraph.svg.scatter.js +58 -1261
  61. data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +28 -865
  62. data/vendor/assets/javascripts/RGraph.svg.waterfall.js +45 -1252
  63. data/vendor/assets/javascripts/RGraph.thermometer.js +63 -1136
  64. data/vendor/assets/javascripts/RGraph.vprogress.js +83 -1470
  65. data/vendor/assets/javascripts/RGraph.waterfall.js +83 -1347
  66. metadata +5 -4
  67. data/vendor/assets/javascripts/financial-data.js +0 -1067
@@ -1,1736 +1,67 @@
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
1
 
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.Bar = 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 = 'bar';
87
- this.coords = [];
88
- this.stackedBackfaces = [];
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
- variant: null,
105
- variant3dOffsetx: 10,
106
- variant3dOffsety: 5,
107
-
108
- backgroundColor: null,
109
- backgroundImage: null,
110
- backgroundImageAspect: 'none',
111
- backgroundImageStretch: true,
112
- backgroundImageOpacity: null,
113
- backgroundImageX: null,
114
- backgroundImageY: null,
115
- backgroundImageW: null,
116
- backgroundImageH: null,
117
- backgroundGrid: true,
118
- backgroundGridColor: '#ddd',
119
- backgroundGridLinewidth: 1,
120
- backgroundGridHlines: true,
121
- backgroundGridHlinesCount: null,
122
- backgroundGridVlines: true,
123
- backgroundGridVlinesCount: null,
124
- backgroundGridBorder: true,
125
-
126
- // 20 colors. If you need more you need to set the colors property
127
- colors: [
128
- 'red', '#0f0', '#00f', '#ff0', '#0ff', '#0f0','pink','orange','gray','black',
129
- 'red', '#0f0', '#00f', '#ff0', '#0ff', '#0f0','pink','orange','gray','black'
130
- ],
131
- colorsSequential: false,
132
- strokestyle: 'rgba(0,0,0,0)',
133
-
134
- hmargin: 3,
135
- hmarginGrouped: 2,
136
-
137
- yaxis: true,
138
- yaxisTickmarks: true,
139
- yaxisTickmarksLength: 3,
140
- yaxisColor: 'black',
141
-
142
- yaxisScale: true,
143
- yaxisLabels: null,
144
- yaxisLabelsOffsetx: 0,
145
- yaxisLabelsOffsety: 0,
146
- yaxisLabelsCount: 5,
147
-
148
- yaxisUnitsPre: '',
149
- yaxisUnitsPost: '',
150
- yaxisStrict: false,
151
- yaxisDecimals: 0,
152
- yaxisPoint: '.',
153
- yaxisThousand: ',',
154
- yaxisRound: false,
155
- yaxisMax: null,
156
- yaxisMin: 0,
157
- yaxisFormatter: null,
158
-
159
- xaxis: true,
160
- xaxisTickmarks: true,
161
- xaxisTickmarksLength: 5,
162
- xaxisLabels: null,
163
- xaxisLabelsPosition: 'section',
164
- xaxisLabelsPositionEdgeTickmarksCount: null,
165
- xaxisColor: 'black',
166
- xaxisLabelsOffsetx: 0,
167
- xaxisLabelsOffsety: 0,
168
-
169
- labelsAbove: false,
170
- labelsAboveFont: null,
171
- labelsAboveSize: null,
172
- labelsAboveBold: null,
173
- labelsAboveItalic: null,
174
- labelsAboveColor: null,
175
- labelsAboveBackground: null,
176
- labelsAboveBackgroundPadding: 0,
177
- labelsAboveUnitsPre: null,
178
- labelsAboveUnitsPost: null,
179
- labelsAbovePoint: null,
180
- labelsAboveThousand: null,
181
- labelsAboveFormatter: null,
182
- labelsAboveDecimals: null,
183
- labelsAboveOffsetx: 0,
184
- labelsAboveOffsety: 0,
185
- labelsAboveHalign: 'center',
186
- labelsAboveValign: 'bottom',
187
- labelsAboveSpecific: null,
188
-
189
- textColor: 'black',
190
- textFont: 'sans-serif',
191
- textSize: 12,
192
- textBold: false,
193
- textItalic: false,
194
-
195
- linewidth: 1,
196
- grouping: 'grouped',
197
-
198
- tooltips: null,
199
- tooltipsOverride: null,
200
- tooltipsEffect: 'fade',
201
- tooltipsCssClass: 'RGraph_tooltip',
202
- tooltipsEvent: 'click',
203
-
204
- highlightStroke: 'rgba(0,0,0,0)',
205
- highlightFill: 'rgba(255,255,255,0.7)',
206
- highlightLinewidth: 1,
207
-
208
- title: '',
209
- titleSize: 16,
210
- titleX: null,
211
- titleY: null,
212
- titleHalign: 'center',
213
- titleValign: null,
214
- titleColor: 'black',
215
- titleFont: null,
216
- titleBold: false,
217
- titleItalic: false,
218
-
219
- titleSubtitle: '',
220
- titleSubtitleSize: 10,
221
- titleSubtitleX: null,
222
- titleSubtitleY: null,
223
- titleSubtitleHalign: 'center',
224
- titleSubtitleValign: null,
225
- titleSubtitleColor: '#aaa',
226
- titleSubtitleFont: null,
227
- titleSubtitleBold: false,
228
- titleSubtitleItalic: false,
229
-
230
- shadow: false,
231
- shadowOffsetx: 2,
232
- shadowOffsety: 2,
233
- shadowBlur: 2,
234
- shadowOpacity: 0.25,
235
-
236
- key: null,
237
- keyColors: null,
238
- keyOffsetx: 0,
239
- keyOffsety: 0,
240
- keyTextOffsetx: 0,
241
- keyTextOffsety: -1,
242
- keyTextSize: null,
243
- keyTextBold: null,
244
- keyTextItalic: null,
245
- keyTextFont: null,
246
-
247
- attribution: true,
248
- attributionX: null,
249
- attributionY: null,
250
- attributionHref: null,// Default is set in RGraph.svg.common.core.js
251
- attributionHalign: 'right',
252
- attributionValign: 'bottom',
253
- attributionSize: 7,
254
- attributionColor: 'gray',
255
- attributionFont: 'sans-serif',
256
- attributionItalic: false,
257
- attributionBold: false
258
- };
259
-
260
-
261
-
262
-
263
-
264
- /**
265
- * "Decorate" the object with the generic effects if the effects library has been included
266
- */
267
- if (RG.SVG.FX && typeof RG.SVG.FX.decorate === 'function') {
268
- RG.SVG.FX.decorate(this);
269
- }
270
-
271
-
272
-
273
-
274
- var prop = this.properties;
275
-
276
-
277
-
278
-
279
-
280
-
281
-
282
-
283
- //
284
- // The draw method draws the Bar chart
285
- //
286
- this.draw = function ()
287
- {
288
- // Fire the beforedraw event
289
- RG.SVG.fireCustomEvent(this, 'onbeforedraw');
290
-
291
-
292
-
293
- // Zero these if the 3D effect is not wanted
294
- if (prop.variant !== '3d') {
295
- prop.variant3dOffsetx = 0;
296
- prop.variant3dOffsety = 0;
297
-
298
- } else {
299
-
300
- // Set the skew transform on the all group if necessary
301
- this.svg.all.setAttribute('transform', 'skewY(5)');
302
- }
303
-
304
-
305
-
306
- // Create the defs tag if necessary
307
- RG.SVG.createDefs(this);
308
-
309
-
310
-
311
-
312
-
313
-
314
-
315
- // Reset the coords array
316
- this.coords = [];
317
-
318
-
319
- this.graphWidth = this.width - prop.gutterLeft - prop.gutterRight;
320
- this.graphHeight = this.height - prop.gutterTop - prop.gutterBottom;
321
-
322
-
323
-
324
- /**
325
- * Parse the colors. This allows for simple gradient syntax
326
- */
327
-
328
- // Parse the colors for gradients
329
- RG.SVG.resetColorsToOriginalValues({object:this});
330
- this.parseColors();
331
-
332
-
333
-
334
- // Go through the data and work out the maximum value
335
- var values = [];
336
-
337
- for (var i=0,max=0; i<this.data.length; ++i) {
338
- if (typeof this.data[i] === 'number') {
339
- values.push(this.data[i]);
340
-
341
- } else if (RG.SVG.isArray(this.data[i]) && prop.grouping === 'grouped') {
342
- values.push(RG.SVG.arrayMax(this.data[i]));
343
-
344
- } else if (RG.SVG.isArray(this.data[i]) && prop.grouping === 'stacked') {
345
- values.push(RG.SVG.arraySum(this.data[i]));
346
- }
347
- }
348
- var max = RG.SVG.arrayMax(values);
349
-
350
- // A custom, user-specified maximum value
351
- if (typeof prop.yaxisMax === 'number') {
352
- max = prop.yaxisMax;
353
- }
354
-
355
- // Set the ymin to zero if it's szet mirror
356
- if (prop.yaxisMin === 'mirror' || prop.yaxisMin === 'middle' || prop.yaxisMin === 'center') {
357
- var mirrorScale = true;
358
- prop.yaxisMin = 0;
359
- }
360
-
361
-
362
- //
363
- // Generate an appropiate scale
364
- //
365
- this.scale = RG.SVG.getScale({
366
- object: this,
367
- numlabels: prop.yaxisLabelsCount,
368
- unitsPre: prop.yaxisUnitsPre,
369
- unitsPost: prop.yaxisUnitsPost,
370
- max: max,
371
- min: prop.yaxisMin,
372
- point: prop.yaxisPoint,
373
- round: prop.yaxisRound,
374
- thousand: prop.yaxisThousand,
375
- decimals: prop.yaxisDecimals,
376
- strict: typeof prop.yaxisMax === 'number',
377
- formatter: prop.yaxisFormatter
378
- });
379
-
380
-
381
-
382
- //
383
- // Get the scale a second time if the ymin should be mirored
384
- //
385
- // Set the ymin to zero if it's szet mirror
386
- if (mirrorScale) {
387
- this.scale = RG.SVG.getScale({
388
- object: this,
389
- numlabels: prop.yaxisLabelsCount,
390
- unitsPre: prop.yaxisUnitsPre,
391
- unitsPost: prop.yaxisUnitsPost,
392
- max: this.scale.max,
393
- min: this.scale.max * -1,
394
- point: prop.yaxisPoint,
395
- round: false,
396
- thousand: prop.yaxisThousand,
397
- decimals: prop.yaxisDecimals,
398
- strict: typeof prop.yaxisMax === 'number',
399
- formatter: prop.yaxisFormatter
400
- });
401
- }
402
-
403
- // Now the scale has been generated adopt its max value
404
- this.max = this.scale.max;
405
- this.min = this.scale.min;
406
- prop.yaxisMax = this.scale.max;
407
- prop.yaxisMin = this.scale.min;
408
-
409
-
410
-
411
- // Draw the background first
412
- RG.SVG.drawBackground(this);
413
-
414
-
415
-
416
- // Draw the threeD axes here so everything else is drawn on top of
417
- // it, but after the scale generation
418
- if (prop.variant === '3d') {
419
-
420
-
421
-
422
-
423
- // Draw the 3D Y axis
424
- RG.SVG.create({
425
- svg: this.svg,
426
- parent: this.svg.all,
427
- type: 'path',
428
- attr: {
429
- d: 'M {1} {2} L {3} {4} L {5} {6} L {7} {8}'.format(
430
- prop.gutterLeft,
431
- prop.gutterTop,
432
-
433
- prop.gutterLeft + prop.variant3dOffsetx,
434
- prop.gutterTop - prop.variant3dOffsety,
435
-
436
- prop.gutterLeft + prop.variant3dOffsetx,
437
- this.height - prop.gutterBottom - prop.variant3dOffsety,
438
-
439
- prop.gutterLeft,
440
- this.height - prop.gutterBottom,
441
-
442
- prop.gutterLeft,
443
- prop.gutterTop
444
- ),
445
- fill: '#ddd',
446
- stroke: '#ccc'
447
- }
448
- });
449
-
450
-
451
-
452
-
453
- // Add the group that the negative bars are added to. This makes them
454
- // appear below the axes
455
- this.threed_xaxis_group = RG.SVG.create({
456
- svg: this.svg,
457
- type: 'g',
458
- parent: this.svg.all,
459
- attr: {
460
- className: 'rgraph_3d_bar_xaxis_negative'
461
- }
462
- });
463
-
464
-
465
-
466
- // Draw the 3D X axis
467
- RG.SVG.create({
468
- svg: this.svg,
469
- parent: this.svg.all,
470
- type: 'path',
471
- attr: {
472
- d: 'M {1} {2} L {3} {4} L {5} {6} L {7} {8}'.format(
473
- prop.gutterLeft,
474
- this.getYCoord(0),
475
-
476
- prop.gutterLeft + prop.variant3dOffsetx,
477
- this.getYCoord(0) - prop.variant3dOffsety,
478
-
479
- this.width - prop.gutterRight + prop.variant3dOffsetx,
480
- this.getYCoord(0) - prop.variant3dOffsety,
481
-
482
- this.width - prop.gutterRight,
483
- this.getYCoord(0),
484
-
485
- prop.gutterLeft,
486
- this.getYCoord(0)
487
- ),
488
- fill: '#ddd',
489
- stroke: '#ccc'
490
- }
491
- });
492
- }
493
-
494
-
495
-
496
-
497
-
498
-
499
- // Draw the bars
500
- this.drawBars();
501
-
502
-
503
- // Draw the axes over the bars
504
- RG.SVG.drawXAxis(this);
505
- RG.SVG.drawYAxis(this);
506
-
507
-
508
- // Draw the labelsAbove labels
509
- this.drawLabelsAbove();
510
-
511
-
512
-
513
-
514
-
515
- // Draw the key
516
- if (typeof prop.key !== null && RG.SVG.drawKey) {
517
- RG.SVG.drawKey(this);
518
- } else if (!RGraph.SVG.isNull(prop.key)) {
519
- alert('The drawKey() function does not exist - have you forgotten to include the key library?');
520
- }
521
-
522
-
523
-
524
-
525
-
526
- // Add the attribution link. If you're adding this elsewhere on your page/site
527
- // and you don't want it displayed then there are options available to not
528
- // show it.
529
- RG.SVG.attribution(this);
530
-
531
-
532
-
533
-
534
- // Add the event listener that clears the highlight rect if
535
- // there is any. Must be MOUSEDOWN (ie before the click event)
536
- //var obj = this;
537
- //document.body.addEventListener('mousedown', function (e)
538
- //{
539
- // //RG.SVG.removeHighlight(obj);
540
- //
541
- //}, false);
542
-
543
-
544
-
545
- // Fire the draw event
546
- RG.SVG.fireCustomEvent(this, 'ondraw');
547
-
548
-
549
-
550
-
551
- return this;
552
- };
553
-
554
-
555
-
556
-
557
-
558
-
559
-
560
-
561
- //
562
- // Draws the bars
563
- //
564
- this.drawBars = function ()
565
- {
566
- var y = this.getYCoord(0);
567
-
568
- if (prop.shadow) {
569
- RG.SVG.setShadow({
570
- object: this,
571
- offsetx: prop.shadowOffsetx,
572
- offsety: prop.shadowOffsety,
573
- blur: prop.shadowBlur,
574
- opacity: prop.shadowOpacity,
575
- id: 'dropShadow'
576
- });
577
- }
578
-
579
- // Go through the bars
580
- for (var i=0,sequentialIndex=0; i<this.data.length; ++i,++sequentialIndex) {
581
-
582
- //
583
- // Regular bars
584
- //
585
- if (typeof this.data[i] === 'number') {
586
-
587
- var outerSegment = this.graphWidth / this.data.length,
588
- height = (ma.abs(this.data[i]) - ma.abs(this.scale.min)) / (ma.abs(this.scale.max) - ma.abs(this.scale.min)) * this.graphHeight,
589
- width = (this.graphWidth / this.data.length) - prop.hmargin - prop.hmargin,
590
- x = prop.gutterLeft + prop.hmargin + (outerSegment * i);
591
-
592
- // Work out the height and the Y coord of the Bar
593
- if (this.scale.min >= 0 && this.scale.max > 0) {
594
- y = this.getYCoord(this.scale.min) - height;
595
-
596
- } else if (this.scale.min < 0 && this.scale.max > 0) {
597
- height = (ma.abs(this.data[i]) / (this.scale.max - this.scale.min)) * this.graphHeight;
598
- y = this.getYCoord(0) - height;
599
-
600
- if (this.data[i] < 0) {
601
- y = this.getYCoord(0);
602
- }
603
- } else if (this.scale.min < 0 && this.scale.max < 0) {
604
- height = (ma.abs(this.data[i]) - ma.abs(this.scale.max)) / (ma.abs(this.scale.min) - ma.abs(this.scale.max)) * this.graphHeight;
605
- y = prop.gutterTop;
606
- }
607
-
608
- var rect = RG.SVG.create({
609
- svg: this.svg,
610
- type: 'rect',
611
- parent: prop.variant === '3d' && this.data[i] < 0 ? this.threed_xaxis_group : this.svg.all,
612
- attr: {
613
- stroke: prop.strokestyle,
614
- fill: prop.colorsSequential ? (prop.colors[sequentialIndex] ? prop.colors[sequentialIndex] : prop.colors[prop.colors.length - 1]) : prop.colors[0],
615
- x: x,
616
- y: y,
617
- width: width < 0 ? 0 : width,
618
- height: height,
619
- 'stroke-width': prop.linewidth,
620
- 'data-original-x': x,
621
- 'data-original-y': y,
622
- 'data-original-width': width,
623
- 'data-original-height': height,
624
- 'data-tooltip': (!RG.SVG.isNull(prop.tooltips) && prop.tooltips.length) ? prop.tooltips[i] : '',
625
- 'data-index': i,
626
- 'data-sequential-index': sequentialIndex,
627
- 'data-value': this.data[i],
628
- filter: prop.shadow ? 'url(#dropShadow)' : ''
629
- }
630
- });
631
-
632
- this.coords.push({
633
- object: rect,
634
- x: x,
635
- y: y - (this.data[i] > 0 ? height : 0),
636
- width: width,
637
- height: height
638
- });
639
-
640
-
641
- //
642
- // Add the 3D faces if required
643
- //
644
- if (prop.variant === '3d') {
645
- this.drawTop3dFace({rect: rect, value: this.data[i]});
646
- this.drawSide3dFace({rect: rect, value: this.data[i]});
647
- }
648
-
649
-
650
-
651
-
652
-
653
-
654
- // Add the tooltip data- attribute
655
- if (!RG.SVG.isNull(prop.tooltips) && prop.tooltips[sequentialIndex]) {
656
-
657
- var obj = this;
658
-
659
- //
660
- // Add tooltip event listeners
661
- //
662
- (function (idx, seq)
663
- {
664
- rect.addEventListener(prop.tooltipsEvent.replace(/^on/, ''), function (e)
665
- {
666
- obj.removeHighlight();
667
-
668
- // Show the tooltip
669
- RG.SVG.tooltip({
670
- object: obj,
671
- index: idx,
672
- group: null,
673
- sequentialIndex: seq,
674
- text: prop.tooltips[seq],
675
- event: e
676
- });
677
-
678
- // Highlight the rect that has been clicked on
679
- obj.highlight(e.target);
680
- }, false);
681
-
682
- rect.addEventListener('mousemove', function (e)
683
- {
684
- e.target.style.cursor = 'pointer'
685
- }, false);
686
- })(i, sequentialIndex);
687
- }
688
-
689
-
690
-
691
-
692
-
693
- //
694
- // Grouped bars
695
- //
696
- } else if (RG.SVG.isArray(this.data[i]) && prop.grouping === 'grouped') {
697
-
698
- var outerSegment = (this.graphWidth / this.data.length),
699
- innerSegment = outerSegment - (2 * prop.hmargin);
700
-
701
- // Loop through the group
702
- for (var j=0; j<this.data[i].length; ++j,++sequentialIndex) {
703
-
704
- var width = ( (innerSegment - ((this.data[i].length - 1) * prop.hmarginGrouped)) / this.data[i].length),
705
- x = (outerSegment * i) + prop.hmargin + prop.gutterLeft + (j * width) + ((j - 1) * prop.hmarginGrouped);
706
-
707
- x = prop.gutterLeft + (outerSegment * i) + (width * j) + prop.hmargin + (j * prop.hmarginGrouped);
708
-
709
-
710
-
711
-
712
-
713
-
714
-
715
-
716
-
717
-
718
-
719
-
720
-
721
-
722
-
723
- // Calculate the height
724
- // eg 0 -> 10
725
- if (this.scale.min === 0 && this.scale.max > this.scale.min) {
726
- var height = ((this.data[i][j] - this.scale.min) / (this.scale.max - this.scale.min)) * this.graphHeight,
727
- y = this.getYCoord(0) - height;
728
-
729
- // eg -5 -> -15
730
- } else if (this.scale.max <= 0 && this.scale.min < this.scale.max) {
731
- var height = ((this.data[i][j] - this.scale.max) / (this.scale.max - this.scale.min)) * this.graphHeight,
732
- y = this.getYCoord(this.scale.max);
733
-
734
- height = ma.abs(height);
735
-
736
- // eg 10 -> -10
737
- } else if (this.scale.max > 0 && this.scale.min < 0) {
738
-
739
- var height = (ma.abs(this.data[i][j]) / (this.scale.max - this.scale.min)) * this.graphHeight,
740
- y = this.data[i][j] < 0 ? this.getYCoord(0) : this.getYCoord(this.data[i][j]);
741
-
742
- // eg 5 -> 10
743
- } else if (this.scale.min > 0 && this.scale.max > this.scale.min) {
744
- var height = (ma.abs(this.data[i][j] - this.scale.min) / (this.scale.max - this.scale.min)) * this.graphHeight,
745
- y = this.getYCoord(this.scale.min) - height;
746
- }
747
-
748
-
749
-
750
-
751
-
752
-
753
-
754
- // Add the rect tag
755
- var rect = RG.SVG.create({
756
- svg: this.svg,
757
- parent: prop.variant === '3d' && this.data[i][j] < 0 ? this.threed_xaxis_group : this.svg.all,
758
- type: 'rect',
759
- attr: {
760
- stroke: prop['strokestyle'],
761
- fill: (prop.colorsSequential && prop.colors[sequentialIndex]) ? prop.colors[sequentialIndex] : prop.colors[j],
762
- x: x,
763
- y: y,
764
- width: width,
765
- height: height,
766
- 'stroke-width': prop.linewidth,
767
- 'data-original-x': x,
768
- 'data-original-y': y,
769
- 'data-original-width': width,
770
- 'data-original-height': height,
771
- 'data-index': i,
772
- 'data-sequential-index': sequentialIndex,
773
- 'data-tooltip': (!RG.SVG.isNull(prop.tooltips) && prop.tooltips.length) ? prop.tooltips[sequentialIndex] : '',
774
- 'data-value': this.data[i][j],
775
- filter: prop.shadow ? 'url(#dropShadow)' : ''
776
- }
777
- });
778
-
779
- this.coords.push({
780
- object: rect,
781
- x: x,
782
- y: y - (this.data[i][j] > 0 ? height : 0),
783
- width: width,
784
- height: height
785
- });
786
-
787
-
788
-
789
-
790
- //
791
- // Add the 3D faces if required
792
- //
793
- if (prop.variant === '3d') {
794
- this.drawTop3dFace({rect: rect, value: this.data[i][j]});
795
- this.drawSide3dFace({rect: rect, value: this.data[i][j]});
796
- }
797
-
798
-
799
-
800
-
801
-
802
-
803
-
804
- // Add the tooltip data- attribute
805
- if (!RG.SVG.isNull(prop.tooltips) && prop.tooltips[sequentialIndex]) {
806
-
807
- var obj = this;
808
-
809
-
810
- //
811
- // Add tooltip event listeners
812
- //
813
- (function (idx, seq)
814
- {
815
- obj.removeHighlight();
816
-
817
- var indexes = RG.SVG.sequentialIndexToGrouped(seq, obj.data);
818
-
819
- rect.addEventListener(prop.tooltipsEvent.replace(/^on/, ''), function (e)
820
- {
821
- // Show the tooltip
822
- RG.SVG.tooltip({
823
- object: obj,
824
- group: idx,
825
- index: indexes[1],
826
- sequentialIndex: seq,
827
- text: prop.tooltips[seq],
828
- event: e
829
- });
830
-
831
- // Highlight the rect that has been clicked on
832
- obj.highlight(e.target);
833
-
834
- }, false);
835
-
836
- rect.addEventListener('mousemove', function (e)
837
- {
838
- e.target.style.cursor = 'pointer'
839
- }, false);
840
- })(i, sequentialIndex);
841
- }
842
- }
843
-
844
- --sequentialIndex;
845
-
846
-
847
-
848
-
849
-
850
-
851
-
852
-
853
-
854
-
855
- //
856
- // Stacked charts
857
- //
858
- } else if (RG.SVG.isArray(this.data[i]) && prop.grouping === 'stacked') {
859
-
860
- var section = (this.graphWidth / this.data.length);
861
-
862
-
863
- // Intialise the Y coordinate to the bottom gutter
864
- var y = this.getYCoord(0);
865
-
866
-
867
-
868
- // Loop through the stack
869
- for (var j=0; j<this.data[i].length; ++j,++sequentialIndex) {
870
-
871
- var height = ma.round((this.data[i][j] / (this.max - this.min)) * this.graphHeight),
872
- width = section - (2 * prop.hmargin),
873
- x = prop.gutterLeft + (i * section) + prop.hmargin,
874
- y = y - height;
875
-
876
- // If this is the first iteration of the loop and a shadow
877
- // is requested draw a rect here to create it.
878
- if (j === 0 && prop.shadow) {
879
-
880
- var fullHeight = ma.abs((RG.SVG.arraySum(this.data[i]) / (this.max - this.min)) * this.graphHeight);
881
-
882
- var rect = RG.SVG.create({
883
- svg: this.svg,
884
- parent: this.svg.all,
885
- type: 'rect',
886
- attr: {
887
- fill: 'white',
888
- x: x,
889
- y: this.height - prop.gutterBottom - fullHeight,
890
- width: width,
891
- height: fullHeight,
892
- 'stroke-width': 0,
893
- 'data-index': i,
894
- filter: 'url(#dropShadow)'
895
- }
896
- });
897
-
898
- this.stackedBackfaces[i] = rect;
899
- }
900
-
901
-
902
-
903
- // Create the visible bar
904
- var rect = RG.SVG.create({
905
- svg: this.svg,
906
- parent: this.svg.all,
907
- type: 'rect',
908
- attr: {
909
- stroke: prop['strokestyle'],
910
- fill: prop.colorsSequential ? (prop.colors[sequentialIndex] ? prop.colors[sequentialIndex] : prop.colors[prop.colors.length - 1]) : prop.colors[j],
911
- x: x,
912
- y: y,
913
- width: width,
914
- height: height,
915
- 'stroke-width': prop.linewidth,
916
- 'data-original-x': x,
917
- 'data-original-y': y,
918
- 'data-original-width': width,
919
- 'data-original-height': height,
920
- 'data-index': i,
921
- 'data-sequential-index': sequentialIndex,
922
- 'data-tooltip': (!RG.SVG.isNull(prop.tooltips) && prop.tooltips.length) ? prop.tooltips[sequentialIndex] : '',
923
- 'data-value': this.data[i][j]
924
- }
925
- });
926
-
927
-
928
- this.coords.push({
929
- object: rect,
930
- x: x,
931
- y: y,
932
- width: width,
933
- height: height
934
- });
935
-
936
-
937
-
938
-
939
-
940
-
941
-
942
- //
943
- // Add the 3D faces if required
944
- //
945
- if (prop.variant === '3d') {
946
- this.drawTop3dFace({rect: rect, value: this.data[i][j]});
947
- this.drawSide3dFace({rect: rect, value: this.data[i][j]});
948
- }
949
-
950
-
951
-
952
-
953
-
954
-
955
-
956
-
957
- // Add the tooltip data- attribute
958
- if (!RG.SVG.isNull(prop.tooltips) && prop.tooltips[sequentialIndex]) {
959
-
960
- var obj = this;
961
-
962
-
963
- //
964
- // Add tooltip event listeners
965
- //
966
- (function (idx, seq)
967
- {
968
- rect.addEventListener(prop.tooltipsEvent.replace(/^on/, ''), function (e)
969
- {
970
- obj.removeHighlight();
971
-
972
- var indexes = RG.SVG.sequentialIndexToGrouped(seq, obj.data);
973
-
974
- // Show the tooltip
975
- RG.SVG.tooltip({
976
- object: obj,
977
- index: indexes[1],
978
- group: idx,
979
- sequentialIndex: seq,
980
- text: prop.tooltips[seq],
981
- event: e
982
- });
983
-
984
- // Highlight the rect that has been clicked on
985
- obj.highlight(e.target);
986
- }, false);
987
-
988
- rect.addEventListener('mousemove', function (e)
989
- {
990
- e.target.style.cursor = 'pointer';
991
- }, false);
992
- })(i, sequentialIndex);
993
- }
994
- }
995
-
996
- --sequentialIndex;
997
- }
998
- }
999
- };
1000
-
1001
-
1002
-
1003
-
1004
-
1005
-
1006
-
1007
-
1008
- /**
1009
- * This function can be used to retrieve the relevant Y coordinate for a
1010
- * particular value.
1011
- *
1012
- * @param int value The value to get the Y coordinate for
1013
- */
1014
- this.getYCoord = function (value)
1015
- {
1016
- if (value > this.scale.max) {
1017
- return null;
1018
- }
1019
-
1020
- var y, xaxispos = prop.xaxispos;
1021
-
1022
- if (value < this.scale.min) {
1023
- return null;
1024
- }
1025
-
1026
- y = ((value - this.scale.min) / (this.scale.max - this.scale.min));
1027
-
1028
- y *= (this.height - prop.gutterTop - prop.gutterBottom);
1029
-
1030
- y = this.height - prop.gutterBottom - y;
1031
-
1032
- return y;
1033
- };
1034
-
1035
-
1036
-
1037
-
1038
-
1039
-
1040
-
1041
-
1042
- /**
1043
- * This function can be used to highlight a bar on the chart
1044
- *
1045
- * @param object rect The rectangle to highlight
1046
- */
1047
- this.highlight = function (rect)
1048
- {
1049
- var x = rect.getAttribute('x'),
1050
- y = rect.getAttribute('y'),
1051
- width = rect.getAttribute('width'),
1052
- height = rect.getAttribute('height');
1053
-
1054
- var highlight = RG.SVG.create({
1055
- svg: this.svg,
1056
- parent: this.svg.all,
1057
- type: 'rect',
1058
- attr: {
1059
- stroke: prop.highlightStroke,
1060
- fill: prop.highlightFill,
1061
- x: x,
1062
- y: y,
1063
- width: width,
1064
- height: height,
1065
- 'stroke-width': prop.highlightLinewidth
1066
- }
1067
- });
1068
-
1069
-
1070
- if (prop.tooltipsEvent === 'mousemove') {
1071
-
1072
- //var obj = this;
1073
-
1074
- //highlight.addEventListener('mouseout', function (e)
1075
- //{
1076
- // obj.removeHighlight();
1077
- // RG.SVG.hideTooltip();
1078
- // RG.SVG.REG.set('highlight', null);
1079
- //}, false);
1080
- }
1081
-
1082
-
1083
- // Store the highlight rect in the rebistry so
1084
- // it can be cleared later
1085
- RG.SVG.REG.set('highlight', highlight);
1086
- };
1087
-
1088
-
1089
-
1090
-
1091
-
1092
-
1093
-
1094
-
1095
- /**
1096
- * This allows for easy specification of gradients
1097
- */
1098
- this.parseColors = function ()
1099
- {
1100
- // Save the original colors so that they can be restored when
1101
- // the canvas is cleared
1102
- if (!Object.keys(this.originalColors).length) {
1103
- this.originalColors = {
1104
- colors: RG.SVG.arrayClone(prop.colors),
1105
- backgroundGridColor: RG.SVG.arrayClone(prop.backgroundGridColor),
1106
- highlightFill: RG.SVG.arrayClone(prop.highlightFill),
1107
- backgroundColor: RG.SVG.arrayClone(prop.backgroundColor)
1108
- }
1109
- }
1110
-
1111
-
1112
- // colors
1113
- var colors = prop.colors;
1114
-
1115
- if (colors) {
1116
- for (var i=0; i<colors.length; ++i) {
1117
- colors[i] = RG.SVG.parseColorLinear({
1118
- object: this,
1119
- color: colors[i]
1120
- });
1121
- }
1122
- }
1123
-
1124
- prop.backgroundGridColor = RG.SVG.parseColorLinear({object: this, color: prop.backgroundGridColor});
1125
- prop.highlightFill = RG.SVG.parseColorLinear({object: this, color: prop.highlightFill});
1126
- prop.backgroundColor = RG.SVG.parseColorLinear({object: this, color: prop.backgroundColor});
1127
- };
1128
-
1129
-
1130
-
1131
-
1132
-
1133
-
1134
-
1135
-
1136
- //
1137
- // Draws the labelsAbove
1138
- //
1139
- this.drawLabelsAbove = function ()
1140
- {
1141
- // Go through the above labels
1142
- if (prop.labelsAbove) {
1143
-
1144
- var data_seq = RG.SVG.arrayLinearize(this.data),
1145
- seq = 0,
1146
- stacked_total = 0;;
1147
-
1148
- for (var i=0; i<this.coords.length; ++i,seq++) {
1149
-
1150
- var num = typeof this.data[i] === 'number' ? this.data[i] : data_seq[seq] ;
1151
-
1152
-
1153
-
1154
-
1155
-
1156
- // If this is a stacked chart then only dothe label
1157
- // if it's the top segment
1158
- if (prop.grouping === 'stacked') {
1159
-
1160
- var indexes = RG.SVG.sequentialIndexToGrouped(i, this.data);
1161
- var group = indexes[0];
1162
- var datapiece = indexes[1];
1163
-
1164
- if (datapiece !== (this.data[group].length - 1) ) {
1165
- continue;
1166
- } else {
1167
- num = RG.SVG.arraySum(this.data[group]);
1168
- }
1169
- }
1170
-
1171
-
1172
-
1173
-
1174
-
1175
- var str = RG.SVG.numberFormat({
1176
- object: this,
1177
- num: num.toFixed(prop.labelsAboveDecimals),
1178
- prepend: typeof prop.labelsAboveUnitsPre === 'string' ? prop.labelsAboveUnitsPre : null,
1179
- append: typeof prop.labelsAboveUnitsPost === 'string' ? prop.labelsAboveUnitsPost : null,
1180
- point: typeof prop.labelsAbovePoint === 'string' ? prop.labelsAbovePoint : null,
1181
- thousand: typeof prop.labelsAboveThousand === 'string' ? prop.labelsAboveThousand : null,
1182
- formatter: typeof prop.labelsAboveFormatter === 'function' ? prop.labelsAboveFormatter : null
1183
- });
1184
-
1185
- // Facilitate labelsAboveSpecific
1186
- if (prop.labelsAboveSpecific && prop.labelsAboveSpecific.length && (typeof prop.labelsAboveSpecific[seq] === 'string' || typeof prop.labelsAboveSpecific[seq] === 'number') ) {
1187
- str = prop.labelsAboveSpecific[seq];
1188
- } else if ( prop.labelsAboveSpecific && prop.labelsAboveSpecific.length && typeof prop.labelsAboveSpecific[seq] !== 'string' && typeof prop.labelsAboveSpecific[seq] !== 'number') {
1189
- continue;
1190
- }
1191
-
1192
- var x = parseFloat(this.coords[i].object.getAttribute('x')) + parseFloat(this.coords[i].object.getAttribute('width') / 2) + prop.labelsAboveOffsetx;
1193
-
1194
- if (data_seq[i] >= 0) {
1195
- var y = parseFloat(this.coords[i].object.getAttribute('y')) - 7 + prop.labelsAboveOffsety;
1196
- var valign = prop.labelsAboveValign;
1197
- } else {
1198
- var y = parseFloat(this.coords[i].object.getAttribute('y')) + parseFloat(this.coords[i].object.getAttribute('height')) + 7 - prop.labelsAboveOffsety;
1199
- var valign = prop.labelsAboveValign === 'top' ? 'bottom' : 'top';
1200
- }
1201
-
1202
- RG.SVG.text({
1203
- object: this,
1204
- parent: this.svg.all,
1205
- text: str,
1206
- x: x,
1207
- y: y,
1208
- halign: prop.labelsAboveHalign,
1209
- valign: valign,
1210
- font: prop.labelsAboveFont || prop.textFont,
1211
- size: prop.labelsAboveSize || prop.textSize,
1212
- bold: prop.labelsAboveBold || prop.textBold,
1213
- italic: prop.labelsAboveItalic || prop.textItalic,
1214
- color: prop.labelsAboveColor || prop.textColor,
1215
- background: prop.labelsAboveBackground || null,
1216
- padding: prop.labelsAboveBackgroundPadding || 0
1217
- });
1218
- }
1219
- }
1220
- };
1221
-
1222
-
1223
-
1224
-
1225
-
1226
-
1227
-
1228
-
1229
- /**
1230
- * Using a function to add events makes it easier to facilitate method
1231
- * chaining
1232
- *
1233
- * @param string type The type of even to add
1234
- * @param function func
1235
- */
1236
- this.on = function (type, func)
1237
- {
1238
- if (type.substr(0,2) !== 'on') {
1239
- type = 'on' + type;
1240
- }
1241
-
1242
- RG.SVG.addCustomEventListener(this, type, func);
1243
-
1244
- return this;
1245
- };
1246
-
1247
-
1248
-
1249
-
1250
-
1251
-
1252
-
1253
-
1254
- //
1255
- // Used in chaining. Runs a function there and then - not waiting for
1256
- // the events to fire (eg the onbeforedraw event)
1257
- //
1258
- // @param function func The function to execute
1259
- //
1260
- this.exec = function (func)
1261
- {
1262
- func(this);
1263
-
1264
- return this;
1265
- };
1266
-
1267
-
1268
-
1269
-
1270
-
1271
-
1272
-
1273
-
1274
- //
1275
- // Remove highlight from the chart (tooltips)
1276
- //
1277
- this.removeHighlight = function ()
1278
- {
1279
- var highlight = RG.SVG.REG.get('highlight');
1280
- if (highlight && highlight.parentNode) {
1281
- highlight.parentNode.removeChild(highlight);
1282
- }
1283
-
1284
- RG.SVG.REG.set('highlight', null);
1285
- };
1286
-
1287
-
1288
-
1289
-
1290
-
1291
-
1292
-
1293
-
1294
- //
1295
- // Draws the top of 3D bars
1296
- //
1297
- this.drawTop3dFace = function (opt)
1298
- {
1299
- var rect = opt.rect,
1300
- arr = [parseInt(rect.getAttribute('fill')), 'rgba(255,255,255,0.7)'],
1301
- x = parseInt(rect.getAttribute('x')),
1302
- y = parseInt(rect.getAttribute('y')),
1303
- w = parseInt(rect.getAttribute('width')),
1304
- h = parseInt(rect.getAttribute('height'));
1305
-
1306
- rect.rgraph_3d_top_face = [];
1307
-
1308
-
1309
- for (var i=0; i<2; ++i) {
1310
-
1311
- var color = (i === 0 ? rect.getAttribute('fill') : 'rgba(255,255,255,0.7)');
1312
-
1313
-
1314
- var face = RG.SVG.create({
1315
- svg: this.svg,
1316
- type: 'path',
1317
- parent: prop.variant === '3d' && opt.value < 0 ? this.threed_xaxis_group : this.svg.all,
1318
- attr: {
1319
- stroke: prop.strokestyle,
1320
- fill: color,
1321
- 'stroke-width': prop.linewidth,
1322
- d: 'M {1} {2} L {3} {4} L {5} {6} L {7} {8}'.format(
1323
- x,
1324
- y,
1325
-
1326
- x + prop.variant3dOffsetx,
1327
- y - prop.variant3dOffsety,
1328
-
1329
- x + w + prop.variant3dOffsetx,
1330
- y - prop.variant3dOffsety,
1331
-
1332
- x + w,
1333
- y
1334
- )
1335
- }
1336
- });
1337
-
1338
-
1339
-
1340
- // Store a reference to the rect on the front face of the bar
1341
- rect.rgraph_3d_top_face[i] = face
1342
- }
1343
- };
1344
-
1345
-
1346
-
1347
-
1348
-
1349
-
1350
-
1351
-
1352
- //
1353
- // Draws the top of 3D bars
1354
- //
1355
- this.drawSide3dFace = function (opt)
1356
- {
1357
- var rect = opt.rect,
1358
- arr = [parseInt(rect.getAttribute('fill')), 'rgba(0,0,0,0.3)'],
1359
- x = parseInt(rect.getAttribute('x')),
1360
- y = parseInt(rect.getAttribute('y')),
1361
- w = parseInt(rect.getAttribute('width')),
1362
- h = parseInt(rect.getAttribute('height'));
1363
-
1364
- rect.rgraph_3d_side_face = [];
1365
-
1366
- for (var i=0; i<2; ++i) {
1367
-
1368
- var color = (i === 0 ? rect.getAttribute('fill') : 'rgba(0,0,0,0.3)');
1369
-
1370
- var face = RG.SVG.create({
1371
- svg: this.svg,
1372
- type: 'path',
1373
- parent: prop.variant === '3d' && opt.value < 0 ? this.threed_xaxis_group : this.svg.all,
1374
- attr: {
1375
- stroke: prop.strokestyle,
1376
- fill: color,
1377
- 'stroke-width': prop.linewidth,
1378
- d: 'M {1} {2} L {3} {4} L {5} {6} L {7} {8}'.format(
1379
- x + w,
1380
- y,
1381
-
1382
- x + w + prop.variant3dOffsetx,
1383
- y - prop.variant3dOffsety,
1384
-
1385
- x + w + prop.variant3dOffsetx,
1386
- y + h - prop.variant3dOffsety,
1387
-
1388
- x + w,
1389
- y + h
1390
- )
1391
- }
1392
- });
1393
-
1394
-
1395
- // Store a reference to the rect on the front face of the bar
1396
- rect.rgraph_3d_side_face[i] = face
1397
- }
1398
- };
1399
-
1400
-
1401
-
1402
-
1403
-
1404
-
1405
-
1406
-
1407
- //
1408
- // The Bar chart grow effect
1409
- //
1410
- this.grow = function ()
1411
- {
1412
- var opt = arguments[0] || {},
1413
- frames = opt.frames || 30,
1414
- frame = 0,
1415
- obj = this,
1416
- data = [],
1417
- height = null,
1418
- seq = 0;
1419
-
1420
- //
1421
- // Copy the data
1422
- //
1423
- data = RG.SVG.arrayClone(this.data);
1424
-
1425
- this.draw();
1426
-
1427
- var iterate = function ()
1428
- {
1429
-
1430
- for (var i=0,seq=0,len=obj.coords.length; i<len; ++i, ++seq) {
1431
-
1432
- var multiplier = (frame / frames)
1433
- * RG.SVG.FX.getEasingMultiplier(frames, frame)
1434
- * RG.SVG.FX.getEasingMultiplier(frames, frame);
1435
-
1436
-
1437
-
1438
-
1439
- // TODO Go through the data and update the value according to
1440
- // the frame number
1441
- if (typeof data[i] === 'number') {
1442
-
1443
- height = ma.abs(obj.getYCoord(data[i]) - obj.getYCoord(0));
1444
- obj.data[i] = data[i] * multiplier;
1445
- height = multiplier * height;
1446
-
1447
- // Set the new height on the rect
1448
- obj.coords[seq].object.setAttribute(
1449
- 'height',
1450
- height
1451
- );
1452
-
1453
- // Set the correct Y coord on the object
1454
- obj.coords[seq].object.setAttribute(
1455
- 'y',
1456
- data[i] < 0 ? obj.getYCoord(0) : obj.getYCoord(0) - height
1457
- );
1458
-
1459
-
1460
-
1461
- // This upadtes the size of the 3D sides to the bar
1462
- if (prop.variant === '3d') {
1463
-
1464
- // Remove the 3D sides to the bar
1465
- if (obj.coords[i].object.rgraph_3d_side_face[0].parentNode) obj.coords[i].object.rgraph_3d_side_face[0].parentNode.removeChild(obj.coords[i].object.rgraph_3d_side_face[0]);
1466
- if (obj.coords[i].object.rgraph_3d_side_face[1].parentNode) obj.coords[i].object.rgraph_3d_side_face[1].parentNode.removeChild(obj.coords[i].object.rgraph_3d_side_face[1]);
1467
-
1468
- if (obj.coords[i].object.rgraph_3d_top_face[0].parentNode) obj.coords[i].object.rgraph_3d_top_face[0].parentNode.removeChild(obj.coords[i].object.rgraph_3d_top_face[0]);
1469
- if (obj.coords[i].object.rgraph_3d_top_face[1].parentNode) obj.coords[i].object.rgraph_3d_top_face[1].parentNode.removeChild(obj.coords[i].object.rgraph_3d_top_face[1]);
1470
-
1471
- // Add the 3D sides to the bar (again)
1472
- obj.drawSide3dFace({rect: obj.coords[i].object});
1473
-
1474
- // Draw the top side of the 3D bar
1475
- if (prop.grouping === 'grouped') {
1476
- obj.drawTop3dFace({rect: obj.coords[i].object });
1477
- }
1478
-
1479
- // Now remove and immediately re-add the front face of
1480
- // the bar - this is so that the front face appears
1481
- // above the other sides
1482
- if (obj.coords[i].object.parentNode) {
1483
- var parent = obj.coords[i].object.parentNode;
1484
- var node = parent.removeChild(obj.coords[i].object);
1485
- parent.appendChild(node);
1486
- }
1487
- }
1488
-
1489
-
1490
- } else if (typeof data[i] === 'object') {
1491
-
1492
- var accumulativeHeight = 0;
1493
-
1494
- for (var j=0,len2=data[i].length; j<len2; ++j, ++seq) {
1495
-
1496
- height = ma.abs(obj.getYCoord(data[i][j]) - obj.getYCoord(0));
1497
- height = multiplier * height;
1498
- obj.data[i][j] = data[i][j] * multiplier;
1499
- height = ma.round(height);
1500
-
1501
- obj.coords[seq].object.setAttribute(
1502
- 'height',
1503
- height
1504
- );
1505
-
1506
- obj.coords[seq].object.setAttribute(
1507
- 'y',
1508
- data[i][j] < 0 ? (obj.getYCoord(0) + accumulativeHeight) : (obj.getYCoord(0) - height - accumulativeHeight)
1509
- );
1510
-
1511
-
1512
-
1513
-
1514
-
1515
- // This updates the size of the 3D sides to the bar
1516
- if (prop.variant === '3d') {
1517
-
1518
- // Remove the 3D sides to the bar
1519
- if (obj.coords[seq].object.rgraph_3d_side_face[0].parentNode) obj.coords[seq].object.rgraph_3d_side_face[0].parentNode.removeChild(obj.coords[seq].object.rgraph_3d_side_face[0]);
1520
- if (obj.coords[seq].object.rgraph_3d_side_face[1].parentNode) obj.coords[seq].object.rgraph_3d_side_face[1].parentNode.removeChild(obj.coords[seq].object.rgraph_3d_side_face[1]);
1521
-
1522
- if (obj.coords[seq].object.rgraph_3d_top_face[0].parentNode) obj.coords[seq].object.rgraph_3d_top_face[0].parentNode.removeChild(obj.coords[seq].object.rgraph_3d_top_face[0]);
1523
- if (obj.coords[seq].object.rgraph_3d_top_face[1].parentNode) obj.coords[seq].object.rgraph_3d_top_face[1].parentNode.removeChild(obj.coords[seq].object.rgraph_3d_top_face[1]);
1524
-
1525
- // Add the 3D sides to the bar (again)
1526
- obj.drawSide3dFace({rect: obj.coords[seq].object});
1527
-
1528
- // Draw the top side of the 3D bar
1529
- // TODO Need to only draw the top face when the bar is either
1530
- // not stacked or is the last segment in the stack
1531
- obj.drawTop3dFace({rect: obj.coords[seq].object});
1532
-
1533
- // Now remove and immediately re-add the front face of
1534
- // the bar - this is so that the front face appears
1535
- // above the other sides
1536
- if (obj.coords[seq].object.parentNode) {
1537
- var parent = obj.coords[seq].object.parentNode;
1538
- var node = parent.removeChild(obj.coords[seq].object);
1539
- parent.appendChild(node);
1540
- }
1541
- }
1542
- accumulativeHeight += (prop.grouping === 'stacked' ? height : 0);
1543
-
1544
- }
1545
-
1546
- //
1547
- // Set the height and Y cooord of the backfaces if necessary
1548
- //
1549
- if (obj.stackedBackfaces[i]) {
1550
- obj.stackedBackfaces[i].setAttribute(
1551
- 'height',
1552
- accumulativeHeight
1553
- );
1554
-
1555
- obj.stackedBackfaces[i].setAttribute(
1556
- 'y',
1557
- obj.height - prop.gutterBottom - accumulativeHeight
1558
- );
1559
- }
1560
-
1561
- // Decrease seq by one so that it's not incremented twice
1562
- --seq;
1563
- }
1564
- }
1565
-
1566
- if (frame++ < frames) {
1567
- //setTimeout(iterate, frame > 1 ? opt.delay : 200);
1568
- RG.SVG.FX.update(iterate);
1569
- } else if (opt.callback) {
1570
- (opt.callback)(obj);
1571
- }
1572
- };
1573
-
1574
- iterate();
1575
-
1576
- return this;
1577
- };
1578
-
1579
-
1580
-
1581
-
1582
-
1583
-
1584
-
1585
-
1586
- /**
1587
- * HBar chart Wave effect.
1588
- *
1589
- * @param object OPTIONAL An object map of options. You specify 'frames'
1590
- * here to give the number of frames in the effect
1591
- * and also callback to specify a callback function
1592
- * thats called at the end of the effect
1593
- */
1594
- this.wave = function ()
1595
- {
1596
- // First draw the chart
1597
- this.draw();
1598
-
1599
-
1600
- var obj = this,
1601
- opt = arguments[0] || {};
1602
-
1603
- opt.frames = opt.frames || 60;
1604
- opt.startFrames = [];
1605
- opt.counters = [];
1606
-
1607
- var framesperbar = opt.frames / 3,
1608
- frame = -1,
1609
- callback = opt.callback || function () {};
1610
-
1611
- for (var i=0,len=this.coords.length; i<len; i+=1) {
1612
- opt.startFrames[i] = ((opt.frames / 2) / (obj.coords.length - 1)) * i;
1613
- opt.counters[i] = 0;
1614
-
1615
- // Now zero the width of the bar (and remove the 3D faces)
1616
- this.coords[i].object.setAttribute('height', 0);
1617
-
1618
- if (this.coords[i].object.rgraph_3d_side_face) {
1619
- this.svg.all.removeChild(this.coords[i].object.rgraph_3d_side_face[0]);
1620
- this.svg.all.removeChild(this.coords[i].object.rgraph_3d_side_face[1]);
1621
-
1622
- this.svg.all.removeChild(this.coords[i].object.rgraph_3d_top_face[0]);
1623
- this.svg.all.removeChild(this.coords[i].object.rgraph_3d_top_face[1]);
1624
- }
1625
- }
1626
-
1627
-
1628
- function iterator ()
1629
- {
1630
- ++frame;
1631
-
1632
- for (var i=0,len=obj.coords.length; i<len; i+=1) {
1633
- if (frame > opt.startFrames[i]) {
1634
-
1635
- var originalHeight = obj.coords[i].object.getAttribute('data-original-height'),
1636
- height,
1637
- value = parseFloat(obj.coords[i].object.getAttribute('data-value'));
1638
-
1639
- var height = ma.min(
1640
- ((frame - opt.startFrames[i]) / framesperbar) * originalHeight,
1641
- originalHeight
1642
- );
1643
- obj.coords[i].object.setAttribute(
1644
- 'height',
1645
- height < 0 ? 0 : height
1646
- );
1647
-
1648
- obj.coords[i].object.setAttribute(
1649
- 'y',
1650
- value >=0 ? obj.getYCoord(0) - height : obj.getYCoord(0)
1651
- );
1652
-
1653
-
1654
-
1655
- // This updates the size of the 3D sides to the bar
1656
- if (prop.variant === '3d') {
1657
-
1658
- // Remove the 3D sides to the bar
1659
- if (obj.coords[i].object.rgraph_3d_side_face[0].parentNode) obj.coords[i].object.rgraph_3d_side_face[0].parentNode.removeChild(obj.coords[i].object.rgraph_3d_side_face[0]);
1660
- if (obj.coords[i].object.rgraph_3d_side_face[1].parentNode) obj.coords[i].object.rgraph_3d_side_face[1].parentNode.removeChild(obj.coords[i].object.rgraph_3d_side_face[1]);
1661
-
1662
- if (obj.coords[i].object.rgraph_3d_top_face[0].parentNode) obj.coords[i].object.rgraph_3d_top_face[0].parentNode.removeChild(obj.coords[i].object.rgraph_3d_top_face[0]);
1663
- if (obj.coords[i].object.rgraph_3d_top_face[1].parentNode) obj.coords[i].object.rgraph_3d_top_face[1].parentNode.removeChild(obj.coords[i].object.rgraph_3d_top_face[1]);
1664
-
1665
-
1666
-
1667
- // Now remove and immediately re-add the front face of
1668
- // the bar - this is so that the front face appears
1669
- // above the other sides
1670
- if (obj.coords[i].object.parentNode) {
1671
- var parent = obj.coords[i].object.parentNode;
1672
- var node = parent.removeChild(obj.coords[i].object);
1673
- parent.appendChild(node);
1674
- }
1675
- }
1676
-
1677
-
1678
- if (prop.grouping === 'stacked') {
1679
-
1680
- var seq = obj.coords[i].object.getAttribute('data-sequential-index');
1681
- var indexes = RG.SVG.sequentialIndexToGrouped(seq, obj.data);
1682
-
1683
- if (indexes[1] > 0) {
1684
- obj.coords[i].object.setAttribute(
1685
- 'y',
1686
- parseInt(obj.coords[i - 1].object.getAttribute('y')) - height
1687
- );
1688
- }
1689
- }
1690
-
1691
- if (prop.variant === '3d') {
1692
- // Add the 3D sides to the bar (again)
1693
- obj.drawSide3dFace({rect: obj.coords[i].object});
1694
-
1695
- // Draw the top side of the 3D bar
1696
- if (prop.grouping === 'grouped' || (prop.grouping === 'stacked' && (indexes[1] + 1) === obj.data[indexes[0]].length) ) {
1697
- obj.drawTop3dFace({rect: obj.coords[i].object });
1698
- }
1699
- }
1700
- }
1701
- }
1702
-
1703
-
1704
- if (frame >= opt.frames) {
1705
- callback(obj);
1706
- } else {
1707
- RG.SVG.FX.update(iterator);
1708
- }
1709
- }
1710
-
1711
- iterator();
1712
-
1713
- return this;
1714
- };
1715
-
1716
-
1717
-
1718
-
1719
-
1720
-
1721
-
1722
-
1723
- //
1724
- // Set the options that the user has provided
1725
- //
1726
- for (i in conf.options) {
1727
- if (typeof i === 'string') {
1728
- this.set(i, conf.options[i]);
1729
- }
1730
- }
1731
- };
1732
-
1733
- return this;
1734
-
1735
- // End module pattern
1736
- })(window, document);
2
+ RGraph=window.RGraph||{isRGraph:true};RGraph.SVG=RGraph.SVG||{};(function(win,doc,undefined)
3
+ {var RG=RGraph,ua=navigator.userAgent,ma=Math,win=window,doc=document;RG.SVG.Bar=function(conf)
4
+ {this.set=function(name,value)
5
+ {if(arguments.length===1&&typeof name==='object'){for(i in arguments[0]){if(typeof i==='string'){var ret=RG.SVG.commonSetter({object:this,name:i,value:arguments[0][i]});name=ret.name;value=ret.value;this.set(name,value);}}}else{var ret=RG.SVG.commonSetter({object:this,name:name,value:value});name=ret.name;value=ret.value;this.properties[name]=value;if(name==='colors'){this.originalColors=RG.SVG.arrayClone(value);this.colorsParsed=false;}}
6
+ return this;};this.id=conf.id;this.uid=RG.SVG.createUID();this.container=document.getElementById(this.id);this.layers={};this.svg=RG.SVG.createSVG({object:this,container:this.container});this.isRGraph=true;this.width=Number(this.svg.getAttribute('width'));this.height=Number(this.svg.getAttribute('height'));this.data=conf.data;this.type='bar';this.coords=[];this.stackedBackfaces=[];this.originalColors={};this.gradientCounter=1;RG.SVG.OR.add(this);this.container.style.display='inline-block';this.properties={gutterLeft:35,gutterRight:35,gutterTop:35,gutterBottom:35,variant:null,variant3dOffsetx:10,variant3dOffsety:5,backgroundColor:null,backgroundImage:null,backgroundImageAspect:'none',backgroundImageStretch:true,backgroundImageOpacity:null,backgroundImageX:null,backgroundImageY:null,backgroundImageW:null,backgroundImageH:null,backgroundGrid:true,backgroundGridColor:'#ddd',backgroundGridLinewidth:1,backgroundGridHlines:true,backgroundGridHlinesCount:null,backgroundGridVlines:true,backgroundGridVlinesCount:null,backgroundGridBorder:true,backgroundGridDashed:false,backgroundGridDotted:false,backgroundGridDashArray:null,colors:['red','#0f0','#00f','#ff0','#0ff','#0f0','pink','orange','gray','black','red','#0f0','#00f','#ff0','#0ff','#0f0','pink','orange','gray','black'],colorsSequential:false,strokestyle:'rgba(0,0,0,0)',hmargin:3,hmarginGrouped:2,yaxis:true,yaxisTickmarks:true,yaxisTickmarksLength:3,yaxisColor:'black',yaxisScale:true,yaxisLabels:null,yaxisLabelsOffsetx:0,yaxisLabelsOffsety:0,yaxisLabelsCount:5,yaxisUnitsPre:'',yaxisUnitsPost:'',yaxisStrict:false,yaxisDecimals:0,yaxisPoint:'.',yaxisThousand:',',yaxisRound:false,yaxisMax:null,yaxisMin:0,yaxisFormatter:null,xaxis:true,xaxisTickmarks:true,xaxisTickmarksLength:5,xaxisLabels:null,xaxisLabelsPosition:'section',xaxisLabelsPositionEdgeTickmarksCount:null,xaxisColor:'black',xaxisLabelsOffsetx:0,xaxisLabelsOffsety:0,labelsAbove:false,labelsAboveFont:null,labelsAboveSize:null,labelsAboveBold:null,labelsAboveItalic:null,labelsAboveColor:null,labelsAboveBackground:null,labelsAboveBackgroundPadding:0,labelsAboveUnitsPre:null,labelsAboveUnitsPost:null,labelsAbovePoint:null,labelsAboveThousand:null,labelsAboveFormatter:null,labelsAboveDecimals:null,labelsAboveOffsetx:0,labelsAboveOffsety:0,labelsAboveHalign:'center',labelsAboveValign:'bottom',labelsAboveSpecific:null,textColor:'black',textFont:'sans-serif',textSize:12,textBold:false,textItalic:false,linewidth:1,grouping:'grouped',tooltips:null,tooltipsOverride:null,tooltipsEffect:'fade',tooltipsCssClass:'RGraph_tooltip',tooltipsEvent:'click',highlightStroke:'rgba(0,0,0,0)',highlightFill:'rgba(255,255,255,0.7)',highlightLinewidth:1,title:'',titleSize:16,titleX:null,titleY:null,titleHalign:'center',titleValign:null,titleColor:'black',titleFont:null,titleBold:false,titleItalic:false,titleSubtitle:'',titleSubtitleSize:10,titleSubtitleX:null,titleSubtitleY:null,titleSubtitleHalign:'center',titleSubtitleValign:null,titleSubtitleColor:'#aaa',titleSubtitleFont:null,titleSubtitleBold:false,titleSubtitleItalic:false,shadow:false,shadowOffsetx:2,shadowOffsety:2,shadowBlur:2,shadowOpacity:0.25,key:null,keyColors:null,keyOffsetx:0,keyOffsety:0,keyTextOffsetx:0,keyTextOffsety:-1,keyTextSize:null,keyTextBold:null,keyTextItalic:null,keyTextFont:null};RG.SVG.getGlobals(this);if(RG.SVG.FX&&typeof RG.SVG.FX.decorate==='function'){RG.SVG.FX.decorate(this);}
7
+ var prop=this.properties;this.draw=function()
8
+ {RG.SVG.fireCustomEvent(this,'onbeforedraw');if(prop.variant!=='3d'){prop.variant3dOffsetx=0;prop.variant3dOffsety=0;}else{this.svg.all.setAttribute('transform','skewY(5)');}
9
+ RG.SVG.createDefs(this);this.coords=[];this.graphWidth=this.width-prop.gutterLeft-prop.gutterRight;this.graphHeight=this.height-prop.gutterTop-prop.gutterBottom;RG.SVG.resetColorsToOriginalValues({object:this});this.parseColors();var values=[];for(var i=0,max=0;i<this.data.length;++i){if(typeof this.data[i]==='number'){values.push(this.data[i]);}else if(RG.SVG.isArray(this.data[i])&&prop.grouping==='grouped'){values.push(RG.SVG.arrayMax(this.data[i]));}else if(RG.SVG.isArray(this.data[i])&&prop.grouping==='stacked'){values.push(RG.SVG.arraySum(this.data[i]));}}
10
+ var max=RG.SVG.arrayMax(values);if(typeof prop.yaxisMax==='number'){max=prop.yaxisMax;}
11
+ if(prop.yaxisMin==='mirror'||prop.yaxisMin==='middle'||prop.yaxisMin==='center'){var mirrorScale=true;prop.yaxisMin=0;}
12
+ this.scale=RG.SVG.getScale({object:this,numlabels:prop.yaxisLabelsCount,unitsPre:prop.yaxisUnitsPre,unitsPost:prop.yaxisUnitsPost,max:max,min:prop.yaxisMin,point:prop.yaxisPoint,round:prop.yaxisRound,thousand:prop.yaxisThousand,decimals:prop.yaxisDecimals,strict:typeof prop.yaxisMax==='number',formatter:prop.yaxisFormatter});if(mirrorScale){this.scale=RG.SVG.getScale({object:this,numlabels:prop.yaxisLabelsCount,unitsPre:prop.yaxisUnitsPre,unitsPost:prop.yaxisUnitsPost,max:this.scale.max,min:this.scale.max* -1,point:prop.yaxisPoint,round:false,thousand:prop.yaxisThousand,decimals:prop.yaxisDecimals,strict:typeof prop.yaxisMax==='number',formatter:prop.yaxisFormatter});}
13
+ this.max=this.scale.max;this.min=this.scale.min;prop.yaxisMax=this.scale.max;prop.yaxisMin=this.scale.min;RG.SVG.drawBackground(this);if(prop.variant==='3d'){RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:'M {1} {2} L {3} {4} L {5} {6} L {7} {8}'.format(prop.gutterLeft,prop.gutterTop,prop.gutterLeft+prop.variant3dOffsetx,prop.gutterTop-prop.variant3dOffsety,prop.gutterLeft+prop.variant3dOffsetx,this.height-prop.gutterBottom-prop.variant3dOffsety,prop.gutterLeft,this.height-prop.gutterBottom,prop.gutterLeft,prop.gutterTop),fill:'#ddd',stroke:'#ccc'}});this.threed_xaxis_group=RG.SVG.create({svg:this.svg,type:'g',parent:this.svg.all,attr:{className:'rgraph_3d_bar_xaxis_negative'}});RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:'M {1} {2} L {3} {4} L {5} {6} L {7} {8}'.format(prop.gutterLeft,this.getYCoord(0),prop.gutterLeft+prop.variant3dOffsetx,this.getYCoord(0)-prop.variant3dOffsety,this.width-prop.gutterRight+prop.variant3dOffsetx,this.getYCoord(0)-prop.variant3dOffsety,this.width-prop.gutterRight,this.getYCoord(0),prop.gutterLeft,this.getYCoord(0)),fill:'#ddd',stroke:'#ccc'}});}
14
+ this.drawBars();RG.SVG.drawXAxis(this);RG.SVG.drawYAxis(this);this.drawLabelsAbove();if(typeof prop.key!==null&&RG.SVG.drawKey){RG.SVG.drawKey(this);}else if(!RGraph.SVG.isNull(prop.key)){alert('The drawKey() function does not exist - have you forgotten to include the key library?');}
15
+ RG.SVG.attribution(this);RG.SVG.fireCustomEvent(this,'ondraw');return this;};this.drawBars=function()
16
+ {var y=this.getYCoord(0);if(prop.shadow){RG.SVG.setShadow({object:this,offsetx:prop.shadowOffsetx,offsety:prop.shadowOffsety,blur:prop.shadowBlur,opacity:prop.shadowOpacity,id:'dropShadow'});}
17
+ for(var i=0,sequentialIndex=0;i<this.data.length;++i,++sequentialIndex){if(typeof this.data[i]==='number'){var outerSegment=this.graphWidth/this.data.length,height=(ma.abs(this.data[i])-ma.abs(this.scale.min))/(ma.abs(this.scale.max)-ma.abs(this.scale.min))*this.graphHeight,width=(this.graphWidth/this.data.length)-prop.hmargin-prop.hmargin,x=prop.gutterLeft+prop.hmargin+(outerSegment*i);if(this.scale.min>=0&&this.scale.max>0){y=this.getYCoord(this.scale.min)-height;}else if(this.scale.min<0&&this.scale.max>0){height=(ma.abs(this.data[i])/(this.scale.max-this.scale.min))*this.graphHeight;y=this.getYCoord(0)-height;if(this.data[i]<0){y=this.getYCoord(0);}}else if(this.scale.min<0&&this.scale.max<0){height=(ma.abs(this.data[i])-ma.abs(this.scale.max))/(ma.abs(this.scale.min)-ma.abs(this.scale.max))*this.graphHeight;y=prop.gutterTop;}
18
+ var rect=RG.SVG.create({svg:this.svg,type:'rect',parent:prop.variant==='3d'&&this.data[i]<0?this.threed_xaxis_group:this.svg.all,attr:{stroke:prop.strokestyle,fill:prop.colorsSequential?(prop.colors[sequentialIndex]?prop.colors[sequentialIndex]:prop.colors[prop.colors.length-1]):prop.colors[0],x:x,y:y,width:width<0?0:width,height:height,'stroke-width':prop.linewidth,'data-original-x':x,'data-original-y':y,'data-original-width':width,'data-original-height':height,'data-tooltip':(!RG.SVG.isNull(prop.tooltips)&&prop.tooltips.length)?prop.tooltips[i]:'','data-index':i,'data-sequential-index':sequentialIndex,'data-value':this.data[i],filter:prop.shadow?'url(#dropShadow)':''}});this.coords.push({object:rect,x:rect.getAttribute('x'),y:rect.getAttribute('y'),width:rect.getAttribute('width'),height:rect.getAttribute('height')});if(prop.variant==='3d'){this.drawTop3dFace({rect:rect,value:this.data[i]});this.drawSide3dFace({rect:rect,value:this.data[i]});}
19
+ if(!RG.SVG.isNull(prop.tooltips)&&prop.tooltips[sequentialIndex]){var obj=this;(function(idx,seq)
20
+ {rect.addEventListener(prop.tooltipsEvent.replace(/^on/,''),function(e)
21
+ {obj.removeHighlight();RG.SVG.tooltip({object:obj,index:idx,group:null,sequentialIndex:seq,text:prop.tooltips[seq],event:e});obj.highlight(e.target);},false);rect.addEventListener('mousemove',function(e)
22
+ {e.target.style.cursor='pointer'},false);})(i,sequentialIndex);}}else if(RG.SVG.isArray(this.data[i])&&prop.grouping==='grouped'){var outerSegment=(this.graphWidth/this.data.length),innerSegment=outerSegment-(2*prop.hmargin);for(var j=0;j<this.data[i].length;++j,++sequentialIndex){var width=((innerSegment-((this.data[i].length-1)*prop.hmarginGrouped))/this.data[i].length),x=(outerSegment*i)+prop.hmargin+prop.gutterLeft+(j*width)+((j-1)*prop.hmarginGrouped);x=prop.gutterLeft+(outerSegment*i)+(width*j)+prop.hmargin+(j*prop.hmarginGrouped);if(this.scale.min===0&&this.scale.max>this.scale.min){var height=((this.data[i][j]-this.scale.min)/(this.scale.max-this.scale.min))*this.graphHeight,y=this.getYCoord(0)-height;}else if(this.scale.max<=0&&this.scale.min<this.scale.max){var height=((this.data[i][j]-this.scale.max)/(this.scale.max-this.scale.min))*this.graphHeight,y=this.getYCoord(this.scale.max);height=ma.abs(height);}else if(this.scale.max>0&&this.scale.min<0){var height=(ma.abs(this.data[i][j])/(this.scale.max-this.scale.min))*this.graphHeight,y=this.data[i][j]<0?this.getYCoord(0):this.getYCoord(this.data[i][j]);}else if(this.scale.min>0&&this.scale.max>this.scale.min){var height=(ma.abs(this.data[i][j]-this.scale.min)/(this.scale.max-this.scale.min))*this.graphHeight,y=this.getYCoord(this.scale.min)-height;}
23
+ var rect=RG.SVG.create({svg:this.svg,parent:prop.variant==='3d'&&this.data[i][j]<0?this.threed_xaxis_group:this.svg.all,type:'rect',attr:{stroke:prop['strokestyle'],fill:(prop.colorsSequential&&prop.colors[sequentialIndex])?prop.colors[sequentialIndex]:prop.colors[j],x:x,y:y,width:width,height:height,'stroke-width':prop.linewidth,'data-original-x':x,'data-original-y':y,'data-original-width':width,'data-original-height':height,'data-index':i,'data-sequential-index':sequentialIndex,'data-tooltip':(!RG.SVG.isNull(prop.tooltips)&&prop.tooltips.length)?prop.tooltips[sequentialIndex]:'','data-value':this.data[i][j],filter:prop.shadow?'url(#dropShadow)':''}});this.coords.push({object:rect,x:rect.getAttribute('x'),y:rect.getAttribute('y'),width:rect.getAttribute('width'),height:rect.getAttribute('height')});if(prop.variant==='3d'){this.drawTop3dFace({rect:rect,value:this.data[i][j]});this.drawSide3dFace({rect:rect,value:this.data[i][j]});}
24
+ if(!RG.SVG.isNull(prop.tooltips)&&prop.tooltips[sequentialIndex]){var obj=this;(function(idx,seq)
25
+ {obj.removeHighlight();var indexes=RG.SVG.sequentialIndexToGrouped(seq,obj.data);rect.addEventListener(prop.tooltipsEvent.replace(/^on/,''),function(e)
26
+ {RG.SVG.tooltip({object:obj,group:idx,index:indexes[1],sequentialIndex:seq,text:prop.tooltips[seq],event:e});obj.highlight(e.target);},false);rect.addEventListener('mousemove',function(e)
27
+ {e.target.style.cursor='pointer'},false);})(i,sequentialIndex);}}
28
+ --sequentialIndex;}else if(RG.SVG.isArray(this.data[i])&&prop.grouping==='stacked'){var section=(this.graphWidth/this.data.length);var y=this.getYCoord(0);for(var j=0;j<this.data[i].length;++j,++sequentialIndex){var height=(this.data[i][j]/(this.max-this.min))*this.graphHeight,width=section-(2*prop.hmargin),x=prop.gutterLeft+(i*section)+prop.hmargin,y=y-height;if(j===0&&prop.shadow){var fullHeight=(RG.SVG.arraySum(this.data[i])/(this.max-this.min))*this.graphHeight;var rect=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',attr:{fill:'white',x:x,y:this.height-prop.gutterBottom-fullHeight,width:width,height:fullHeight,'stroke-width':0,'data-index':i,filter:'url(#dropShadow)'}});this.stackedBackfaces[i]=rect;}
29
+ var rect=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',attr:{stroke:prop['strokestyle'],fill:prop.colorsSequential?(prop.colors[sequentialIndex]?prop.colors[sequentialIndex]:prop.colors[prop.colors.length-1]):prop.colors[j],x:x,y:y,width:width,height:height,'stroke-width':prop.linewidth,'data-original-x':x,'data-original-y':y,'data-original-width':width,'data-original-height':height,'data-index':i,'data-sequential-index':sequentialIndex,'data-tooltip':(!RG.SVG.isNull(prop.tooltips)&&prop.tooltips.length)?prop.tooltips[sequentialIndex]:'','data-value':this.data[i][j]}});this.coords.push({object:rect,x:rect.getAttribute('x'),y:rect.getAttribute('y'),width:rect.getAttribute('width'),height:rect.getAttribute('height')});if(prop.variant==='3d'){this.drawTop3dFace({rect:rect,value:this.data[i][j]});this.drawSide3dFace({rect:rect,value:this.data[i][j]});}
30
+ if(!RG.SVG.isNull(prop.tooltips)&&prop.tooltips[sequentialIndex]){var obj=this;(function(idx,seq)
31
+ {rect.addEventListener(prop.tooltipsEvent.replace(/^on/,''),function(e)
32
+ {obj.removeHighlight();var indexes=RG.SVG.sequentialIndexToGrouped(seq,obj.data);RG.SVG.tooltip({object:obj,index:indexes[1],group:idx,sequentialIndex:seq,text:prop.tooltips[seq],event:e});obj.highlight(e.target);},false);rect.addEventListener('mousemove',function(e)
33
+ {e.target.style.cursor='pointer';},false);})(i,sequentialIndex);}}
34
+ --sequentialIndex;}}};this.getYCoord=function(value)
35
+ {if(value>this.scale.max){return null;}
36
+ var y,xaxispos=prop.xaxispos;if(value<this.scale.min){return null;}
37
+ y=((value-this.scale.min)/(this.scale.max-this.scale.min));y*=(this.height-prop.gutterTop-prop.gutterBottom);y=this.height-prop.gutterBottom-y;return y;};this.highlight=function(rect)
38
+ {var x=rect.getAttribute('x'),y=rect.getAttribute('y'),width=rect.getAttribute('width'),height=rect.getAttribute('height');var highlight=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',attr:{stroke:prop.highlightStroke,fill:prop.highlightFill,x:x,y:y,width:width,height:height,'stroke-width':prop.highlightLinewidth}});if(prop.tooltipsEvent==='mousemove'){}
39
+ RG.SVG.REG.set('highlight',highlight);};this.parseColors=function()
40
+ {if(!Object.keys(this.originalColors).length){this.originalColors={colors:RG.SVG.arrayClone(prop.colors),backgroundGridColor:RG.SVG.arrayClone(prop.backgroundGridColor),highlightFill:RG.SVG.arrayClone(prop.highlightFill),backgroundColor:RG.SVG.arrayClone(prop.backgroundColor)}}
41
+ var colors=prop.colors;if(colors){for(var i=0;i<colors.length;++i){colors[i]=RG.SVG.parseColorLinear({object:this,color:colors[i]});}}
42
+ prop.backgroundGridColor=RG.SVG.parseColorLinear({object:this,color:prop.backgroundGridColor});prop.highlightFill=RG.SVG.parseColorLinear({object:this,color:prop.highlightFill});prop.backgroundColor=RG.SVG.parseColorLinear({object:this,color:prop.backgroundColor});};this.drawLabelsAbove=function()
43
+ {if(prop.labelsAbove){var data_seq=RG.SVG.arrayLinearize(this.data),seq=0,stacked_total=0;;for(var i=0;i<this.coords.length;++i,seq++){var num=typeof this.data[i]==='number'?this.data[i]:data_seq[seq];if(prop.grouping==='stacked'){var indexes=RG.SVG.sequentialIndexToGrouped(i,this.data);var group=indexes[0];var datapiece=indexes[1];if(datapiece!==(this.data[group].length-1)){continue;}else{num=RG.SVG.arraySum(this.data[group]);}}
44
+ var str=RG.SVG.numberFormat({object:this,num:num.toFixed(prop.labelsAboveDecimals),prepend:typeof prop.labelsAboveUnitsPre==='string'?prop.labelsAboveUnitsPre:null,append:typeof prop.labelsAboveUnitsPost==='string'?prop.labelsAboveUnitsPost:null,point:typeof prop.labelsAbovePoint==='string'?prop.labelsAbovePoint:null,thousand:typeof prop.labelsAboveThousand==='string'?prop.labelsAboveThousand:null,formatter:typeof prop.labelsAboveFormatter==='function'?prop.labelsAboveFormatter:null});if(prop.labelsAboveSpecific&&prop.labelsAboveSpecific.length&&(typeof prop.labelsAboveSpecific[seq]==='string'||typeof prop.labelsAboveSpecific[seq]==='number')){str=prop.labelsAboveSpecific[seq];}else if(prop.labelsAboveSpecific&&prop.labelsAboveSpecific.length&&typeof prop.labelsAboveSpecific[seq]!=='string'&&typeof prop.labelsAboveSpecific[seq]!=='number'){continue;}
45
+ var x=parseFloat(this.coords[i].object.getAttribute('x'))+parseFloat(this.coords[i].object.getAttribute('width')/2)+prop.labelsAboveOffsetx;if(data_seq[i]>=0){var y=parseFloat(this.coords[i].object.getAttribute('y'))-7+prop.labelsAboveOffsety;var valign=prop.labelsAboveValign;}else{var y=parseFloat(this.coords[i].object.getAttribute('y'))+parseFloat(this.coords[i].object.getAttribute('height'))+7-prop.labelsAboveOffsety;var valign=prop.labelsAboveValign==='top'?'bottom':'top';}
46
+ RG.SVG.text({object:this,parent:this.svg.all,text:str,x:x,y:y,halign:prop.labelsAboveHalign,valign:valign,font:prop.labelsAboveFont||prop.textFont,size:prop.labelsAboveSize||prop.textSize,bold:prop.labelsAboveBold||prop.textBold,italic:prop.labelsAboveItalic||prop.textItalic,color:prop.labelsAboveColor||prop.textColor,background:prop.labelsAboveBackground||null,padding:prop.labelsAboveBackgroundPadding||0});}}};this.on=function(type,func)
47
+ {if(type.substr(0,2)!=='on'){type='on'+type;}
48
+ RG.SVG.addCustomEventListener(this,type,func);return this;};this.exec=function(func)
49
+ {func(this);return this;};this.removeHighlight=function()
50
+ {var highlight=RG.SVG.REG.get('highlight');if(highlight&&highlight.parentNode){highlight.parentNode.removeChild(highlight);}
51
+ RG.SVG.REG.set('highlight',null);};this.drawTop3dFace=function(opt)
52
+ {var rect=opt.rect,arr=[parseInt(rect.getAttribute('fill')),'rgba(255,255,255,0.7)'],x=parseInt(rect.getAttribute('x')),y=parseInt(rect.getAttribute('y')),w=parseInt(rect.getAttribute('width')),h=parseInt(rect.getAttribute('height')),value=parseFloat(rect.getAttribute('data-value'));rect.rgraph_3d_top_face=[];for(var i=0;i<2;++i){var color=(i===0?rect.getAttribute('fill'):'rgba(255,255,255,0.7)');var face=RG.SVG.create({svg:this.svg,type:'path',parent:prop.variant==='3d'&&opt.value<0?this.threed_xaxis_group:this.svg.all,attr:{stroke:prop.strokestyle,fill:color,'stroke-width':prop.linewidth,d:'M {1} {2} L {3} {4} L {5} {6} L {7} {8}'.format(x,y,x+prop.variant3dOffsetx,y-prop.variant3dOffsety,x+w+prop.variant3dOffsetx,y-prop.variant3dOffsety,x+w,y)}});rect.rgraph_3d_top_face[i]=face}};this.drawSide3dFace=function(opt)
53
+ {var rect=opt.rect,arr=[parseInt(rect.getAttribute('fill')),'rgba(0,0,0,0.3)'],x=parseInt(rect.getAttribute('x')),y=parseInt(rect.getAttribute('y')),w=parseInt(rect.getAttribute('width')),h=parseInt(rect.getAttribute('height'));rect.rgraph_3d_side_face=[];for(var i=0;i<2;++i){var color=(i===0?rect.getAttribute('fill'):'rgba(0,0,0,0.3)');var face=RG.SVG.create({svg:this.svg,type:'path',parent:prop.variant==='3d'&&opt.value<0?this.threed_xaxis_group:this.svg.all,attr:{stroke:prop.strokestyle,fill:color,'stroke-width':prop.linewidth,d:'M {1} {2} L {3} {4} L {5} {6} L {7} {8}'.format(x+w,y,x+w+prop.variant3dOffsetx,y-prop.variant3dOffsety,x+w+prop.variant3dOffsetx,y+h-prop.variant3dOffsety,x+w,y+h)}});rect.rgraph_3d_side_face[i]=face}};this.grow=function()
54
+ {var opt=arguments[0]||{},frames=opt.frames||30,frame=0,obj=this,data=[],height=null,seq=0;data=RG.SVG.arrayClone(this.data);this.draw();var iterate=function()
55
+ {for(var i=0,seq=0,len=obj.coords.length;i<len;++i,++seq){var multiplier=(frame/frames)*RG.SVG.FX.getEasingMultiplier(frames,frame)*RG.SVG.FX.getEasingMultiplier(frames,frame);if(typeof data[i]==='number'){height=ma.abs(obj.getYCoord(data[i])-obj.getYCoord(0));obj.data[i]=data[i]*multiplier;height=multiplier*height;obj.coords[seq].object.setAttribute('height',height);obj.coords[seq].object.setAttribute('y',data[i]<0?obj.getYCoord(0):obj.getYCoord(0)-height);if(prop.variant==='3d'){if(obj.coords[i].object.rgraph_3d_side_face[0].parentNode)obj.coords[i].object.rgraph_3d_side_face[0].parentNode.removeChild(obj.coords[i].object.rgraph_3d_side_face[0]);if(obj.coords[i].object.rgraph_3d_side_face[1].parentNode)obj.coords[i].object.rgraph_3d_side_face[1].parentNode.removeChild(obj.coords[i].object.rgraph_3d_side_face[1]);if(obj.coords[i].object.rgraph_3d_top_face[0].parentNode)obj.coords[i].object.rgraph_3d_top_face[0].parentNode.removeChild(obj.coords[i].object.rgraph_3d_top_face[0]);if(obj.coords[i].object.rgraph_3d_top_face[1].parentNode)obj.coords[i].object.rgraph_3d_top_face[1].parentNode.removeChild(obj.coords[i].object.rgraph_3d_top_face[1]);obj.drawSide3dFace({rect:obj.coords[i].object});if(prop.grouping==='grouped'){obj.drawTop3dFace({rect:obj.coords[i].object});}
56
+ if(obj.coords[i].object.parentNode){var parent=obj.coords[i].object.parentNode;var node=parent.removeChild(obj.coords[i].object);parent.appendChild(node);}}}else if(typeof data[i]==='object'){var accumulativeHeight=0;for(var j=0,len2=data[i].length;j<len2;++j,++seq){height=ma.abs(obj.getYCoord(data[i][j])-obj.getYCoord(0));height=multiplier*height;obj.data[i][j]=data[i][j]*multiplier;height=ma.round(height);obj.coords[seq].object.setAttribute('height',height);obj.coords[seq].object.setAttribute('y',data[i][j]<0?(obj.getYCoord(0)+accumulativeHeight):(obj.getYCoord(0)-height-accumulativeHeight));if(prop.variant==='3d'){if(obj.coords[seq].object.rgraph_3d_side_face[0].parentNode)obj.coords[seq].object.rgraph_3d_side_face[0].parentNode.removeChild(obj.coords[seq].object.rgraph_3d_side_face[0]);if(obj.coords[seq].object.rgraph_3d_side_face[1].parentNode)obj.coords[seq].object.rgraph_3d_side_face[1].parentNode.removeChild(obj.coords[seq].object.rgraph_3d_side_face[1]);if(obj.coords[seq].object.rgraph_3d_top_face[0].parentNode)obj.coords[seq].object.rgraph_3d_top_face[0].parentNode.removeChild(obj.coords[seq].object.rgraph_3d_top_face[0]);if(obj.coords[seq].object.rgraph_3d_top_face[1].parentNode)obj.coords[seq].object.rgraph_3d_top_face[1].parentNode.removeChild(obj.coords[seq].object.rgraph_3d_top_face[1]);obj.drawSide3dFace({rect:obj.coords[seq].object});obj.drawTop3dFace({rect:obj.coords[seq].object});if(obj.coords[seq].object.parentNode){var parent=obj.coords[seq].object.parentNode;var node=parent.removeChild(obj.coords[seq].object);parent.appendChild(node);}}
57
+ accumulativeHeight+=(prop.grouping==='stacked'?height:0);}
58
+ if(obj.stackedBackfaces[i]){obj.stackedBackfaces[i].setAttribute('height',accumulativeHeight);obj.stackedBackfaces[i].setAttribute('y',obj.height-prop.gutterBottom-accumulativeHeight);}
59
+ --seq;}}
60
+ if(frame++<frames){RG.SVG.FX.update(iterate);}else if(opt.callback){(opt.callback)(obj);}};iterate();return this;};this.wave=function()
61
+ {this.draw();var obj=this,opt=arguments[0]||{};opt.frames=opt.frames||60;opt.startFrames=[];opt.counters=[];var framesperbar=opt.frames/3,frame=-1,callback=opt.callback||function(){};for(var i=0,len=this.coords.length;i<len;i+=1){opt.startFrames[i]=((opt.frames/2)/(obj.coords.length-1))*i;opt.counters[i]=0;this.coords[i].object.setAttribute('height',0);if(this.coords[i].object.rgraph_3d_side_face){var parent=this.coords[i].object.rgraph_3d_side_face[0].parentNode;parent.removeChild(this.coords[i].object.rgraph_3d_side_face[0]);parent.removeChild(this.coords[i].object.rgraph_3d_side_face[1]);parent.removeChild(this.coords[i].object.rgraph_3d_top_face[0]);parent.removeChild(this.coords[i].object.rgraph_3d_top_face[1]);}}
62
+ function iterator()
63
+ {++frame;for(var i=0,len=obj.coords.length;i<len;i+=1){if(frame>opt.startFrames[i]){var originalHeight=obj.coords[i].object.getAttribute('data-original-height'),height,value=parseFloat(obj.coords[i].object.getAttribute('data-value'));var height=ma.min(((frame-opt.startFrames[i])/framesperbar)*originalHeight,originalHeight);obj.coords[i].object.setAttribute('height',height<0?0:height);obj.coords[i].object.setAttribute('y',value>=0?obj.getYCoord(0)-height:obj.getYCoord(0));if(prop.variant==='3d'){var parent=obj.coords[i].object.rgraph_3d_side_face[0].parentNode;if(parent)parent.removeChild(obj.coords[i].object.rgraph_3d_side_face[0]);if(parent)parent.removeChild(obj.coords[i].object.rgraph_3d_side_face[1]);var parent=obj.coords[i].object.rgraph_3d_top_face[0].parentNode;if(parent)parent.removeChild(obj.coords[i].object.rgraph_3d_top_face[0]);if(parent)parent.removeChild(obj.coords[i].object.rgraph_3d_top_face[1]);if(obj.coords[i].object.parentNode){var parent=obj.coords[i].object.parentNode;var node=parent.removeChild(obj.coords[i].object);parent.appendChild(node);}}
64
+ if(prop.grouping==='stacked'){var seq=obj.coords[i].object.getAttribute('data-sequential-index');var indexes=RG.SVG.sequentialIndexToGrouped(seq,obj.data);if(indexes[1]>0){obj.coords[i].object.setAttribute('y',parseInt(obj.coords[i-1].object.getAttribute('y'))-height);}}
65
+ if(prop.variant==='3d'){obj.drawSide3dFace({rect:obj.coords[i].object,value:obj.coords[i].object.getAttribute('data-value')});if(prop.grouping==='grouped'||(prop.grouping==='stacked'&&(indexes[1]+1)===obj.data[indexes[0]].length)){obj.drawTop3dFace({rect:obj.coords[i].object,value:obj.coords[i].object.getAttribute('data-value')});}}}}
66
+ if(frame>=opt.frames){callback(obj);}else{RG.SVG.FX.update(iterator);}}
67
+ iterator();return this;};for(i in conf.options){if(typeof i==='string'){this.set(i,conf.options[i]);}}};return this;})(window,document);