rgraph-rails 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/CODE_OF_CONDUCT.md +13 -0
  6. data/Gemfile +4 -0
  7. data/README.md +73 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +7 -0
  11. data/lib/rgraph-rails/version.rb +3 -0
  12. data/lib/rgraph-rails.rb +8 -0
  13. data/license.txt +19 -0
  14. data/rgraph-rails.gemspec +26 -0
  15. data/vendor/assets/images/bg.png +0 -0
  16. data/vendor/assets/images/bullet.png +0 -0
  17. data/vendor/assets/images/facebook-large.png +0 -0
  18. data/vendor/assets/images/google-plus-large.png +0 -0
  19. data/vendor/assets/images/logo.png +0 -0
  20. data/vendor/assets/images/meter-image-sd-needle.png +0 -0
  21. data/vendor/assets/images/meter-image-sd.png +0 -0
  22. data/vendor/assets/images/meter-sketch-needle.png +0 -0
  23. data/vendor/assets/images/meter-sketch.png +0 -0
  24. data/vendor/assets/images/odometer-background.png +0 -0
  25. data/vendor/assets/images/rgraph.jpg +0 -0
  26. data/vendor/assets/images/title.png +0 -0
  27. data/vendor/assets/images/twitter-large.png +0 -0
  28. data/vendor/assets/javascripts/RGraph.bar.js +3246 -0
  29. data/vendor/assets/javascripts/RGraph.bipolar.js +2003 -0
  30. data/vendor/assets/javascripts/RGraph.common.annotate.js +399 -0
  31. data/vendor/assets/javascripts/RGraph.common.context.js +600 -0
  32. data/vendor/assets/javascripts/RGraph.common.core.js +4751 -0
  33. data/vendor/assets/javascripts/RGraph.common.csv.js +275 -0
  34. data/vendor/assets/javascripts/RGraph.common.deprecated.js +454 -0
  35. data/vendor/assets/javascripts/RGraph.common.dynamic.js +1194 -0
  36. data/vendor/assets/javascripts/RGraph.common.effects.js +1524 -0
  37. data/vendor/assets/javascripts/RGraph.common.key.js +735 -0
  38. data/vendor/assets/javascripts/RGraph.common.resizing.js +550 -0
  39. data/vendor/assets/javascripts/RGraph.common.tooltips.js +605 -0
  40. data/vendor/assets/javascripts/RGraph.common.zoom.js +223 -0
  41. data/vendor/assets/javascripts/RGraph.drawing.background.js +636 -0
  42. data/vendor/assets/javascripts/RGraph.drawing.circle.js +579 -0
  43. data/vendor/assets/javascripts/RGraph.drawing.image.js +810 -0
  44. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +710 -0
  45. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +672 -0
  46. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +568 -0
  47. data/vendor/assets/javascripts/RGraph.drawing.poly.js +623 -0
  48. data/vendor/assets/javascripts/RGraph.drawing.rect.js +603 -0
  49. data/vendor/assets/javascripts/RGraph.drawing.text.js +648 -0
  50. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +815 -0
  51. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +860 -0
  52. data/vendor/assets/javascripts/RGraph.fuel.js +965 -0
  53. data/vendor/assets/javascripts/RGraph.funnel.js +988 -0
  54. data/vendor/assets/javascripts/RGraph.gantt.js +1242 -0
  55. data/vendor/assets/javascripts/RGraph.gauge.js +1391 -0
  56. data/vendor/assets/javascripts/RGraph.hbar.js +1794 -0
  57. data/vendor/assets/javascripts/RGraph.hprogress.js +1307 -0
  58. data/vendor/assets/javascripts/RGraph.line.js +3940 -0
  59. data/vendor/assets/javascripts/RGraph.meter.js +1242 -0
  60. data/vendor/assets/javascripts/RGraph.modaldialog.js +292 -0
  61. data/vendor/assets/javascripts/RGraph.odo.js +1265 -0
  62. data/vendor/assets/javascripts/RGraph.pie.js +1979 -0
  63. data/vendor/assets/javascripts/RGraph.radar.js +1840 -0
  64. data/vendor/assets/javascripts/RGraph.rose.js +1860 -0
  65. data/vendor/assets/javascripts/RGraph.rscatter.js +1332 -0
  66. data/vendor/assets/javascripts/RGraph.scatter.js +3029 -0
  67. data/vendor/assets/javascripts/RGraph.thermometer.js +1131 -0
  68. data/vendor/assets/javascripts/RGraph.vprogress.js +1326 -0
  69. data/vendor/assets/javascripts/RGraph.waterfall.js +1252 -0
  70. data/vendor/assets/javascripts/financial-data.js +1067 -0
  71. data/vendor/assets/stylesheets/ModalDialog.css +90 -0
  72. data/vendor/assets/stylesheets/animations.css +3347 -0
  73. data/vendor/assets/stylesheets/website.css +402 -0
  74. metadata +175 -0
