rgraph-rails 4.62 → 4.64

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +3 -4
  3. data/lib/rgraph-rails/version.rb +1 -1
  4. data/vendor/assets/javascripts/RGraph.bar.js +240 -3742
  5. data/vendor/assets/javascripts/RGraph.bipolar.js +165 -2005
  6. data/vendor/assets/javascripts/RGraph.common.annotate.js +35 -395
  7. data/vendor/assets/javascripts/RGraph.common.context.js +30 -595
  8. data/vendor/assets/javascripts/RGraph.common.core.js +418 -5359
  9. data/vendor/assets/javascripts/RGraph.common.csv.js +20 -276
  10. data/vendor/assets/javascripts/RGraph.common.deprecated.js +35 -450
  11. data/vendor/assets/javascripts/RGraph.common.dynamic.js +88 -1395
  12. data/vendor/assets/javascripts/RGraph.common.effects.js +90 -1545
  13. data/vendor/assets/javascripts/RGraph.common.key.js +52 -753
  14. data/vendor/assets/javascripts/RGraph.common.resizing.js +37 -563
  15. data/vendor/assets/javascripts/RGraph.common.sheets.js +29 -352
  16. data/vendor/assets/javascripts/RGraph.common.tooltips.js +32 -450
  17. data/vendor/assets/javascripts/RGraph.common.zoom.js +14 -219
  18. data/vendor/assets/javascripts/RGraph.cornergauge.js +71 -0
  19. data/vendor/assets/javascripts/RGraph.drawing.background.js +34 -570
  20. data/vendor/assets/javascripts/RGraph.drawing.circle.js +33 -544
  21. data/vendor/assets/javascripts/RGraph.drawing.image.js +51 -755
  22. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +37 -645
  23. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +36 -633
  24. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +35 -514
  25. data/vendor/assets/javascripts/RGraph.drawing.poly.js +37 -559
  26. data/vendor/assets/javascripts/RGraph.drawing.rect.js +33 -548
  27. data/vendor/assets/javascripts/RGraph.drawing.text.js +36 -664
  28. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +50 -812
  29. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +51 -856
  30. data/vendor/assets/javascripts/RGraph.fuel.js +58 -964
  31. data/vendor/assets/javascripts/RGraph.funnel.js +55 -984
  32. data/vendor/assets/javascripts/RGraph.gantt.js +77 -1354
  33. data/vendor/assets/javascripts/RGraph.gauge.js +85 -1421
  34. data/vendor/assets/javascripts/RGraph.hbar.js +162 -2788
  35. data/vendor/assets/javascripts/RGraph.hprogress.js +80 -1401
  36. data/vendor/assets/javascripts/RGraph.line.js +249 -4248
  37. data/vendor/assets/javascripts/RGraph.meter.js +74 -1280
  38. data/vendor/assets/javascripts/RGraph.modaldialog.js +19 -301
  39. data/vendor/assets/javascripts/RGraph.odo.js +71 -1264
  40. data/vendor/assets/javascripts/RGraph.pie.js +137 -2288
  41. data/vendor/assets/javascripts/RGraph.radar.js +110 -1847
  42. data/vendor/assets/javascripts/RGraph.rose.js +108 -1977
  43. data/vendor/assets/javascripts/RGraph.rscatter.js +80 -1432
  44. data/vendor/assets/javascripts/RGraph.scatter.js +172 -3163
  45. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +60 -1120
  46. data/vendor/assets/javascripts/RGraph.svg.bar.js +66 -1735
  47. data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +21 -246
  48. data/vendor/assets/javascripts/RGraph.svg.common.core.js +255 -3937
  49. data/vendor/assets/javascripts/RGraph.svg.common.csv.js +20 -276
  50. data/vendor/assets/javascripts/RGraph.svg.common.fx.js +68 -1303
  51. data/vendor/assets/javascripts/RGraph.svg.common.key.js +19 -205
  52. data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +29 -352
  53. data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +22 -273
  54. data/vendor/assets/javascripts/RGraph.svg.funnel.js +32 -0
  55. data/vendor/assets/javascripts/RGraph.svg.hbar.js +59 -1400
  56. data/vendor/assets/javascripts/RGraph.svg.line.js +70 -1580
  57. data/vendor/assets/javascripts/RGraph.svg.pie.js +55 -1131
  58. data/vendor/assets/javascripts/RGraph.svg.radar.js +57 -1502
  59. data/vendor/assets/javascripts/RGraph.svg.rose.js +66 -1817
  60. data/vendor/assets/javascripts/RGraph.svg.scatter.js +58 -1261
  61. data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +28 -865
  62. data/vendor/assets/javascripts/RGraph.svg.waterfall.js +45 -1252
  63. data/vendor/assets/javascripts/RGraph.thermometer.js +63 -1136
  64. data/vendor/assets/javascripts/RGraph.vprogress.js +83 -1470
  65. data/vendor/assets/javascripts/RGraph.waterfall.js +83 -1347
  66. metadata +5 -4
  67. data/vendor/assets/javascripts/financial-data.js +0 -1067
@@ -1,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;};};