rgraph-rails 4.62 → 4.64

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