@@ -0,0 +1,965 @@
1
+ // version: 2015-11-02
2
+ /**
3
+ * o--------------------------------------------------------------------------------o
4
+ * | This file is part of the RGraph package - you can learn more at: |
5
+ * | |
6
+ * | http://www.rgraph.net |
7
+ * | |
8
+ * | RGraph is dual licensed under the Open Source GPL (General Public License) |
9
+ * | v2.0 license and a commercial license which means that you're not bound by |
10
+ * | the terms of the GPL. The commercial license is just �99 (GBP) and you can |
11
+ * | read about it here: |
12
+ * | http://www.rgraph.net/license |
13
+ * o--------------------------------------------------------------------------------o
14
+ */
15
+
16
+ RGraph = window.RGraph || {isRGraph: true};
17
+
18
+ /**
19
+ * The Fuel widget constructor
20
+ *
21
+ * @param object canvas The canvas object
22
+ * @param int min The minimum value
23
+ * @param int max The maximum value
24
+ * @param int value The indicated value
25
+ */
26
+ RGraph.Fuel = function (conf)
27
+ {
28
+ /**
29
+ * Allow for object config style
30
+ */
31
+ if ( typeof conf === 'object'
32
+ && typeof conf.min === 'number'
33
+ && typeof conf.max === 'number'
34
+ && typeof conf.id === 'string') {
35
+
36
+ var id = conf.id
37
+ var canvas = document.getElementById(id);
38
+ var min = conf.min;
39
+ var max = conf.max;
40
+ var value = conf.value;
41
+ var parseConfObjectForOptions = true; // Set this so the config is parsed (at the end of the constructor)
42
+
43
+ } else {
44
+
45
+ var id = conf;
46
+ var canvas = document.getElementById(id);
47
+ var min = arguments[1];
48
+ var max = arguments[2];
49
+ var value = arguments[3];
50
+ }
51
+
52
+ // 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 = 'fuel';
58
+ this.isRGraph = true;
59
+ this.min = min;
60
+ this.max = max;
61
+ this.value = RGraph.stringsToNumbers(value);
62
+ this.angles = {};
63
+ this.currentValue = null;
64
+ this.uid = RGraph.CreateUID();
65
+ this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.CreateUID();
66
+ this.coordsText = [];
67
+ this.original_colors = [];
68
+ this.firstDraw = true; // After the first draw this will be false
69
+
70
+
71
+ /**
72
+ * Compatibility with older browsers
73
+ */
74
+ //RGraph.OldBrowserCompat(this.context);
75
+
76
+
77
+ // Check for support
78
+ if (!this.canvas) {
79
+ alert('[FUEL] No canvas support');
80
+ return;
81
+ }
82
+
83
+ /**
84
+ * The funnel charts properties
85
+ */
86
+ this.properties =
87
+ {
88
+ 'chart.colors': ['Gradient(white:red)'],
89
+ 'chart.needle.color': 'red',
90
+ 'chart.gutter.left': 5,
91
+ 'chart.gutter.right': 5,
92
+ 'chart.gutter.top': 5,
93
+ 'chart.gutter.bottom': 5,
94
+ 'chart.text.size': 12,
95
+ 'chart.text.color': 'black', // Does not support gradients
96
+ 'chart.text.font': 'Arial',
97
+ 'chart.contextmenu': null,
98
+ 'chart.annotatable': false,
99
+ 'chart.annotate.color': 'black',
100
+ 'chart.zoom.factor': 1.5,
101
+ 'chart.zoom.fade.in': true,
102
+ 'chart.zoom.fade.out': true,
103
+ 'chart.zoom.factor': 1.5,
104
+ 'chart.zoom.fade.in': true,
105
+ 'chart.zoom.fade.out': true,
106
+ 'chart.zoom.hdir': 'right',
107
+ 'chart.zoom.vdir': 'down',
108
+ 'chart.zoom.frames': 25,
109
+ 'chart.zoom.delay': 16.666,
110
+ 'chart.zoom.shadow': true,
111
+ 'chart.zoom.background': true,
112
+ 'chart.zoom.action': 'zoom',
113
+ 'chart.adjustable': false,
114
+ 'chart.resizable': false,
115
+ 'chart.resize.handle.background': null,
116
+ 'chart.icon': 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAfCAYAAAD0ma06AAAEGElEQVRIS7VXSyhtYRT+jnfe5FEMjAwUBiQGHikzRWIkkgy8YyDK+xnJK5JCeZSUGKBMiAyYkMxMJAMpSfJ+2/d8695/33NunSPnHqt2Z5+91/9/' + '/' + '/et9a/1b8Pn56dmMBhg/IWDgwNoNzc38PHxkXtN0+Tiexp9eH18fIDj1Bj63N/fw8vLS/wsmcHoqKmXT09PuL29RVFREU5OTvTJ6UIAgioQ+vLe09MTb29v8PX1RWBgICYnJ+XXIqDRWXN0dJT3nIDsWlpadP+lpSWZlD4KmL/8/' + '/7+Ls/S09N1/7y8PISHh+sK/QssDJWcHEyGCnB1dRUDAwPIzMzUx5GpAnZ1dcXy8jK2trbM5j06OsLc3JzISx8q4OzsLOOsAq6treHg4AAeHh4WJbq7u0Nzc7P+PiYmBnt7ezg9PcXExAQCAgLg5OSEx8dHuLu7Wwfc3t7G/v6+yEcjO8rIROGKaWdnZ+jr6zMDjI6OxvT0tDzr6uqS2KtksspwZ2cHjY2NuqSUhnHmilUCraysmElaWloKJpQCjI2NRX5+Pl5eXr6WlCv08/MTEMVOZDH+Zzw4CdlfX1/rDHt7ezE1NQXGkcYEKi4ulkVKYlpLGouBs/JiaGgIZL25uSlecXFxohAz/ccAz8/P4e/vj7q6Ojw8PMje5DNRy94MQ0JCUFtbK2wqKipE+sHBQbi4uPwMQ86ak5ODxMREVFdXIywsDCUlJRJDXnZlmJqaip6eHuTm5kqikGlycjIyMjL+ZrY9JSUgMzQiIgINDQ2ypaqqqkCZWXHsnjQEHB8fR0pKigAxabq7uyWOlJNxtLukTJDs7GxUVlZKDNl5oqKi8Pr6+jOAIyMjiI+Pl5JGQG4F1Qy+LN7f3fiUdGZmBsHBwRgbG8Pw8LD01ba2NmlX0rTtnTQLCwvSjEdHR3FxcSExLCwsRGRkpBR9vePzeMDyw3bT1NT0XXLiT4a7u7s4Pj4GGzd7K8GCgoKEsRR8I4Cm6hwHXV5eiv62GAE5npMTmFuBTCkzmzT7qs5Q9TlW/o6ODlvwhCHPM5SVPZIxYzNeXFxEa2srvL29YTC2GI3aMm3Zeq6urv4LMC0tDRsbG1K8k5KS9DgS0IwhKVFjSsJA22r9/f0oKCgQdvPz83JEmZ2dlcpD9maSshow0KZnlO8Csx9yK3BLKCMJPpf2xGMigdi9WXooaWdn53dxdP+amhrZh4eHh1hfX5cTW319vZyBnp+ffzNkBWBmhYaGysB/j322oCckJCArK0uGMlsJ5ubmBoPxRiMzFlomjr2MGdne3i5ANILRJEtJt6ysTG8h9gDl4am8vFwSUWron1O9LulXIOqk9pWftfdSS40yyj5Uh101wPRryuR7R1ZMX/U1pfy5IF40xcgUnGAc9wsGYxsFhy87kwAAAABJRU5ErkJggg==',
117
+ 'chart.icon.redraw': true,
118
+ 'chart.background.image.stretch': false,
119
+ 'chart.background.image.x': null,
120
+ 'chart.background.image.y': null,
121
+ 'chart.labels.full': 'F',
122
+ 'chart.labels.empty': 'E',
123
+ 'chart.labels.count': 5,
124
+ 'chart.centerx': null,
125
+ 'chart.centery': null,
126
+ 'chart.radius': null,
127
+ 'chart.scale.visible': false,
128
+ 'chart.scale.decimals': 0,
129
+ 'chart.units.pre': '',
130
+ 'chart.units.post': ''
131
+ }
132
+
133
+ /**
134
+ * Bounds checking - if the value is outside the scale
135
+ */
136
+ if (this.value > this.max) this.value = this.max;
137
+ if (this.value < this.min) this.value = this.min;
138
+
139
+
140
+
141
+
142
+
143
+ /*
144
+ * Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
145
+ * done already
146
+ */
147
+ if (!this.canvas.__rgraph_aa_translated__) {
148
+ this.context.translate(0.5,0.5);
149
+
150
+ this.canvas.__rgraph_aa_translated__ = true;
151
+ }
152
+
153
+
154
+
155
+ // Short variable names
156
+ var RG = RGraph,
157
+ ca = this.canvas,
158
+ co = ca.getContext('2d'),
159
+ prop = this.properties,
160
+ pa = RG.Path,
161
+ pa2 = RG.path2,
162
+ win = window,
163
+ doc = document,
164
+ ma = Math
165
+
166
+
167
+
168
+ /**
169
+ * "Decorate" the object with the generic effects if the effects library has been included
170
+ */
171
+ if (RG.Effects && typeof RG.Effects.decorate === 'function') {
172
+ RG.Effects.decorate(this);
173
+ }
174
+
175
+
176
+ /**
177
+ * A setter
178
+ *
179
+ * @param name string The name of the property to set
180
+ * @param value mixed The value of the property
181
+ */
182
+ this.set =
183
+ this.Set = function (name)
184
+ {
185
+ var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
186
+
187
+ /**
188
+ * the number of arguments is only one and it's an
189
+ * object - parse it for configuration data and return.
190
+ */
191
+ if (arguments.length === 1 && typeof name === 'object') {
192
+ RG.parseObjectStyleConfig(this, name);
193
+ return this;
194
+ }
195
+
196
+
197
+
198
+
199
+
200
+ /**
201
+ * This should be done first - prepend the propertyy name with "chart." if necessary
202
+ */
203
+ if (name.substr(0,6) != 'chart.') {
204
+ name = 'chart.' + name;
205
+ }
206
+
207
+
208
+
209
+
210
+ // Convert uppercase letters to dot+lower case letter
211
+ name = name.replace(/([A-Z])/g, function (str)
212
+ {
213
+ return '.' + String(RegExp.$1).toLowerCase();
214
+ });
215
+
216
+
217
+
218
+
219
+
220
+
221
+ prop[name] = value;
222
+
223
+ return this;
224
+ };
225
+
226
+
227
+
228
+
229
+ /**
230
+ * A getter
231
+ *
232
+ * @param name string The name of the property to get
233
+ */
234
+ this.get =
235
+ this.Get = function (name)
236
+ {
237
+ /**
238
+ * This should be done first - prepend the property name with "chart." if necessary
239
+ */
240
+ if (name.substr(0,6) != 'chart.') {
241
+ name = 'chart.' + name;
242
+ }
243
+
244
+ // Convert uppercase letters to dot+lower case letter
245
+ name = name.replace(/([A-Z])/g, function (str)
246
+ {
247
+ return '.' + String(RegExp.$1).toLowerCase()
248
+ });
249
+
250
+ return prop[name.toLowerCase()];
251
+ };
252
+
253
+
254
+
255
+
256
+ /**
257
+ * The function you call to draw the bar chart
258
+ */
259
+ this.draw =
260
+ this.Draw = function ()
261
+ {
262
+ /**
263
+ * Fire the onbeforedraw event
264
+ */
265
+ RG.FireCustomEvent(this, 'onbeforedraw');
266
+
267
+
268
+
269
+ /**
270
+ * Set the current value
271
+ */
272
+ this.currentValue = this.value;
273
+
274
+
275
+
276
+ /**
277
+ * This is new in May 2011 and facilitates indiviual gutter settings,
278
+ * eg chart.gutter.left
279
+ */
280
+ this.gutterLeft = prop['chart.gutter.left'];
281
+ this.gutterRight = prop['chart.gutter.right'];
282
+ this.gutterTop = prop['chart.gutter.top'];
283
+ this.gutterBottom = prop['chart.gutter.bottom'];
284
+
285
+
286
+
287
+ /**
288
+ * Get the center X and Y of the chart. This is the center of the needle bulb
289
+ */
290
+ this.centerx = ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
291
+ this.centery = ca.height - 20 - this.gutterBottom
292
+
293
+
294
+
295
+ /**
296
+ * Work out the radius of the chart
297
+ */
298
+ this.radius = ca.height - this.gutterTop - this.gutterBottom - 20;
299
+
300
+ /**
301
+ * Stop this growing uncntrollably
302
+ */
303
+ this.coordsText = [];
304
+
305
+
306
+
307
+ /**
308
+ * You can now specify chart.centerx, chart.centery and chart.radius
309
+ */
310
+ if (typeof(prop['chart.centerx']) == 'number') this.centerx = prop['chart.centerx'];
311
+ if (typeof(prop['chart.centery']) == 'number') this.centery = prop['chart.centery'];
312
+ if (typeof(prop['chart.radius']) == 'number') this.radius = prop['chart.radius'];
313
+
314
+
315
+
316
+
317
+ /**
318
+ * Parse the colors. This allows for simple gradient syntax
319
+ */
320
+ if (!this.colorsParsed) {
321
+ this.parseColors();
322
+
323
+ // Don't want to do this again
324
+ this.colorsParsed = true;
325
+ }
326
+
327
+
328
+ /**
329
+ * The start and end angles of the chart
330
+ */
331
+ this.angles.start = (RG.PI + RG.HALFPI) - 0.5;
332
+ this.angles.end = (RG.PI + RG.HALFPI) + 0.5;
333
+ this.angles.needle = this.getAngle(this.value);
334
+
335
+
336
+
337
+ /**
338
+ * Draw the labels on the chart
339
+ */
340
+ this.DrawLabels();
341
+
342
+
343
+ /**
344
+ * Draw the fuel guage
345
+ */
346
+ this.DrawChart();
347
+
348
+
349
+
350
+
351
+
352
+ /**
353
+ * Setup the context menu if required
354
+ */
355
+ if (prop['chart.contextmenu']) {
356
+ RG.ShowContext(this);
357
+ }
358
+
359
+
360
+ /**
361
+ * This function enables resizing
362
+ */
363
+ if (prop['chart.resizable']) {
364
+ RG.AllowResizing(this);
365
+ }
366
+
367
+
368
+ /**
369
+ * This installs the event listeners
370
+ */
371
+ RG.InstallEventListeners(this);
372
+
373
+
374
+
375
+ /**
376
+ * Fire the onfirstdraw event
377
+ */
378
+ if (this.firstDraw) {
379
+ RG.fireCustomEvent(this, 'onfirstdraw');
380
+ this.firstDraw = false;
381
+ this.firstDrawFunc();
382
+ }
383
+
384
+
385
+
386
+ /**
387
+ * Fire the RGraph ondraw event
388
+ */
389
+ RG.FireCustomEvent(this, 'ondraw');
390
+
391
+ return this;
392
+ };
393
+
394
+
395
+
396
+ /**
397
+ * Used in chaining. Runs a function there and then - not waiting for
398
+ * the events to fire (eg the onbeforedraw event)
399
+ *
400
+ * @param function func The function to execute
401
+ */
402
+ this.exec = function (func)
403
+ {
404
+ func(this);
405
+
406
+ return this;
407
+ };
408
+
409
+
410
+
411
+
412
+ /**
413
+ * This function actually draws the chart
414
+ */
415
+ this.drawChart =
416
+ this.DrawChart = function ()
417
+ {
418
+ /**
419
+ * Draw the "Scale"
420
+ */
421
+ this.DrawScale();
422
+
423
+ /**
424
+ * Place the icon on the canvas
425
+ */
426
+ if (!RG.ISOLD) {
427
+ this.DrawIcon();
428
+ }
429
+
430
+
431
+
432
+ /**
433
+ * Draw the needle
434
+ */
435
+ this.DrawNeedle();
436
+ };
437
+
438
+
439
+
440
+
441
+ /**
442
+ * Draws the labels
443
+ */
444
+ this.drawLabels =
445
+ this.DrawLabels = function ()
446
+ {
447
+ if (!prop['chart.scale.visible']) {
448
+ var radius = (this.radius - 20);
449
+ co.fillStyle = prop['chart.text.color'];
450
+
451
+ // Draw the left label
452
+ var y = this.centery - Math.sin(this.angles.start - RG.PI) * (this.radius - 25);
453
+ var x = this.centerx - Math.cos(this.angles.start - RG.PI) * (this.radius - 25);
454
+ RG.Text2(this, {'font':prop['chart.text.font'],
455
+ 'size':prop['chart.text.size'],
456
+ 'x':x,
457
+ 'y':y,
458
+ 'text':prop['chart.labels.empty'],
459
+ 'halign': 'center',
460
+ 'valign':'center',
461
+ 'tag': 'labels'
462
+ });
463
+
464
+ // Draw the right label
465
+ var y = this.centery - Math.sin(this.angles.start - RG.PI) * (this.radius - 25);
466
+ var x = this.centerx + Math.cos(this.angles.start - RG.PI) * (this.radius - 25);
467
+ RG.Text2(this, {'font':prop['chart.text.font'],
468
+ 'size':prop['chart.text.size'],
469
+ 'x':x,
470
+ 'y':y,
471
+ 'text':prop['chart.labels.full'],
472
+ 'halign': 'center',
473
+ 'valign':'center',
474
+ 'tag': 'labels'
475
+ });
476
+ }
477
+ };
478
+
479
+
480
+
481
+
482
+
483
+ /**
484
+ * Draws the needle
485
+ */
486
+ this.drawNeedle =
487
+ this.DrawNeedle = function ()
488
+ {
489
+ // Draw the actual needle
490
+ co.beginPath();
491
+ co.lineWidth = 5;
492
+ co.lineCap = 'round';
493
+ co.strokeStyle = prop['chart.needle.color'];
494
+
495
+ /**
496
+ * The angle for the needle
497
+ */
498
+ var angle = this.angles.needle;
499
+
500
+ co.arc(this.centerx, this.centery, this.radius - 30, angle, angle + 0.0001, false);
501
+ co.lineTo(this.centerx, this.centery);
502
+ co.stroke();
503
+
504
+ co.lineWidth = 1;
505
+
506
+ // Create the gradient for the bulb
507
+ var cx = this.centerx + 10;
508
+ var cy = this.centery - 10
509
+
510
+ var grad = co.createRadialGradient(cx, cy, 35, cx, cy, 0);
511
+ grad.addColorStop(0, 'black');
512
+ grad.addColorStop(1, '#eee');
513
+
514
+ if (navigator.userAgent.indexOf('Firefox/6.0') > 0) {
515
+ grad = co.createLinearGradient(cx + 10, cy - 10, cx - 10, cy + 10);
516
+ grad.addColorStop(1, '#666');
517
+ grad.addColorStop(0.5, '#ccc');
518
+ }
519
+
520
+ // Draw the bulb
521
+ co.beginPath();
522
+ co.fillStyle = grad;
523
+ co.moveTo(this.centerx, this.centery);
524
+ co.arc(this.centerx, this.centery, 20, 0, RG.TWOPI, 0);
525
+ co.fill();
526
+ };
527
+
528
+
529
+ /**
530
+ * Draws the "scale"
531
+ */
532
+ this.drawScale =
533
+ this.DrawScale = function ()
534
+ {
535
+ var a, x, y;
536
+
537
+ //First draw the fill background
538
+ co.beginPath();
539
+ co.strokeStyle = 'black';
540
+ co.fillStyle = 'white';
541
+ co.arc(this.centerx, this.centery, this.radius, this.angles.start, this.angles.end, false);
542
+ co.arc(this.centerx, this.centery, this.radius - 10, this.angles.end, this.angles.start, true);
543
+ co.closePath();
544
+ co.stroke();
545
+ co.fill();
546
+
547
+ //First draw the fill itself
548
+ var start = this.angles.start;
549
+ var end = this.angles.needle;
550
+
551
+ co.beginPath();
552
+ co.fillStyle = prop['chart.colors'][0];
553
+ co.arc(this.centerx, this.centery, this.radius, start, end, false);
554
+ co.arc(this.centerx, this.centery, this.radius - 10, end, start, true);
555
+ co.closePath();
556
+ //co.stroke();
557
+ co.fill();
558
+
559
+ // This draws the tickmarks
560
+ for (a = this.angles.start; a<=this.angles.end+0.01; a+=((this.angles.end - this.angles.start) / 5)) {
561
+ co.beginPath();
562
+ co.arc(this.centerx, this.centery, this.radius - 10, a, a + 0.0001, false);
563
+ co.arc(this.centerx, this.centery, this.radius - 15, a + 0.0001, a, true);
564
+ co.stroke();
565
+ }
566
+
567
+ /**
568
+ * If chart.scale.visible is specified draw the textual scale
569
+ */
570
+ if (prop['chart.scale.visible']) {
571
+
572
+ co.fillStyle = prop['chart.text.color'];
573
+
574
+ // The labels
575
+ var numLabels = prop['chart.labels.count'];
576
+ var decimals = prop['chart.scale.decimals'];
577
+ var font = prop['chart.text.font'];
578
+ var size = prop['chart.text.size'];
579
+ var units_post = prop['chart.units.post'];
580
+ var units_pre = prop['chart.units.pre'];
581
+
582
+ for (var i=0; i<=numLabels; ++i) {
583
+ a = ((this.angles.end - this.angles.start) * (i/numLabels)) + this.angles.start;
584
+ y = this.centery - Math.sin(a - RG.PI) * (this.radius - 25);
585
+ x = this.centerx - Math.cos(a - RG.PI) * (this.radius - 25);
586
+
587
+
588
+ RG.Text2(this, {'font':font,
589
+ 'size':size,
590
+ 'x':x,
591
+ 'y':y,
592
+ 'text': RG.number_format(this, (this.min + ((this.max - this.min) * (i/numLabels))).toFixed(decimals),units_pre,units_post),
593
+ 'halign': 'center',
594
+ 'valign':'center',
595
+ 'tag': 'scale'
596
+ });
597
+ }
598
+ }
599
+ };
600
+
601
+
602
+
603
+
604
+ /**
605
+ * A placeholder function that is here to prevent errors
606
+ */
607
+ this.getShape = function (e) {};
608
+
609
+
610
+
611
+
612
+ /**
613
+ * This function returns the pertinent value based on a click
614
+ *
615
+ * @param object e An event object
616
+ * @return number The relevant value at the point of click
617
+ */
618
+ this.getValue = function (e)
619
+ {
620
+ var mouseXY = RG.getMouseXY(e);
621
+ var angle = RG.getAngleByXY(this.centerx, this.centery, mouseXY[0], mouseXY[1]);
622
+
623
+ /**
624
+ * Boundary checking
625
+ */
626
+ if (angle >= this.angles.end) {
627
+ return this.max;
628
+ } else if (angle <= this.angles.start) {
629
+ return this.min;
630
+ }
631
+
632
+ var value = (angle - this.angles.start) / (this.angles.end - this.angles.start);
633
+ value = value * (this.max - this.min);
634
+ value = value + this.min;
635
+
636
+ return value;
637
+ };
638
+
639
+
640
+
641
+
642
+ /**
643
+ * The getObjectByXY() worker method. Don't call this call:
644
+ *
645
+ * RG.ObjectRegistry.getObjectByXY(e)
646
+ *
647
+ * @param object e The event object
648
+ */
649
+ this.getObjectByXY = function (e)
650
+ {
651
+ var mouseXY = RG.getMouseXY(e);
652
+ var angle = RG.getAngleByXY(this.centerx, this.centery, mouseXY[0], mouseXY[1]);
653
+ var accuracy = 15;
654
+
655
+ var leftMin = this.centerx - this.radius;
656
+ var rightMax = this.centerx + this.radius;
657
+ var topMin = this.centery - this.radius;
658
+ var bottomMax = this.centery + this.radius;
659
+
660
+ if (
661
+ mouseXY[0] > leftMin
662
+ && mouseXY[0] < rightMax
663
+ && mouseXY[1] > topMin
664
+ && mouseXY[1] < bottomMax
665
+ ) {
666
+
667
+ return this;
668
+ }
669
+ };
670
+
671
+
672
+
673
+
674
+ /**
675
+ * Draws the icon
676
+ */
677
+ this.drawIcon =
678
+ this.DrawIcon = function ()
679
+ {
680
+ if (!RG.ISOLD) {
681
+
682
+ if (!this.__icon__ || !this.__icon__.__loaded__) {
683
+ var img = new Image();
684
+ img.src = prop['chart.icon'];
685
+ img.__object__ = this;
686
+ this.__icon__ = img;
687
+
688
+
689
+ img.onload = function (e)
690
+ {
691
+ img.__loaded__ = true;
692
+ var obj = img.__object__;
693
+ //var co = obj.context;
694
+ //var prop = obj.properties;
695
+
696
+ co.drawImage(img,obj.centerx - (img.width / 2), obj.centery - obj.radius + 35);
697
+
698
+ obj.DrawNeedle();
699
+
700
+ if (prop['chart.icon.redraw']) {
701
+ obj.Set('chart.icon.redraw', false);
702
+ RG.Clear(obj.canvas);
703
+ RG.RedrawCanvas(ca);
704
+ }
705
+ }
706
+ } else {
707
+ var img = this.__icon__;
708
+ co.drawImage(img,this.centerx - (img.width / 2), this.centery - this.radius + 35);
709
+ }
710
+ }
711
+
712
+ this.DrawNeedle();
713
+ };
714
+
715
+
716
+
717
+
718
+ /**
719
+ * This method handles the adjusting calculation for when the mouse is moved
720
+ *
721
+ * @param object e The event object
722
+ */
723
+ this.adjusting_mousemove =
724
+ this.Adjusting_mousemove = function (e)
725
+ {
726
+ /**
727
+ * Handle adjusting for the Fuel gauge
728
+ */
729
+ if (prop['chart.adjustable'] && RG.Registry.Get('chart.adjusting') && RG.Registry.Get('chart.adjusting').uid == this.uid) {
730
+ this.value = this.getValue(e);
731
+ //RG.Clear(ca);
732
+ RG.redrawCanvas(ca);
733
+ RG.fireCustomEvent(this, 'onadjust');
734
+ }
735
+ };
736
+
737
+
738
+
739
+
740
+ /**
741
+ * This method gives you the relevant angle (in radians) that a particular value is
742
+ *
743
+ * @param number value The relevant angle
744
+ */
745
+ this.getAngle = function (value)
746
+ {
747
+ // Range checking
748
+ if (value < this.min || value > this.max) {
749
+ return null;
750
+ }
751
+
752
+ var angle = (((value - this.min) / (this.max - this.min)) * (this.angles.end - this.angles.start)) + this.angles.start;
753
+
754
+ return angle;
755
+ };
756
+
757
+
758
+
759
+
760
+ /**
761
+ * This allows for easy specification of gradients
762
+ */
763
+ this.parseColors = function ()
764
+ {
765
+ // Save the original colors so that they can be restored when the canvas is reset
766
+ if (this.original_colors.length === 0) {
767
+ this.original_colors['chart.colors'] = RG.array_clone(prop['chart.colors']);
768
+ this.original_colors['chart.needle.color'] = RG.array_clone(prop['chart.needle.color']);
769
+ }
770
+
771
+ var props = this.properties;
772
+ var colors = props['chart.colors'];
773
+
774
+ for (var i=0; i<colors.length; ++i) {
775
+ colors[i] = this.parseSingleColorForLinearGradient(colors[i]);
776
+ }
777
+
778
+ props['chart.needle.color'] = this.parseSingleColorForRadialGradient(props['chart.needle.color']);
779
+ };
780
+
781
+
782
+
783
+
784
+ /**
785
+ * Use this function to reset the object to the post-constructor state. Eg reset colors if
786
+ * need be etc
787
+ */
788
+ this.reset = function ()
789
+ {
790
+ };
791
+
792
+
793
+
794
+
795
+ /**
796
+ * This parses a single color value
797
+ */
798
+ this.parseSingleColorForLinearGradient = function (color)
799
+ {
800
+ if (!color || typeof(color) != 'string') {
801
+ return color;
802
+ }
803
+
804
+ if (color.match(/^gradient\((.*)\)$/i)) {
805
+
806
+ var parts = RegExp.$1.split(':');
807
+
808
+ // Create the gradient
809
+ var grad = co.createLinearGradient(prop['chart.gutter.left'],0,ca.width - prop['chart.gutter.right'],0);
810
+
811
+ var diff = 1 / (parts.length - 1);
812
+
813
+ grad.addColorStop(0, RG.trim(parts[0]));
814
+
815
+ for (var j=1; j<parts.length; ++j) {
816
+ grad.addColorStop(j * diff, RG.trim(parts[j]));
817
+ }
818
+ }
819
+
820
+ return grad ? grad : color;
821
+ };
822
+
823
+
824
+
825
+
826
+ /**
827
+ * This parses a single color value
828
+ */
829
+ this.parseSingleColorForRadialGradient = function (color)
830
+ {
831
+ if (!color || typeof color != 'string') {
832
+ return color;
833
+ }
834
+
835
+ if (color.match(/^gradient\((.*)\)$/i)) {
836
+
837
+ var parts = RegExp.$1.split(':');
838
+
839
+ // Create the gradient
840
+ var grad = co.createRadialGradient(this.centerx, this.centery, 0, this.centerx, this.centery, this.radius);
841
+
842
+ var diff = 1 / (parts.length - 1);
843
+
844
+ grad.addColorStop(0, RG.trim(parts[0]));
845
+
846
+ for (var j=1; j<parts.length; ++j) {
847
+ grad.addColorStop(j * diff, RG.trim(parts[j]));
848
+ }
849
+ }
850
+
851
+ return grad ? grad : color;
852
+ };
853
+
854
+
855
+
856
+
857
+ /**
858
+ * Using a function to add events makes it easier to facilitate method chaining
859
+ *
860
+ * @param string type The type of even to add
861
+ * @param function func
862
+ */
863
+ this.on = function (type, func)
864
+ {
865
+ if (type.substr(0,2) !== 'on') {
866
+ type = 'on' + type;
867
+ }
868
+
869
+ this[type] = func;
870
+
871
+ return this;
872
+ };
873
+
874
+
875
+
876
+
877
+ /**
878
+ * This function runs once only
879
+ * (put at the end of the file (before any effects))
880
+ */
881
+ this.firstDrawFunc = function ()
882
+ {
883
+ };
884
+
885
+
886
+
887
+
888
+ /**
889
+ * Grow
890
+ *
891
+ * The Fuel chart Grow effect gradually increases the values of the Fuel chart
892
+ *
893
+ * @param object obj The graph object
894
+ */
895
+ this.grow = function ()
896
+ {
897
+ var callback = arguments[1] || function () {};
898
+ var opt = arguments[0] || {};
899
+ var numFrames = opt.frames || 30;
900
+ var frame = 0;
901
+ var obj = this;
902
+ var origValue = Number(this.currentValue);
903
+
904
+ if (this.currentValue == null) {
905
+ this.currentValue = this.min;
906
+ origValue = this.min;
907
+ }
908
+
909
+ var newValue = this.value;
910
+ var diff = newValue - origValue;
911
+ var step = (diff / numFrames);
912
+ var frame = 0;
913
+
914
+
915
+ function iterator ()
916
+ {
917
+ frame++;
918
+
919
+ obj.value = ((frame / numFrames) * diff) + origValue
920
+
921
+ if (obj.value > obj.max) obj.value = obj.max;
922
+ if (obj.value < obj.min) obj.value = obj.min;
923
+
924
+ RGraph.clear(obj.canvas);
925
+ RGraph.redrawCanvas(obj.canvas);
926
+
927
+ if (frame < numFrames) {
928
+ RGraph.Effects.updateCanvas(iterator);
929
+
930
+ // The callback variable is always function
931
+ } else {
932
+ callback(obj);
933
+ }
934
+ }
935
+
936
+ iterator();
937
+
938
+ return this;
939
+ };
940
+
941
+
942
+
943
+ RG.att(ca);
944
+
945
+
946
+
947
+
948
+ /**
949
+ * Now need to register all chart types. MUST be after the setters/getters are defined
950
+ *
951
+ * *** MUST BE LAST IN THE CONSTRUCTOR ***
952
+ */
953
+ RG.Register(this);
954
+
955
+
956
+
957
+
958
+ /**
959
+ * This is the 'end' of the constructor so if the first argument
960
+ * contains configuration data - handle that.
961
+ */
962
+ if (parseConfObjectForOptions) {
963
+ RG.parseObjectStyleConfig(this, conf.options);
964
+ }
965
+ };