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