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,1242 @@
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 bar chart constructor
20
+ *
21
+ * @param string canvas The canvas ID
22
+ * @param min integer The minimum value
23
+ * @param max integer The maximum value
24
+ * @param value integer The indicated value
25
+ */
26
+ RGraph.Meter = function (conf)
27
+ {
28
+ /**
29
+ * Allow for object config style
30
+ */
31
+ if ( typeof conf === 'object'
32
+ && typeof conf.min === 'number'
33
+ && typeof conf.max === 'number'
34
+ && typeof conf.value !== 'undefined'
35
+ && typeof conf.id === 'string') {
36
+
37
+ var id = conf.id
38
+ var canvas = document.getElementById(id);
39
+ var min = conf.min;
40
+ var max = conf.max;
41
+ var value = conf.value;
42
+ var parseConfObjectForOptions = true; // Set this so the config is parsed (at the end of the constructor)
43
+
44
+ } else {
45
+
46
+ var id = conf;
47
+ var canvas = document.getElementById(id);
48
+ var min = arguments[1];
49
+ var max = arguments[2];
50
+ var value = arguments[3];
51
+ }
52
+
53
+
54
+
55
+
56
+ // id, min, max, value
57
+ // Get the canvas and context objects
58
+ this.id = id;
59
+ this.canvas = canvas;
60
+ this.context = this.canvas.getContext ? this.canvas.getContext("2d", {alpha: (typeof id === 'object' && id.alpha === false) ? false : true}) : null;
61
+ this.canvas.__object__ = this;
62
+ this.type = 'meter';
63
+ this.min = min;
64
+ this.max = max;
65
+ this.value = RGraph.stringsToNumbers(value);
66
+ this.centerx = null;
67
+ this.centery = null;
68
+ this.radius = null;
69
+ this.isRGraph = true;
70
+ this.currentValue = null;
71
+ this.uid = RGraph.CreateUID();
72
+ this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.CreateUID();
73
+ this.colorsParsed = false;
74
+ this.coordsText = [];
75
+ this.original_colors = [];
76
+ this.firstDraw = true; // After the first draw this will be false
77
+
78
+
79
+ /**
80
+ * Compatibility with older browsers
81
+ */
82
+ //RGraph.OldBrowserCompat(this.context);
83
+
84
+
85
+ // Various config type stuff
86
+ this.properties =
87
+ {
88
+ 'chart.background.image.url': null,
89
+ 'chart.background.image.offsetx': 0,
90
+ 'chart.background.image.offsety': 0,
91
+ 'chart.background.image.stretch': true,
92
+ 'chart.background.color': 'white',
93
+ 'chart.gutter.left': 15,
94
+ 'chart.gutter.right': 15,
95
+ 'chart.gutter.top': 15,
96
+ 'chart.gutter.bottom': 20,
97
+ 'chart.linewidth': 1,
98
+ 'chart.linewidth.segments': 0,
99
+ 'chart.strokestyle': null,
100
+ 'chart.border': true,
101
+ 'chart.border.color': 'black',
102
+ 'chart.text.font': 'Arial',
103
+ 'chart.text.size': 12,
104
+ 'chart.text.color': 'black',
105
+ 'chart.text.valign': 'center',
106
+ 'chart.value.text.decimals': 0,
107
+ 'chart.value.text.units.pre': '',
108
+ 'chart.value.text.units.post': '',
109
+ 'chart.title': '',
110
+ 'chart.title.background': null,
111
+ 'chart.title.hpos': null,
112
+ 'chart.title.vpos': null,
113
+ 'chart.title.color': 'black',
114
+ 'chart.title.bold': true,
115
+ 'chart.title.font': null,
116
+ 'chart.title.x': null,
117
+ 'chart.title.y': null,
118
+ 'chart.title.halign': null,
119
+ 'chart.title.valign': null,
120
+ 'chart.green.start': ((this.max - this.min) * 0.35) + this.min,
121
+ 'chart.green.end': this.max,
122
+ 'chart.green.color': '#207A20',
123
+ 'chart.yellow.start': ((this.max - this.min) * 0.1) + this.min,
124
+ 'chart.yellow.end': ((this.max - this.min) * 0.35) + this.min,
125
+ 'chart.yellow.color': '#D0AC41',
126
+ 'chart.red.start': this.min,
127
+ 'chart.red.end': ((this.max - this.min) * 0.1) + this.min,
128
+ 'chart.red.color': '#9E1E1E',
129
+ 'chart.colors.ranges': null,
130
+ 'chart.units.pre': '',
131
+ 'chart.units.post': '',
132
+ 'chart.contextmenu': null,
133
+ 'chart.zoom.factor': 1.5,
134
+ 'chart.zoom.fade.in': true,
135
+ 'chart.zoom.fade.out': true,
136
+ 'chart.zoom.hdir': 'right',
137
+ 'chart.zoom.vdir': 'down',
138
+ 'chart.zoom.frames': 25,
139
+ 'chart.zoom.delay': 16.666,
140
+ 'chart.zoom.shadow': true,
141
+ 'chart.zoom.background': true,
142
+ 'chart.zoom.action': 'zoom',
143
+ 'chart.annotatable': false,
144
+ 'chart.annotate.color': 'black',
145
+ 'chart.shadow': false,
146
+ 'chart.shadow.color': 'rgba(0,0,0,0.5)',
147
+ 'chart.shadow.blur': 3,
148
+ 'chart.shadow.offsetx': 3,
149
+ 'chart.shadow.offsety': 3,
150
+ 'chart.resizable': false,
151
+ 'chart.resize.handle.adjust': [0,0],
152
+ 'chart.resize.handle.background': null,
153
+ 'chart.tickmarks.small.num': 100,
154
+ 'chart.tickmarks.big.num': 10,
155
+ 'chart.tickmarks.small.color': '#bbb',
156
+ 'chart.tickmarks.big.color': 'black',
157
+ 'chart.scale.decimals': 0,
158
+ 'chart.scale.point': '.',
159
+ 'chart.scale.thousand': ',',
160
+ 'chart.radius': null,
161
+ 'chart.centerx': null,
162
+ 'chart.centery': null,
163
+ 'chart.labels': true,
164
+ 'chart.labels.count': 10,
165
+ 'chart.segment.radius.start': 0,
166
+ 'chart.needle.radius': null,
167
+ 'chart.needle.tail': false,
168
+ 'chart.needle.head': true,
169
+ 'chart.needle.color': 'black',
170
+ 'chart.needle.image.url': null,
171
+ 'chart.needle.image.offsetx': 0,
172
+ 'chart.needle.image.offsety': 0,
173
+ 'chart.adjustable': false,
174
+ 'chart.angles.start': RGraph.PI,
175
+ 'chart.angles.end': RGraph.TWOPI,
176
+ 'chart.centerpin.stroke': 'black',
177
+ 'chart.centerpin.fill': 'white'
178
+ }
179
+
180
+
181
+ // Check for support
182
+ if (!this.canvas) {
183
+ alert('[METER] No canvas support');
184
+ return;
185
+ }
186
+
187
+
188
+
189
+ /*
190
+ * Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
191
+ * done already
192
+ */
193
+ if (!this.canvas.__rgraph_aa_translated__) {
194
+ this.context.translate(0.5,0.5);
195
+
196
+ this.canvas.__rgraph_aa_translated__ = true;
197
+ }
198
+
199
+
200
+
201
+
202
+ // Short variable names
203
+ var RG = RGraph,
204
+ ca = this.canvas,
205
+ co = ca.getContext('2d'),
206
+ prop = this.properties,
207
+ pa = RG.Path,
208
+ pa2 = RG.path2,
209
+ win = window,
210
+ doc = document,
211
+ ma = Math
212
+
213
+
214
+
215
+ /**
216
+ * "Decorate" the object with the generic effects if the effects library has been included
217
+ */
218
+ if (RG.Effects && typeof RG.Effects.decorate === 'function') {
219
+ RG.Effects.decorate(this);
220
+ }
221
+
222
+
223
+
224
+ /**
225
+ * A setter
226
+ *
227
+ * @param name string The name of the property to set
228
+ * @param value mixed The value of the property
229
+ */
230
+ this.set =
231
+ this.Set = function (name)
232
+ {
233
+ var value = arguments[1] || null;
234
+
235
+ /**
236
+ * the number of arguments is only one and it's an
237
+ * object - parse it for configuration data and return.
238
+ */
239
+ if (arguments.length === 1 && typeof name === 'object') {
240
+ RG.parseObjectStyleConfig(this, name);
241
+ return this;
242
+ }
243
+
244
+
245
+
246
+
247
+
248
+ /**
249
+ * This should be done first - prepend the propertyy name with "chart." if necessary
250
+ */
251
+ if (name.substr(0,6) != 'chart.') {
252
+ name = 'chart.' + name;
253
+ }
254
+
255
+
256
+
257
+
258
+ // Convert uppercase letters to dot+lower case letter
259
+ name = name.replace(/([A-Z])/g, function (str)
260
+ {
261
+ return '.' + String(RegExp.$1).toLowerCase();
262
+ });
263
+
264
+
265
+
266
+
267
+ if (name == 'chart.value') {
268
+ this.value = value;
269
+ return;
270
+ }
271
+
272
+
273
+
274
+
275
+
276
+
277
+ prop[name] = value;
278
+
279
+ return this;
280
+ };
281
+
282
+
283
+
284
+
285
+ /**
286
+ * A getter
287
+ *
288
+ * @param name string The name of the property to get
289
+ */
290
+ this.get =
291
+ this.Get = function (name)
292
+ {
293
+ /**
294
+ * This should be done first - prepend the property name with "chart." if necessary
295
+ */
296
+ if (name.substr(0,6) != 'chart.') {
297
+ name = 'chart.' + name;
298
+ }
299
+
300
+ // Convert uppercase letters to dot+lower case letter
301
+ name = name.replace(/([A-Z])/g, function (str)
302
+ {
303
+ return '.' + String(RegExp.$1).toLowerCase()
304
+ });
305
+
306
+ if (name == 'chart.value') {
307
+ return this.value;
308
+ }
309
+
310
+ return prop[name];
311
+ };
312
+
313
+
314
+
315
+
316
+ /**
317
+ * The function you call to draw the bar chart
318
+ */
319
+ this.draw =
320
+ this.Draw = function ()
321
+ {
322
+ /**
323
+ * Fire the onbeforedraw event
324
+ */
325
+ RG.FireCustomEvent(this, 'onbeforedraw');
326
+
327
+ /**
328
+ * Constrain the value to be within the min and max
329
+ */
330
+ if (this.value > this.max) this.value = this.max;
331
+ if (this.value < this.min) this.value = this.min;
332
+
333
+ /**
334
+ * Set the current value
335
+ */
336
+ this.currentValue = this.value;
337
+
338
+ /**
339
+ * This is new in May 2011 and facilitates indiviual gutter settings,
340
+ * eg chart.gutter.left
341
+ */
342
+ this.gutterLeft = prop['chart.gutter.left'];
343
+ this.gutterRight = prop['chart.gutter.right'];
344
+ this.gutterTop = prop['chart.gutter.top'];
345
+ this.gutterBottom = prop['chart.gutter.bottom'];
346
+
347
+ this.centerx = ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
348
+ this.centery = ca.height - this.gutterBottom;
349
+ this.radius = Math.min(
350
+ (ca.width - this.gutterLeft - this.gutterRight) / 2,
351
+ (ca.height - this.gutterTop - this.gutterBottom)
352
+ );
353
+
354
+ /**
355
+ * Stop this growing uncontrollably
356
+ */
357
+ this.coordsText = [];
358
+
359
+
360
+
361
+ /**
362
+ * Custom centerx, centery and radius
363
+ */
364
+ if (typeof(prop['chart.centerx']) == 'number') this.centerx = prop['chart.centerx'];
365
+ if (typeof(prop['chart.centery']) == 'number') this.centery = prop['chart.centery'];
366
+ if (typeof(prop['chart.radius']) == 'number') this.radius = prop['chart.radius'];
367
+
368
+
369
+ /**
370
+ * Parse the colors for gradients. Its down here so that the center X/Y can be used
371
+ */
372
+ if (!this.colorsParsed) {
373
+
374
+ this.parseColors();
375
+
376
+ // Don't want to do this again
377
+ this.colorsParsed = true;
378
+ }
379
+
380
+
381
+ this.drawBackground();
382
+ this.drawLabels();
383
+ this.drawNeedle();
384
+ this.drawReadout();
385
+
386
+ /**
387
+ * Draw the title
388
+ */
389
+ RG.DrawTitle(this, prop['chart.title'], this.gutterTop, null, prop['chart.title.size'] ? prop['chart.title.size'] : prop['chart.text.size'] + 2);
390
+
391
+ /**
392
+ * Setup the context menu if required
393
+ */
394
+ if (prop['chart.contextmenu']) {
395
+ RG.ShowContext(this);
396
+ }
397
+
398
+
399
+ /**
400
+ * This function enables resizing
401
+ */
402
+ if (prop['chart.resizable']) {
403
+ RG.AllowResizing(this);
404
+ }
405
+
406
+
407
+ /**
408
+ * This installs the event listeners
409
+ */
410
+ RG.InstallEventListeners(this);
411
+
412
+
413
+
414
+ /**
415
+ * Fire the onfirstdraw event
416
+ */
417
+ if (this.firstDraw) {
418
+ RG.fireCustomEvent(this, 'onfirstdraw');
419
+ this.firstDraw = false;
420
+ this.firstDrawFunc();
421
+ }
422
+
423
+
424
+
425
+
426
+ /**
427
+ * Fire the RGraph ondraw event
428
+ */
429
+ RG.FireCustomEvent(this, 'ondraw');
430
+
431
+
432
+
433
+ return this;
434
+ };
435
+
436
+
437
+
438
+ /**
439
+ * Used in chaining. Runs a function there and then - not waiting for
440
+ * the events to fire (eg the onbeforedraw event)
441
+ *
442
+ * @param function func The function to execute
443
+ */
444
+ this.exec = function (func)
445
+ {
446
+ func(this);
447
+
448
+ return this;
449
+ };
450
+
451
+
452
+
453
+
454
+ /**
455
+ * Draws the background of the chart
456
+ */
457
+ this.drawBackground =
458
+ this.DrawBackground = function ()
459
+ {
460
+ /**
461
+ * First draw the background image if it's defined
462
+ */
463
+ if (typeof prop['chart.background.image.url'] === 'string' && !this.__background_image__) {
464
+
465
+ var x = 0 + prop['chart.background.image.offsetx'];
466
+ var y = 0 + prop['chart.background.image.offsety'];
467
+ var img = new Image();
468
+
469
+ this.__background_image__ = img;
470
+ img.src = prop['chart.background.image.url'];
471
+
472
+ img.onload = function ()
473
+ {
474
+ if (prop['chart.background.image.stretch']) {
475
+ co.drawImage(this, x,y,ca.width, ca.height);
476
+ } else {
477
+ co.drawImage(this, x,y);
478
+ }
479
+ RG.redraw();
480
+ }
481
+
482
+ } else if (this.__background_image__) {
483
+
484
+ var x = 0 + prop['chart.background.image.offsetx'];
485
+ var y = 0 + prop['chart.background.image.offsety'];
486
+
487
+ if (prop['chart.background.image.stretch']) {
488
+ co.drawImage(this.__background_image__, x,y,ca.width, ca.height);
489
+ } else {
490
+ co.drawImage(this.__background_image__, x,y);
491
+ }
492
+ }
493
+
494
+
495
+
496
+ /**
497
+ * Draw the white background
498
+ */
499
+ co.beginPath();
500
+
501
+ co.fillStyle = prop['chart.background.color'];
502
+
503
+ if (prop['chart.shadow']) {
504
+ RG.SetShadow(this, prop['chart.shadow.color'],prop['chart.shadow.offsetx'],prop['chart.shadow.offsety'], prop['chart.shadow.blur']);
505
+ }
506
+ co.moveTo(this.centerx,this.centery);
507
+ co.arc(this.centerx,
508
+ this.centery,
509
+ this.radius,
510
+ prop['chart.angles.start'],
511
+ prop['chart.angles.end'],
512
+ false);
513
+
514
+ co.fill();
515
+
516
+ RG.NoShadow(this);
517
+
518
+
519
+ // Draw the shadow
520
+ if (prop['chart.shadow']) {
521
+
522
+ co.beginPath();
523
+ var r = (this.radius * 0.06) > 40 ? 40 : (this.radius * 0.06);
524
+ co.arc(this.centerx, this.centery, r, 0, RG.TWOPI, 0);
525
+ co.fill();
526
+
527
+ RG.NoShadow(this);
528
+ }
529
+
530
+
531
+
532
+ // First, draw the grey tickmarks
533
+ if (prop['chart.tickmarks.small.num']) {
534
+ for (var i=0; i<(prop['chart.angles.end'] - prop['chart.angles.start']); i+=(RG.PI / prop['chart.tickmarks.small.num'])) {
535
+ co.beginPath();
536
+ co.strokeStyle = prop['chart.tickmarks.small.color'];
537
+ co.arc(this.centerx, this.centery, this.radius, prop['chart.angles.start'] + i, prop['chart.angles.start'] + i + 0.00001, 0);
538
+ co.arc(this.centerx, this.centery, this.radius - 5, prop['chart.angles.start'] + i, prop['chart.angles.start'] + i + 0.00001, 0);
539
+ co.stroke();
540
+ }
541
+
542
+ // Draw the semi-circle that makes the tickmarks
543
+ co.beginPath();
544
+ co.fillStyle = prop['chart.background.color'];
545
+ co.arc(this.centerx, this.centery, this.radius - 4, prop['chart.angles.start'], prop['chart.angles.end'], false);
546
+ co.closePath();
547
+ co.fill();
548
+ }
549
+
550
+
551
+ // Second, draw the darker tickmarks. First run draws them in white to get rid of the existing tickmark,
552
+ // then the second run draws them in the requested color
553
+
554
+
555
+ if (prop['chart.tickmarks.big.num']) {
556
+ var colors = ['white','white',prop['chart.tickmarks.big.color']];
557
+ for (var j=0; j<colors.length; ++j) {
558
+ for (var i=0; i<(prop['chart.angles.end'] - prop['chart.angles.start']); i+=((prop['chart.angles.end'] - prop['chart.angles.start']) / prop['chart.tickmarks.big.num'])) {
559
+ co.beginPath();
560
+ co.strokeStyle = colors[j];
561
+ co.arc(this.centerx, this.centery, this.radius, prop['chart.angles.start'] + i, prop['chart.angles.start'] + i + 0.001, 0);
562
+ co.arc(this.centerx, this.centery, this.radius - 5, prop['chart.angles.start'] + i, prop['chart.angles.start'] + i + 0.0001, 0);
563
+ co.stroke();
564
+ }
565
+ }
566
+ }
567
+
568
+ // Draw the white circle that makes the tickmarks
569
+ co.beginPath();
570
+ co.fillStyle = prop['chart.background.color'];
571
+ co.moveTo(this.centerx, this.centery);
572
+ co.arc(this.centerx, this.centery, this.radius - 7, prop['chart.angles.start'], prop['chart.angles.end'], false);
573
+ co.closePath();
574
+ co.fill();
575
+
576
+ /**
577
+ * Color ranges - either green/yellow/red or an arbitrary number of ranges
578
+ */
579
+ var ranges = prop['chart.colors.ranges'];
580
+
581
+ if (RG.is_array(prop['chart.colors.ranges'])) {
582
+
583
+ var ranges = prop['chart.colors.ranges'];
584
+
585
+ for (var i=0; i<ranges.length; ++i) {
586
+
587
+ co.strokeStyle = prop['chart.strokestyle'] ? prop['chart.strokestyle'] : ranges[i][2];
588
+ co.fillStyle = ranges[i][2];
589
+ co.lineWidth = prop['chart.linewidth.segments'];
590
+
591
+ co.beginPath();
592
+ co.arc(this.centerx,
593
+ this.centery,
594
+ this.radius * 0.85,
595
+ (((ranges[i][0] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
596
+ (((ranges[i][1] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
597
+ false);
598
+
599
+ if (prop['chart.segment.radius.start'] > 0) {
600
+ co.arc(this.centerx,
601
+ this.centery,
602
+ prop['chart.segment.radius.start'],
603
+ (((ranges[i][1] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
604
+ (((ranges[i][0] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
605
+ true);
606
+ } else {
607
+ co.lineTo(this.centerx, this.centery);
608
+ }
609
+
610
+ co.closePath();
611
+ co.stroke();
612
+ co.fill();
613
+ }
614
+
615
+ // Stops the last line from being changed to a big linewidth.
616
+ co.beginPath();
617
+
618
+ } else {
619
+ co.lineWidth = prop['chart.linewidth'];
620
+
621
+ // Draw the green area
622
+ co.strokeStyle = prop['chart.strokestyle'] ? prop['chart.strokestyle'] : prop['chart.green.color'];
623
+ co.fillStyle = prop['chart.green.color'];
624
+ co.lineWidth = prop['chart.linewidth.segments'];
625
+
626
+ co.beginPath();
627
+ co.arc(this.centerx,
628
+ this.centery,
629
+ this.radius * 0.85,
630
+ (((prop['chart.green.start'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - this.properties['chart.angles.start'])) + prop['chart.angles.start'],
631
+ (((prop['chart.green.end'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
632
+ false);
633
+
634
+ if (prop['chart.segment.radius.start'] > 0) {
635
+
636
+ co.arc(this.centerx,
637
+ this.centery,
638
+ prop['chart.segment.radius.start'],
639
+ (((prop['chart.green.end'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
640
+ (((prop['chart.green.start'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
641
+ true);
642
+ } else {
643
+ co.lineTo(this.centerx, this.centery);
644
+ }
645
+
646
+ co.closePath();
647
+ co.stroke();
648
+ co.fill();
649
+
650
+ // Draw the yellow area
651
+ co.strokeStyle = prop['chart.strokestyle'] ? prop['chart.strokestyle'] : prop['chart.yellow.color'];
652
+ co.fillStyle = prop['chart.yellow.color'];
653
+ co.lineWidth = prop['chart.linewidth.segments'];
654
+ co.beginPath();
655
+ co.arc(this.centerx,
656
+ this.centery,
657
+ this.radius * 0.85,
658
+ (((prop['chart.yellow.start'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
659
+ (((prop['chart.yellow.end'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
660
+ false);
661
+
662
+ if (prop['chart.segment.radius.start'] > 0) {
663
+ co.arc(this.centerx,
664
+ this.centery,
665
+ prop['chart.segment.radius.start'],
666
+ (((prop['chart.yellow.end'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
667
+ (((prop['chart.yellow.start'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
668
+ true);
669
+ } else {
670
+ co.lineTo(this.centerx, this.centery);
671
+ }
672
+
673
+ co.closePath();
674
+ co.stroke();
675
+ co.fill();
676
+
677
+ // Draw the red area
678
+ co.strokeStyle = prop['chart.strokestyle'] ? prop['chart.strokestyle'] : prop['chart.red.color'];
679
+ co.fillStyle = prop['chart.red.color'];
680
+ co.lineWidth = prop['chart.linewidth.segments'];
681
+
682
+ co.beginPath();
683
+ co.arc(this.centerx,
684
+ this.centery,this.radius * 0.85,
685
+ (((prop['chart.red.start'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
686
+ (((prop['chart.red.end'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
687
+ false);
688
+
689
+ if (prop['chart.segment.radius.start'] > 0) {
690
+ co.arc(this.centerx,
691
+ this.centery,
692
+ prop['chart.segment.radius.start'],
693
+ (((prop['chart.red.end'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
694
+ (((prop['chart.red.start'] - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'],
695
+ true);
696
+ } else {
697
+ co.lineTo(this.centerx, this.centery);
698
+ }
699
+
700
+ co.closePath();
701
+ co.stroke();
702
+ co.fill();
703
+
704
+ // Revert the linewidth
705
+ co.lineWidth = 1;
706
+ }
707
+
708
+ // Draw the outline
709
+ if (prop['chart.border']) {
710
+ co.strokeStyle = prop['chart.border.color'];
711
+ co.lineWidth = prop['chart.linewidth'];
712
+
713
+ co.beginPath();
714
+ co.moveTo(this.centerx, this.centery);
715
+ co.arc(this.centerx,
716
+ this.centery,
717
+ this.radius,
718
+ prop['chart.angles.start'],
719
+ prop['chart.angles.end'],
720
+ false);
721
+ co.closePath();
722
+ }
723
+
724
+ co.stroke();
725
+
726
+ // Reset the linewidth back to 1
727
+ co.lineWidth = 1;
728
+ };
729
+
730
+
731
+
732
+
733
+ /**
734
+ * Draws the pointer
735
+ */
736
+ this.drawNeedle =
737
+ this.DrawNeedle = function ()
738
+ {
739
+ /**
740
+ * The angle that the needle is at
741
+ */
742
+ var a = (((this.value - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'];
743
+
744
+ /**
745
+ * First draw the background image if it's defined
746
+ */
747
+ if (typeof prop['chart.needle.image.url'] === 'string' && !this.__needle_image__) {
748
+
749
+ var img = new Image();
750
+
751
+ this.__needle_image__ = img;
752
+ img.src = prop['chart.needle.image.url'];
753
+
754
+ img.onload = function ()
755
+ {
756
+ co.save();
757
+ RG.rotateCanvas(ca, this.centerx, this.centery, a);
758
+ co.drawImage(this,
759
+ this.centerx + prop['chart.needle.image.offsetx'],
760
+ this.centery + prop['chart.needle.image.offsety']);
761
+ co.restore();
762
+
763
+ RG.redraw();
764
+ }
765
+
766
+ } else if (this.__needle_image__) {
767
+
768
+ co.save();
769
+ RG.rotateCanvas(ca, this.centerx, this.centery, a);
770
+ co.drawImage(this.__needle_image__,
771
+ this.centerx + prop['chart.needle.image.offsetx'],
772
+ this.centery + prop['chart.needle.image.offsety']);
773
+ //pa(co, ['b', 'r', this.centerx, this.centery, 1, 1, 'f', 'red']);
774
+ co.restore();
775
+ }
776
+
777
+
778
+
779
+
780
+
781
+
782
+
783
+
784
+ // Allow customising the needle radius
785
+ var needleRadius = typeof(prop['chart.needle.radius']) == 'number' ? prop['chart.needle.radius'] : this.radius * 0.7;
786
+
787
+ // First draw the circle at the bottom
788
+ co.fillStyle = 'black';
789
+ co.lineWidth = this.radius >= 200 ? 7 : 3;
790
+ co.lineCap = 'round';
791
+
792
+ // Now, draw the arm of the needle
793
+ co.beginPath();
794
+ co.strokeStyle = prop['chart.needle.color'];
795
+ if (typeof(prop['chart.needle.linewidth']) == 'number') co.lineWidth = prop['chart.needle.linewidth'];
796
+
797
+
798
+ co.arc(this.centerx, this.centery, needleRadius, a, a + 0.001, false);
799
+ co.lineTo(this.centerx, this.centery);
800
+ co.stroke();
801
+
802
+ // Draw the triangular needle head
803
+ if (prop['chart.needle.head']) {
804
+
805
+ co.fillStyle = prop['chart.needle.color'];
806
+ co.beginPath();
807
+ co.lineWidth = 1;
808
+ //co.moveTo(this.centerx, this.centery);
809
+ co.arc(this.centerx, this.centery, needleRadius + 15, a, a + 0.001, 0);
810
+ co.arc(this.centerx, this.centery, needleRadius - 15, a + 0.087, a + 0.087999, 0);
811
+ co.arc(this.centerx, this.centery, needleRadius - 15, a - 0.087, a - 0.087999, 1);
812
+ co.fill();
813
+ }
814
+
815
+ // Draw the tail if requested
816
+ if (prop['chart.needle.tail']) {
817
+ co.beginPath();
818
+ co.strokeStyle = prop['chart.needle.color'];
819
+ if (typeof(prop['chart.needle.linewidth']) == 'number') co.lineWidth = prop['chart.needle.linewidth'];
820
+
821
+ var a = ((this.value - this.min) / (this.max - this.min) * (this.properties['chart.angles.end'] - this.properties['chart.angles.start'])) + this.properties['chart.angles.start'] + RG.PI;
822
+ co.arc(this.centerx, this.centery, 25, a, a + 0.001, false);
823
+ co.lineTo(this.centerx, this.centery);
824
+ co.stroke();
825
+ }
826
+
827
+ // Draw the center circle (the stroke)
828
+ var r = (this.radius * 0.06) > 40 ? 40 : (this.radius * 0.06);
829
+
830
+ co.beginPath();
831
+ co.fillStyle = prop['chart.centerpin.stroke'];
832
+ co.arc(this.centerx, this.centery, r, 0 + 0.001, RG.TWOPI, 0);
833
+ co.fill();
834
+
835
+
836
+
837
+
838
+
839
+
840
+
841
+
842
+
843
+
844
+
845
+
846
+
847
+
848
+ // Draw the centre bit of the circle (the fill)
849
+ co.fillStyle = prop['chart.centerpin.fill'];
850
+ co.beginPath();
851
+ co.arc(this.centerx, this.centery, r - 2, 0 + 0.001, RG.TWOPI, 0);
852
+ co.fill();
853
+ };
854
+
855
+
856
+
857
+
858
+ /**
859
+ * Draws the labels
860
+ */
861
+ this.drawLabels =
862
+ this.DrawLabels = function ()
863
+ {
864
+ if (!prop['chart.labels']) {
865
+ return;
866
+ }
867
+
868
+ var radius = this.radius;
869
+ var text_size = prop['chart.text.size'];
870
+ var text_font = prop['chart.text.font'];
871
+ var units_post = prop['chart.units.post'];
872
+ var units_pre = prop['chart.units.pre'];
873
+ var centerx = this.centerx;
874
+ var centery = this.centery;
875
+ var min = this.min;
876
+ var max = this.max;
877
+ var decimals = prop['chart.scale.decimals'];
878
+ var numLabels = prop['chart.labels.count'];
879
+
880
+ co.fillStyle = prop['chart.text.color'];
881
+ co.lineWidth = 1;
882
+
883
+ co.beginPath();
884
+
885
+ for (var i=0; i<=numLabels; ++i) {
886
+
887
+ var angle = ((prop['chart.angles.end'] - prop['chart.angles.start']) * (i / numLabels)) + prop['chart.angles.start'];
888
+ var coords = RG.getRadiusEndPoint(centerx, centery, angle + (((i == 0 || i == numLabels) && prop['chart.border']) ? (i == 0 ? 0.05 : -0.05) : 0), (this.radius * 0.925) - (prop['chart.text.valign'] === 'bottom' ? 15 : 0));
889
+
890
+ var angleStart = prop['chart.angles.start'];
891
+ var angleEnd = prop['chart.angles.end'];
892
+ var angleRange = angleEnd - angleStart;
893
+
894
+ var angleStart_degrees = angleStart * (180 / RG.PI);
895
+ var angleEnd_degrees = angleEnd * (180 / RG.PI);
896
+ var angleRange_degrees = angleRange * (180 / RG.PI);
897
+
898
+ // Vertical alignment
899
+ valign = prop['chart.text.valign'];
900
+
901
+ // Horizontal alignment
902
+ if (prop['chart.border']) {
903
+ if (i == 0) {
904
+ halign = 'left';
905
+ } else if (i == numLabels) {
906
+ halign = 'right';
907
+ } else {
908
+ halign = 'center'
909
+ }
910
+ } else {
911
+ halign = 'center';
912
+ }
913
+
914
+ RG.Text2(this, {'font':text_font,
915
+ 'size':text_size,
916
+ 'x':coords[0],
917
+ 'y':coords[1],
918
+ 'text':RG.numberFormat(this, (((this.max - this.min) * (i / numLabels)) + this.min).toFixed(decimals),units_pre,units_post),
919
+ 'halign':halign,
920
+ 'valign':valign,
921
+ 'angle':((angleRange_degrees * (1 / numLabels) * i) + angleStart_degrees) - 270,
922
+ 'bounding':false,
923
+ 'boundingFill':(i == 0 || i == numLabels) ? 'white': null,
924
+ 'tag': 'scale'
925
+ });
926
+ }
927
+ };
928
+
929
+
930
+
931
+
932
+ /**
933
+ * This function draws the text readout if specified
934
+ */
935
+ this.drawReadout =
936
+ this.DrawReadout = function ()
937
+ {
938
+ if (prop['chart.value.text']) {
939
+ co.beginPath();
940
+ co.fillStyle = prop['chart.text.color'];
941
+ RG.Text2(this, {'font':prop['chart.text.font'],
942
+ 'size':prop['chart.text.size'],
943
+ 'x':this.centerx,
944
+ 'y':this.centery - prop['chart.text.size'] - 15,
945
+ 'text': prop['chart.value.text.units.pre'] + (this.value).toFixed(prop['chart.value.text.decimals']) + prop['chart.value.text.units.post'],
946
+ 'halign':'center',
947
+ 'valign':'bottom',
948
+ 'bounding':true,
949
+ 'boundingFill':'white',
950
+ 'tag': 'value.text'
951
+ });
952
+
953
+ co.stroke();
954
+ co.fill();
955
+ }
956
+ };
957
+
958
+
959
+
960
+
961
+ /**
962
+ * A placeholder function
963
+ *
964
+ * @param object The event object
965
+ */
966
+ this.getShape = function (e) {};
967
+
968
+
969
+
970
+
971
+ /**
972
+ * This function returns the pertinent value for a particular click (or other mouse event)
973
+ *
974
+ * @param obj e The event object
975
+ */
976
+ this.getValue = function (e)
977
+ {
978
+ var mouseXY = RG.getMouseXY(e);
979
+ var angle = RG.getAngleByXY(this.centerx, this.centery, mouseXY[0], mouseXY[1]);
980
+
981
+ // Work out the radius
982
+ var radius = RG.getHypLength(this.centerx, this.centery, mouseXY[0], mouseXY[1]);
983
+ if (radius > this.radius) {
984
+ return null;
985
+ }
986
+
987
+
988
+ if (angle < RG.HALFPI) {
989
+ angle += RG.TWOPI;
990
+ }
991
+
992
+ var value = (((angle - prop['chart.angles.start']) / (prop['chart.angles.end'] - prop['chart.angles.start'])) * (this.max - this.min)) + this.min;
993
+
994
+ value = Math.max(value, this.min);
995
+ value = Math.min(value, this.max);
996
+
997
+ return value;
998
+ };
999
+
1000
+
1001
+
1002
+
1003
+ /**
1004
+ * The getObjectByXY() worker method. Don't call this call:
1005
+ *
1006
+ * RGraph.ObjectRegistry.getObjectByXY(e)
1007
+ *
1008
+ * @param object e The event object
1009
+ */
1010
+ this.getObjectByXY = function (e)
1011
+ {
1012
+ var mouseXY = RGraph.getMouseXY(e);
1013
+
1014
+ // Work out the radius
1015
+ var radius = RG.getHypLength(this.centerx, this.centery, mouseXY[0], mouseXY[1]);
1016
+
1017
+ if (
1018
+ mouseXY[0] > (this.centerx - this.radius)
1019
+ && mouseXY[0] < (this.centerx + this.radius)
1020
+ && mouseXY[1] > (this.centery - this.radius)
1021
+ && mouseXY[1] < (this.centery + this.radius)
1022
+ && radius <= this.radius
1023
+ ) {
1024
+
1025
+ return this;
1026
+ }
1027
+ };
1028
+
1029
+
1030
+
1031
+
1032
+ /**
1033
+ * This method handles the adjusting calculation for when the mouse is moved
1034
+ *
1035
+ * @param object e The event object
1036
+ */
1037
+ this.adjusting_mousemove =
1038
+ this.Adjusting_mousemove = function (e)
1039
+ {
1040
+ /**
1041
+ * Handle adjusting for the Bar
1042
+ */
1043
+ if (prop['chart.adjustable'] && RG.Registry.Get('chart.adjusting') && RG.Registry.Get('chart.adjusting').uid == this.uid) {
1044
+ this.value = this.getValue(e);
1045
+ RG.clear(this.canvas);
1046
+ RG.redrawCanvas(this.canvas);
1047
+ RG.fireCustomEvent(this, 'onadjust');
1048
+ }
1049
+ };
1050
+
1051
+
1052
+
1053
+
1054
+ /**
1055
+ * This method returns the appropriate angle for a value
1056
+ *
1057
+ * @param number value The value
1058
+ */
1059
+ this.getAngle = function (value)
1060
+ {
1061
+ // Higher than max
1062
+ if (value > this.max || value < this.min) {
1063
+ return null;
1064
+ }
1065
+
1066
+ var angle = (((value - this.min) / (this.max - this.min)) * (prop['chart.angles.end'] - prop['chart.angles.start'])) + prop['chart.angles.start'];
1067
+
1068
+ return angle;
1069
+ };
1070
+
1071
+
1072
+
1073
+
1074
+ /**
1075
+ * This allows for easy specification of gradients
1076
+ */
1077
+ this.parseColors = function ()
1078
+ {
1079
+ // Save the original colors so that they can be restored when the canvas is reset
1080
+ if (this.original_colors.length === 0) {
1081
+ this.original_colors['chart.green.color'] = RG.array_clone(prop['chart.green.color']);
1082
+ this.original_colors['chart.yellow.color'] = RG.array_clone(prop['chart.yellow.color']);
1083
+ this.original_colors['chart.red.color'] = RG.array_clone(prop['chart.red.color']);
1084
+ this.original_colors['chart.colors.ranges'] = RG.array_clone(prop['chart.colors.ranges']);
1085
+ }
1086
+
1087
+ // Parse the basic colors
1088
+ prop['chart.green.color'] = this.parseSingleColorForGradient(prop['chart.green.color']);
1089
+ prop['chart.yellow.color'] = this.parseSingleColorForGradient(prop['chart.yellow.color']);
1090
+ prop['chart.red.color'] = this.parseSingleColorForGradient(prop['chart.red.color']);
1091
+
1092
+ // Parse chart.colors.ranges
1093
+ var ranges = prop['chart.colors.ranges'];
1094
+ if (ranges && ranges.length) {
1095
+ for (var i=0; i<ranges.length; ++i) {
1096
+ ranges[i][2] = this.parseSingleColorForGradient(ranges[i][2]);
1097
+ }
1098
+ }
1099
+ };
1100
+
1101
+
1102
+
1103
+
1104
+ /**
1105
+ * Use this function to reset the object to the post-constructor state. Eg reset colors if
1106
+ * need be etc
1107
+ */
1108
+ this.reset = function ()
1109
+ {
1110
+ };
1111
+
1112
+
1113
+
1114
+
1115
+ /**
1116
+ * This parses a single color value
1117
+ */
1118
+ this.parseSingleColorForGradient = function (color)
1119
+ {
1120
+ if (!color || typeof(color) != 'string') {
1121
+ return color;
1122
+ }
1123
+
1124
+ if (color.match(/^gradient\((.*)\)$/i)) {
1125
+
1126
+ var parts = RegExp.$1.split(':');
1127
+
1128
+ // Create the gradient
1129
+ var grad = co.createRadialGradient(this.centerx, this.centery, prop['chart.segment.radius.start'], this.centerx, this.centery, this.radius * 0.85);
1130
+
1131
+ var diff = 1 / (parts.length - 1);
1132
+
1133
+ for (var j=0; j<parts.length; ++j) {
1134
+ grad.addColorStop(j * diff, RG.trim(parts[j]));
1135
+ }
1136
+ }
1137
+
1138
+ return grad ? grad : color;
1139
+ };
1140
+
1141
+
1142
+
1143
+
1144
+ /**
1145
+ * Using a function to add events makes it easier to facilitate method chaining
1146
+ *
1147
+ * @param string type The type of even to add
1148
+ * @param function func
1149
+ */
1150
+ this.on = function (type, func)
1151
+ {
1152
+ if (type.substr(0,2) !== 'on') {
1153
+ type = 'on' + type;
1154
+ }
1155
+
1156
+ this[type] = func;
1157
+
1158
+ return this;
1159
+ };
1160
+
1161
+
1162
+
1163
+
1164
+ /**
1165
+ * This function runs once only
1166
+ * (put at the end of the file (before any effects))
1167
+ */
1168
+ this.firstDrawFunc = function ()
1169
+ {
1170
+ };
1171
+
1172
+
1173
+
1174
+
1175
+ /**
1176
+ * Meter Grow
1177
+ *
1178
+ * This effect gradually increases the represented value
1179
+ *
1180
+ * @param An object of options - eg: {frames: 60}
1181
+ * @param function An optional callback function
1182
+ */
1183
+ this.grow = function ()
1184
+ {
1185
+ var obj = this;
1186
+
1187
+ obj.currentValue = obj.currentValue || obj.min;
1188
+
1189
+ var opt = arguments[0] || {};
1190
+ var frames = opt.frames || 30;
1191
+ var frame = 0;
1192
+ var diff = obj.value - obj.currentValue;
1193
+ var step = diff / frames;
1194
+ var callback = arguments[1] || function () {};
1195
+ var initial = obj.currentValue;
1196
+
1197
+
1198
+
1199
+ function iterator ()
1200
+ {
1201
+ obj.value = initial + (frame++ * step);
1202
+
1203
+ RG.clear(obj.canvas);
1204
+ RG.redrawCanvas(obj.canvas);
1205
+
1206
+ if (frame <= frames) {
1207
+ RG.Effects.updateCanvas(iterator);
1208
+ } else {
1209
+ callback(obj);
1210
+ }
1211
+ }
1212
+
1213
+ iterator();
1214
+
1215
+ return this;
1216
+ };
1217
+
1218
+
1219
+
1220
+
1221
+
1222
+ RG.att(ca);
1223
+
1224
+
1225
+
1226
+
1227
+ /**
1228
+ * Register the object
1229
+ */
1230
+ RG.register(this);
1231
+
1232
+
1233
+
1234
+
1235
+ /**
1236
+ * This is the 'end' of the constructor so if the first argument
1237
+ * contains configuration data - handle that.
1238
+ */
1239
+ if (parseConfObjectForOptions) {
1240
+ RG.parseObjectStyleConfig(this, conf.options);
1241
+ }
1242
+ };