rgraph-rails 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/CODE_OF_CONDUCT.md +13 -0
  6. data/Gemfile +4 -0
  7. data/README.md +73 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +7 -0
  11. data/lib/rgraph-rails/version.rb +3 -0
  12. data/lib/rgraph-rails.rb +8 -0
  13. data/license.txt +19 -0
  14. data/rgraph-rails.gemspec +26 -0
  15. data/vendor/assets/images/bg.png +0 -0
  16. data/vendor/assets/images/bullet.png +0 -0
  17. data/vendor/assets/images/facebook-large.png +0 -0
  18. data/vendor/assets/images/google-plus-large.png +0 -0
  19. data/vendor/assets/images/logo.png +0 -0
  20. data/vendor/assets/images/meter-image-sd-needle.png +0 -0
  21. data/vendor/assets/images/meter-image-sd.png +0 -0
  22. data/vendor/assets/images/meter-sketch-needle.png +0 -0
  23. data/vendor/assets/images/meter-sketch.png +0 -0
  24. data/vendor/assets/images/odometer-background.png +0 -0
  25. data/vendor/assets/images/rgraph.jpg +0 -0
  26. data/vendor/assets/images/title.png +0 -0
  27. data/vendor/assets/images/twitter-large.png +0 -0
  28. data/vendor/assets/javascripts/RGraph.bar.js +3246 -0
  29. data/vendor/assets/javascripts/RGraph.bipolar.js +2003 -0
  30. data/vendor/assets/javascripts/RGraph.common.annotate.js +399 -0
  31. data/vendor/assets/javascripts/RGraph.common.context.js +600 -0
  32. data/vendor/assets/javascripts/RGraph.common.core.js +4751 -0
  33. data/vendor/assets/javascripts/RGraph.common.csv.js +275 -0
  34. data/vendor/assets/javascripts/RGraph.common.deprecated.js +454 -0
  35. data/vendor/assets/javascripts/RGraph.common.dynamic.js +1194 -0
  36. data/vendor/assets/javascripts/RGraph.common.effects.js +1524 -0
  37. data/vendor/assets/javascripts/RGraph.common.key.js +735 -0
  38. data/vendor/assets/javascripts/RGraph.common.resizing.js +550 -0
  39. data/vendor/assets/javascripts/RGraph.common.tooltips.js +605 -0
  40. data/vendor/assets/javascripts/RGraph.common.zoom.js +223 -0
  41. data/vendor/assets/javascripts/RGraph.drawing.background.js +636 -0
  42. data/vendor/assets/javascripts/RGraph.drawing.circle.js +579 -0
  43. data/vendor/assets/javascripts/RGraph.drawing.image.js +810 -0
  44. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +710 -0
  45. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +672 -0
  46. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +568 -0
  47. data/vendor/assets/javascripts/RGraph.drawing.poly.js +623 -0
  48. data/vendor/assets/javascripts/RGraph.drawing.rect.js +603 -0
  49. data/vendor/assets/javascripts/RGraph.drawing.text.js +648 -0
  50. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +815 -0
  51. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +860 -0
  52. data/vendor/assets/javascripts/RGraph.fuel.js +965 -0
  53. data/vendor/assets/javascripts/RGraph.funnel.js +988 -0
  54. data/vendor/assets/javascripts/RGraph.gantt.js +1242 -0
  55. data/vendor/assets/javascripts/RGraph.gauge.js +1391 -0
  56. data/vendor/assets/javascripts/RGraph.hbar.js +1794 -0
  57. data/vendor/assets/javascripts/RGraph.hprogress.js +1307 -0
  58. data/vendor/assets/javascripts/RGraph.line.js +3940 -0
  59. data/vendor/assets/javascripts/RGraph.meter.js +1242 -0
  60. data/vendor/assets/javascripts/RGraph.modaldialog.js +292 -0
  61. data/vendor/assets/javascripts/RGraph.odo.js +1265 -0
  62. data/vendor/assets/javascripts/RGraph.pie.js +1979 -0
  63. data/vendor/assets/javascripts/RGraph.radar.js +1840 -0
  64. data/vendor/assets/javascripts/RGraph.rose.js +1860 -0
  65. data/vendor/assets/javascripts/RGraph.rscatter.js +1332 -0
  66. data/vendor/assets/javascripts/RGraph.scatter.js +3029 -0
  67. data/vendor/assets/javascripts/RGraph.thermometer.js +1131 -0
  68. data/vendor/assets/javascripts/RGraph.vprogress.js +1326 -0
  69. data/vendor/assets/javascripts/RGraph.waterfall.js +1252 -0
  70. data/vendor/assets/javascripts/financial-data.js +1067 -0
  71. data/vendor/assets/stylesheets/ModalDialog.css +90 -0
  72. data/vendor/assets/stylesheets/animations.css +3347 -0
  73. data/vendor/assets/stylesheets/website.css +402 -0
  74. metadata +175 -0
