rgraph-rails 1.0.5 → 1.0.6

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