rgraph-rails 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. checksums.yaml +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;};};