rgraph-rails 4.62 → 4.64

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 +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);