rgraph-rails 4.62 → 4.64

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