@@ -0,0 +1,1307 @@
1
+ // version: 2015-11-02
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 is just �99 (GBP) and you can |
11
+ * | read about it here: |
12
+ * | http://www.rgraph.net/license |
13
+ * o--------------------------------------------------------------------------------o
14
+ */
15
+
16
+ RGraph = window.RGraph || {isRGraph: true};
17
+
18
+ /**
19
+ * The progress bar constructor
20
+ *
21
+ * @param int id The ID of the canvas tag
22
+ * @param int value The indicated value of the meter.
23
+ * @param int max The end value (the upper most) of the meter
24
+ */
25
+ RGraph.HProgress = function (conf)
26
+ {
27
+ /**
28
+ * Allow for object config style
29
+ */
30
+ if ( typeof conf === 'object'
31
+ && typeof conf.min === 'number'
32
+ && typeof conf.max === 'number'
33
+ && typeof conf.value !== 'undefined'
34
+ && typeof conf.id === 'string') {
35
+
36
+ var id = conf.id
37
+ var canvas = document.getElementById(id);
38
+ var min = conf.min;
39
+ var max = conf.max;
40
+ var value = conf.value;
41
+ var parseConfObjectForOptions = true; // Set this so the config is parsed (at the end of the constructor)
42
+
43
+ } else {
44
+
45
+ var id = conf;
46
+ var canvas = document.getElementById(id);
47
+ var min = arguments[1];
48
+ var max = arguments[2];
49
+ var value = arguments[3];
50
+ }
51
+
52
+
53
+
54
+ this.id = id;
55
+ this.canvas = canvas;
56
+ this.context = this.canvas.getContext('2d');
57
+ this.canvas.__object__ = this;
58
+
59
+ this.min = min;
60
+ this.max = max;
61
+ this.value = RGraph.stringsToNumbers(value);
62
+ this.type = 'hprogress';
63
+ this.coords = [];
64
+ this.isRGraph = true;
65
+ this.currentValue = null;
66
+ this.uid = RGraph.CreateUID();
67
+ this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.CreateUID();
68
+ this.colorsParsed = false;
69
+ this.coordsText = [];
70
+ this.original_colors = [];
71
+ this.firstDraw = true; // After the first draw this will be false
72
+
73
+
74
+ /**
75
+ * Compatibility with older browsers
76
+ */
77
+ //RGraph.OldBrowserCompat(this.context);
78
+
79
+ this.properties =
80
+ {
81
+ 'chart.colors': ['Gradient(white:#0c0)','Gradient(white:red)','Gradient(white:green)','yellow','pink','cyan','black','white','gray'],
82
+ 'chart.strokestyle.inner': '#999',
83
+ 'chart.strokestyle.outer': '#999',
84
+ 'chart.tickmarks': true,
85
+ 'chart.tickmarks.color': '#999',
86
+ 'chart.tickmarks.inner': false,
87
+ 'chart.tickmarks.zerostart':true,
88
+ 'chart.gutter.left': 25,
89
+ 'chart.gutter.right': 25,
90
+ 'chart.gutter.top': 25,
91
+ 'chart.gutter.bottom': 25,
92
+ 'chart.numticks': 10,
93
+ 'chart.numticks.inner': 50,
94
+ 'chart.background.color': '#eee',
95
+ 'chart.shadow': false,
96
+ 'chart.shadow.color': 'rgba(0,0,0,0.5)',
97
+ 'chart.shadow.blur': 3,
98
+ 'chart.shadow.offsetx': 3,
99
+ 'chart.shadow.offsety': 3,
100
+ 'chart.title': '',
101
+ 'chart.title.background': null,
102
+ 'chart.title.bold': true,
103
+ 'chart.title.font': null,
104
+ 'chart.title.x': null,
105
+ 'chart.title.y': null,
106
+ 'chart.title.halign': null,
107
+ 'chart.title.valign': null,
108
+ 'chart.text.size': 12,
109
+ 'chart.text.color': 'black',
110
+ 'chart.text.font': 'Arial',
111
+ 'chart.contextmenu': null,
112
+ 'chart.units.pre': '',
113
+ 'chart.units.post': '',
114
+ 'chart.tooltips': null,
115
+ 'chart.tooltips.effect': 'fade',
116
+ 'chart.tooltips.css.class': 'RGraph_tooltip',
117
+ 'chart.tooltips.highlight': true,
118
+ 'chart.tooltips.event': 'onclick',
119
+ 'chart.highlight.stroke': 'rgba(0,0,0,0)',
120
+ 'chart.highlight.fill': 'rgba(255,255,255,0.7)',
121
+ 'chart.annotatable': false,
122
+ 'chart.annotate.color': 'black',
123
+ 'chart.zoom.factor': 1.5,
124
+ 'chart.zoom.fade.in': true,
125
+ 'chart.zoom.fade.out': true,
126
+ 'chart.zoom.hdir': 'right',
127
+ 'chart.zoom.vdir': 'down',
128
+ 'chart.zoom.frames': 25,
129
+ 'chart.zoom.delay': 16.666,
130
+ 'chart.zoom.shadow': true,
131
+ 'chart.zoom.background': true,
132
+ 'chart.arrows': false,
133
+ 'chart.margin': 0,
134
+ 'chart.resizable': false,
135
+ 'chart.resize.handle.adjust':[0,0],
136
+ 'chart.resize.handle.background':null,
137
+ 'chart.labels.specific': null,
138
+ 'chart.labels.count': 10,
139
+ 'chart.adjustable': false,
140
+ 'chart.scale.decimals': 0,
141
+ 'chart.scale.point': '.',
142
+ 'chart.scale.thousand': ',',
143
+ 'chart.key': null,
144
+ 'chart.key.background': 'white',
145
+ 'chart.key.position': 'gutter',
146
+ 'chart.key.halign': 'right',
147
+ 'chart.key.shadow': false,
148
+ 'chart.key.shadow.color': '#666',
149
+ 'chart.key.shadow.blur': 3,
150
+ 'chart.key.shadow.offsetx': 2,
151
+ 'chart.key.shadow.offsety': 2,
152
+ 'chart.key.position.gutter.boxed': false,
153
+ 'chart.key.position.x': null,
154
+ 'chart.key.position.y': null,
155
+ 'chart.key.color.shape': 'square',
156
+ 'chart.key.rounded': true,
157
+ 'chart.key.linewidth': 1,
158
+ 'chart.key.colors': null,
159
+ 'chart.key.color.shape': 'square',
160
+ 'chart.key.interactive': false,
161
+ 'chart.key.interactive.highlight.chart.stroke': 'black',
162
+ 'chart.key.interactive.highlight.chart.fill': 'rgba(255,255,255,0.7)',
163
+ 'chart.key.interactive.highlight.label': 'rgba(255,0,0,0.2)',
164
+ 'chart.key.text.color': 'black',
165
+ 'chart.labels.position': 'bottom',
166
+ 'chart.events.mousemove': null,
167
+ 'chart.events.click': null,
168
+ 'chart.border.inner': true
169
+ }
170
+
171
+
172
+ // Check for support
173
+ if (!this.canvas) {
174
+ alert('[HPROGRESS] No canvas support');
175
+ return;
176
+ }
177
+
178
+
179
+ /**
180
+ * Create the dollar objects so that functions can be added to them
181
+ */
182
+ var linear_data = RGraph.array_linearize(value);
183
+ for (var i=0; i<linear_data.length; ++i) {
184
+ this['$' + i] = {};
185
+ }
186
+
187
+
188
+ /**
189
+ * Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
190
+ * done already
191
+ */
192
+ if (!this.canvas.__rgraph_aa_translated__) {
193
+ this.context.translate(0.5,0.5);
194
+
195
+ this.canvas.__rgraph_aa_translated__ = true;
196
+ }
197
+
198
+
199
+
200
+ // Short variable names
201
+ var RG = RGraph,
202
+ ca = this.canvas,
203
+ co = ca.getContext('2d'),
204
+ prop = this.properties,
205
+ pa = RG.Path,
206
+ pa2 = RG.path2,
207
+ win = window,
208
+ doc = document,
209
+ ma = Math
210
+
211
+
212
+
213
+ /**
214
+ * "Decorate" the object with the generic effects if the effects library has been included
215
+ */
216
+ if (RG.Effects && typeof RG.Effects.decorate === 'function') {
217
+ RG.Effects.decorate(this);
218
+ }
219
+
220
+
221
+
222
+
223
+ /**
224
+ * A generic setter
225
+ *
226
+ * @param string name The name of the property to set
227
+ * @param string value The value of the poperty
228
+ */
229
+ this.set =
230
+ this.Set = function (name)
231
+ {
232
+ var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
233
+
234
+ /**
235
+ * the number of arguments is only one and it's an
236
+ * object - parse it for configuration data and return.
237
+ */
238
+ if (arguments.length === 1 && typeof name === 'object') {
239
+ RG.parseObjectStyleConfig(this, name);
240
+ return this;
241
+ }
242
+
243
+
244
+
245
+
246
+
247
+ /**
248
+ * This should be done first - prepend the propertyy name with "chart." if necessary
249
+ */
250
+ if (name.substr(0,6) != 'chart.') {
251
+ name = 'chart.' + name;
252
+ }
253
+
254
+
255
+
256
+
257
+ // Convert uppercase letters to dot+lower case letter
258
+ name = name.replace(/([A-Z])/g, function (str)
259
+ {
260
+ return '.' + String(RegExp.$1).toLowerCase();
261
+ });
262
+
263
+
264
+ /**
265
+ * chart.strokestyle now sets both chart.strokestyle.inner and chart.strokestyle.outer
266
+ */
267
+ if (name == 'chart.strokestyle') {
268
+ this.Set('chart.strokestyle.inner', value);
269
+ this.Set('chart.strokestyle.outer', value);
270
+ return;
271
+ }
272
+
273
+
274
+
275
+
276
+
277
+
278
+ prop[name] = value;
279
+
280
+ return this;
281
+ };
282
+
283
+
284
+
285
+
286
+ /**
287
+ * A generic getter
288
+ *
289
+ * @param string name The name of the property to get
290
+ */
291
+ this.get =
292
+ this.Get = function (name)
293
+ {
294
+ /**
295
+ * This should be done first - prepend the property name with "chart." if necessary
296
+ */
297
+ if (name.substr(0,6) != 'chart.') {
298
+ name = 'chart.' + name;
299
+ }
300
+
301
+ // Convert uppercase letters to dot+lower case letter
302
+ name = name.replace(/([A-Z])/g, function (str)
303
+ {
304
+ return '.' + String(RegExp.$1).toLowerCase()
305
+ });
306
+
307
+ return prop[name.toLowerCase()];
308
+ };
309
+
310
+
311
+
312
+
313
+ /**
314
+ * Draws the progress bar
315
+ */
316
+ this.draw =
317
+ this.Draw = function ()
318
+ {
319
+ /**
320
+ * Fire the onbeforedraw event
321
+ */
322
+ RG.FireCustomEvent(this, 'onbeforedraw');
323
+
324
+
325
+
326
+ /**
327
+ * Parse the colors. This allows for simple gradient syntax
328
+ */
329
+ if (!this.colorsParsed) {
330
+
331
+ this.parseColors();
332
+
333
+
334
+ // Don't want to do this again
335
+ this.colorsParsed = true;
336
+ }
337
+
338
+
339
+ /**
340
+ * Set the current value
341
+ */
342
+ this.currentValue = this.value;
343
+
344
+ /**
345
+ * This is new in May 2011 and facilitates individual gutter settings,
346
+ * eg chart.gutter.left
347
+ */
348
+ this.gutterLeft = prop['chart.gutter.left'];
349
+ this.gutterRight = prop['chart.gutter.right'];
350
+ this.gutterTop = prop['chart.gutter.top'];
351
+ this.gutterBottom = prop['chart.gutter.bottom'];
352
+
353
+ // Figure out the width and height
354
+ this.width = ca.width - this.gutterLeft - this.gutterRight;
355
+ this.height = ca.height - this.gutterTop - this.gutterBottom;
356
+ this.coords = [];
357
+ this.coordsText = [];
358
+
359
+ this.Drawbar();
360
+ this.DrawTickMarks();
361
+ this.DrawLabels();
362
+ this.DrawTitle();
363
+
364
+ co.stroke();
365
+ co.fill();
366
+
367
+
368
+ /**
369
+ * Draw the bevel effect if requested
370
+ */
371
+ if (prop['chart.bevel']) {
372
+ this.DrawBevel();
373
+ }
374
+
375
+
376
+ /**
377
+ * Setup the context menu if required
378
+ */
379
+ if (prop['chart.contextmenu']) {
380
+ RG.ShowContext(this);
381
+ }
382
+
383
+
384
+ // Draw the key if necessary
385
+ if (prop['chart.key'] && prop['chart.key'].length) {
386
+ RG.DrawKey(this, prop['chart.key'], prop['chart.colors']);
387
+ }
388
+
389
+
390
+ /**
391
+ * This function enables resizing
392
+ */
393
+ if (prop['chart.resizable']) {
394
+ RG.AllowResizing(this);
395
+ }
396
+
397
+
398
+
399
+ /**
400
+ * This installs the event listeners
401
+ */
402
+ RG.InstallEventListeners(this);
403
+
404
+ /**
405
+ * Fire the onfirstdraw event
406
+ */
407
+ if (this.firstDraw) {
408
+ RG.fireCustomEvent(this, 'onfirstdraw');
409
+ this.firstDraw = false;
410
+ this.firstDrawFunc();
411
+ }
412
+
413
+
414
+ /**
415
+ * Fire the RGraph ondraw event
416
+ */
417
+ RG.FireCustomEvent(this, 'ondraw');
418
+
419
+ return this;
420
+ };
421
+
422
+
423
+
424
+ /**
425
+ * Used in chaining. Runs a function there and then - not waiting for
426
+ * the events to fire (eg the onbeforedraw event)
427
+ *
428
+ * @param function func The function to execute
429
+ */
430
+ this.exec = function (func)
431
+ {
432
+ func(this);
433
+
434
+ return this;
435
+ };
436
+
437
+
438
+
439
+
440
+ /**
441
+ * Draws the bar
442
+ */
443
+ this.drawbar =
444
+ this.Drawbar = function ()
445
+ {
446
+ /**
447
+ * First get the scale
448
+ */
449
+
450
+ this.scale2 = RG.getScale2(this, {
451
+ 'max':this.max,
452
+ 'min':this.min,
453
+ 'strict':true,
454
+ 'scale.thousand':prop['chart.scale.thousand'],
455
+ 'scale.point':prop['chart.scale.point'],
456
+ 'scale.decimals':prop['chart.scale.decimals'],
457
+ 'ylabels.count':prop['chart.labels.count'],
458
+ 'scale.round':prop['chart.scale.round'],
459
+ 'units.pre': prop['chart.units.pre'],
460
+ 'units.post': prop['chart.units.post']
461
+ });
462
+
463
+ // Set a shadow if requested
464
+ if (prop['chart.shadow']) {
465
+ RG.SetShadow(this, prop['chart.shadow.color'], prop['chart.shadow.offsetx'], prop['chart.shadow.offsety'], prop['chart.shadow.blur']);
466
+ }
467
+
468
+ // Draw the shadow for MSIE
469
+ if (RG.ISOLD && prop['chart.shadow']) {
470
+ co.fillStyle = prop['chart.shadow.color'];
471
+ co.fillRect(this.gutterLeft + prop['chart.shadow.offsetx'], this.gutterTop + prop['chart.shadow.offsety'], this.width, this.height);
472
+ }
473
+
474
+ // Draw the outline
475
+ co.fillStyle = prop['chart.background.color'];
476
+ co.strokeStyle = prop['chart.strokestyle.outer'];
477
+ co.strokeRect(this.gutterLeft, this.gutterTop, this.width, this.height);
478
+ co.fillRect(this.gutterLeft, this.gutterTop, this.width, this.height);
479
+
480
+ // Turn off any shadow
481
+ RG.NoShadow(this);
482
+
483
+ co.fillStyle = prop['chart.colors'][0];
484
+ co.strokeStyle = prop['chart.strokestyle.outer'];
485
+
486
+ var margin = prop['chart.margin'];
487
+
488
+ // Draw the actual bar itself
489
+ var barWidth = Math.min(this.width, ((RG.array_sum(this.value) - this.min) / (this.max - this.min) ) * this.width);
490
+
491
+ if (prop['chart.tickmarks.inner']) {
492
+
493
+ var spacing = (ca.width - this.gutterLeft - this.gutterRight) / prop['chart.numticks.inner'];
494
+
495
+ co.lineWidth = 1;
496
+ co.strokeStyle = prop['chart.strokestyle.outer'];
497
+
498
+ co.beginPath();
499
+ for (var x = this.gutterLeft; x<ca.width - this.gutterRight; x+=spacing) {
500
+ co.moveTo(Math.round(x), this.gutterTop);
501
+ co.lineTo(Math.round(x), this.gutterTop + 2);
502
+
503
+ co.moveTo(Math.round(x), ca.height - this.gutterBottom);
504
+ co.lineTo(Math.round(x), ca.height - this.gutterBottom - 2);
505
+ }
506
+ co.stroke();
507
+ }
508
+
509
+ /**
510
+ * This bit draws the actual progress bar
511
+ */
512
+ if (typeof(this.value) == 'number') {
513
+ co.beginPath();
514
+ co.strokeStyle = prop['chart.strokestyle.inner'];
515
+ co.fillStyle = prop['chart.colors'][0];
516
+
517
+ if (prop['chart.border.inner']) {
518
+ co.strokeRect(this.gutterLeft, this.gutterTop + margin, barWidth, this.height - margin - margin);
519
+ }
520
+ co.fillRect(this.gutterLeft, this.gutterTop + margin, barWidth, this.height - margin - margin);
521
+
522
+ // Store the coords
523
+ this.coords.push([this.gutterLeft,
524
+ this.gutterTop + margin,
525
+ barWidth,
526
+ this.height - margin - margin]);
527
+
528
+ } else if (typeof(this.value) == 'object') {
529
+
530
+ co.beginPath();
531
+ co.strokeStyle = prop['chart.strokestyle.inner'];
532
+
533
+ var startPoint = this.gutterLeft;
534
+
535
+ for (var i=0; i<this.value.length; ++i) {
536
+
537
+ var segmentLength = (this.value[i] / RG.array_sum(this.value)) * barWidth;
538
+ co.fillStyle = prop['chart.colors'][i];
539
+
540
+ if (prop['chart.border.inner']) {
541
+ co.strokeRect(startPoint, this.gutterTop + margin, segmentLength, this.height - margin - margin);
542
+ }
543
+ co.fillRect(startPoint, this.gutterTop + margin, segmentLength, this.height - margin - margin);
544
+
545
+
546
+ // Store the coords
547
+ this.coords.push([startPoint,
548
+ this.gutterTop + margin,
549
+ segmentLength,
550
+ this.height - margin - margin]);
551
+
552
+ startPoint += segmentLength;
553
+ }
554
+ }
555
+
556
+ /**
557
+ * Draw the arrows indicating the level if requested
558
+ */
559
+ if (prop['chart.arrows']) {
560
+ var x = this.gutterLeft + barWidth;
561
+ var y = this.gutterTop;
562
+
563
+ co.lineWidth = 1;
564
+ co.fillStyle = 'black';
565
+ co.strokeStyle = 'black';
566
+
567
+ co.beginPath();
568
+ co.moveTo(x, y - 3);
569
+ co.lineTo(x + 2, y - 7);
570
+ co.lineTo(x - 2, y - 7);
571
+ co.closePath();
572
+
573
+ co.stroke();
574
+ co.fill();
575
+
576
+ co.beginPath();
577
+ co.moveTo(x, y + this.height + 4);
578
+ co.lineTo(x + 2, y + this.height + 9);
579
+ co.lineTo(x - 2, y + this.height + 9);
580
+ co.closePath();
581
+
582
+ co.stroke();
583
+ co.fill()
584
+ }
585
+
586
+
587
+ /**
588
+ * Draw the "in-bar" label
589
+ */
590
+ if (prop['chart.label.inner']) {
591
+ co.fillStyle = 'black';
592
+ RG.Text2(this, {'font':prop['chart.text.font'],
593
+ 'size':prop['chart.text.size'] + 2,
594
+ 'x':this.gutterLeft + barWidth + 5,
595
+ 'y':this.gutterTop + (this.height / 2),
596
+ 'text': String(prop['chart.units.pre'] + this.value + prop['chart.units.post']),
597
+ 'valign':'bottom',
598
+ 'halign':'left',
599
+ 'bounding':true,
600
+ 'boundingFill':'white',
601
+ 'tag': 'label.inner'
602
+ });
603
+ }
604
+ };
605
+
606
+
607
+
608
+
609
+ /**
610
+ * The function that draws the tick marks. Apt name...
611
+ */
612
+ this.drawTickMarks =
613
+ this.DrawTickMarks = function ()
614
+ {
615
+ co.strokeStyle = prop['chart.tickmarks.color'];
616
+
617
+ if (prop['chart.tickmarks']) {
618
+
619
+ co.beginPath();
620
+
621
+ // This is used by the label function below
622
+ this.tickInterval = this.width / prop['chart.numticks'];
623
+
624
+ var start = prop['chart.tickmarks.zerostart'] ? 0 : this.tickInterval;
625
+
626
+ if (prop['chart.labels.position'] == 'top') {
627
+ for (var i=this.gutterLeft + start; i<=(this.width + this.gutterLeft + 0.1); i+=this.tickInterval) {
628
+ co.moveTo(Math.round(i), this.gutterTop);
629
+ co.lineTo(Math.round(i), this.gutterTop - 4);
630
+ }
631
+
632
+ } else {
633
+
634
+ for (var i=this.gutterLeft + start; i<=(this.width + this.gutterLeft + 0.1); i+=this.tickInterval) {
635
+ co.moveTo(Math.round(i), this.gutterTop + this.height);
636
+ co.lineTo(Math.round(i), this.gutterTop + this.height + 4);
637
+ }
638
+ }
639
+
640
+ co.stroke();
641
+ }
642
+ };
643
+
644
+
645
+
646
+
647
+ /**
648
+ * The function that draws the labels
649
+ */
650
+ this.drawLabels =
651
+ this.DrawLabels = function ()
652
+ {
653
+ if (!RG.is_null(prop['chart.labels.specific'])) {
654
+ return this.DrawSpecificLabels();
655
+ }
656
+
657
+ co.fillStyle = prop['chart.text.color'];
658
+
659
+ var xPoints = [];
660
+ var yPoints = [];
661
+ var font = prop['chart.text.font'];
662
+ var size = prop['chart.text.size'];
663
+
664
+ for (i=0,len=this.scale2.labels.length; i<len; i++) {
665
+
666
+
667
+ if (prop['chart.labels.position'] == 'top') {
668
+ var x = this.width * (i/this.scale2.labels.length) + this.gutterLeft + (this.width / this.scale2.labels.length);
669
+ var y = this.gutterTop - 6;
670
+ var valign = 'bottom';
671
+ } else {
672
+ var x = this.width * (i/this.scale2.labels.length) + this.gutterLeft + (this.width / this.scale2.labels.length);
673
+ var y = this.height + this.gutterTop + 4;
674
+ var valign = 'top';
675
+ }
676
+
677
+ RG.Text2(this, {'font':font,
678
+ 'size':size,
679
+ 'x':x,
680
+ 'y':y,
681
+ 'text': this.scale2.labels[i],
682
+ 'valign':valign,
683
+ 'halign':'center',
684
+ 'tag': 'scale'
685
+ });
686
+ }
687
+
688
+ if (prop['chart.tickmarks.zerostart']) {
689
+ if (prop['chart.labels.position'] == 'top') {
690
+ RG.Text2(this, {'font':font,
691
+ 'size':size,
692
+ 'x':this.gutterLeft,
693
+ 'y':this.gutterTop - 6,
694
+ 'text': prop['chart.units.pre'] + Number(this.min).toFixed(prop['chart.scale.decimals']) + prop['chart.units.post'],
695
+ 'valign':'bottom',
696
+ 'halign':'center',
697
+ 'tag': 'scale'
698
+ });
699
+ } else {
700
+ RG.Text2(this, {'font':font,
701
+ 'size':size,
702
+ 'x':this.gutterLeft,
703
+ 'y':ca.height - this.gutterBottom + 5,
704
+ 'text': prop['chart.units.pre'] + Number(this.min).toFixed(prop['chart.scale.decimals']) + prop['chart.units.post'],
705
+ 'valign':'top',
706
+ 'halign':'center',
707
+ 'tag': 'scale'
708
+ });
709
+ }
710
+ }
711
+ };
712
+
713
+
714
+
715
+
716
+ /**
717
+ * Returns the focused bar
718
+ *
719
+ * @param event e The event object
720
+ */
721
+ this.getShape =
722
+ this.getBar = function (e)
723
+ {
724
+ var mouseCoords = RG.getMouseXY(e)
725
+
726
+ for (var i=0; i<this.coords.length; i++) {
727
+
728
+ var mouseCoords = RG.getMouseXY(e);
729
+ var mouseX = mouseCoords[0];
730
+ var mouseY = mouseCoords[1];
731
+ var left = this.coords[i][0];
732
+ var top = this.coords[i][1];
733
+ var width = this.coords[i][2];
734
+ var height = this.coords[i][3];
735
+ var idx = i;
736
+
737
+ if (mouseX >= left && mouseX <= (left + width) && mouseY >= top && mouseY <= (top + height) ) {
738
+
739
+ var tooltip = RG.parseTooltipText(prop['chart.tooltips'], idx);
740
+
741
+ return {
742
+ 0: this, 1: left, 2: top, 3: width, 4: height, 5: idx,
743
+ 'object':this, 'x':left, 'y':top, 'width': width, 'height': height, 'index': idx, 'tooltip': tooltip
744
+ }
745
+ }
746
+ }
747
+ };
748
+
749
+
750
+
751
+
752
+ /**
753
+ * This function returns the value that the mouse is positioned at, regardless of
754
+ * the actual indicated value.
755
+ *
756
+ * @param object e The event object
757
+ */
758
+ this.getValue = function (e)
759
+ {
760
+ var mouseXY = RG.getMouseXY(e);
761
+
762
+ var value = (mouseXY[0] - this.gutterLeft) / this.width;
763
+ value *= this.max - this.min;
764
+ value += this.min;
765
+
766
+ if (mouseXY[0] < this.gutterLeft) {
767
+ value = this.min;
768
+ }
769
+ if (mouseXY[0] > (ca.width - this.gutterRight) ) {
770
+ value = this.max
771
+ }
772
+
773
+ return value;
774
+ };
775
+
776
+
777
+
778
+
779
+ /**
780
+ * Each object type has its own Highlight() function which highlights the appropriate shape
781
+ *
782
+ * @param object shape The shape to highlight
783
+ */
784
+ this.highlight =
785
+ this.Highlight = function (shape)
786
+ {
787
+ // Add the new highlight
788
+ RG.Highlight.Rect(this, shape);
789
+ };
790
+
791
+
792
+
793
+
794
+ /**
795
+ * The getObjectByXY() worker method. Don't call this call:
796
+ *
797
+ * RGraph.ObjectRegistry.getObjectByXY(e)
798
+ *
799
+ * @param object e The event object
800
+ */
801
+ this.getObjectByXY = function (e)
802
+ {
803
+ var mouseXY = RG.getMouseXY(e);
804
+
805
+ if (
806
+ mouseXY[0] > this.gutterLeft
807
+ && mouseXY[0] < (ca.width - this.gutterRight)
808
+ && mouseXY[1] > this.gutterTop
809
+ && mouseXY[1] < (ca.height - this.gutterBottom)
810
+ ) {
811
+
812
+ return this;
813
+ }
814
+ };
815
+
816
+
817
+
818
+
819
+ /**
820
+ * This method handles the adjusting calculation for when the mouse is moved
821
+ *
822
+ * @param object e The event object
823
+ */
824
+ this.adjusting_mousemove =
825
+ this.Adjusting_mousemove = function (e)
826
+ {
827
+ /**
828
+ * Handle adjusting for the HProgress
829
+ */
830
+ if (prop['chart.adjustable'] && RG.Registry.Get('chart.adjusting') && RG.Registry.Get('chart.adjusting').uid == this.uid) {
831
+
832
+ var mouseXY = RG.getMouseXY(e);
833
+ var value = this.getValue(e);
834
+
835
+ if (typeof(value) == 'number') {
836
+
837
+ this.value = Number(value.toFixed(prop['chart.scale.decimals']));
838
+ RG.redrawCanvas(ca);
839
+
840
+ // Fire the onadjust event
841
+ RG.fireCustomEvent(this, 'onadjust');
842
+ }
843
+ }
844
+ };
845
+
846
+
847
+
848
+
849
+ /**
850
+ * Draws chart.labels.specific
851
+ */
852
+ this.drawSpecificLabels =
853
+ this.DrawSpecificLabels = function ()
854
+ {
855
+ var labels = prop['chart.labels.specific'];
856
+
857
+ if (labels) {
858
+
859
+ var font = prop['chart.text.font'];
860
+ var size = prop['chart.text.size'];
861
+ var valign = (prop['chart.labels.position'] == 'top' ? 'bottom' : 'top');
862
+ var step = this.width / (labels.length - 1);
863
+
864
+ co.beginPath();
865
+ co.fillStyle = prop['chart.text.color'];
866
+ for (var i=0; i<labels.length; ++i) {
867
+ RG.Text2(this, {'font':font,
868
+ 'size':size,
869
+ 'x': this.gutterLeft + (step * i),
870
+ 'y':prop['chart.labels.position'] == 'top' ? this.gutterTop - 7 : ca.height - this.gutterBottom + 7,
871
+ 'text': labels[i],
872
+ 'valign':valign,
873
+ 'halign':'center',
874
+ 'tag': 'labels.specific'
875
+ });
876
+ }
877
+ co.fill();
878
+ }
879
+ };
880
+
881
+
882
+
883
+
884
+ /**
885
+ * This function positions a tooltip when it is displayed
886
+ *
887
+ * @param obj object The chart object
888
+ * @param int x The X coordinate specified for the tooltip
889
+ * @param int y The Y coordinate specified for the tooltip
890
+ * @param objec tooltip The tooltips DIV element
891
+ */
892
+ this.positionTooltip = function (obj, x, y, tooltip, idx)
893
+ {
894
+ var coordX = obj.coords[tooltip.__index__][0];
895
+ var coordY = obj.coords[tooltip.__index__][1];
896
+ var coordW = obj.coords[tooltip.__index__][2];
897
+ var coordH = obj.coords[tooltip.__index__][3];
898
+ var canvasXY = RG.getCanvasXY(obj.canvas);
899
+ var gutterLeft = this.gutterLeft;
900
+ var gutterTop = this.gutterTop;
901
+ var width = tooltip.offsetWidth;
902
+ var height = tooltip.offsetHeight;
903
+
904
+ // Set the top position
905
+ tooltip.style.left = 0;
906
+ tooltip.style.top = canvasXY[1] + coordY - height - 7 + 'px';
907
+
908
+ // By default any overflow is hidden
909
+ tooltip.style.overflow = '';
910
+
911
+ // The arrow
912
+ var img = new Image();
913
+ img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAFCAYAAACjKgd3AAAARUlEQVQYV2NkQAN79+797+RkhC4M5+/bd47B2dmZEVkBCgcmgcsgbAaA9GA1BCSBbhAuA/AagmwQPgMIGgIzCD0M0AMMAEFVIAa6UQgcAAAAAElFTkSuQmCC';
914
+ img.style.position = 'absolute';
915
+ img.id = '__rgraph_tooltip_pointer__';
916
+ img.style.top = (tooltip.offsetHeight - 2) + 'px';
917
+ tooltip.appendChild(img);
918
+
919
+ // Reposition the tooltip if at the edges:
920
+
921
+ // LEFT edge
922
+ if ((canvasXY[0] + coordX + (coordW / 2) - (width / 2)) < 10) {
923
+ tooltip.style.left = (canvasXY[0] + coordX - (width * 0.1)) + (coordW / 2) + 'px';
924
+ img.style.left = ((width * 0.1) - 8.5) + 'px';
925
+
926
+ // RIGHT edge
927
+ } else if ((canvasXY[0] + (coordW / 2) + coordX + (width / 2)) > document.body.offsetWidth) {
928
+ tooltip.style.left = canvasXY[0] + coordX - (width * 0.9) + (coordW / 2) + 'px';
929
+ img.style.left = ((width * 0.9) - 8.5) + 'px';
930
+
931
+ // Default positioning - CENTERED
932
+ } else {
933
+ tooltip.style.left = (canvasXY[0] + coordX + (coordW / 2) - (width * 0.5)) + 'px';
934
+ img.style.left = ((width * 0.5) - 8.5) + 'px';
935
+ }
936
+ };
937
+
938
+
939
+
940
+
941
+ /**
942
+ * This function returns the appropriate X coordinate for the given value
943
+ *
944
+ * @param int value The value you want the coordinate for
945
+ * @returm int The coordinate
946
+ */
947
+ this.getXCoord = function (value)
948
+ {
949
+ var min = this.min;
950
+
951
+ if (value < min || value > this.max) {
952
+ return null;
953
+ }
954
+
955
+ var barWidth = ca.width - this.gutterLeft - this.gutterRight;
956
+ var coord = ((value - min) / (this.max - min)) * barWidth;
957
+ coord = this.gutterLeft + coord;
958
+
959
+ return coord;
960
+ };
961
+
962
+
963
+
964
+
965
+ /**
966
+ * This returns true/false as to whether the cursor is over the chart area.
967
+ * The cursor does not necessarily have to be over the bar itself.
968
+ */
969
+ this.overChartArea = function (e)
970
+ {
971
+ var mouseXY = RGraph.getMouseXY(e);
972
+ var mouseX = mouseXY[0];
973
+ var mouseY = mouseXY[1];
974
+
975
+ if ( mouseX >= this.gutterLeft
976
+ && mouseX <= (ca.width - this.gutterRight)
977
+ && mouseY >= this.gutterTop
978
+ && mouseY <= (ca.height - this.gutterBottom)
979
+ ) {
980
+
981
+ return true;
982
+ }
983
+
984
+ return false;
985
+ };
986
+
987
+
988
+
989
+
990
+ /**
991
+ *
992
+ */
993
+ this.parseColors = function ()
994
+ {
995
+
996
+ // Save the original colors so that they can be restored when the canvas is reset
997
+ if (this.original_colors.length === 0) {
998
+ this.original_colors['chart.colors'] = RG.array_clone(prop['chart.colors']);
999
+ this.original_colors['chart.tickmarks.color'] = RG.array_clone(prop['chart.tickmarks.color']);
1000
+ this.original_colors['chart.strokestyle.inner'] = RG.array_clone(prop['chart.strokestyle.inner']);
1001
+ this.original_colors['chart.strokestyle.outer'] = RG.array_clone(prop['chart.strokestyle.outer']);
1002
+ this.original_colors['chart.highlight.fill'] = RG.array_clone(prop['chart.highlight.fill']);
1003
+ this.original_colors['chart.highlight.stroke'] = RG.array_clone(prop['chart.highlight.stroke']);
1004
+ this.original_colors['chart.highlight.color'] = RG.array_clone(prop['chart.highlight.color']);
1005
+ }
1006
+
1007
+
1008
+
1009
+
1010
+ var colors = prop['chart.colors'];
1011
+
1012
+ for (var i=0; i<colors.length; ++i) {
1013
+ colors[i] = this.parseSingleColorForGradient(colors[i]);
1014
+ }
1015
+
1016
+ prop['chart.tickmarks.color'] = this.parseSingleColorForGradient(prop['chart.tickmarks.color']);
1017
+ prop['chart.strokestyle.inner'] = this.parseSingleColorForGradient(prop['chart.strokestyle.inner']);
1018
+ prop['chart.strokestyle.outer'] = this.parseSingleColorForGradient(prop['chart.strokestyle.outer']);
1019
+ prop['chart.highlight.fill'] = this.parseSingleColorForGradient(prop['chart.highlight.fill']);
1020
+ prop['chart.highlight.stroke'] = this.parseSingleColorForGradient(prop['chart.highlight.stroke']);
1021
+ prop['chart.background.color'] = this.parseSingleColorForGradient(prop['chart.background.color']);
1022
+ };
1023
+
1024
+
1025
+
1026
+
1027
+ /**
1028
+ * Use this function to reset the object to the post-constructor state. Eg reset colors if
1029
+ * need be etc
1030
+ */
1031
+ this.reset = function ()
1032
+ {
1033
+ };
1034
+
1035
+
1036
+
1037
+
1038
+ /**
1039
+ * This parses a single color value
1040
+ */
1041
+ this.parseSingleColorForGradient = function (color)
1042
+ {
1043
+ if (!color || typeof(color) != 'string') {
1044
+ return color;
1045
+ }
1046
+
1047
+ if (color.match(/^gradient\((.*)\)$/i)) {
1048
+
1049
+ var parts = RegExp.$1.split(':');
1050
+
1051
+ // Create the gradient
1052
+ var grad = co.createLinearGradient(prop['chart.gutter.left'],0,ca.width - prop['chart.gutter.right'],0);
1053
+
1054
+ var diff = 1 / (parts.length - 1);
1055
+
1056
+ grad.addColorStop(0, RG.trim(parts[0]));
1057
+
1058
+ for (var j=1; j<parts.length; ++j) {
1059
+ grad.addColorStop(j * diff, RG.trim(parts[j]));
1060
+ }
1061
+ }
1062
+
1063
+ return grad ? grad : color;
1064
+ };
1065
+
1066
+
1067
+
1068
+
1069
+ /**
1070
+ * Draws the bevel effect
1071
+ */
1072
+ this.drawBevel =
1073
+ this.DrawBevel = function ()
1074
+ {
1075
+ // In case of multiple segments - this adds up all the lengths
1076
+ for (var i=0,len=0; i<this.coords.length; ++i) len += this.coords[i][2];
1077
+
1078
+ co.save();
1079
+ // Draw a path to clip to
1080
+ co.beginPath();
1081
+ co.rect(this.coords[0][0], this.coords[0][1], len, this.coords[0][3]);
1082
+ co.clip();
1083
+
1084
+ // Now draw the rect with a shadow
1085
+ co.beginPath();
1086
+
1087
+ co.shadowColor = 'black';
1088
+ co.shadowOffsetX = 0;
1089
+ co.shadowOffsetY = 0;
1090
+ co.shadowBlur = 15;
1091
+
1092
+ co.lineWidth = 2;
1093
+
1094
+ co.rect(this.coords[0][0] - 1, this.coords[0][1] - 1, len + 2, this.coords[0][3] + 2);
1095
+
1096
+ co.stroke();
1097
+
1098
+ co.restore();
1099
+ };
1100
+
1101
+
1102
+
1103
+
1104
+ /**
1105
+ * Draw the titles
1106
+ */
1107
+ this.drawTitle =
1108
+ this.DrawTitle = function ()
1109
+ {
1110
+ // Draw the title text
1111
+ if (prop['chart.title'].length) {
1112
+
1113
+ var x = ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
1114
+ var text = prop['chart.title'];
1115
+ var size = prop['chart.title.size'] ? prop['chart.title.size'] : prop['chart.text.size'] + 2;
1116
+ var font = prop['chart.title.font'] ? prop['chart.title.font'] : prop['chart.text.font'];
1117
+
1118
+ if (prop['chart.labels.position'] == 'top') {
1119
+ y = ca.height - this.gutterBottom +5;
1120
+ x = ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
1121
+ valign = 'top';
1122
+ } else {
1123
+ x = ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
1124
+ y = this.gutterTop - 5;
1125
+ valign = 'bottom';
1126
+ }
1127
+
1128
+
1129
+ RG.Text2(this, {'font':font,
1130
+ 'size':size,
1131
+ 'x': typeof(prop['chart.title.x']) == 'number' ? prop['chart.title.x'] : x,
1132
+ 'y': typeof(prop['chart.title.y']) == 'number' ? prop['chart.title.y'] : y,
1133
+ 'text': text,
1134
+ 'valign': prop['chart.title.valign'] ? prop['chart.title.valign'] : valign,
1135
+ 'halign': prop['chart.title.halign'] ? prop['chart.title.halign'] : 'center',
1136
+ 'bold':prop['chart.title.bold'],
1137
+ 'bounding': prop['chart.title.background'] ? true : false,
1138
+ 'boundingFill': prop['chart.title.background'],
1139
+ 'tag': 'title'
1140
+ });
1141
+ }
1142
+ };
1143
+
1144
+
1145
+
1146
+
1147
+ /**
1148
+ * This function handles highlighting an entire data-series for the interactive
1149
+ * key
1150
+ *
1151
+ * @param int index The index of the data series to be highlighted
1152
+ */
1153
+ this.interactiveKeyHighlight = function (index)
1154
+ {
1155
+ var coords = this.coords[index];
1156
+
1157
+ co.beginPath();
1158
+
1159
+ co.strokeStyle = prop['chart.key.interactive.highlight.chart.stroke'];
1160
+ co.lineWidth = 2;
1161
+ co.fillStyle = prop['chart.key.interactive.highlight.chart.fill'];
1162
+
1163
+ co.rect(coords[0], coords[1], coords[2], coords[3]);
1164
+ co.fill();
1165
+ co.stroke();
1166
+
1167
+ // Reset the linewidth
1168
+ co.lineWidth = 1;
1169
+ };
1170
+
1171
+
1172
+
1173
+
1174
+ /**
1175
+ * Using a function to add events makes it easier to facilitate method chaining
1176
+ *
1177
+ * @param string type The type of even to add
1178
+ * @param function func
1179
+ */
1180
+ this.on = function (type, func)
1181
+ {
1182
+ if (type.substr(0,2) !== 'on') {
1183
+ type = 'on' + type;
1184
+ }
1185
+
1186
+ this[type] = func;
1187
+
1188
+ return this;
1189
+ };
1190
+
1191
+
1192
+
1193
+
1194
+ /**
1195
+ * This function runs once only
1196
+ * (put at the end of the file (before any effects))
1197
+ */
1198
+ this.firstDrawFunc = function ()
1199
+ {
1200
+ };
1201
+
1202
+
1203
+
1204
+
1205
+ /**
1206
+ * HProgress Grow effect (which is also the VPogress Grow effect)
1207
+ *
1208
+ * @param object obj The chart object
1209
+ */
1210
+ this.grow = function ()
1211
+ {
1212
+ var obj = this;
1213
+ var canvas = obj.canvas;
1214
+ var context = obj.context;
1215
+ var initial_value = obj.currentValue;
1216
+ var opt = arguments[0] || {};
1217
+ var numFrames = opt.frames || 30;
1218
+ var frame = 0
1219
+ var callback = arguments[1] || function () {};
1220
+
1221
+ if (typeof obj.value === 'object') {
1222
+
1223
+ if (RG.is_null(obj.currentValue)) {
1224
+ obj.currentValue = [];
1225
+ for (var i=0,len=obj.value.length; i<len; ++i) {
1226
+ obj.currentValue[i] = 0;
1227
+ }
1228
+ }
1229
+
1230
+ var diff = [];
1231
+ var increment = [];
1232
+
1233
+ for (var i=0,len=obj.value.length; i<len; ++i) {
1234
+ diff[i] = obj.value[i] - Number(obj.currentValue[i]);
1235
+ increment[i] = diff[i] / numFrames;
1236
+ }
1237
+
1238
+ if (initial_value == null) {
1239
+ initial_value = [];
1240
+ for (var i=0,len=obj.value.length; i<len; ++i) {
1241
+ initial_value[i] = 0;
1242
+ }
1243
+ }
1244
+
1245
+ } else {
1246
+
1247
+ var diff = obj.value - Number(obj.currentValue);
1248
+ var increment = diff / numFrames;
1249
+ }
1250
+
1251
+
1252
+
1253
+
1254
+
1255
+
1256
+ function iterator ()
1257
+ {
1258
+ frame++;
1259
+
1260
+ if (frame <= numFrames) {
1261
+
1262
+ if (typeof obj.value == 'object') {
1263
+ obj.value = [];
1264
+ for (var i=0,len=initial_value.length; i<len; ++i) {
1265
+ obj.value[i] = initial_value[i] + (increment[i] * frame);
1266
+ }
1267
+ } else {
1268
+ obj.value = initial_value + (increment * frame);
1269
+ }
1270
+
1271
+ RGraph.clear(obj.canvas);
1272
+ RGraph.redrawCanvas(obj.canvas);
1273
+
1274
+ RGraph.Effects.updateCanvas(iterator);
1275
+ } else {
1276
+ callback();
1277
+ }
1278
+ }
1279
+
1280
+ iterator();
1281
+
1282
+ return this;
1283
+ };
1284
+
1285
+
1286
+
1287
+ RG.att(ca);
1288
+
1289
+
1290
+
1291
+
1292
+ /**
1293
+ * Register the object for redrawing
1294
+ */
1295
+ RG.Register(this);
1296
+
1297
+
1298
+
1299
+
1300
+ /**
1301
+ * This is the 'end' of the constructor so if the first argument
1302
+ * contains configuration data - handle that.
1303
+ */
1304
+ if (parseConfObjectForOptions) {
1305
+ RG.parseObjectStyleConfig(this, conf.options);
1306
+ }
1307
+ };