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,2006 +1,166 @@
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
-
15
- /**
16
- * The bi-polar/age frequency constructor.
17
- *
18
- * @param string id The id of the canvas
19
- * @param array left The left set of data points
20
- * @param array right The right set of data points
21
- *
22
- * REMEMBER If ymin is implemented you need to update the .getValue() method
23
- */
24
- RGraph.Bipolar = function (conf)
25
- {
26
- /**
27
- * Allow for object config style
28
- */
29
- if ( typeof conf === 'object'
30
- && typeof conf.left === 'object'
31
- && typeof conf.right === 'object'
32
- && typeof conf.id === 'string') {
33
-
34
- var id = conf.id,
35
- canvas = document.getElementById(id),
36
- left = conf.left,
37
- right = conf.right,
38
- parseConfObjectForOptions = true // Set this so the config is parsed (at the end of the constructor)
39
-
40
- } else {
41
-
42
- var id = conf,
43
- canvas = document.getElementById(id),
44
- left = arguments[1],
45
- right = arguments[2]
46
- }
47
-
48
-
49
-
50
- // Get the canvas and context objects
51
- this.id = id;
52
- this.canvas = canvas;
53
- this.context = this.canvas.getContext('2d');
54
- this.canvas.__object__ = this;
55
- this.type = 'bipolar';
56
- this.coords = [];
57
- this.coordsLeft = [];
58
- this.coordsRight = [];
59
- this.max = 0;
60
- this.isRGraph = true;
61
- this.uid = RGraph.CreateUID();
62
- this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.CreateUID();
63
- this.coordsText = [];
64
- this.original_colors = [];
65
- this.firstDraw = true; // After the first draw this will be false
66
-
67
-
68
- /**
69
- * Compatibility with older browsers
70
- */
71
- //RGraph.OldBrowserCompat(this.context);
72
-
73
-
74
- // The left and right data respectively. Ensure that the data is an array
75
- // of numbers
76
- for (var i=0; i<left.length; ++i) left[i] = parseFloat(left[i]);
77
- for (var i=0; i<right.length; ++i) right[i] = parseFloat(right[i]);
78
-
79
- this.left = left;
80
- this.right = right;
81
- this.data = [left, right];
82
-
83
- this.properties =
84
- {
85
- 'chart.background.grid': true,
86
- 'chart.background.grid.color': '#ddd',
87
- 'chart.background.grid.vlines': true,
88
- 'chart.background.grid.hlines': true,
89
- 'chart.background.grid.linewidth': 1,
90
- 'chart.background.grid.autofit.numvlines': null,
91
- 'chart.background.grid.autofit.numhlines': null,
92
- 'chart.margin': 2,
93
- 'chart.xtickinterval': null,
94
- 'chart.labels': [],
95
- 'chart.labels.color': null,
96
- 'chart.labels.above': false,
97
- 'chart.text.size': 12,
98
- 'chart.text.color': 'black', // (Simple) gradients are not supported
99
- 'chart.text.font': 'Segoe UI, Arial, Verdana, sans-serif',
100
- 'chart.text.accessible': true,
101
- 'chart.text.accessible.overflow': 'visible',
102
- 'chart.text.accessible.pointerevents': true,
103
- 'chart.title.left': '',
104
- 'chart.title.right': '',
105
- 'chart.gutter.center': 60,
106
- 'chart.gutter.left': 25,
107
- 'chart.gutter.right': 25,
108
- 'chart.gutter.top': 25,
109
- 'chart.gutter.bottom': 30,
110
- 'chart.title': '',
111
- 'chart.title.background': null,
112
- 'chart.title.hpos': null,
113
- 'chart.title.vpos': null,
114
- 'chart.title.bold': true,
115
- 'chart.title.font': null,
116
- 'chart.title.x': null,
117
- 'chart.title.y': null,
118
- 'chart.title.halign': null,
119
- 'chart.title.valign': null,
120
- 'chart.colors': ['#0f0'],
121
- 'chart.colors.sequential': false,
122
- 'chart.contextmenu': null,
123
- 'chart.tooltips': null,
124
- 'chart.tooltips.effect': 'fade',
125
- 'chart.tooltips.css.class': 'RGraph_tooltip',
126
- 'chart.tooltips.highlight': true,
127
- 'chart.tooltips.event': 'onclick',
128
- 'chart.highlight.stroke': 'rgba(0,0,0,0)',
129
- 'chart.highlight.fill': 'rgba(255,255,255,0.7)',
130
- 'chart.units.pre': '',
131
- 'chart.units.post': '',
132
- 'chart.shadow': false,
133
- 'chart.shadow.color': '#666',
134
- 'chart.shadow.offsetx': 3,
135
- 'chart.shadow.offsety': 3,
136
- 'chart.shadow.blur': 3,
137
- 'chart.annotatable': false,
138
- 'chart.annotate.color': 'black',
139
- 'chart.xmax': null,
140
- 'chart.xmin': 0,
141
- 'chart.scale.zerostart': true,
142
- 'chart.scale.decimals': null,
143
- 'chart.scale.point': '.',
144
- 'chart.scale.thousand': ',',
145
- 'chart.axis.color': 'black',
146
- 'chart.zoom.factor': 1.5,
147
- 'chart.zoom.fade.in': true,
148
- 'chart.zoom.fade.out': true,
149
- 'chart.zoom.hdir': 'right',
150
- 'chart.zoom.vdir': 'down',
151
- 'chart.zoom.frames': 25,
152
- 'chart.zoom.delay': 16.666,
153
- 'chart.zoom.shadow': true,
154
- 'chart.zoom.background': true,
155
- 'chart.zoom.action': 'zoom',
156
- 'chart.resizable': false,
157
- 'chart.resize.handle.background': null,
158
- 'chart.strokestyle': 'rgba(0,0,0,0)',
159
- 'chart.events.mousemove': null,
160
- 'chart.events.click': null,
161
- 'chart.linewidth': 1,
162
- 'chart.noaxes': false,
163
- 'chart.xlabels': true,
164
- 'chart.numyticks': null,
165
- 'chart.numxticks': 5,
166
- 'chart.axis.linewidth': 1,
167
- 'chart.labels.count': 5,
168
- 'chart.variant.threed.offsetx': 10,
169
- 'chart.variant.threed.offsety': 5,
170
- 'chart.variant.threed.angle': 0.1,
171
- 'chart.clearto': 'rgba(0,0,0,0)'
172
- }
173
-
174
- // Pad the arrays so they're the same size
175
- while (this.left.length < this.right.length) this.left.push(null);
176
- while (this.left.length > this.right.length) this.right.push(null);
177
-
178
- /**
179
- * Set the default for the number of Y tickmarks
180
- */
181
- this.properties['chart.numyticks'] = this.left.length;
182
-
183
-
184
-
185
-
186
- /**
187
- * Create the dollar objects so that functions can be added to them
188
- */
189
- var linear_data = RGraph.arrayLinearize(this.left, this.right);
190
-
191
- for (var i=0; i<linear_data.length; ++i) {
192
- this['$' + i] = {};
193
- }
194
-
195
-
196
- /**
197
- * Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
198
- * done already
199
- */
200
- if (!this.canvas.__rgraph_aa_translated__) {
201
- this.context.translate(0.5,0.5);
202
-
203
- this.canvas.__rgraph_aa_translated__ = true;
204
- }
205
-
206
-
207
-
208
-
209
- // Short variable names
210
- var RG = RGraph,
211
- ca = this.canvas,
212
- co = ca.getContext('2d'),
213
- prop = this.properties,
214
- pa2 = RG.path2,
215
- win = window,
216
- doc = document,
217
- ma = Math
218
-
219
-
220
-
221
- /**
222
- * "Decorate" the object with the generic effects if the effects library has been included
223
- */
224
- if (RG.Effects && typeof RG.Effects.decorate === 'function') {
225
- RG.Effects.decorate(this);
226
- }
227
-
228
-
229
-
230
-
231
-
232
-
233
-
234
- /**
235
- * The setter
236
- *
237
- * @param name string The name of the parameter to set
238
- * @param value mixed The value of the paraneter
239
- */
240
- this.set =
241
- this.Set = function (name)
242
- {
243
- var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
244
-
245
-
246
- /**
247
- * the number of arguments is only one and it's an
248
- * object - parse it for configuration data and return.
249
- */
250
- if (arguments.length === 1 && typeof name === 'object') {
251
- RG.parseObjectStyleConfig(this, name);
252
- return this;
253
- }
254
-
255
-
256
-
257
-
258
-
259
- /**
260
- * This should be done first - prepend the propertyy name with "chart." if necessary
261
- */
262
- if (name.substr(0,6) != 'chart.') {
263
- name = 'chart.' + name;
264
- }
265
-
266
-
267
-
268
-
269
- // Convert uppercase letters to dot+lower case letter
270
- while(name.match(/([A-Z])/)) {
271
- name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
272
- }
273
-
274
-
275
-
276
-
277
-
278
-
279
- prop[name] = value;
280
-
281
- return this;
282
- };
283
-
284
-
285
-
286
-
287
- /**
288
- * The getter
289
- *
290
- * @param name string The name of the parameter to get
291
- */
292
- this.get =
293
- this.Get = function (name)
294
- {
295
- /**
296
- * This should be done first - prepend the property name with "chart." if necessary
297
- */
298
- if (name.substr(0,6) != 'chart.') {
299
- name = 'chart.' + name;
300
- }
301
-
302
- // Convert uppercase letters to dot+lower case letter
303
- while(name.match(/([A-Z])/)) {
304
- name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
305
- }
306
-
307
- return this.properties[name.toLowerCase()];
308
- };
309
-
310
-
311
-
312
-
313
- /**
314
- * Draws the graph
315
- */
316
- this.draw =
317
- this.Draw = function ()
318
- {
319
- /**
320
- * Fire the onbeforedraw event
321
- */
322
- RG.FireCustomEvent(this, 'onbeforedraw');
323
-
324
-
325
- /**
326
- * Parse the colors. This allows for simple gradient syntax
327
- */
328
- if (!this.colorsParsed) {
329
- this.parseColors();
330
-
331
- // Don't want to do this again
332
- this.colorsParsed = true;
333
- }
334
-
335
-
336
- /**
337
- * This is new in May 2011 and facilitates indiviual gutter settings,
338
- * eg chart.gutter.left
339
- */
340
- this.gutterLeft = prop['chart.gutter.left'];
341
- this.gutterRight = prop['chart.gutter.right'];
342
- this.gutterTop = prop['chart.gutter.top'];
343
- this.gutterBottom = prop['chart.gutter.bottom'];
344
- this.gutterCenter = prop['chart.gutter.center'];
345
-
346
-
347
-
348
- // Reset the data to what was initially supplied
349
- this.left = this.data[0];
350
- this.right = this.data[1];
351
-
352
-
353
- /**
354
- * Reset the coords array
355
- */
356
- this.coords = [];
357
-
358
-
359
-
360
- /**
361
- * Stop this growing uncontrollably
362
- */
363
- this.coordsText = [];
364
-
365
-
366
- if (prop['chart.variant'] === '3d') {
367
- if (prop['chart.text.accessible']) {
368
- // Nada
369
- } else {
370
- co.setTransform(1,prop['chart.variant.threed.angle'],0,1,0.5,0.5);
371
- }
372
- }
373
-
374
-
375
-
376
- // Some necessary variables
377
- this.axisWidth = (ca.width - prop['chart.gutter.center'] - this.gutterLeft - this.gutterRight) / 2;
378
- this.axisHeight = ca.height - this.gutterTop - this.gutterBottom;
379
-
380
-
381
- // Reset the sequential index
382
- this.sequentialFullIndex = 0;
383
-
384
-
385
-
386
- this.getMax();
387
- this.drawBackgroundGrid();
388
- this.draw3DAxes();
389
- this.drawAxes();
390
- this.drawTicks();
391
-
392
- co.save();
393
- co.beginPath();
394
- co.rect(this.gutterLeft, this.gutterTop - (prop['chart.variant.threed.offsety'] || 0), ca.width - this.gutterLeft - this.gutterRight, ca.height - this.gutterTop - this.gutterBottom + (2 * (prop['chart.variant.threed.offsety'] || 0)) );
395
- co.clip();
396
-
397
- this.drawLeftBars();
398
- this.drawRightBars();
399
-
400
- // Redraw the bars so that shadows on not on top
401
- this.drawLeftBars({shadow: false});
402
- this.drawRightBars({shadow: false});
403
- co.restore();
404
-
405
- this.drawAxes();
406
-
407
- this.drawLabels();
408
- this.drawTitles();
409
-
410
-
411
- /**
412
- * Setup the context menu if required
413
- */
414
- if (prop['chart.contextmenu']) {
415
- RG.ShowContext(this);
416
- }
417
-
418
-
419
- /**
420
- * This function enables resizing
421
- */
422
- if (prop['chart.resizable']) {
423
- RG.AllowResizing(this);
424
- }
425
-
426
-
427
- /**
428
- * This installs the event listeners
429
- */
430
- RG.InstallEventListeners(this);
431
-
432
-
433
- /**
434
- * Fire the onfirstdraw event
435
- */
436
- if (this.firstDraw) {
437
- RG.fireCustomEvent(this, 'onfirstdraw');
438
- this.firstDraw = false;
439
- this.firstDrawFunc();
440
- }
441
-
442
-
443
- /**
444
- * Fire the RGraph ondraw event
445
- */
446
- RG.FireCustomEvent(this, 'ondraw');
447
-
448
- return this;
449
- };
450
-
451
-
452
-
453
- /**
454
- * Used in chaining. Runs a function there and then - not waiting for
455
- * the events to fire (eg the onbeforedraw event)
456
- *
457
- * @param function func The function to execute
458
- */
459
- this.exec = function (func)
460
- {
461
- func(this);
462
-
463
- return this;
464
- };
465
-
466
-
467
-
468
-
469
- /**
470
- * Draws the axes
471
- */
472
- this.draw3DAxes = function ()
473
- {
474
- if (prop['chart.variant'] === '3d') {
475
- var offsetx = prop['chart.variant.threed.offsetx'],
476
- offsety = prop['chart.variant.threed.offsety'];
477
-
478
- // Set the linewidth
479
- co.lineWidth = prop['chart.axis.linewidth'] + 0.001;
480
-
481
-
482
- // Draw the left set of axes
483
- co.beginPath();
484
- co.strokeStyle = prop['chart.axis.color'];
485
-
486
- // Draw the horizontal 3d axis
487
- // The left horizontal axis
488
- pa2(co,
489
- 'b m % % l % % l % % l % % s #aaa f #ddd',
490
- this.gutterLeft, ma.round( ca.height - this.gutterBottom),
491
- this.gutterLeft + offsetx, ma.round( ca.height - this.gutterBottom - offsety),
492
- this.gutterLeft + offsetx + this.axisWidth, ma.round( ca.height - this.gutterBottom - offsety),
493
- this.gutterLeft + this.axisWidth, ma.round( ca.height - this.gutterBottom)
494
- );
495
-
496
- // The left vertical axis
497
- this.draw3DLeftVerticalAxis();
498
-
499
-
500
-
501
-
502
- // Draw the right horizontal axes
503
- pa2(co,
504
- 'b m % % l % % l % % l % % s #aaa f #ddd',
505
- this.gutterLeft + this.gutterCenter + this.axisWidth, ma.round( ca.height - this.gutterBottom),
506
- this.gutterLeft + this.gutterCenter + this.axisWidth + offsetx, ma.round( ca.height - this.gutterBottom - offsety),
507
- this.gutterLeft + this.gutterCenter + this.axisWidth + this.axisWidth + offsetx, ma.round( ca.height - this.gutterBottom - offsety),
508
- this.gutterLeft + this.gutterCenter + this.axisWidth + this.axisWidth, ma.round( ca.height - this.gutterBottom)
509
- );
510
-
511
-
512
-
513
-
514
- // Draw the right vertical axes
515
- pa2(co,
516
- 'b m % % l % % l % % l % % s #aaa f #ddd',
517
- this.gutterLeft + this.gutterCenter + this.axisWidth, ca.height - this.gutterBottom,
518
- this.gutterLeft + this.gutterCenter + this.axisWidth, ca.height - this.gutterBottom - this.axisHeight,
519
- this.gutterLeft + this.gutterCenter + this.axisWidth + offsetx, ca.height - this.gutterBottom - this.axisHeight - offsety,
520
- this.gutterLeft + this.gutterCenter + this.axisWidth + offsetx, ca.height - this.gutterBottom - offsety
521
- );
522
- }
523
- }
524
-
525
-
526
-
527
-
528
- this.draw3DLeftVerticalAxis = function ()
529
- {
530
- if (prop['chart.variant'] === '3d') {
531
- var offsetx = prop['chart.variant.threed.offsetx'],
532
- offsety = prop['chart.variant.threed.offsety'];
533
-
534
- // The left vertical axis
535
- pa2(co,
536
- 'b m % % l % % l % % l % % s #aaa f #ddd',
537
- this.gutterLeft + this.axisWidth, this.gutterTop,
538
- this.gutterLeft + this.axisWidth + offsetx, this.gutterTop - offsety,
539
- this.gutterLeft + this.axisWidth + offsetx, ca.height - this.gutterBottom - offsety,
540
- this.gutterLeft + this.axisWidth, ca.height - this.gutterBottom
541
- );
542
- }
543
- };
544
-
545
-
546
-
547
-
548
- /**
549
- * Draws the axes
550
- */
551
- this.drawAxes =
552
- this.DrawAxes = function ()
553
- {
554
- // Set the linewidth
555
- co.lineWidth = prop['chart.axis.linewidth'] + 0.001;
556
-
557
-
558
- // Draw the left set of axes
559
- co.beginPath();
560
- co.strokeStyle = prop['chart.axis.color'];
561
-
562
- this.axisWidth = (ca.width - prop['chart.gutter.center'] - this.gutterLeft - this.gutterRight) / 2;
563
- this.axisHeight = ca.height - this.gutterTop - this.gutterBottom;
564
-
565
-
566
- // This must be here so that the two above variables are calculated
567
- if (prop['chart.noaxes']) {
568
- return;
569
- }
570
-
571
- co.moveTo(this.gutterLeft, Math.round( ca.height - this.gutterBottom));
572
- co.lineTo(this.gutterLeft + this.axisWidth, Math.round( ca.height - this.gutterBottom));
573
-
574
- co.moveTo(ma.round( this.gutterLeft + this.axisWidth), ca.height - this.gutterBottom);
575
- co.lineTo(ma.round( this.gutterLeft + this.axisWidth), this.gutterTop);
576
-
577
- co.stroke();
578
-
579
-
580
- // Draw the right set of axes
581
- co.beginPath();
582
-
583
- var x = this.gutterLeft + this.axisWidth + prop['chart.gutter.center'];
584
-
585
- co.moveTo(Math.round( x), this.gutterTop);
586
- co.lineTo(Math.round( x), ca.height - this.gutterBottom);
587
-
588
- co.moveTo(Math.round( x), Math.round( ca.height - this.gutterBottom));
589
- co.lineTo(ca.width - this.gutterRight, Math.round( ca.height - this.gutterBottom));
590
-
591
- co.stroke();
592
- };
593
-
594
-
595
-
596
-
597
- /**
598
- * Draws the tick marks on the axes
599
- */
600
- this.drawTicks =
601
- this.DrawTicks = function ()
602
- {
603
- // Set the linewidth
604
- co.lineWidth = prop['chart.axis.linewidth'] + 0.001;
605
-
606
- var numDataPoints = this.left.length;
607
- var barHeight = ( (ca.height - this.gutterTop - this.gutterBottom)- (this.left.length * (prop['chart.margin'] * 2) )) / numDataPoints;
608
-
609
- // Store this for later
610
- this.barHeight = barHeight;
611
-
612
- // If no axes - no tickmarks
613
- if (prop['chart.noaxes']) {
614
- return;
615
- }
616
-
617
- // Draw the left Y tick marks
618
- if (prop['chart.numyticks'] > 0) {
619
- co.beginPath();
620
- for (var i=0; i<prop['chart.numyticks']; ++i) {
621
- var y = prop['chart.gutter.top'] + (((ca.height - this.gutterTop - this.gutterBottom) / prop['chart.numyticks']) * i);
622
- co.moveTo(this.gutterLeft + this.axisWidth , y);
623
- co.lineTo(this.gutterLeft + this.axisWidth + 3, y);
624
- }
625
- co.stroke();
626
-
627
- //Draw the right axis Y tick marks
628
- co.beginPath();
629
- for (var i=0; i<prop['chart.numyticks']; ++i) {
630
- var y = prop['chart.gutter.top'] + (((ca.height - this.gutterTop - this.gutterBottom) / prop['chart.numyticks']) * i);
631
- co.moveTo(this.gutterLeft + this.axisWidth + prop['chart.gutter.center'], y);
632
- co.lineTo(this.gutterLeft + this.axisWidth + prop['chart.gutter.center'] - 3, y);
633
- }
634
- co.stroke();
635
- }
636
-
637
-
638
-
639
- /**
640
- * X tickmarks
641
- */
642
- if (prop['chart.numxticks'] > 0) {
643
- var xInterval = this.axisWidth / prop['chart.numxticks'];
644
-
645
- // Is chart.xtickinterval specified ? If so, use that.
646
- if (typeof(prop['chart.xtickinterval']) == 'number') {
647
- xInterval = prop['chart.xtickinterval'];
648
- }
649
-
650
-
651
- // Draw the left sides X tick marks
652
- for (i=this.gutterLeft; i<(this.gutterLeft + this.axisWidth); i+=xInterval) {
653
- co.beginPath();
654
- co.moveTo(Math.round( i), ca.height - this.gutterBottom);
655
- co.lineTo(Math.round( i), (ca.height - this.gutterBottom) + 4);
656
- co.closePath();
657
-
658
- co.stroke();
659
- }
660
-
661
- // Draw the right sides X tick marks
662
- var stoppingPoint = ca.width - this.gutterRight;
663
-
664
- for (i=(this.gutterLeft + this.axisWidth + prop['chart.gutter.center'] + xInterval); i<=stoppingPoint; i+=xInterval) {
665
- co.beginPath();
666
- co.moveTo(Math.round(i), ca.height - this.gutterBottom);
667
- co.lineTo(Math.round(i), (ca.height - this.gutterBottom) + 4);
668
- co.closePath();
669
-
670
- co.stroke();
671
- }
672
- }
673
- };
674
-
675
-
676
-
677
-
678
- /**
679
- * Figures out the maximum value, or if defined, uses xmax
680
- */
681
- this.getMax =
682
- this.GetMax = function()
683
- {
684
- var dec = prop['chart.scale.decimals'];
685
-
686
- // chart.xmax defined
687
- if (prop['chart.xmax']) {
688
-
689
- var max = prop['chart.xmax'];
690
- var min = prop['chart.xmin'];
691
-
692
- this.scale2 = RG.getScale2(this, {
693
- 'max':max,
694
- 'min':min,
695
- 'strict': true,
696
- 'scale.thousand':prop['chart.scale.thousand'],
697
- 'scale.point':prop['chart.scale.point'],
698
- 'scale.decimals':prop['chart.scale.decimals'],
699
- 'ylabels.count':prop['chart.labels.count'],
700
- 'scale.round':prop['chart.scale.round'],
701
- 'units.pre': prop['chart.units.pre'],
702
- 'units.post': prop['chart.units.post']
703
- });
704
- this.max = this.scale2.max;
705
- this.min = this.scale2.min;
706
-
707
-
708
- /**
709
- * Generate the scale ourselves
710
- */
711
- } else {
712
-
713
- var max = Math.max(RG.array_max(this.left), RG.array_max(this.right));
714
-
715
- this.scale2 = RG.getScale2(this, {
716
- 'max':max,
717
- //'strict': true,
718
- 'min':prop['chart.xmin'],
719
- 'scale.thousand':prop['chart.scale.thousand'],
720
- 'scale.point':prop['chart.scale.point'],
721
- 'scale.decimals':prop['chart.scale.decimals'],
722
- 'ylabels.count':prop['chart.labels.count'],
723
- 'scale.round':prop['chart.scale.round'],
724
- 'units.pre': prop['chart.units.pre'],
725
- 'units.post': prop['chart.units.post']
726
- });
727
-
728
-
729
- this.max = this.scale2.max;
730
- this.min = this.scale2.min;
731
- }
732
-
733
- // Don't need to return it as it is stored in this.max
734
- };
735
-
736
-
737
-
738
-
739
- /**
740
- * Function to draw the left hand bars
741
- */
742
- this.drawLeftBars =
743
- this.DrawLeftBars = function ()
744
- {
745
- var opt = {};
746
-
747
- if (typeof arguments[0] === 'object') {
748
- opt.shadow = arguments[0].shadow;
749
- } else {
750
- opt.shadow = true;
751
- }
752
-
753
- var offsetx = prop['chart.variant.threed.offsetx'],
754
- offsety = prop['chart.variant.threed.offsety'];
755
-
756
- // Set the stroke colour
757
- co.strokeStyle = prop['chart.strokestyle'];
758
-
759
- // Set the linewidth
760
- co.lineWidth = prop['chart.linewidth'];
761
-
762
- for (var i=(this.left.length - 1); i>=0; i-=1) {
763
-
764
- /**
765
- * Turn on a shadow if requested
766
- */
767
- if (prop['chart.shadow'] && prop['chart.variant'] !== '3d' && opt.shadow) {
768
- co.shadowColor = prop['chart.shadow.color'];
769
- co.shadowBlur = prop['chart.shadow.blur'];
770
- co.shadowOffsetX = prop['chart.shadow.offsetx'];
771
- co.shadowOffsetY = prop['chart.shadow.offsety'];
772
- }
773
-
774
-
775
-
776
-
777
- // If chart.colors.sequential is specified - handle that
778
- // ** There's another instance of this further down **
779
- if (prop['chart.colors.sequential']) {
780
- co.fillStyle = prop['chart.colors'][i];
781
-
782
- } else {
783
- co.fillStyle = prop['chart.colors'][0];
784
- }
785
-
786
-
787
-
788
-
789
- /**
790
- * Work out the coordinates
791
- */
792
-
793
- var width = (( (this.left[i] - this.min) / (this.max - this.min)) * this.axisWidth);
794
-
795
- var coords = [
796
- ma.round( this.gutterLeft + this.axisWidth - width),
797
- ma.round( this.gutterTop + (i * ( this.axisHeight / this.left.length)) + prop['chart.margin']),
798
- width,
799
- this.barHeight
800
- ];
801
-
802
- // Draw the IE shadow if necessary
803
- if (RG.ISOLD && prop['chart.shadow']) {
804
- this.drawIEShadow(coords);
805
- }
806
-
807
-
808
- if (this.left[i] !== null) {
809
- co.strokeRect(coords[0], coords[1], coords[2], coords[3]);
810
- co.fillRect(coords[0], coords[1], coords[2], coords[3]);
811
- }
812
-
813
-
814
-
815
-
816
-
817
-
818
-
819
-
820
-
821
-
822
-
823
-
824
-
825
-
826
-
827
-
828
- // Draw the 3D sides if required
829
- if (prop['chart.variant'] === '3d' && this.left[i] !== null) {
830
-
831
- // If the shadow is enabled draw the backface for
832
- // (that we don't actually see
833
- if (prop['chart.shadow'] && opt.shadow) {
834
-
835
- co.shadowColor = prop['chart.shadow.color'];
836
- co.shadowBlur = prop['chart.shadow.blur'];
837
- co.shadowOffsetX = prop['chart.shadow.offsetx'];
838
- co.shadowOffsetY = prop['chart.shadow.offsety'];
839
-
840
-
841
- pa2(co,
842
- 'b m % % l % % l % % l % % f black sc rgba(0,0,0,0) sx 0 sy 0 sb 0',
843
- coords[0] + offsetx, coords[1] - offsety,
844
- coords[0] + offsetx + coords[2], coords[1] - offsety,
845
- coords[0] + offsetx + coords[2], coords[1] - offsety + coords[3],
846
- coords[0] + offsetx,coords[1] - offsety + coords[3]
847
- );
848
- }
849
-
850
-
851
-
852
- // If chart.colors.sequential is specified - handle that (again)
853
- //
854
- // ** There's another instance of this further up **
855
- if (prop['chart.colors.sequential']) {
856
- co.fillStyle = prop['chart.colors'][i];
857
-
858
- } else {
859
- co.fillStyle = prop['chart.colors'][0];
860
- }
861
-
862
- pa2(co,
863
- 'b m % % l % % l % % l % % f %',
864
- coords[0],coords[1],
865
- coords[0] + offsetx, coords[1] - offsety,
866
- coords[0] + offsetx + coords[2], coords[1] - offsety,
867
- coords[0] + coords[2], coords[1]
868
- );
869
-
870
- pa2(co,
871
- 'b m % % l % % l % % l % % f rgba(255,255,255,0.4)',
872
- coords[0],coords[1],
873
- coords[0] + offsetx, coords[1] - offsety,
874
- coords[0] + offsetx + coords[2], coords[1] - offsety,
875
- coords[0] + coords[2], coords[1]
876
- );
877
- }
878
-
879
- this.draw3DLeftVerticalAxis();
880
-
881
-
882
-
883
-
884
-
885
-
886
-
887
-
888
-
889
-
890
-
891
-
892
-
893
-
894
-
895
- // Add the coordinates to the coords array
896
- this.coords.push([coords[0],coords[1],coords[2],coords[3]]);
897
- this.coordsLeft.push([coords[0],coords[1],coords[2],coords[3]]);
898
- }
899
-
900
- /**
901
- * Turn off any shadow
902
- */
903
- RG.noShadow(this);
904
-
905
- // Reset the linewidth
906
- co.lineWidth = 1;
907
- };
908
-
909
-
910
-
911
-
912
- /**
913
- * Function to draw the right hand bars
914
- */
915
- this.drawRightBars =
916
- this.DrawRightBars = function ()
917
- {
918
- var opt = {};
919
-
920
- if (typeof arguments[0] === 'object') {
921
- opt.shadow = arguments[0].shadow;
922
- } else {
923
- opt.shadow = true;
924
- }
925
-
926
- var offsetx = prop['chart.variant.threed.offsetx'],
927
- offsety = prop['chart.variant.threed.offsety'];
928
-
929
-
930
-
931
-
932
- // Set the stroke colour
933
- co.strokeStyle = prop['chart.strokestyle'];
934
-
935
- // Set the linewidth
936
- co.lineWidth = prop['chart.linewidth'];
937
-
938
- /**
939
- * Turn on a shadow if requested
940
- */
941
- if (prop['chart.shadow'] && prop['chart.variant'] !== '3d' && opt.shadow) {
942
- co.shadowColor = prop['chart.shadow.color'];
943
- co.shadowBlur = prop['chart.shadow.blur'];
944
- co.shadowOffsetX = prop['chart.shadow.offsetx'];
945
- co.shadowOffsetY = prop['chart.shadow.offsety'];
946
- }
947
-
948
- for (var i=(this.right.length - 1); i>=0; i-=1) {
949
-
950
-
951
- // If chart.colors.sequential is specified - handle that
952
- if (prop['chart.colors.sequential']) {
953
- co.fillStyle = prop['chart.colors'][i];
954
-
955
- } else {
956
- co.fillStyle = prop['chart.colors'][0];
957
- }
958
-
959
-
960
- var width = (((this.right[i] - this.min) / (this.max - this.min)) * this.axisWidth);
961
-
962
- var coords = [
963
- ma.round( this.gutterLeft + this.axisWidth + prop['chart.gutter.center']),
964
- ma.round( prop['chart.margin'] + (i * (this.axisHeight / this.right.length)) + this.gutterTop),
965
- width,
966
- this.barHeight
967
- ];
968
-
969
- // Draw the IE shadow if necessary
970
- if (RG.ISOLD && prop['chart.shadow']) {
971
- this.DrawIEShadow(coords);
972
- }
973
-
974
- if (this.right[i] !== null) {
975
- co.strokeRect(ma.round( coords[0]), Math.round( coords[1]), coords[2], coords[3]);
976
- co.fillRect(ma.round( coords[0]), Math.round( coords[1]), coords[2], coords[3]);
977
- }
978
-
979
-
980
-
981
-
982
-
983
-
984
-
985
-
986
-
987
-
988
-
989
-
990
-
991
- // Draw the 3D sides if required
992
- if (prop['chart.variant'] === '3d' && this.right[i] !== null) {
993
-
994
- var color = co.fillStyle;
995
-
996
-
997
- // If the shadow is enabled draw the backface for
998
- // (that we don't actually see
999
- if (prop['chart.shadow'] && opt.shadow) {
1000
-
1001
- co.shadowColor = prop['chart.shadow.color'];
1002
- co.shadowBlur = prop['chart.shadow.blur'];
1003
- co.shadowOffsetX = prop['chart.shadow.offsetx'];
1004
- co.shadowOffsetY = prop['chart.shadow.offsety'];
1005
-
1006
- pa2(co,
1007
- 'b m % % l % % l % % l % % f black sc rgba(0,0,0,0) sx 0 sy 0 sb 0',
1008
- coords[0] + offsetx, coords[1] - offsety,
1009
- coords[0] + offsetx + coords[2], coords[1] - offsety,
1010
- coords[0] + offsetx + coords[2], coords[1] - offsety + coords[3],
1011
- coords[0] + offsetx,coords[1] - offsety + coords[3]
1012
- );
1013
- }
1014
-
1015
- // Draw the top
1016
- pa2(co,
1017
- 'b m % % l % % l % % l % % f %',
1018
- coords[0],coords[1],
1019
- coords[0] + offsetx, coords[1] - offsety,
1020
- coords[0] + offsetx + coords[2], coords[1] - offsety,
1021
- coords[0] + coords[2], coords[1],
1022
- color
1023
- );
1024
-
1025
-
1026
- // Draw the right hand side
1027
- pa2(co,
1028
- 'b m % % l % % l % % l % % f %',
1029
- coords[0] + coords[2],coords[1],
1030
- coords[0] + coords[2] + offsetx, coords[1] - offsety,
1031
- coords[0] + coords[2] + offsetx, coords[1] - offsety + coords[3],
1032
- coords[0] + coords[2],coords[1] + coords[3],
1033
- color
1034
- );
1035
-
1036
- // Draw the LIGHTER top
1037
- pa2(co,
1038
- 'b m % % l % % l % % l % % f rgba(255,255,255,0.6)',
1039
- coords[0],coords[1],
1040
- coords[0] + offsetx, coords[1] - offsety,
1041
- coords[0] + offsetx + coords[2], coords[1] - offsety,
1042
- coords[0] + coords[2], coords[1]
1043
- );
1044
-
1045
-
1046
- // Draw the DARKER right hand side
1047
- pa2(co,
1048
- 'b m % % l % % l % % l % % f rgba(0,0,0,0.3)',
1049
- coords[0] + coords[2],coords[1],
1050
- coords[0] + coords[2] + offsetx, coords[1] - offsety,
1051
- coords[0] + coords[2] + offsetx, coords[1] - offsety + coords[3],
1052
- coords[0] + coords[2],coords[1] + coords[3]
1053
- );
1054
- }
1055
-
1056
-
1057
-
1058
-
1059
-
1060
-
1061
-
1062
-
1063
-
1064
-
1065
-
1066
-
1067
-
1068
- /**
1069
- * Add the coordinates to the coords array
1070
- */
1071
- this.coords.push([coords[0],coords[1],coords[2],coords[3]]);
1072
- this.coordsRight.push([coords[0],coords[1],coords[2],coords[3]]);
1073
- }
1074
-
1075
-
1076
-
1077
-
1078
-
1079
-
1080
-
1081
-
1082
-
1083
-
1084
-
1085
-
1086
-
1087
-
1088
-
1089
-
1090
-
1091
-
1092
-
1093
-
1094
-
1095
-
1096
-
1097
-
1098
-
1099
-
1100
-
1101
- /**
1102
- * Turn off any shadow
1103
- */
1104
- RG.NoShadow(this);
1105
-
1106
- // Reset the linewidth
1107
- co.lineWidth = 1;
1108
- };
1109
-
1110
-
1111
-
1112
-
1113
- /**
1114
- * Draws the titles
1115
- */
1116
- this.drawLabels =
1117
- this.DrawLabels = function ()
1118
- {
1119
-
1120
- var font = prop['chart.text.font'],
1121
- color = prop['chart.labels.color'] || prop['chart.text.color'],
1122
- size = prop['chart.text.size'],
1123
- labels = prop['chart.labels'],
1124
- barAreaHeight = ca.height - this.gutterTop - this.gutterBottom
1125
-
1126
- co.fillStyle = color;
1127
-
1128
- for (var i=0,len=labels.length; i<len; i+=1) {
1129
- RG.Text2(this, {
1130
- 'color': color,
1131
- 'font':font,
1132
- 'size':size,
1133
- 'x':this.gutterLeft + this.axisWidth + (prop['chart.gutter.center'] / 2),
1134
- 'y':this.gutterTop + ((barAreaHeight / labels.length) * (i)) + ((barAreaHeight / labels.length) / 2),
1135
- 'text':String(labels[i] ? String(labels[i]) : ''),
1136
- 'halign':'center',
1137
- 'valign':'center',
1138
- 'marker':false,
1139
- 'tag': 'labels'
1140
- });
1141
- }
1142
-
1143
-
1144
-
1145
- co.fillStyle = prop['chart.text.color'];
1146
-
1147
-
1148
-
1149
- if (prop['chart.xlabels']) {
1150
-
1151
- var grapharea = (ca.width - prop['chart.gutter.center'] - this.gutterLeft - this.gutterRight) / 2;
1152
-
1153
- // Now draw the X labels for the left hand side
1154
- for (var i=0; i<this.scale2.labels.length; ++i) {
1155
- RG.text2(this, {
1156
- 'font':font,
1157
- 'size':size,
1158
- 'x':this.gutterLeft + ((grapharea / this.scale2.labels.length) * i),
1159
- 'y':ca.height - this.gutterBottom + 3,
1160
- 'text':this.scale2.labels[this.scale2.labels.length - i - 1],
1161
- 'valign':'top',
1162
- 'halign':'center',
1163
- 'tag': 'scale'
1164
- });
1165
-
1166
-
1167
-
1168
-
1169
- // Draw the scale for the right hand side
1170
- RG.text2(this, {
1171
- 'font':font,
1172
- 'size':size,
1173
- 'x':this.gutterLeft+ grapharea + prop['chart.gutter.center'] + ((grapharea / this.scale2.labels.length) * (i + 1)),
1174
- 'y':ca.height - this.gutterBottom + 3,
1175
- 'text':this.scale2.labels[i],
1176
- 'valign':'top',
1177
- 'halign':'center',
1178
- 'tag': 'scale'
1179
- });
1180
- }
1181
-
1182
-
1183
-
1184
-
1185
- // Draw zero?
1186
- if (prop['chart.scale.zerostart']) {
1187
- RG.text2(this, {
1188
- 'font':font,
1189
- 'size':size,
1190
- 'x':this.gutterLeft + this.axisWidth,
1191
- 'y':ca.height - this.gutterBottom + 3,
1192
- 'text':'0',
1193
- 'valign':'top',
1194
- 'halign':'center',
1195
- 'tag': 'scale'
1196
- });
1197
-
1198
-
1199
- RG.text2(this, {
1200
- 'font':font,
1201
- 'size':size,
1202
- 'x':this.gutterLeft + this.axisWidth + this.gutterCenter,
1203
- 'y':ca.height - this.gutterBottom + 3,
1204
- 'text':'0',
1205
- 'valign':'top',
1206
- 'halign':'center',
1207
- 'tag': 'scale'
1208
- });
1209
- }
1210
- }
1211
-
1212
- /**
1213
- * Draw above labels
1214
- */
1215
- if (prop['chart.labels.above']) {
1216
-
1217
- // Draw the left sides above labels
1218
-
1219
- var coordsLeft = RG.arrayReverse(this.coordsLeft);
1220
-
1221
- for (var i=0; i<coordsLeft.length; ++i) {
1222
-
1223
- if (typeof this.left[i] !== 'number') {
1224
- continue;
1225
- }
1226
-
1227
- var coords = coordsLeft[i];
1228
-
1229
- RG.text2(this, {
1230
- font:font,
1231
- size:size,
1232
- x:coords[0] - 5,
1233
- y:coords[1] + (coords[3] / 2),
1234
- text:RG.numberFormat(
1235
- this,
1236
- this.left[i],
1237
- prop['chart.units.pre'],
1238
- prop['chart.units.post']
1239
- ),
1240
- valign:'center',
1241
- halign:'right',
1242
- tag:'labels.above'
1243
- });
1244
- }
1245
-
1246
-
1247
-
1248
-
1249
-
1250
-
1251
-
1252
-
1253
- // Draw the right sides above labels
1254
-
1255
- var coordsRight = RG.arrayReverse(this.coordsRight);
1256
-
1257
- for (i=0; i<coordsRight.length; ++i) {
1258
-
1259
- if (typeof this.right[i] != 'number') {
1260
- continue;
1261
- }
1262
-
1263
- var coords = coordsRight[i];
1264
-
1265
- RG.Text2(this, {
1266
- 'font':font,
1267
- 'size':size,
1268
- 'x':coords[0] + coords[2] + 5,
1269
- 'y':coords[1] + (coords[3] / 2),
1270
- 'text':RG.number_format(this, this.right[i], prop['chart.units.pre'], prop['chart.units.post']),
1271
- 'valign':'center',
1272
- 'halign':'left',
1273
- 'tag': 'labels.above'
1274
- });
1275
- }
1276
- }
1277
- };
1278
-
1279
-
1280
-
1281
-
1282
- /**
1283
- * Draws the titles
1284
- */
1285
- this.drawTitles =
1286
- this.DrawTitles = function ()
1287
- {
1288
- RG.Text2(this, {
1289
- 'font':prop['chart.text.font'],
1290
- 'size':prop['chart.text.size'],
1291
- 'x':this.gutterLeft + 5,
1292
- 'y':this.gutterTop - 5,
1293
- 'text':String(prop['chart.title.left']),
1294
- 'halign':'left',
1295
- 'valign':'bottom',
1296
- 'tag': 'title.left'
1297
- });
1298
-
1299
- RG.Text2(this, {
1300
- 'font':prop['chart.text.font'],
1301
- 'size':prop['chart.text.size'],
1302
- 'x': ca.width - this.gutterRight - 5,
1303
- 'y':this.gutterTop - 5,
1304
- 'text':String(prop['chart.title.right']),
1305
- 'halign':'right',
1306
- 'valign':'bottom',
1307
- 'tag': 'title.right'
1308
- });
1309
-
1310
-
1311
-
1312
- // Draw the main title for the whole chart
1313
- RG.drawTitle(
1314
- this,
1315
- prop['chart.title'],
1316
- this.gutterTop,
1317
- null,
1318
- prop['chart.title.size'] ? prop['chart.title.size'] : null
1319
- );
1320
- };
1321
-
1322
-
1323
-
1324
-
1325
- /**
1326
- * This function is used by MSIE only to manually draw the shadow
1327
- *
1328
- * @param array coords The coords for the bar
1329
- */
1330
- this.drawIEShadow =
1331
- this.DrawIEShadow = function (coords)
1332
- {
1333
- var prevFillStyle = co.fillStyle;
1334
- var offsetx = prop['chart.shadow.offsetx'];
1335
- var offsety = prop['chart.shadow.offsety'];
1336
-
1337
- co.lineWidth = prop['chart.linewidth'];
1338
- co.fillStyle = prop['chart.shadow.color'];
1339
- co.beginPath();
1340
-
1341
- // Draw shadow here
1342
- co.fillRect(coords[0] + offsetx, coords[1] + offsety, coords[2],coords[3]);
1343
-
1344
- co.fill();
1345
-
1346
- // Change the fillstyle back to what it was
1347
- co.fillStyle = prevFillStyle;
1348
- }
1349
-
1350
-
1351
-
1352
-
1353
- /**
1354
- * Returns the appropriate focussed bar coordinates
1355
- *
1356
- * @param e object The event object
1357
- */
1358
- this.getShape =
1359
- this.getBar = function (e)
1360
- {
1361
- var canvas = this.canvas,
1362
- context = this.context,
1363
- mouseCoords = RG.getMouseXY(e)
1364
-
1365
- /**
1366
- * Loop through the bars determining if the mouse is over a bar
1367
- */
1368
- for (var i=0; i<this.coords.length; i++) {
1369
-
1370
- var mouseX = mouseCoords[0],
1371
- mouseY = mouseCoords[1],
1372
- left = this.coords[i][0],
1373
- top = this.coords[i][1],
1374
- width = this.coords[i][2],
1375
- height = this.coords[i][3]
1376
-
1377
- //if (mouseX >= left && mouseX <= (left + width) && mouseY >= top && mouseY <= (top + height) ) {
1378
- pa2(co,
1379
- 'b r % % % %',
1380
- left,
1381
- top,
1382
- width,
1383
- height
1384
- );
1385
-
1386
- if (co.isPointInPath(mouseX, mouseY)) {
1387
-
1388
- var tooltip = RG.parseTooltipText(prop['chart.tooltips'], i);
1389
-
1390
- return {
1391
- 0: this,1: left,2: top,3: width,4: height,5: i,
1392
- 'object': this, 'x': left, 'y': top, 'width': width, 'height': height, 'index': i, 'tooltip': tooltip
1393
- };
1394
- }
1395
- }
1396
-
1397
- return null;
1398
- };
1399
-
1400
-
1401
-
1402
-
1403
- /**
1404
- * Each object type has its own Highlight() function which highlights the appropriate shape
1405
- *
1406
- * @param object shape The shape to highlight
1407
- */
1408
- this.highlight =
1409
- this.Highlight = function (shape)
1410
- {
1411
- if (typeof prop['chart.highlight.style'] === 'function') {
1412
- (prop['chart.highlight.style'])(shape);
1413
- } else {
1414
- RG.Highlight.Rect(this, shape);
1415
- }
1416
- };
1417
-
1418
-
1419
-
1420
-
1421
- /**
1422
- * When you click on the canvas, this will return the relevant value (if any)
1423
- *
1424
- * REMEMBER This function will need updating if the Bipolar ever gets chart.ymin
1425
- *
1426
- * @param object e The event object
1427
- */
1428
- this.getValue = function (e)
1429
- {
1430
- var obj = e.target.__object__;
1431
- var mouseXY = RG.getMouseXY(e);
1432
- var mouseX = mouseXY[0];
1433
-
1434
- /**
1435
- * Left hand side
1436
- */
1437
- if (mouseX > this.gutterLeft && mouseX < ( (ca.width / 2) - (prop['chart.gutter.center'] / 2) )) {
1438
- var value = (mouseX - prop['chart.gutter.left']) / this.axisWidth;
1439
- value = this.max - (value * this.max);
1440
- }
1441
-
1442
- /**
1443
- * Right hand side
1444
- */
1445
- if (mouseX < (ca.width - this.gutterRight) && mouseX > ( (ca.width / 2) + (prop['chart.gutter.center'] / 2) )) {
1446
- var value = (mouseX - prop['chart.gutter.left'] - this.axisWidth - prop['chart.gutter.center']) / this.axisWidth;
1447
- value = (value * this.max);
1448
- }
1449
-
1450
- return value;
1451
- };
1452
-
1453
-
1454
-
1455
-
1456
- /**
1457
- * The getObjectByXY() worker method. Don't call this call:
1458
- *
1459
- * RGraph.ObjectRegistry.getObjectByXY(e)
1460
- *
1461
- * @param object e The event object
1462
- */
1463
- this.getObjectByXY = function (e)
1464
- {
1465
- var mouseXY = RG.getMouseXY(e);
1466
-
1467
- // Adjust the mouse Y coordinate for when the bar chart is
1468
- // a 3D variant
1469
-
1470
- if (prop['chart.variant'] === '3d') {
1471
- var adjustment = prop['chart.variant.threed.angle'] * mouseXY[0];
1472
- mouseXY[1] -= adjustment;
1473
- }
1474
-
1475
-
1476
-
1477
- if (
1478
- mouseXY[0] > prop['chart.gutter.left']
1479
- && mouseXY[0] < (ca.width - prop['chart.gutter.right'])
1480
- && mouseXY[1] > prop['chart.gutter.top']
1481
- && mouseXY[1] < (ca.height - prop['chart.gutter.bottom'])
1482
- ) {
1483
-
1484
- return this;
1485
- }
1486
- };
1487
-
1488
-
1489
-
1490
-
1491
- /**
1492
- * This function positions a tooltip when it is displayed
1493
- *
1494
- * @param obj object The chart object
1495
- * @param int x The X coordinate specified for the tooltip
1496
- * @param int y The Y coordinate specified for the tooltip
1497
- * @param objec tooltip The tooltips DIV element
1498
- *
1499
- this.positionTooltip = function (obj, x, y, tooltip, idx)
1500
- {
1501
- var coordX = obj.coords[tooltip.__index__][0],
1502
- coordY = obj.coords[tooltip.__index__][1],
1503
- coordW = obj.coords[tooltip.__index__][2],
1504
- coordH = obj.coords[tooltip.__index__][3],
1505
- canvasXY = RG.getCanvasXY(obj.canvas),
1506
- mouseXY = RG.getMouseXY(window.event),
1507
- gutterLeft = obj.Get('chart.gutter.left'),
1508
- gutterTop = obj.Get('chart.gutter.top'),
1509
- width = tooltip.offsetWidth,
1510
- height = tooltip.offsetHeight
1511
-
1512
- // If the chart is a 3D version the tooltip Y position needs this
1513
- // adjustment
1514
- if (prop['chart.variant'] === '3d' && mouseXY) {
1515
- var adjustment = (prop['chart.variant.threed.angle'] * mouseXY[0]);
1516
- }
1517
-
1518
- // Set the top position
1519
- tooltip.style.left = 0;
1520
- tooltip.style.top = window.event.pageY - height - 5 + 'px';
1521
-
1522
-
1523
- // By default any overflow is hidden
1524
- tooltip.style.overflow = '';
1525
-
1526
- // LEFT edge
1527
- if (canvasXY[0] + mouseXY[0] - (width / 2) < 0) {
1528
- tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.1) + 'px';
1529
-
1530
- // RIGHT edge
1531
- } else if (canvasXY[0] + mouseXY[0] + (width / 2) > doc.body.offsetWidth) {
1532
- tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.9) + 'px';
1533
-
1534
- // Default positioning - CENTERED
1535
- } else {
1536
- tooltip.style.left = canvasXY[0] + mouseXY[0] - (width / 2) + 'px';
1537
- }
1538
- };*/
1539
-
1540
-
1541
-
1542
-
1543
- /**
1544
- * Returns the X coords for a value. Returns two coords because there are... two scales.
1545
- *
1546
- * @param number value The value to get the coord for
1547
- */
1548
- this.getXCoord = function (value)
1549
- {
1550
- if (value > this.max || value < 0) {
1551
- return null;
1552
- }
1553
-
1554
- var ret = [];
1555
-
1556
- // The offset into the graph area
1557
- var offset = ((value / this.max) * this.axisWidth);
1558
-
1559
- // Get the coords (one fo each side)
1560
- ret[0] = (this.gutterLeft + this.axisWidth) - offset;
1561
- ret[1] = (ca.width - this.gutterRight - this.axisWidth) + offset;
1562
-
1563
- return ret;
1564
- };
1565
-
1566
-
1567
-
1568
-
1569
- /**
1570
- * This allows for easy specification of gradients
1571
- */
1572
- this.parseColors = function ()
1573
- {
1574
- // Save the original colors so that they can be restored when the canvas is reset
1575
- if (this.original_colors.length === 0) {
1576
- this.original_colors['chart.colors'] = RG.array_clone(prop['chart.colors']);
1577
- this.original_colors['chart.highlight.stroke'] = RG.array_clone(prop['chart.highlight.fill']);
1578
- this.original_colors['chart.highlight.fill'] = RG.array_clone(prop['chart.highlight.fill']);
1579
- this.original_colors['chart.axis.color'] = RG.array_clone(prop['chart.axis.color']);
1580
- this.original_colors['chart.strokestyle'] = RG.array_clone(prop['chart.strokestyle']);
1581
- }
1582
-
1583
- var props = this.properties;
1584
- var colors = props['chart.colors'];
1585
-
1586
- for (var i=0; i<colors.length; ++i) {
1587
- colors[i] = this.parseSingleColorForGradient(colors[i]);
1588
- }
1589
-
1590
- props['chart.highlight.stroke'] = this.parseSingleColorForGradient(props['chart.highlight.stroke']);
1591
- props['chart.highlight.fill'] = this.parseSingleColorForGradient(props['chart.highlight.fill']);
1592
- props['chart.axis.color'] = this.parseSingleColorForGradient(props['chart.axis.color']);
1593
- props['chart.strokestyle'] = this.parseSingleColorForGradient(props['chart.strokestyle']);
1594
- };
1595
-
1596
-
1597
-
1598
-
1599
- /**
1600
- * Use this function to reset the object to the post-constructor state. Eg reset colors if
1601
- * need be etc
1602
- */
1603
- this.reset = function ()
1604
- {
1605
- };
1606
-
1607
-
1608
-
1609
-
1610
- /**
1611
- * This parses a single color value
1612
- */
1613
- this.parseSingleColorForGradient = function (color)
1614
- {
1615
- if (!color || typeof(color) != 'string') {
1616
- return color;
1617
- }
1618
-
1619
- if (color.match(/^gradient\((.*)\)$/i)) {
1620
-
1621
- var parts = RegExp.$1.split(':');
1622
-
1623
- // Create the gradient
1624
- var grad = co.createLinearGradient(prop['chart.gutter.left'],0,ca.width - prop['chart.gutter.right'],0);
1625
-
1626
- var diff = 1 / (parts.length - 1);
1627
-
1628
- grad.addColorStop(0, RG.trim(parts[0]));
1629
-
1630
- for (var j=1; j<parts.length; ++j) {
1631
- grad.addColorStop(j * diff, RG.trim(parts[j]));
1632
- }
1633
- }
1634
-
1635
- return grad ? grad : color;
1636
- };
1637
-
1638
-
1639
-
1640
-
1641
- /**
1642
- * Using a function to add events makes it easier to facilitate method chaining
1643
- *
1644
- * @param string type The type of even to add
1645
- * @param function func
1646
- */
1647
- this.on = function (type, func)
1648
- {
1649
- if (type.substr(0,2) !== 'on') {
1650
- type = 'on' + type;
1651
- }
1652
-
1653
- if (typeof this[type] !== 'function') {
1654
- this[type] = func;
1655
- } else {
1656
- RG.addCustomEventListener(this, type, func);
1657
- }
1658
-
1659
- return this;
1660
- };
1661
-
1662
-
1663
-
1664
-
1665
- //
1666
- // Draw the background grid
1667
- //
1668
- this.drawBackgroundGrid = function ()
1669
- {
1670
- if (prop['chart.background.grid']) {
1671
-
1672
- var variant = prop['chart.variant'],
1673
- color = prop['chart.background.grid.color'],
1674
- numvlines = prop['chart.labels.count'],
1675
- numhlines = this.left.length,
1676
- vlines = prop['chart.background.grid.vlines'],
1677
- hlines = prop['chart.background.grid.hlines'],
1678
- linewidth = prop['chart.background.grid.linewidth'];
1679
-
1680
- // Autofit
1681
- if (typeof prop['chart.background.grid.autofit.numhlines'] === 'number') {
1682
- numhlines = prop['chart.background.grid.autofit.numhlines'];
1683
- }
1684
-
1685
- if (typeof prop['chart.background.grid.autofit.numvlines'] === 'number') {
1686
- numvlines = prop['chart.background.grid.autofit.numvlines'];
1687
- }
1688
-
1689
- co.lineWidth = linewidth;
1690
-
1691
- // If it's a bar and 3D variant, translate
1692
- if (variant == '3d') {
1693
- co.save();
1694
- co.translate(
1695
- prop['chart.variant.threed.offsetx'],
1696
- -1 * prop['chart.variant.threed.offsety']
1697
- );
1698
- }
1699
-
1700
- // Draw vertical grid lines for the left side
1701
- if (vlines) {
1702
- for (var i=0; i<=numvlines; i+=1) {
1703
- pa2(co,
1704
- 'b m % % l % % s %',
1705
- this.gutterLeft + (this.axisWidth / numvlines) * i, this.gutterTop,
1706
- this.gutterLeft + (this.axisWidth / numvlines) * i, this.gutterTop + this.axisHeight,
1707
- color
1708
- );
1709
-
1710
- }
1711
- }
1712
-
1713
- // Draw horizontal grid lines for the left side
1714
- if (hlines) {
1715
- for (var i=0; i<=numhlines; i+=1) {
1716
- pa2(co,
1717
- 'b m % % l % % s %',
1718
- this.gutterLeft, this.gutterTop + (this.axisHeight / numhlines) * i,
1719
- this.gutterLeft + this.axisWidth, this.gutterTop + (this.axisHeight / numhlines) * i,
1720
- color
1721
- );
1722
- }
1723
- }
1724
-
1725
-
1726
- // Draw vertical grid lines for the right side
1727
- if (vlines) {
1728
- for (var i=0; i<=numvlines; i+=1) {
1729
- pa2(co,
1730
- 'b m % % l % % s %',
1731
- this.gutterLeft + this.gutterCenter + this.axisWidth + (this.axisWidth / numvlines) * i, this.gutterTop,
1732
- this.gutterLeft + this.gutterCenter + this.axisWidth + (this.axisWidth / numvlines) * i, this.gutterTop + this.axisHeight,
1733
- color
1734
- );
1735
- }
1736
- }
1737
-
1738
- // Draw horizontal grid lines for the right side
1739
- if (hlines) {
1740
- for (var i=0; i<=numhlines; i+=1) {
1741
- pa2(co,
1742
- 'b m % % l % % s %',
1743
- this.gutterLeft + this.axisWidth + this.gutterCenter, this.gutterTop + (this.axisHeight / numhlines) * i,
1744
- this.gutterLeft + this.axisWidth + this.gutterCenter + this.axisWidth, this.gutterTop + (this.axisHeight / numhlines) * i,
1745
- color
1746
- );
1747
- }
1748
- }
1749
-
1750
-
1751
- // If it's a bar and 3D variant, translate
1752
- if (variant == '3d') {
1753
- co.restore();
1754
- }
1755
- }
1756
- };
1757
-
1758
-
1759
-
1760
-
1761
- /**
1762
- * This function runs once only
1763
- * (put at the end of the file (before any effects))
1764
- */
1765
- this.firstDrawFunc = function ()
1766
- {
1767
- // Tooltips need reversing now because the bars
1768
- // are drawn from the bottom up
1769
- if (prop['chart.tooltips']) {
1770
- prop['chart.tooltips'] = RG.arrayReverse(prop['chart.tooltips']);
1771
- }
1772
- };
1773
-
1774
-
1775
-
1776
-
1777
-
1778
-
1779
-
1780
-
1781
- /**
1782
- * Objects are now always registered so that when RGraph.Redraw()
1783
- * is called this chart will be redrawn.
1784
- */
1785
- RG.Register(this);
1786
-
1787
-
1788
-
1789
-
1790
- /**
1791
- * This is the 'end' of the constructor so if the first argument
1792
- * contains configuration dsta - handle that.
1793
- */
1794
- if (parseConfObjectForOptions) {
1795
- RG.parseObjectStyleConfig(this, conf.options);
1796
- }
1797
-
1798
-
1799
-
1800
-
1801
- /**
1802
- * Grow
1803
- *
1804
- * The Bipolar chart Grow effect gradually increases the values of the bars
1805
- *
1806
- * @param object An object of options - eg: {frames: 30}
1807
- * @param function A function to call when the effect is complete
1808
- */
1809
- this.grow = function ()
1810
- {
1811
- // Callback
1812
- var opt = arguments[0] || {};
1813
- var frames = opt.frames || 30;
1814
- var frame = 0;
1815
- var callback = arguments[1] || function () {};
1816
- var obj = this;
1817
-
1818
- // Save the data
1819
- var originalLeft = RG.arrayClone(this.left);
1820
- var originalRight = RG.arrayClone(this.right);
1821
-
1822
-
1823
- // Stop the scale from changing by setting xmax (if it's not already set)
1824
- if (RG.isNull(prop['chart.xmax'])) {
1825
-
1826
- var xmax = 0;
1827
-
1828
- // Go through the left and right data
1829
- for (var i=0; i<this.left.length; i+=1) { xmax = ma.max(xmax, ma.abs(this.left[i])); }
1830
- for (var i=0; i<this.right.length; i+=1) { xmax = ma.max(xmax, ma.abs(this.right[i])); }
1831
-
1832
- var scale = RG.getScale2(obj, {'max':xmax});
1833
- this.Set('chart.xmax', scale.max);
1834
- }
1835
-
1836
-
1837
-
1838
-
1839
-
1840
-
1841
-
1842
-
1843
-
1844
-
1845
-
1846
-
1847
- var iterator = function ()
1848
- {
1849
- var easingMultiplier = RG.Effects.getEasingMultiplier(frames, frame);
1850
-
1851
- for (var i=0; i<obj.left.length; i+=1) { obj.left[i] = easingMultiplier * originalLeft[i]; }
1852
- for (var i=0; i<obj.right.length; i+=1) { obj.right[i] = easingMultiplier * originalRight[i]; }
1853
-
1854
- RG.redrawCanvas(obj.canvas);
1855
-
1856
- // Repeat or call the end function if one is defined
1857
- if (frame < frames) {
1858
- frame += 1;
1859
- RG.Effects.updateCanvas(iterator);
1860
- } else {
1861
- callback(obj);
1862
- }
1863
- };
1864
-
1865
- iterator();
1866
-
1867
- return this;
1868
- };
1869
-
1870
-
1871
-
1872
-
1873
- /**
1874
- * Bipolar chart Wave effect.
1875
- *
1876
- * @param object OPTIONAL An object map of options. You specify 'frames' here to give the number of frames in the effect
1877
- * @param function OPTIONAL A function that will be called when the effect is complete
1878
- */
1879
- this.wave = function ()
1880
- {
1881
- var obj = this,
1882
- opt = arguments[0] || {};
1883
- opt.frames = opt.frames || 60;
1884
- opt.startFrames_left = [];
1885
- opt.startFrames_right = [];
1886
- opt.counters_left = [];
1887
- opt.counters_right = [];
1888
-
1889
- var framesperbar = opt.frames / 3,
1890
- frame_left = -1,
1891
- frame_right = -1,
1892
- callback = arguments[1] || function () {},
1893
- original_left = RG.arrayClone(obj.left),
1894
- original_right = RG.arrayClone(obj.right);
1895
-
1896
- for (var i=0,len=obj.left.length; i<len; i+=1) {
1897
- opt.startFrames_left[i] = ((opt.frames / 2) / (obj.left.length - 1)) * i;
1898
- opt.startFrames_right[i] = ((opt.frames / 2) / (obj.right.length - 1)) * i;
1899
- opt.counters_left[i] = 0;
1900
- opt.counters_right[i] = 0;
1901
- }
1902
-
1903
- // This stops the chart from jumping
1904
- obj.draw();
1905
- obj.set('xmax', obj.scale2.max);
1906
- RG.clear(obj.canvas);
1907
-
1908
-
1909
- // Zero all of the data
1910
- for (var i=0,len=obj.left.length; i<len; i+=1) {
1911
- if (typeof obj.left[i] === 'number') obj.left[i] = 0;
1912
- if (typeof obj.right[i] === 'number') obj.right[i] = 0;
1913
- }
1914
-
1915
- //
1916
- // Iterate over the left side
1917
- //
1918
- function iteratorLeft ()
1919
- {
1920
- ++frame_left;
1921
-
1922
- for (var i=0,len=obj.left.length; i<len; i+=1) {
1923
- if (frame_left > opt.startFrames_left[i]) {
1924
-
1925
- var isNull = RG.isNull(obj.left[i]);
1926
-
1927
- obj.left[i] = ma.min(
1928
- ma.abs(original_left[i]),
1929
- ma.abs(original_left[i] * ( (opt.counters_left[i]++) / framesperbar))
1930
- );
1931
-
1932
- // Make the number negative if the original was
1933
- if (original_left[i] < 0) {
1934
- obj.left[i] *= -1;
1935
- }
1936
-
1937
- if (isNull) {
1938
- obj.left[i] = null;
1939
- }
1940
- } else {
1941
- obj.left[i] = typeof obj.left[i] === 'object' && obj.left[i] ? RG.arrayPad([], obj.left[i].length, 0) : (RG.isNull(obj.left[i]) ? null : 0);
1942
- }
1943
-
1944
- }
1945
-
1946
-
1947
- // No callback here - only called by the right function
1948
- if (frame_left < opt.frames) {
1949
- RG.redrawCanvas(obj.canvas);
1950
- RG.Effects.updateCanvas(iteratorLeft);
1951
- }
1952
- }
1953
-
1954
-
1955
-
1956
-
1957
- //
1958
- // Iterate over the right side
1959
- //
1960
- function iteratorRight ()
1961
- {
1962
- ++frame_right;
1963
-
1964
- for (var i=0,len=obj.right.length; i<len; i+=1) {
1965
- if (frame_right > opt.startFrames_right[i]) {
1966
-
1967
- var isNull = RG.isNull(obj.right[i]);
1968
-
1969
- obj.right[i] = ma.min(
1970
- ma.abs(original_right[i]),
1971
- ma.abs(original_right[i] * ( (opt.counters_right[i]++) / framesperbar))
1972
- );
1973
-
1974
- // Make the number negative if the original was
1975
- if (original_right[i] < 0) {
1976
- obj.right[i] *= -1;
1977
- }
1978
-
1979
- if (isNull) {
1980
- obj.right[i] = null;
1981
- }
1982
-
1983
- } else {
1984
- obj.right[i] = typeof obj.right[i] === 'object' && obj.right[i] ? RG.arrayPad([], obj.right[i].length, 0) : (RG.isNull(obj.right[i]) ? null : 0);
1985
- }
1986
- }
1987
-
1988
-
1989
- // No callback here - only called by the right function
1990
- if (frame_right < opt.frames) {
1991
- RG.redrawCanvas(obj.canvas);
1992
- RG.Effects.updateCanvas(iteratorRight);
1993
- } else {
1994
- callback(this);
1995
- }
1996
- }
1997
-
1998
-
1999
-
2000
-
2001
- iteratorLeft();
2002
- iteratorRight();
2003
-
2004
- return this;
2005
- };
2006
- };
2
+ RGraph=window.RGraph||{isRGraph:true};RGraph.Bipolar=function(conf)
3
+ {if(typeof conf==='object'&&typeof conf.left==='object'&&typeof conf.right==='object'&&typeof conf.id==='string'){var id=conf.id,canvas=document.getElementById(id),left=conf.left,right=conf.right,parseConfObjectForOptions=true}else{var id=conf,canvas=document.getElementById(id),left=arguments[1],right=arguments[2]}
4
+ this.id=id;this.canvas=canvas;this.context=this.canvas.getContext('2d');this.canvas.__object__=this;this.type='bipolar';this.coords=[];this.coords2=[];this.coordsLeft=[];this.coordsRight=[];this.coords2Left=[];this.coords2Right=[];this.max=0;this.isRGraph=true;this.uid=RGraph.CreateUID();this.canvas.uid=this.canvas.uid?this.canvas.uid:RGraph.CreateUID();this.coordsText=[];this.original_colors=[];this.firstDraw=true;var data=[left,right];for(var i=0;i<2;++i){data[i].forEach(function(v,k,arr)
5
+ {if(RGraph.isNull(v)){}else if(typeof v==='object'){v.forEach(function(v2,k2,arr2)
6
+ {arr[k][k2]=parseFloat(v2);});}else{arr[k]=parseFloat(v);}
7
+ arr[k]=RGraph.stringsToNumbers(arr[k]);});}
8
+ this.left=left;this.right=right;this.data=[left,right];this.properties={'chart.background.grid':true,'chart.background.grid.color':'#ddd','chart.background.grid.vlines':true,'chart.background.grid.hlines':true,'chart.background.grid.linewidth':1,'chart.background.grid.autofit.numvlines':null,'chart.background.grid.autofit.numhlines':null,'chart.margin':5,'chart.margin.grouped':3,'chart.xtickinterval':null,'chart.labels':[],'chart.labels.color':null,'chart.labels.above':false,'chart.labels.above.font':null,'chart.labels.above.size':null,'chart.labels.above.bold':null,'chart.labels.above.italic':null,'chart.labels.above.color':null,'chart.labels.above.units.pre':null,'chart.labels.above.units.post':null,'chart.labels.above.decimals':null,'chart.labels.above.formatter':null,'chart.text.bold':false,'chart.text.italic':false,'chart.text.size':12,'chart.text.color':'black','chart.text.font':'Segoe UI, Arial, Verdana, sans-serif','chart.text.accessible':true,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':true,'chart.title':null,'chart.title.font':null,'chart.title.size':null,'chart.title.bold':null,'chart.title.italic':null,'chart.title.color':null,'chart.title.left':null,'chart.title.left.font':null,'chart.title.left.size':null,'chart.title.left.bold':false,'chart.title.left.italic':false,'chart.title.left.color':null,'chart.title.right':null,'chart.title.right.font':null,'chart.title.right.size':null,'chart.title.right.bold':false,'chart.title.right.italic':false,'chart.title.right.color':null,'chart.gutter.center':0,'chart.gutter.center.autosize':true,'chart.gutter.left':25,'chart.gutter.right':25,'chart.gutter.top':25,'chart.gutter.bottom':30,'chart.title':null,'chart.title.background':null,'chart.title.hpos':null,'chart.title.vpos':null,'chart.title.bold':true,'chart.title.font':null,'chart.title.x':null,'chart.title.y':null,'chart.title.halign':null,'chart.title.valign':null,'chart.colors':['#afa','#faa','#aaf','#aff','#ffa','#faf','cyan','brown','gray','black','pink','#afa','#faa','#aaf','#aff','#ffa','#faf','cyan','brown','gray','black','pink'],'chart.colors.sequential':false,'chart.contextmenu':null,'chart.tooltips':null,'chart.tooltips.effect':'fade','chart.tooltips.css.class':'RGraph_tooltip','chart.tooltips.highlight':true,'chart.tooltips.event':'onclick','chart.highlight.stroke':'rgba(0,0,0,0)','chart.highlight.fill':'rgba(255,255,255,0.7)','chart.units.pre':'','chart.units.post':'','chart.shadow':false,'chart.shadow.color':'#ccc','chart.shadow.offsetx':3,'chart.shadow.offsety':3,'chart.shadow.blur':3,'chart.annotatable':false,'chart.annotate.color':'black','chart.xmax':null,'chart.xmin':0,'chart.scale.zerostart':true,'chart.scale.decimals':null,'chart.scale.point':'.','chart.scale.thousand':',','chart.axis.color':'black','chart.zoom.factor':1.5,'chart.zoom.fade.in':true,'chart.zoom.fade.out':true,'chart.zoom.hdir':'right','chart.zoom.vdir':'down','chart.zoom.frames':25,'chart.zoom.delay':16.666,'chart.zoom.shadow':true,'chart.zoom.background':true,'chart.zoom.action':'zoom','chart.resizable':false,'chart.resize.handle.background':null,'chart.strokestyle':'rgba(0,0,0,0)','chart.events.mousemove':null,'chart.events.click':null,'chart.linewidth':1,'chart.noaxes':false,'chart.noxaxis':false,'chart.noyaxis':false,'chart.xlabels':true,'chart.numyticks':null,'chart.numxticks':5,'chart.axis.linewidth':1,'chart.labels.count':5,'chart.variant.threed.offsetx':10,'chart.variant.threed.offsety':5,'chart.variant.threed.angle':0.1,'chart.grouping':'grouped','chart.clearto':'rgba(0,0,0,0)'}
9
+ this.properties['chart.numyticks']=this.left.length;var linear_data=RGraph.arrayLinearize(this.left,this.right);for(var i=0;i<linear_data.length;++i){this['$'+i]={};}
10
+ if(!this.canvas.__rgraph_aa_translated__){this.context.translate(0.5,0.5);this.canvas.__rgraph_aa_translated__=true;}
11
+ var RG=RGraph,ca=this.canvas,co=ca.getContext('2d'),prop=this.properties,pa2=RG.path2,win=window,doc=document,ma=Math
12
+ if(RG.Effects&&typeof RG.Effects.decorate==='function'){RG.Effects.decorate(this);}
13
+ this.set=this.Set=function(name)
14
+ {var value=typeof arguments[1]==='undefined'?null:arguments[1];if(arguments.length===1&&typeof name==='object'){RG.parseObjectStyleConfig(this,name);return this;}
15
+ if(name.substr(0,6)!='chart.'){name='chart.'+name;}
16
+ while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
17
+ if(name==='chart.vmargin'){name='chart.margin';}
18
+ if(name==='chart.vmargin.grouped'){name='chart.margin.grouped';}
19
+ prop[name]=value;return this;};this.get=this.Get=function(name)
20
+ {if(name.substr(0,6)!='chart.'){name='chart.'+name;}
21
+ while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
22
+ return this.properties[name.toLowerCase()];};this.draw=this.Draw=function()
23
+ {RG.fireCustomEvent(this,'onbeforedraw');if(!this.colorsParsed){this.parseColors();this.colorsParsed=true;}
24
+ this.gutterLeft=prop['chart.gutter.left'];this.gutterRight=prop['chart.gutter.right'];this.gutterTop=prop['chart.gutter.top'];this.gutterBottom=prop['chart.gutter.bottom'];if(prop['chart.gutter.center.autosize']&&!prop['chart.gutter.center']){prop['chart.gutter.center']=this.getGutterCenter();}
25
+ this.gutterCenter=prop['chart.gutter.center'];this.left=this.data[0];this.right=this.data[1];this.coords=[];this.coords2=[];this.coordsLeft=[];this.coordsRight=[];this.coords2Left=[];this.coords2Right=[];this.coordsText=[];if(prop['chart.variant']==='3d'){if(prop['chart.text.accessible']){}else{co.setTransform(1,prop['chart.variant.threed.angle'],0,1,0.5,0.5);}}
26
+ this.axisWidth=(ca.width-prop['chart.gutter.center']-this.gutterLeft-this.gutterRight)/2;this.axisHeight=ca.height-this.gutterTop-this.gutterBottom;this.sequentialFullIndex=0;this.getMax();this.drawBackgroundGrid();this.draw3DAxes();this.drawAxes();this.drawTicks();this.drawLeftBars();this.drawRightBars();this.drawLeftBars({shadow:false});this.drawRightBars({shadow:false});this.drawAxes();this.drawLabels();this.drawTitles();if(prop['chart.contextmenu']){RG.ShowContext(this);}
27
+ if(prop['chart.resizable']){RG.AllowResizing(this);}
28
+ RG.InstallEventListeners(this);if(this.firstDraw){this.firstDraw=false;RG.fireCustomEvent(this,'onfirstdraw');this.firstDrawFunc();}
29
+ RG.FireCustomEvent(this,'ondraw');return this;};this.exec=function(func)
30
+ {func(this);return this;};this.draw3DAxes=function()
31
+ {if(prop['chart.variant']==='3d'){var offsetx=prop['chart.variant.threed.offsetx'],offsety=prop['chart.variant.threed.offsety'];co.lineWidth=prop['chart.axis.linewidth']+0.001;co.beginPath();co.strokeStyle=prop['chart.axis.color'];pa2(co,'b m % % l % % l % % l % % s #aaa f #ddd',this.gutterLeft,ma.round(ca.height-this.gutterBottom),this.gutterLeft+offsetx,ma.round(ca.height-this.gutterBottom-offsety),this.gutterLeft+offsetx+this.axisWidth,ma.round(ca.height-this.gutterBottom-offsety),this.gutterLeft+this.axisWidth,ma.round(ca.height-this.gutterBottom));this.draw3DLeftVerticalAxis();pa2(co,'b m % % l % % l % % l % % s #aaa f #ddd',this.gutterLeft+this.gutterCenter+this.axisWidth,ma.round(ca.height-this.gutterBottom),this.gutterLeft+this.gutterCenter+this.axisWidth+offsetx,ma.round(ca.height-this.gutterBottom-offsety),this.gutterLeft+this.gutterCenter+this.axisWidth+this.axisWidth+offsetx,ma.round(ca.height-this.gutterBottom-offsety),this.gutterLeft+this.gutterCenter+this.axisWidth+this.axisWidth,ma.round(ca.height-this.gutterBottom));pa2(co,'b m % % l % % l % % l % % s #aaa f #ddd',this.gutterLeft+this.gutterCenter+this.axisWidth,ca.height-this.gutterBottom,this.gutterLeft+this.gutterCenter+this.axisWidth,ca.height-this.gutterBottom-this.axisHeight,this.gutterLeft+this.gutterCenter+this.axisWidth+offsetx,ca.height-this.gutterBottom-this.axisHeight-offsety,this.gutterLeft+this.gutterCenter+this.axisWidth+offsetx,ca.height-this.gutterBottom-offsety);}}
32
+ this.draw3DLeftVerticalAxis=function()
33
+ {if(prop['chart.variant']==='3d'){var offsetx=prop['chart.variant.threed.offsetx'],offsety=prop['chart.variant.threed.offsety'];pa2(co,'b m % % l % % l % % l % % s #aaa f #ddd',this.gutterLeft+this.axisWidth,this.gutterTop,this.gutterLeft+this.axisWidth+offsetx,this.gutterTop-offsety,this.gutterLeft+this.axisWidth+offsetx,ca.height-this.gutterBottom-offsety,this.gutterLeft+this.axisWidth,ca.height-this.gutterBottom);}};this.drawAxes=this.DrawAxes=function()
34
+ {co.lineWidth=prop['chart.axis.linewidth']+0.001;co.beginPath();co.strokeStyle=prop['chart.axis.color'];this.axisWidth=(ca.width-prop['chart.gutter.center']-this.gutterLeft-this.gutterRight)/2;this.axisHeight=ca.height-this.gutterTop-this.gutterBottom;if(prop['chart.noaxes']){return;}
35
+ if(!prop['chart.noxaxis']){co.moveTo(this.gutterLeft,ma.round(ca.height-this.gutterBottom));co.lineTo(this.gutterLeft+this.axisWidth,ma.round(ca.height-this.gutterBottom));}
36
+ if(!prop['chart.noyaxis']){co.moveTo(ma.round(this.gutterLeft+this.axisWidth),ca.height-this.gutterBottom);co.lineTo(ma.round(this.gutterLeft+this.axisWidth),this.gutterTop);}
37
+ co.stroke();co.beginPath();var x=this.gutterLeft+this.axisWidth+prop['chart.gutter.center'];if(!prop['chart.noyaxis']){co.moveTo(ma.round(x),this.gutterTop);co.lineTo(ma.round(x),ca.height-this.gutterBottom);}
38
+ if(!prop['chart.noxaxis']){co.moveTo(ma.round(x),ma.round(ca.height-this.gutterBottom));co.lineTo(ca.width-this.gutterRight,ma.round(ca.height-this.gutterBottom));}
39
+ co.stroke();};this.drawTicks=this.DrawTicks=function()
40
+ {co.lineWidth=prop['chart.axis.linewidth']+0.001;var numDataPoints=this.left.length;var barHeight=((ca.height-this.gutterTop-this.gutterBottom)-(this.left.length*(prop['chart.margin']*2)))/numDataPoints;this.barHeight=barHeight;if(prop['chart.noaxes']){return;}
41
+ if(!prop['chart.noyaxis']&&prop['chart.numyticks']>0){co.beginPath();for(var i=0;i<prop['chart.numyticks'];++i){var y=prop['chart.gutter.top']+(((ca.height-this.gutterTop-this.gutterBottom)/prop['chart.numyticks'])*i);co.moveTo(this.gutterLeft+this.axisWidth,y);co.lineTo(this.gutterLeft+this.axisWidth+3,y);}
42
+ co.stroke();co.beginPath();for(var i=0;i<prop['chart.numyticks'];++i){var y=prop['chart.gutter.top']+(((ca.height-this.gutterTop-this.gutterBottom)/prop['chart.numyticks'])*i);co.moveTo(this.gutterLeft+this.axisWidth+prop['chart.gutter.center'],y);co.lineTo(this.gutterLeft+this.axisWidth+prop['chart.gutter.center']-3,y);}
43
+ co.stroke();if(prop['chart.noxaxis']){pa2(co,'b m % % l % % s %',ma.round(this.gutterLeft+this.axisWidth),ca.height-this.gutterBottom,ma.round(this.gutterLeft+this.axisWidth+4),(ca.height-this.gutterBottom),co.strokeStyle);pa2(co,'b m % % l % % s %',ma.round(this.gutterLeft+this.axisWidth+prop['chart.gutter.center']),ca.height-this.gutterBottom,ma.round(this.gutterLeft+this.axisWidth+prop['chart.gutter.center'])-4,(ca.height-this.gutterBottom),co.strokeStyle);}}
44
+ if(!prop['chart.noxaxis']&&prop['chart.numxticks']>0){var xInterval=this.axisWidth/prop['chart.numxticks'];if(typeof(prop['chart.xtickinterval'])=='number'){xInterval=prop['chart.xtickinterval'];}
45
+ for(i=this.gutterLeft;i<(this.gutterLeft+this.axisWidth);i+=xInterval){co.beginPath();co.moveTo(ma.round(i),ca.height-this.gutterBottom);co.lineTo(ma.round(i),(ca.height-this.gutterBottom)+4);co.closePath();co.stroke();}
46
+ var stoppingPoint=ca.width-this.gutterRight;for(i=(this.gutterLeft+this.axisWidth+prop['chart.gutter.center']+xInterval);i<=stoppingPoint;i+=xInterval){co.beginPath();co.moveTo(ma.round(i),ca.height-this.gutterBottom);co.lineTo(ma.round(i),(ca.height-this.gutterBottom)+4);co.closePath();co.stroke();}
47
+ if(prop['chart.noyaxis']){pa2(co,'b m % % l % % s %',ma.round(this.gutterLeft+this.axisWidth),ca.height-this.gutterBottom,ma.round(this.gutterLeft+this.axisWidth),(ca.height-this.gutterBottom)+4,co.strokeStyle);pa2(co,'b m % % l % % s %',ma.round(this.gutterLeft+this.axisWidth+prop['chart.gutter.center']),ca.height-this.gutterBottom,ma.round(this.gutterLeft+this.axisWidth+prop['chart.gutter.center']),(ca.height-this.gutterBottom)+4,co.strokeStyle);}}};this.getMax=this.GetMax=function()
48
+ {var dec=prop['chart.scale.decimals'];if(prop['chart.xmax']){var max=prop['chart.xmax'];var min=prop['chart.xmin'];this.scale2=RG.getScale2(this,{max:max,min:min,strict:true,'scale.thousand':prop['chart.scale.thousand'],'scale.point':prop['chart.scale.point'],'scale.decimals':prop['chart.scale.decimals'],'ylabels.count':prop['chart.labels.count'],'scale.round':prop['chart.scale.round'],'units.pre':prop['chart.units.pre'],'units.post':prop['chart.units.post']});this.max=this.scale2.max;this.min=this.scale2.min;}else{var max=1;for(var i=0;i<this.left.length;++i){if(typeof this.left[i]==='number'){max=ma.max(max,this.left[i]);}else if(RG.isNull(this.left[i])){}else{max=ma.max(max,prop['chart.grouping']==='stacked'?RG.arraySum(this.left[i]):RG.arrayMax(this.left[i]));}}
49
+ for(var i=0;i<this.right.length;++i){if(typeof this.right[i]==='number'){max=ma.max(max,this.right[i]);}else if(RG.isNull(this.right[i])){}else{max=ma.max(max,prop['chart.grouping']==='stacked'?RG.arraySum(this.right[i]):RG.arrayMax(this.right[i]));}}
50
+ this.scale2=RG.getScale2(this,{max:max,min:prop['chart.xmin'],'scale.thousand':prop['chart.scale.thousand'],'scale.point':prop['chart.scale.point'],'scale.decimals':prop['chart.scale.decimals'],'ylabels.count':prop['chart.labels.count'],'scale.round':prop['chart.scale.round'],'units.pre':prop['chart.units.pre'],'units.post':prop['chart.units.post']});this.max=this.scale2.max;this.min=this.scale2.min;}};this.drawLeftBars=this.DrawLeftBars=function()
51
+ {var opt={};if(typeof arguments[0]==='object'){opt.shadow=arguments[0].shadow;}else{opt.shadow=true;}
52
+ var offsetx=prop['chart.variant.threed.offsetx'],offsety=prop['chart.variant.threed.offsety'];co.strokeStyle=prop['chart.strokestyle'];co.lineWidth=prop['chart.linewidth'];for(var i=0,sequentialColorIndex=0;i<this.left.length;++i){if(prop['chart.shadow']&&prop['chart.variant']!=='3d'&&opt.shadow){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];}
53
+ if(typeof this.left[i]==='number'){if(prop['chart.colors.sequential']){co.fillStyle=prop['chart.colors'][sequentialColorIndex];}else{co.fillStyle=prop['chart.colors'][0];}
54
+ var width=(((this.left[i]-this.min)/(this.max-this.min))*this.axisWidth);var coords=[ma.round(this.gutterLeft+this.axisWidth-width),ma.round(this.gutterTop+(i*(this.axisHeight/this.left.length))+prop['chart.margin']),width,this.barHeight];if(this.left[i]!==null){co.strokeRect(coords[0],coords[1],coords[2],coords[3]);co.fillRect(coords[0],coords[1],coords[2],coords[3]);}
55
+ if(prop['chart.variant']==='3d'&&this.left[i]!==null){if(prop['chart.shadow']&&opt.shadow){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];pa2(co,'b m % % l % % l % % l % % f black sc rgba(0,0,0,0) sx 0 sy 0 sb 0',coords[0]+offsetx,coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety+coords[3],coords[0]+offsetx,coords[1]-offsety+coords[3]);}
56
+ if(prop['chart.colors.sequential']){co.fillStyle=prop['chart.colors'][i];}else{co.fillStyle=prop['chart.colors'][0];}
57
+ pa2(co,'b m % % l % % l % % l % % f %',coords[0],coords[1],coords[0]+offsetx,coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety,coords[0]+coords[2],coords[1]);pa2(co,'b m % % l % % l % % l % % f rgba(255,255,255,0.4)',coords[0],coords[1],coords[0]+offsetx,coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety,coords[0]+coords[2],coords[1]);}
58
+ if(!opt.shadow){this.coords.push([coords[0],coords[1],coords[2],coords[3]]);this.coordsLeft.push([coords[0],coords[1],coords[2],coords[3]]);}
59
+ sequentialColorIndex++;}else if(typeof this.left[i]==='object'&&prop['chart.grouping']==='stacked'){for(var j=0,accumulatedWidth=0;j<this.left[i].length;++j){if(prop['chart.colors.sequential']){co.fillStyle=prop['chart.colors'][sequentialColorIndex];}else{co.fillStyle=prop['chart.colors'][j];}
60
+ var value=this.left[i][j],min=this.min,max=this.max,margin=prop['chart.margin'],width=(((value-min)/(max-min))*this.axisWidth),sectionHeight=ma.round((this.axisHeight/this.left.length)),height=ma.round((sectionHeight-(2*margin))),x=ma.round(this.gutterLeft+this.axisWidth-width-accumulatedWidth),y=ma.round(this.gutterTop+margin+(i*sectionHeight));accumulatedWidth+=width;if(this.left[i]!==null){co.strokeRect(x,y,width,height);co.fillRect(x,y,width,height);}
61
+ if(prop['chart.variant']==='3d'&&this.left[i]!==null){if(prop['chart.shadow']&&opt.shadow){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];pa2(co,'b m % % l % % l % % l % % f black sc rgba(0,0,0,0) sx 0 sy 0 sb 0',x+offsetx,y-offsety,x+offsetx+width,y-offsety,x+offsetx+width,y-offsety+height,x+offsetx,y-offsety+height);}
62
+ if(prop['chart.colors.sequential']){co.fillStyle=prop['chart.colors'][sequentialColorIndex];}else{co.fillStyle=prop['chart.colors'][j];}
63
+ pa2(co,'b m % % l % % l % % l % % f %',x,y,x+offsetx,y-offsety,x+offsetx+width,y-offsety,x+width,y);pa2(co,'b m % % l % % l % % l % % f rgba(255,255,255,0.4)',x,y,x+offsetx,y-offsety,x+offsetx+width,y-offsety,x+width,y);}
64
+ if(!opt.shadow){this.coords.push([x,y,width,height]);this.coordsLeft.push([x,y,width,height]);if(!RG.isArray(this.coords2[i])){this.coords2[i]=[];}
65
+ this.coords2[i].push([x,y,width,height]);if(!RG.isArray(this.coords2Left[i])){this.coords2Left[i]=[];}
66
+ this.coords2Left[i].push([x,y,width,height]);}
67
+ sequentialColorIndex++;}}else if(typeof this.left[i]==='object'&&!RG.isNull(this.left[i])){for(var j=0;j<this.left[i].length;++j){if(prop['chart.colors.sequential']){co.fillStyle=prop['chart.colors'][sequentialColorIndex];}else{co.fillStyle=prop['chart.colors'][j];}
68
+ var value=this.left[i][j],min=this.min,max=this.max,margin=prop['chart.margin'],marginGrouped=prop['chart.margin.grouped'],width=(((value-min)/(max-min))*this.axisWidth),sectionHeight=ma.round((this.axisHeight/this.left.length)),height=ma.round((sectionHeight-(2*margin)-(2*marginGrouped))/this.left[i].length),x=ma.round(this.gutterLeft+this.axisWidth-width),y=ma.round(this.gutterTop+margin+(i*sectionHeight)+(height*j)+(j*marginGrouped));if(this.left[i]!==null){co.strokeRect(x,y,width,height);co.fillRect(x,y,width,height);}
69
+ if(prop['chart.variant']==='3d'&&this.left[i]!==null){if(prop['chart.shadow']&&opt.shadow){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];pa2(co,'b m % % l % % l % % l % % f black sc rgba(0,0,0,0) sx 0 sy 0 sb 0',x+offsetx,y-offsety,x+offsetx+width,y-offsety,x+offsetx+width,y-offsety+height,x+offsetx,y-offsety+height);}
70
+ if(prop['chart.colors.sequential']){co.fillStyle=prop['chart.colors'][sequentialColorIndex];}else{co.fillStyle=prop['chart.colors'][j];}
71
+ pa2(co,'b m % % l % % l % % l % % f %',x,y,x+offsetx,y-offsety,x+offsetx+width,y-offsety,x+width,y);pa2(co,'b m % % l % % l % % l % % f rgba(255,255,255,0.4)',x,y,x+offsetx,y-offsety,x+offsetx+width,y-offsety,x+width,y);}
72
+ if(!opt.shadow){this.coords.push([x,y,width,height]);this.coordsLeft.push([x,y,width,height]);if(!RG.isArray(this.coords2[i])){this.coords2[i]=[];}
73
+ this.coords2[i].push([x,y,width,height]);if(!RG.isArray(this.coords2Left[i])){this.coords2Left[i]=[];}
74
+ this.coords2Left[i].push([x,y,width,height]);}
75
+ sequentialColorIndex++;}}
76
+ this.draw3DLeftVerticalAxis();}
77
+ RG.noShadow(this);co.lineWidth=1;};this.drawRightBars=this.DrawRightBars=function()
78
+ {var opt={};if(typeof arguments[0]==='object'){opt.shadow=arguments[0].shadow;}else{opt.shadow=true;}
79
+ var offsetx=prop['chart.variant.threed.offsetx'],offsety=prop['chart.variant.threed.offsety'];co.strokeStyle=prop['chart.strokestyle'];co.lineWidth=prop['chart.linewidth'];if(prop['chart.shadow']&&prop['chart.variant']!=='3d'&&opt.shadow){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];}
80
+ for(var i=0,sequentialColorIndex=this.left.length;i<this.right.length;++i){if(typeof this.right[i]==='number'){if(prop['chart.colors.sequential']){co.fillStyle=prop['chart.colors'][sequentialColorIndex];}else{co.fillStyle=prop['chart.colors'][0];}
81
+ var width=(((this.right[i]-this.min)/(this.max-this.min))*this.axisWidth);var coords=[ma.round(this.gutterLeft+this.axisWidth+prop['chart.gutter.center']),ma.round(prop['chart.margin']+(i*(this.axisHeight/this.right.length))+this.gutterTop),width,this.barHeight];if(this.right[i]!==null){co.strokeRect(ma.round(coords[0]),Math.round(coords[1]),coords[2],coords[3]);co.fillRect(ma.round(coords[0]),Math.round(coords[1]),coords[2],coords[3]);}
82
+ if(prop['chart.variant']==='3d'&&this.right[i]!==null){var color=co.fillStyle;if(prop['chart.shadow']&&opt.shadow){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];pa2(co,'b m % % l % % l % % l % % f black sc rgba(0,0,0,0) sx 0 sy 0 sb 0',coords[0]+offsetx,coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety+coords[3],coords[0]+offsetx,coords[1]-offsety+coords[3]);}
83
+ pa2(co,'b m % % l % % l % % l % % f %',coords[0],coords[1],coords[0]+offsetx,coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety,coords[0]+coords[2],coords[1],color);pa2(co,'b m % % l % % l % % l % % f %',coords[0]+coords[2],coords[1],coords[0]+coords[2]+offsetx,coords[1]-offsety,coords[0]+coords[2]+offsetx,coords[1]-offsety+coords[3],coords[0]+coords[2],coords[1]+coords[3],color);pa2(co,'b m % % l % % l % % l % % f rgba(255,255,255,0.6)',coords[0],coords[1],coords[0]+offsetx,coords[1]-offsety,coords[0]+offsetx+coords[2],coords[1]-offsety,coords[0]+coords[2],coords[1]);pa2(co,'b m % % l % % l % % l % % f rgba(0,0,0,0.3)',coords[0]+coords[2],coords[1],coords[0]+coords[2]+offsetx,coords[1]-offsety,coords[0]+coords[2]+offsetx,coords[1]-offsety+coords[3],coords[0]+coords[2],coords[1]+coords[3]);}
84
+ if(!opt.shadow){this.coords[sequentialColorIndex]=[coords[0],coords[1],coords[2],coords[3]];this.coordsRight[i]=[coords[0],coords[1],coords[2],coords[3]];}}else if(typeof this.left==='object'&&prop['chart.grouping']==='stacked'){for(var j=0,accumulatedWidth=0;j<this.right[i].length;++j){if(prop['chart.colors.sequential']){co.fillStyle=prop['chart.colors'][sequentialColorIndex];}else{co.fillStyle=prop['chart.colors'][j];}
85
+ var value=this.right[i][j],min=this.min,max=this.max,margin=prop['chart.margin'],width=(((value-min)/(max-min))*this.axisWidth),sectionHeight=ma.round((this.axisHeight/this.right.length)),height=ma.round((sectionHeight-(2*margin))),x=ma.round(this.gutterLeft+this.axisWidth+prop['chart.gutter.center']+accumulatedWidth),y=ma.round(this.gutterTop+margin+(i*sectionHeight));accumulatedWidth+=width;if(this.right[i]!==null){co.strokeRect(x,y,width,height);co.fillRect(x,y,width,height);}
86
+ if(prop['chart.variant']==='3d'&&this.right[i]!==null){var color=co.fillStyle;if(prop['chart.shadow']&&opt.shadow){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];pa2(co,'b m % % l % % l % % l % % f black sc rgba(0,0,0,0) sx 0 sy 0 sb 0',x+offsetx,y-offsety,x+offsetx+width,y-offsety,x+offsetx+width,y-offsety+height,x+offsetx,y-offsety+height);}
87
+ pa2(co,'b m % % l % % l % % l % % f %',x,y,x+offsetx,y-offsety,x+offsetx+width,y-offsety,x+width,y,color);if(j===(this.right[i].length-1)){pa2(co,'b m % % l % % l % % l % % f %',x+width,y,x+width+offsetx,y-offsety,x+width+offsetx,y-offsety+height,x+width,y+height,color);pa2(co,'b m % % l % % l % % l % % f rgba(0,0,0,0.3)',x+width,y,x+width+offsetx,y-offsety,x+width+offsetx,y-offsety+height,x+width,y+height);}
88
+ pa2(co,'b m % % l % % l % % l % % f rgba(255,255,255,0.6)',x,y,x+offsetx,y-offsety,x+offsetx+width,y-offsety,x+width,y);}
89
+ if(!opt.shadow){this.coords.push([x,y,width,height]);if(!RG.isArray(this.coords2[sequentialColorIndex])){this.coords2[sequentialColorIndex]=[];}
90
+ this.coords2[sequentialColorIndex].push([x,y,width,height]);this.coordsRight.push([x,y,width,height]);if(!RG.isArray(this.coords2Right[i])){this.coords2Right[i]=[];}
91
+ this.coords2Right[i].push([x,y,width,height]);}
92
+ sequentialColorIndex++;}}else if(typeof this.right[i]==='object'){for(var j=0;j<this.right[i].length;++j){if(prop['chart.colors.sequential']){co.fillStyle=prop['chart.colors'][sequentialColorIndex];}else{co.fillStyle=prop['chart.colors'][j];}
93
+ var value=this.right[i][j],min=this.min,max=this.max,margin=prop['chart.margin'],marginGrouped=prop['chart.margin.grouped'],width=(((value-min)/(max-min))*this.axisWidth),sectionHeight=ma.round((this.axisHeight/this.right.length)),height=ma.round((sectionHeight-(2*margin)-(2*marginGrouped))/this.right[i].length),x=ma.round(this.gutterLeft+this.axisWidth+prop['chart.gutter.center']),y=ma.round(this.gutterTop+margin+(i*sectionHeight)+(height*j)+(j*marginGrouped));if(this.right[i]!==null){co.strokeRect(x,y,width,height);co.fillRect(x,y,width,height);}
94
+ if(!opt.shadow){this.coords.push([x,y,width,height]);this.coordsRight.push([x,y,width,height]);if(!RG.isArray(this.coords2[this.left.length+i])){this.coords2[this.left.length+i]=[];}
95
+ this.coords2[this.left.length+i].push([x,y,width,height]);if(!RG.isArray(this.coords2Right[i])){this.coords2Right[i]=[];}
96
+ this.coords2Right[i].push([x,y,width,height]);}
97
+ sequentialColorIndex++;if(prop['chart.variant']==='3d'&&this.right[i]!==null){var color=co.fillStyle;if(prop['chart.shadow']&&opt.shadow){co.shadowColor=prop['chart.shadow.color'];co.shadowBlur=prop['chart.shadow.blur'];co.shadowOffsetX=prop['chart.shadow.offsetx'];co.shadowOffsetY=prop['chart.shadow.offsety'];pa2(co,'b m % % l % % l % % l % % f black sc rgba(0,0,0,0) sx 0 sy 0 sb 0',x+offsetx,y-offsety,x+offsetx+width,y-offsety,x+offsetx+width,y-offsety+height,x+offsetx,y-offsety+height);}
98
+ pa2(co,'b m % % l % % l % % l % % f %',x,y,x+offsetx,y-offsety,x+offsetx+width,y-offsety,x+width,y,color);pa2(co,'b m % % l % % l % % l % % f %',x+width,y,x+width+offsetx,y-offsety,x+width+offsetx,y-offsety+height,x+width,y+height,color);pa2(co,'b m % % l % % l % % l % % f rgba(255,255,255,0.6)',x,y,x+offsetx,y-offsety,x+offsetx+width,y-offsety,x+width,y);pa2(co,'b m % % l % % l % % l % % f rgba(0,0,0,0.3)',x+width,y,x+width+offsetx,y-offsety,x+width+offsetx,y-offsety+height,x+width,y+height);}}}
99
+ sequentialColorIndex++;}
100
+ RG.noShadow(this);co.lineWidth=1;};this.drawLabels=this.DrawLabels=function()
101
+ {var font=prop['chart.labels.font']||prop['chart.text.font'],color=prop['chart.labels.color']||prop['chart.text.color'],size=prop['chart.labels.size']||prop['chart.text.size'],bold=typeof prop['chart.labels.bold']==='boolean'?prop['chart.labels.bold']:prop['chart.text.bold'],italic=typeof prop['chart.labels.italic']==='boolean'?prop['chart.labels.italic']:prop['chart.text.italic'],labels=prop['chart.labels'],barAreaHeight=ca.height-this.gutterTop-this.gutterBottom
102
+ co.fillStyle=color;for(var i=0,len=labels.length;i<len;++i){RG.text2(this,{color:color,font:font,size:size,x:this.gutterLeft+this.axisWidth+(prop['chart.gutter.center']/2),y:this.gutterTop+((barAreaHeight/labels.length)*(i))+((barAreaHeight/labels.length)/2),text:String(labels[i]?String(labels[i]):''),halign:'center',valign:'center',marker:false,bold:bold,italic:italic,tag:'labels'});}
103
+ co.fillStyle=prop['chart.text.color'];if(prop['chart.xlabels']){var grapharea=(ca.width-prop['chart.gutter.center']-this.gutterLeft-this.gutterRight)/2,font=prop['chart.text.font'],size=prop['chart.text.size'],bold=prop['chart.text.bold'],italic=prop['chart.text.italic'],color=prop['chart.text.color'];for(var i=0;i<this.scale2.labels.length;++i){RG.text2(this,{font:font,size:size,bold:bold,italic:italic,x:this.gutterLeft+((grapharea/this.scale2.labels.length)*i),y:ca.height-this.gutterBottom+3,text:this.scale2.labels[this.scale2.labels.length-i-1],valign:'top',halign:'center',color:color,tag:'scale'});RG.text2(this,{font:font,size:size,bold:bold,italic:italic,x:this.gutterLeft+grapharea+prop['chart.gutter.center']+((grapharea/this.scale2.labels.length)*(i+1)),y:ca.height-this.gutterBottom+3,text:this.scale2.labels[i],valign:'top',halign:'center',tag:'scale'});}
104
+ if(prop['chart.scale.zerostart']){RG.text2(this,{font:font,size:size,bold:bold,italic:italic,x:this.gutterLeft+this.axisWidth,y:ca.height-this.gutterBottom+3,text:'0',valign:'top',halign:'center',tag:'scale'});RG.text2(this,{font:font,size:size,bold:bold,italic:italic,x:this.gutterLeft+this.axisWidth+this.gutterCenter,y:ca.height-this.gutterBottom+3,text:'0',valign:'top',halign:'center',tag:'scale'});}}
105
+ if(prop['chart.labels.above']){this.drawLabelsAbove();}};this.drawLabelsAbove=function()
106
+ {var coordsLeft=RG.arrayReverse(this.coordsLeft);var coordsRight=RG.arrayReverse(this.coordsRight);for(var i=0,seq=0;i<coordsLeft.length;++i,++seq){if(typeof this.left[i]=='number'){var coords=coordsLeft[i];RG.text2(this,{font:prop['chart.labels.above.font']||prop['chart.text.font'],size:prop['chart.labels.above.size']||prop['chart.text.size'],x:coords[0]-5,y:coords[1]+(coords[3]/2),text:typeof prop['chart.labels.above.formatter']==='function'?prop['chart.labels.above.formatter'](this,this.left[i]):RG.numberFormat(this,this.left[i].toFixed(typeof prop['chart.labels.above.decimals']==='number'?prop['chart.labels.above.decimals']:0),prop['chart.labels.above.units.pre'],prop['chart.labels.above.units.post']),valign:'center',halign:'right',color:prop['chart.labels.above.color']||prop['chart.text.color'],bold:typeof prop['chart.labels.above.bold']==='boolean'?prop['chart.labels.above.bold']:prop['chart.text.bold'],italic:typeof prop['chart.labels.above.italic']==='boolean'?prop['chart.labels.above.italic']:prop['chart.text.italic'],tag:'labels.above'});}else if(typeof this.left[i]==='object'){for(var j=0;j<this.left[i].length;++j,++seq){if(prop['chart.grouping']==='stacked'&&j!==0){continue;}
107
+ var coords=coordsLeft[seq];RG.text2(this,{font:prop['chart.labels.above.font']||prop['chart.text.font'],size:prop['chart.labels.above.size']||prop['chart.text.size'],x:coords[0]-5,y:coords[1]+(coords[3]/2),text:typeof prop['chart.labels.above.formatter']==='function'?prop['chart.labels.above.formatter'](this,this.left[i][j]):RG.numberFormat(this,RG.isNull(this.left[i][j])||isNaN(this.left[i][j])?'':(prop['chart.grouping']==='stacked'?RG.arraySum(this.left[i]):Number(this.left[i][j])).toFixed(typeof prop['chart.labels.above.decimals']==='number'?prop['chart.labels.above.decimals']:0),prop['chart.labels.above.units.pre'],prop['chart.labels.above.units.post']),valign:'center',halign:'right',color:prop['chart.labels.above.color']||null,bold:typeof prop['chart.labels.above.bold']==='boolean'?prop['chart.labels.above.bold']:false,italic:typeof prop['chart.labels.above.italic']==='boolean'?prop['chart.labels.above.italic']:false,tag:'labels.above'});}
108
+ seq--;}}
109
+ for(i=0,seq=0;i<coordsRight.length;++i,++seq){if(typeof this.right[i]==='number'){var coords=coordsRight[i];RG.text2(this,{font:prop['chart.labels.above.font']||prop['chart.text.font'],size:prop['chart.labels.above.size']||prop['chart.text.size'],x:coords[0]+coords[2]+5,y:coords[1]+(coords[3]/2),text:typeof prop['chart.labels.above.formatter']==='function'?prop['chart.labels.above.formatter'](this,this.right[i]):RG.numberFormat(this,this.right[i].toFixed(typeof prop['chart.labels.above.decimals']==='number'?prop['chart.labels.above.decimals']:0),prop['chart.labels.above.units.pre'],prop['chart.labels.above.units.post']),valign:'center',halign:'left',color:prop['chart.labels.above.color']||null,bold:typeof prop['chart.labels.above.bold']==='boolean'?prop['chart.labels.above.bold']:false,italic:typeof prop['chart.labels.above.italic']==='boolean'?prop['chart.labels.above.italic']:false,tag:'labels.above'});}else if(typeof this.right[i]==='object'){for(var j=0;j<this.right[i].length;++j,++seq){if(prop['chart.grouping']==='stacked'&&j!==0){continue;}
110
+ var coords=coordsRight[seq];RG.text2(this,{font:prop['chart.labels.above.font']||prop['chart.text.font'],size:prop['chart.labels.above.size']||prop['chart.text.size'],x:coords[0]+coords[2]+5,y:coords[1]+(coords[3]/2),text:typeof prop['chart.labels.above.formatter']==='function'?prop['chart.labels.above.formatter'](this,this.right[i][j]):RG.numberFormat(this,RG.isNull(this.right[i][j])||isNaN(this.right[i][j])?'':Number(this.right[i][j]).toFixed(typeof prop['chart.labels.above.decimals']==='number'?prop['chart.labels.above.decimals']:0),prop['chart.labels.above.units.pre'],prop['chart.labels.above.units.post']),valign:'center',halign:'left',color:prop['chart.labels.above.color']||null,bold:typeof prop['chart.labels.above.bold']==='boolean'?prop['chart.labels.above.bold']:false,italic:typeof prop['chart.labels.above.italic']==='boolean'?prop['chart.labels.above.italic']:false,tag:'labels.above'});}
111
+ --seq;}}};this.drawTitles=this.DrawTitles=function()
112
+ {if(typeof prop['chart.title.left']==='string'){RG.text2(this,{font:prop['chart.title.left.font']||prop['chart.text.font'],size:prop['chart.title.left.size']||prop['chart.text.size'],x:this.gutterLeft+5,y:this.gutterTop-5,text:prop['chart.title.left'],halign:'left',valign:'bottom',bold:typeof prop['chart.title.left.bold']==='boolean'?prop['chart.title.left.bold']:prop['chart.text.bold'],italic:typeof prop['chart.title.left.italic']==='boolean'?prop['chart.title.left.italic']:prop['chart.text.italic'],color:prop['chart.title.left.color']||prop['chart.text.color'],tag:'title.left'});}
113
+ if(typeof prop['chart.title.right']==='string'){RG.text2(this,{font:prop['chart.title.right.font']||prop['chart.text.font'],size:prop['chart.title.right.size']||prop['chart.text.size'],x:ca.width-this.gutterRight-5,y:this.gutterTop-5,text:prop['chart.title.right'],halign:'right',valign:'bottom',bold:typeof prop['chart.title.right.bold']==='boolean'?prop['chart.title.right.bold']:prop['chart.right.bold'],italic:typeof prop['chart.title.right.italic']==='boolean'?prop['chart.title.right.italic']:prop['chart.right.italic'],color:prop['chart.title.right.color']||prop['chart.text.color'],tag:'title.right'});}
114
+ if(typeof prop['chart.title']==='string'){RG.drawTitle(this,prop['chart.title'],this.gutterTop,null,prop['chart.title.size']?prop['chart.title.size']:null);}};this.drawIEShadow=this.DrawIEShadow=function(coords)
115
+ {var prevFillStyle=co.fillStyle;var offsetx=prop['chart.shadow.offsetx'];var offsety=prop['chart.shadow.offsety'];co.lineWidth=prop['chart.linewidth'];co.fillStyle=prop['chart.shadow.color'];co.beginPath();co.fillRect(coords[0]+offsetx,coords[1]+offsety,coords[2],coords[3]);co.fill();co.fillStyle=prevFillStyle;}
116
+ this.getShape=this.getBar=function(e)
117
+ {var canvas=this.canvas,context=this.context,mouseXY=RG.getMouseXY(e)
118
+ for(var i=0;i<this.coords.length;i++){var mouseX=mouseXY[0],mouseY=mouseXY[1],left=this.coords[i][0],top=this.coords[i][1],width=this.coords[i][2],height=this.coords[i][3]
119
+ if(prop['chart.variant']==='3d'){pa2(co,'b r % % % %',left,top,width,height);var over=co.isPointInPath(mouseX,mouseY);}else{var over=(mouseX>=left&&mouseX<=(left+width)&&mouseY>=top&&mouseY<=(top+height));}
120
+ if(over){var tooltip=RG.parseTooltipText(prop['chart.tooltips'],i);return{0:this,1:left,2:top,3:width,4:height,5:i,object:this,x:left,y:top,width:width,height:height,index:i,tooltip:tooltip};}}
121
+ return null;};this.highlight=this.Highlight=function(shape)
122
+ {if(typeof prop['chart.highlight.style']==='function'){(prop['chart.highlight.style'])(shape);}else{RG.Highlight.Rect(this,shape);}};this.getValue=function(e)
123
+ {var obj=e.target.__object__;var mouseXY=RG.getMouseXY(e);var mouseX=mouseXY[0];if(mouseX>this.gutterLeft&&mouseX<((ca.width/2)-(prop['chart.gutter.center']/2))){var value=(mouseX-prop['chart.gutter.left'])/this.axisWidth;value=this.max-(value*this.max);}
124
+ if(mouseX<(ca.width-this.gutterRight)&&mouseX>((ca.width/2)+(prop['chart.gutter.center']/2))){var value=(mouseX-prop['chart.gutter.left']-this.axisWidth-prop['chart.gutter.center'])/this.axisWidth;value=(value*this.max);}
125
+ return value;};this.getObjectByXY=function(e)
126
+ {var mouseXY=RG.getMouseXY(e);if(mouseXY[0]>prop['chart.gutter.left']&&mouseXY[0]<(ca.width-prop['chart.gutter.right'])&&mouseXY[1]>prop['chart.gutter.top']&&mouseXY[1]<(ca.height-prop['chart.gutter.bottom'])){return this;}};this.getXCoord=function(value)
127
+ {if(value>this.max||value<0){return null;}
128
+ var ret=[];var offset=((value/this.max)*this.axisWidth);ret[0]=(this.gutterLeft+this.axisWidth)-offset;ret[1]=(ca.width-this.gutterRight-this.axisWidth)+offset;return ret;};this.parseColors=function()
129
+ {if(this.original_colors.length===0){this.original_colors['chart.colors']=RG.array_clone(prop['chart.colors']);this.original_colors['chart.highlight.stroke']=RG.array_clone(prop['chart.highlight.fill']);this.original_colors['chart.highlight.fill']=RG.array_clone(prop['chart.highlight.fill']);this.original_colors['chart.axis.color']=RG.array_clone(prop['chart.axis.color']);this.original_colors['chart.strokestyle']=RG.array_clone(prop['chart.strokestyle']);}
130
+ var props=this.properties;var colors=props['chart.colors'];for(var i=0;i<colors.length;++i){colors[i]=this.parseSingleColorForGradient(colors[i]);}
131
+ props['chart.highlight.stroke']=this.parseSingleColorForGradient(props['chart.highlight.stroke']);props['chart.highlight.fill']=this.parseSingleColorForGradient(props['chart.highlight.fill']);props['chart.axis.color']=this.parseSingleColorForGradient(props['chart.axis.color']);props['chart.strokestyle']=this.parseSingleColorForGradient(props['chart.strokestyle']);};this.reset=function()
132
+ {};this.parseSingleColorForGradient=function(color)
133
+ {if(!color||typeof(color)!='string'){return color;}
134
+ if(color.match(/^gradient\((.*)\)$/i)){var parts=RegExp.$1.split(':');var grad=co.createLinearGradient(prop['chart.gutter.left'],0,ca.width-prop['chart.gutter.right'],0);var diff=1/(parts.length-1);grad.addColorStop(0,RG.trim(parts[0]));for(var j=1;j<parts.length;++j){grad.addColorStop(j*diff,RG.trim(parts[j]));}}
135
+ return grad?grad:color;};this.on=function(type,func)
136
+ {if(type.substr(0,2)!=='on'){type='on'+type;}
137
+ if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
138
+ return this;};this.drawBackgroundGrid=function()
139
+ {if(prop['chart.background.grid']){var variant=prop['chart.variant'],color=prop['chart.background.grid.color'],numvlines=prop['chart.labels.count'],numhlines=this.left.length,vlines=prop['chart.background.grid.vlines'],hlines=prop['chart.background.grid.hlines'],linewidth=prop['chart.background.grid.linewidth'];if(typeof prop['chart.background.grid.autofit.numhlines']==='number'){numhlines=prop['chart.background.grid.autofit.numhlines'];}
140
+ if(typeof prop['chart.background.grid.autofit.numvlines']==='number'){numvlines=prop['chart.background.grid.autofit.numvlines'];}
141
+ co.lineWidth=linewidth;if(variant=='3d'){co.save();co.translate(prop['chart.variant.threed.offsetx'],-1*prop['chart.variant.threed.offsety']);}
142
+ if(vlines){for(var i=0;i<=numvlines;i+=1){pa2(co,'b m % % l % % s %',this.gutterLeft+(this.axisWidth/numvlines)*i,this.gutterTop,this.gutterLeft+(this.axisWidth/numvlines)*i,this.gutterTop+this.axisHeight,color);}}
143
+ if(hlines){for(var i=0;i<=numhlines;i+=1){pa2(co,'b m % % l % % s %',this.gutterLeft,this.gutterTop+(this.axisHeight/numhlines)*i,this.gutterLeft+this.axisWidth,this.gutterTop+(this.axisHeight/numhlines)*i,color);}}
144
+ if(vlines){for(var i=0;i<=numvlines;i+=1){pa2(co,'b m % % l % % s %',this.gutterLeft+this.gutterCenter+this.axisWidth+(this.axisWidth/numvlines)*i,this.gutterTop,this.gutterLeft+this.gutterCenter+this.axisWidth+(this.axisWidth/numvlines)*i,this.gutterTop+this.axisHeight,color);}}
145
+ if(hlines){for(var i=0;i<=numhlines;i+=1){pa2(co,'b m % % l % % s %',this.gutterLeft+this.axisWidth+this.gutterCenter,this.gutterTop+(this.axisHeight/numhlines)*i,this.gutterLeft+this.axisWidth+this.gutterCenter+this.axisWidth,this.gutterTop+(this.axisHeight/numhlines)*i,color);}}
146
+ if(variant=='3d'){co.restore();}}};this.firstDrawFunc=function()
147
+ {};this.getGutterCenter=function()
148
+ {var bold=typeof prop['chart.labels.bold']==='boolean'?prop['chart.labels.bold']:prop['chart.text.bold'],font=typeof prop['chart.labels.font']==='string'?prop['chart.labels.font']:prop['chart.text.font'],size=typeof prop['chart.labels.size']==='number'?prop['chart.labels.size']:prop['chart.text.size'];for(var i=0,len=0;i<prop['chart.labels'].length;++i){len=ma.max(len,RG.measureText(prop['chart.labels'][i],bold,font,size)[0]);}
149
+ return len+15;};RG.Register(this);if(parseConfObjectForOptions){RG.parseObjectStyleConfig(this,conf.options);}
150
+ this.grow=function()
151
+ {var opt=arguments[0]||{},frames=opt.frames||30,frame=0,callback=arguments[1]||function(){},obj=this;var originalLeft=RG.arrayClone(this.left),originalRight=RG.arrayClone(this.right);if(RG.isNull(prop['chart.xmax'])){var xmax=0;this.getMax();this.Set('chart.xmax',this.scale2.max);}
152
+ var iterator=function()
153
+ {var easingMultiplier=RG.Effects.getEasingMultiplier(frames,frame);for(var i=0;i<obj.left.length;i+=1){if(typeof obj.left[i]==='number'){obj.left[i]=easingMultiplier*originalLeft[i];}else{for(var j=0;j<obj.left[i].length;++j){obj.left[i][j]=easingMultiplier*originalLeft[i][j];}}}
154
+ for(var i=0;i<obj.right.length;i+=1){if(typeof obj.right[i]==='number'){obj.right[i]=easingMultiplier*originalRight[i];}else{for(var j=0;j<obj.right[i].length;++j){obj.right[i][j]=easingMultiplier*originalRight[i][j];}}}
155
+ RG.redrawCanvas(obj.canvas);if(frame<frames){frame+=1;RG.Effects.updateCanvas(iterator);}else{callback(obj);}};iterator();return this;};this.wave=function()
156
+ {var obj=this,opt=arguments[0]||{};opt.frames=opt.frames||120;opt.startFrames_left=[];opt.startFrames_right=[];opt.counters_left=[];opt.counters_right=[];var framesperbar=opt.frames/3,frame_left=-1,frame_right=-1,callback=arguments[1]||function(){},original_left=RG.arrayClone(obj.left),original_right=RG.arrayClone(obj.right);for(var i=0,len=obj.left.length;i<len;i+=1){opt.startFrames_left[i]=((opt.frames/3)/(obj.left.length-1))*i;opt.startFrames_right[i]=((opt.frames/3)/(obj.right.length-1))*i;opt.counters_left[i]=0;opt.counters_right[i]=0;}
157
+ obj.draw();obj.set('xmax',obj.scale2.max);RG.clear(obj.canvas);for(var i=0,len=obj.left.length;i<len;i+=1){if(typeof obj.left[i]==='number')obj.left[i]=0;if(typeof obj.right[i]==='number')obj.right[i]=0;}
158
+ function iteratorLeft()
159
+ {++frame_left;for(var i=0,len=obj.left.length;i<len;i+=1){if(frame_left>opt.startFrames_left[i]){var isNull=RG.isNull(obj.left[i]);if(typeof obj.left[i]==='number'){obj.left[i]=ma.min(ma.abs(original_left[i]),ma.abs(original_left[i]*((opt.counters_left[i]++)/framesperbar)));if(original_left[i]<0){obj.left[i]*=-1;}}else if(RG.isArray(obj.left[i])){for(var j=0;j<obj.left[i].length;++j){obj.left[i][j]=ma.min(ma.abs(original_left[i][j]),ma.abs(original_left[i][j]*((opt.counters_left[i]++)/framesperbar)));if(original_left[i][j]<0){obj.left[i][j]*=-1;}}}
160
+ if(isNull){obj.left[i]=null;}}else{obj.left[i]=typeof obj.left[i]==='object'&&obj.left[i]?RG.arrayPad([],obj.left[i].length,0):(RG.isNull(obj.left[i])?null:0);}}
161
+ if(frame_left<opt.frames){RG.redrawCanvas(obj.canvas);RG.Effects.updateCanvas(iteratorLeft);}}
162
+ function iteratorRight()
163
+ {++frame_right;for(var i=0,len=obj.right.length;i<len;i+=1){if(frame_right>opt.startFrames_right[i]){var isNull=RG.isNull(obj.right[i]);if(typeof obj.left[i]==='number'){obj.right[i]=ma.min(ma.abs(original_right[i]),ma.abs(original_right[i]*((opt.counters_right[i]++)/framesperbar)));if(original_right[i]<0){obj.right[i]*=-1;}
164
+ if(isNull){obj.right[i]=null;}}else if(RG.isArray(obj.right[i])){for(var j=0;j<obj.right[i].length;++j){obj.right[i][j]=ma.min(ma.abs(original_right[i][j]),ma.abs(original_right[i][j]*((opt.counters_right[i]++)/framesperbar)));if(original_right[i][j]<0){obj.right[i][j]*=-1;}}}}else{obj.right[i]=typeof obj.right[i]==='object'&&obj.right[i]?RG.arrayPad([],obj.right[i].length,0):(RG.isNull(obj.right[i])?null:0);}}
165
+ if(frame_right<opt.frames){RG.redrawCanvas(obj.canvas);RG.Effects.updateCanvas(iteratorRight);}else{callback(this);}}
166
+ iteratorLeft();iteratorRight();return this;};};