rgraph-rails 1.0.1

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 (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
+ };