rgraph-rails 5.00 → 6.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/publish-geml.yaml +46 -0
  3. data/.gitignore +1 -0
  4. data/README.md +4 -5
  5. data/lib/rgraph-rails/version.rb +1 -1
  6. data/rgraph-rails.gemspec +4 -4
  7. data/vendor/assets/javascripts/RGraph.activity.js +1691 -0
  8. data/vendor/assets/javascripts/RGraph.bar.js +4253 -236
  9. data/vendor/assets/javascripts/RGraph.bipolar.js +3958 -162
  10. data/vendor/assets/javascripts/RGraph.common.annotate.js +414 -35
  11. data/vendor/assets/javascripts/RGraph.common.context.js +635 -30
  12. data/vendor/assets/javascripts/RGraph.common.core.js +10485 -419
  13. data/vendor/assets/javascripts/RGraph.common.csv.js +508 -27
  14. data/vendor/assets/javascripts/RGraph.common.dynamic.js +1693 -90
  15. data/vendor/assets/javascripts/RGraph.common.effects.js +1629 -89
  16. data/vendor/assets/javascripts/RGraph.common.key.js +1003 -53
  17. data/vendor/assets/javascripts/RGraph.common.moment.js +5670 -0
  18. data/vendor/assets/javascripts/RGraph.common.sheets.js +541 -31
  19. data/vendor/assets/javascripts/RGraph.common.sheets.php +351 -0
  20. data/vendor/assets/javascripts/RGraph.common.starburst.js +382 -0
  21. data/vendor/assets/javascripts/RGraph.common.table.js +386 -0
  22. data/vendor/assets/javascripts/RGraph.common.tooltips.js +1433 -32
  23. data/vendor/assets/javascripts/RGraph.drawing.background.js +660 -35
  24. data/vendor/assets/javascripts/RGraph.drawing.circle.js +618 -34
  25. data/vendor/assets/javascripts/RGraph.drawing.image.js +857 -52
  26. data/vendor/assets/javascripts/RGraph.drawing.line.js +712 -0
  27. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +760 -38
  28. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +740 -37
  29. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +573 -36
  30. data/vendor/assets/javascripts/RGraph.drawing.poly.js +667 -36
  31. data/vendor/assets/javascripts/RGraph.drawing.rect.js +638 -34
  32. data/vendor/assets/javascripts/RGraph.drawing.text.js +672 -37
  33. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +653 -52
  34. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +714 -51
  35. data/vendor/assets/javascripts/RGraph.fuel.js +1149 -59
  36. data/vendor/assets/javascripts/RGraph.funnel.js +1277 -56
  37. data/vendor/assets/javascripts/RGraph.gantt.js +1646 -82
  38. data/vendor/assets/javascripts/RGraph.gauge.js +1773 -89
  39. data/vendor/assets/javascripts/RGraph.hbar.js +3869 -159
  40. data/vendor/assets/javascripts/RGraph.horseshoe.js +970 -0
  41. data/vendor/assets/javascripts/RGraph.hprogress.js +1829 -81
  42. data/vendor/assets/javascripts/RGraph.line.js +5293 -244
  43. data/vendor/assets/javascripts/RGraph.meter.js +1570 -77
  44. data/vendor/assets/javascripts/RGraph.modaldialog.js +300 -19
  45. data/vendor/assets/javascripts/RGraph.odo.js +1553 -68
  46. data/vendor/assets/javascripts/RGraph.pie.js +3273 -129
  47. data/vendor/assets/javascripts/RGraph.radar.js +2333 -108
  48. data/vendor/assets/javascripts/RGraph.rose.js +2685 -114
  49. data/vendor/assets/javascripts/RGraph.rscatter.js +1920 -80
  50. data/vendor/assets/javascripts/RGraph.scatter.js +4215 -171
  51. data/vendor/assets/javascripts/RGraph.segmented.js +1006 -0
  52. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +1980 -59
  53. data/vendor/assets/javascripts/RGraph.svg.activity.js +1696 -0
  54. data/vendor/assets/javascripts/RGraph.svg.bar.js +2575 -77
  55. data/vendor/assets/javascripts/RGraph.svg.bipolar.js +3533 -106
  56. data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +240 -21
  57. data/vendor/assets/javascripts/RGraph.svg.common.core.js +7105 -299
  58. data/vendor/assets/javascripts/RGraph.svg.common.csv.js +408 -28
  59. data/vendor/assets/javascripts/RGraph.svg.common.fx.js +1291 -68
  60. data/vendor/assets/javascripts/RGraph.svg.common.key.js +451 -20
  61. data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +543 -31
  62. data/vendor/assets/javascripts/RGraph.svg.common.table.js +391 -0
  63. data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +1072 -23
  64. data/vendor/assets/javascripts/RGraph.svg.funnel.js +1151 -32
  65. data/vendor/assets/javascripts/RGraph.svg.gauge.js +1429 -34
  66. data/vendor/assets/javascripts/RGraph.svg.hbar.js +2692 -65
  67. data/vendor/assets/javascripts/RGraph.svg.horseshoe.js +969 -0
  68. data/vendor/assets/javascripts/RGraph.svg.line.js +2855 -86
  69. data/vendor/assets/javascripts/RGraph.svg.pie.js +1630 -58
  70. data/vendor/assets/javascripts/RGraph.svg.radar.js +1772 -58
  71. data/vendor/assets/javascripts/RGraph.svg.rose.js +2419 -83
  72. data/vendor/assets/javascripts/RGraph.svg.scatter.js +2280 -65
  73. data/vendor/assets/javascripts/RGraph.svg.segmented.js +930 -0
  74. data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +1612 -29
  75. data/vendor/assets/javascripts/RGraph.svg.waterfall.js +1525 -50
  76. data/vendor/assets/javascripts/RGraph.thermometer.js +1411 -64
  77. data/vendor/assets/javascripts/RGraph.vprogress.js +1915 -81
  78. data/vendor/assets/javascripts/RGraph.waterfall.js +1896 -89
  79. data/vendor/assets/javascripts/financial-data.js +1067 -0
  80. metadata +37 -16
  81. data/.travis.yml +0 -11
  82. data/vendor/assets/javascripts/RGraph.common.deprecated.js +0 -35
  83. data/vendor/assets/javascripts/RGraph.common.resizing.js +0 -38
  84. data/vendor/assets/javascripts/RGraph.common.zoom.js +0 -15
  85. data/vendor/assets/javascripts/RGraph.cornergauge.js +0 -71
@@ -0,0 +1,1691 @@
1
+ 'version:2023-09-16 (6.14)';
2
+ //
3
+ // o--------------------------------------------------------------------------------o
4
+ // | This file is part of the RGraph package - you can learn more at: |
5
+ // | |
6
+ // | https://www.rgraph.net |
7
+ // | |
8
+ // | RGraph is licensed under the Open Source MIT license. That means that it's |
9
+ // | totally free to use and there are no restrictions on what you can do with it! |
10
+ // o--------------------------------------------------------------------------------o
11
+
12
+ RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true};
13
+
14
+ //
15
+ // The Activity meter constructor
16
+ //
17
+ RGraph.Activity = function (conf)
18
+ {
19
+ var id = conf.id,
20
+ canvas = document.getElementById(id),
21
+ min = conf.min,
22
+ max = conf.max,
23
+ value = conf.value;
24
+
25
+ // id, min, max, value
26
+ // Get the canvas and context objects
27
+ this.id = id;
28
+ this.canvas = canvas;
29
+ this.context = this.canvas.getContext ? this.canvas.getContext("2d", {alpha: (typeof id === 'object' && id.alpha === false) ? false : true}) : null;
30
+ this.canvas.__object__ = this;
31
+ this.type = 'activity';
32
+ this.min = RGraph.stringsToNumbers(min);
33
+ this.max = RGraph.stringsToNumbers(max);
34
+ this.value = RGraph.stringsToNumbers(value);
35
+ this.centerx = null;
36
+ this.centery = null;
37
+ this.radius = null;
38
+ this.isRGraph = true;
39
+ this.isrgraph = true;
40
+ this.rgraph = true;
41
+ this.currentValue = null;
42
+ this.uid = RGraph.createUID();
43
+ this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.createUID();
44
+ this.colorsParsed = false;
45
+ this.coordsText = [];
46
+ this.angles =
47
+ this.coords = [];
48
+ this.original_colors = [];
49
+ this.images = [];
50
+ this.firstDraw = true; // After the first draw this will be false
51
+ this.stopAnimationRequested = false;// Used to control the animations
52
+
53
+ //
54
+ // If the value is zero set it to very
55
+ // slightly more than zero so the meter
56
+ // is drawn correctly.
57
+ //
58
+ // Likewise with the maximum value
59
+ //
60
+ if (typeof this.value === 'number') {
61
+ this.value = [this.value];
62
+ }
63
+
64
+ for (var i=0; i<this.value.length; ++i) {
65
+ if (this.value[i] <= 0.0000001) {
66
+ this.value[i] = 0.0000001;
67
+ }
68
+ }
69
+
70
+
71
+
72
+ // Various config type stuff
73
+ this.properties =
74
+ {
75
+ radius: null,
76
+ centerx: null,
77
+ centery: null,
78
+ width: null,
79
+ ends: 'round',
80
+
81
+ marginLeft: 15,
82
+ marginRight: 15,
83
+ marginTop: 15,
84
+ marginBottom: 15,
85
+ marginInner: 1,
86
+
87
+ backgroundGrid: false,
88
+ backgroundGridColor: '#666',
89
+ backgroundGridCircles: true,
90
+ backgroundGridCirclesCount: null,
91
+ backgroundGridRadials: true,
92
+ backgroundGridRadialsCount: 8,
93
+ backgroundRings: true,
94
+ backgroundRingsColors: null,
95
+ backgroundRingsAlpha: 0.5,
96
+
97
+ backgroundColor: 'black',
98
+ colors: ['#F45B5B','#90EE7E','#2B908F','red','green','blue','yellow','pink'],
99
+
100
+
101
+ icons: [],
102
+ iconsWidth: null,
103
+ iconsHeight: null,
104
+ iconsOffsetx: 0,
105
+ iconsOffsety: 0,
106
+
107
+ textFont: 'Arial, Verdana, sans-serif',
108
+ textSize: 12,
109
+ textColor: '#aaa',
110
+ textBold: false,
111
+ textItalic: false,
112
+ textAccessible: false,
113
+ textAccessibleOverflow: 'visible',
114
+ textAccessiblePointerevents: false,
115
+ text: null,
116
+
117
+ labelsCenter: false,
118
+ labelsCenterIndex: 0,
119
+ labelsCenterFont: null,
120
+ labelsCenterSize: 50,
121
+ labelsCenterColor: null,
122
+ labelsCenterBold: null,
123
+ labelsCenterItalic: null,
124
+ labelsCenterUnitsPre: '',
125
+ labelsCenterUnitsPost: '',
126
+ labelsCenterDecimals: 0,
127
+ labelsCenterPoint: '.',
128
+ labelsCenterThousand: ',',
129
+ labelsCenterSpecific: '',
130
+ labelsCenterOffsetx: 0,
131
+ labelsCenterOffsety: 0,
132
+ labels: [],
133
+ labelsColor: null,
134
+ labelsFont: null,
135
+ labelsSize: null,
136
+ labelsBold: null,
137
+ labelsItalic: null,
138
+ labelsBackgroundFill: 'transparent',
139
+ labelsBackgroundStroke: 'transparent',
140
+ labelsOffsetx: 0,
141
+ labelsOffsety: 0,
142
+ labelsFormattedDecimals: 0,
143
+ labelsFormattedPoint: '.',
144
+ labelsFormattedThousand: ',',
145
+ labelsFormattedUnitsPre: '',
146
+ labelsFormattedUnitsPost: '',
147
+
148
+ contextmenu: null,
149
+ annotatable: false,
150
+ annotatableColor: 'black',
151
+ annotatableLinewidth: 1,
152
+ adjustable: false,
153
+ tooltips: null,
154
+ tooltipsEffect: 'slide',
155
+ tooltipsCssClass: 'RGraph_tooltip',
156
+ tooltipsCss: null,
157
+ tooltipsEvent: 'onclick',
158
+ tooltipsHighlight: true,
159
+ tooltipsHotspotXonly: false,
160
+ tooltipsHotspotIgnore: null,
161
+ tooltipsFormattedThousand: ',',
162
+ tooltipsFormattedPoint: '.',
163
+ tooltipsFormattedDecimals: 0,
164
+ tooltipsFormattedUnitsPre: '',
165
+ tooltipsFormattedUnitsPost: '',
166
+ tooltipsFormattedKeyColors: null,
167
+ tooltipsFormattedKeyColorsShape: 'square',
168
+ tooltipsFormattedKeyLabels: [],
169
+ tooltipsFormattedListType: 'ul',
170
+ tooltipsFormattedListItems: null,
171
+ tooltipsFormattedTableHeaders: null,
172
+ tooltipsFormattedTableData: null,
173
+ tooltipsPointer: true,
174
+ tooltipsPointerOffsetx: 0,
175
+ tooltipsPointerOffsety: 0,
176
+ tooltipsPositionStatic: true,
177
+
178
+ highlightStyle: null,
179
+ highlightStroke: 'rgba(0,0,0,0)',
180
+ highlightFill: 'rgba(255,255,255,0.5)',
181
+
182
+ clearto: 'rgba(0,0,0,0)'
183
+ }
184
+
185
+
186
+ // Check for support
187
+ if (!this.canvas) {
188
+ alert('[ACTIVITY] No canvas support');
189
+ return;
190
+ }
191
+
192
+
193
+
194
+
195
+ // Easy access to properties and the path function
196
+ var properties = this.properties;
197
+ this.path = RGraph.pathObjectFunction;
198
+
199
+
200
+
201
+ //
202
+ // "Decorate" the object with the generic effects if the effects library has been included
203
+ //
204
+ if (RGraph.Effects && typeof RGraph.Effects.decorate === 'function') {
205
+ RGraph.Effects.decorate(this);
206
+ }
207
+
208
+
209
+
210
+ // Add the responsive method. This method resides in the common file.
211
+ this.responsive = RGraph.responsive;
212
+
213
+
214
+ //
215
+ // A setter
216
+ //
217
+ this.set = function (name)
218
+ {
219
+ var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
220
+
221
+ // the number of arguments is only one and it's an
222
+ // object - parse it for configuration data and return.
223
+ if (arguments.length === 1 && typeof arguments[0] === 'object') {
224
+ for (i in arguments[0]) {
225
+ if (typeof i === 'string') {
226
+ this.set(i, arguments[0][i]);
227
+ }
228
+ }
229
+
230
+ return this;
231
+ }
232
+
233
+ properties[name] = value;
234
+
235
+ return this;
236
+ };
237
+
238
+
239
+
240
+
241
+
242
+
243
+
244
+
245
+ //
246
+ // A getter
247
+ //
248
+ // @param name string The name of the property to get
249
+ //
250
+ this.get = function (name)
251
+ {
252
+ return properties[name];
253
+ };
254
+
255
+
256
+
257
+
258
+
259
+
260
+
261
+
262
+ //
263
+ // The function you call to draw the bar chart
264
+ //
265
+ this.draw = function ()
266
+ {
267
+ //
268
+ // Fire the onbeforedraw event
269
+ //
270
+ RGraph.fireCustomEvent(this, 'onbeforedraw');
271
+
272
+
273
+
274
+ // Translate half a pixel for antialiasing purposes - but only if it hasn't been
275
+ // done already
276
+ //
277
+ // MUST be the first thing done!
278
+ //
279
+ if (!this.canvas.__rgraph_aa_translated__) {
280
+ this.context.translate(0.5,0.5);
281
+
282
+ this.canvas.__rgraph_aa_translated__ = true;
283
+ }
284
+
285
+ // Ensure that the obj.value property is an array
286
+ if (typeof this.value === 'number') {
287
+ this.value = [this.value];
288
+ }
289
+
290
+
291
+
292
+
293
+ //
294
+ // Constrain the value to be within the min and max
295
+ //
296
+ for (var i=0; i<this.value.length; ++i) {
297
+ if (this.value[i] > this.max) this.value[i] = this.max;
298
+ if (this.value[i] < this.min) this.value[i] = this.min;
299
+ }
300
+
301
+ //
302
+ // Set the current value
303
+ //
304
+ this.currentValue = RGraph.arrayClone(this.value);
305
+
306
+
307
+
308
+ //
309
+ // Make the margins easy to access
310
+ //
311
+ this.marginLeft = properties.marginLeft;
312
+ this.marginRight = properties.marginRight;
313
+ this.marginTop = properties.marginTop;
314
+ this.marginBottom = properties.marginBottom;
315
+
316
+ this.centerx = ((this.canvas.width - this.marginLeft - this.marginRight) / 2) + this.marginLeft;
317
+ this.centery = ((this.canvas.height - this.marginBottom - this.marginTop) / 2) + this.marginTop;
318
+ this.radius = Math.min(
319
+ (this.canvas.width - this.marginLeft - this.marginRight) / 2,
320
+ (this.canvas.height - this.marginTop - this.marginBottom) / 2
321
+ );
322
+
323
+ //
324
+ // Stop this growing uncontrollably
325
+ //
326
+ this.coordsText = [];
327
+
328
+
329
+
330
+ //
331
+ // Custom centerx, centery and radius
332
+ //
333
+ if (typeof properties.centerx === 'number') this.centerx = properties.centerx;
334
+ if (typeof properties.centery === 'number') this.centery = properties.centery;
335
+ if (typeof properties.radius === 'number') this.radius = properties.radius;
336
+
337
+ // The width variable is the width of an individual ring
338
+ this.width = typeof properties.width === 'number' ? properties.width : ((this.radius * 0.75) / this.value.length);
339
+ this.width = this.width - properties.marginInner - properties.marginInner;
340
+
341
+ // Allow for +/-xx style width
342
+ if (typeof properties.width === 'string') {
343
+ this.width += Number(properties.width);
344
+ }
345
+
346
+
347
+ //
348
+ // Parse the colors for gradients. Its down here so that the center X/Y can be used
349
+ //
350
+ if (!this.colorsParsed) {
351
+
352
+ this.parseColors();
353
+
354
+ // Don't want to do this again
355
+ this.colorsParsed = true;
356
+ }
357
+
358
+
359
+ //
360
+ // Draw the meter and its label
361
+ //
362
+ this.drawBackground();
363
+ this.drawMeter();
364
+ this.drawLabels();
365
+ this.drawIcons();
366
+ this.drawEnds();
367
+
368
+ //
369
+ // Setup the context menu if required
370
+ //
371
+ if (properties.contextmenu) {
372
+ RGraph.showContext(this);
373
+ }
374
+
375
+
376
+
377
+
378
+ //
379
+ // Add custom text thats specified
380
+ //
381
+ RGraph.addCustomText(this);
382
+
383
+
384
+
385
+
386
+
387
+ //
388
+ // This installs the event listeners
389
+ //
390
+ RGraph.installEventListeners(this);
391
+
392
+
393
+
394
+ //
395
+ // Fire the onfirstdraw event
396
+ //
397
+ if (this.firstDraw) {
398
+ this.firstDraw = false;
399
+ RGraph.fireCustomEvent(this, 'onfirstdraw');
400
+ this.firstDrawFunc();
401
+ }
402
+
403
+
404
+
405
+
406
+ //
407
+ // Fire the RGraph draw event
408
+ //
409
+ RGraph.fireCustomEvent(this, 'ondraw');
410
+
411
+
412
+
413
+
414
+
415
+
416
+
417
+
418
+ //
419
+ // Install any inline responsive configuration. This
420
+ // should be last in the draw function - even after
421
+ // the draw events.
422
+ //
423
+ RGraph.installInlineResponsive(this);
424
+
425
+
426
+
427
+
428
+
429
+
430
+
431
+
432
+
433
+
434
+
435
+ return this;
436
+ };
437
+
438
+
439
+
440
+
441
+
442
+
443
+
444
+
445
+ //
446
+ // Used in chaining. Runs a function there and then - not waiting for
447
+ // the events to fire (eg the onbeforedraw event)
448
+ //
449
+ // @param function func The function to execute
450
+ //
451
+ this.exec = function (func)
452
+ {
453
+ func(this);
454
+
455
+ return this;
456
+ };
457
+
458
+
459
+
460
+
461
+
462
+
463
+
464
+
465
+ //
466
+ // Draw the background"grid"
467
+ //
468
+ this.drawBackground = function ()
469
+ {
470
+ // First thing to do is clear the canvas to the backgroundColor
471
+ if (properties.backgroundColor) {
472
+ this.path(
473
+ 'fs % fr -5 -5 % %',
474
+ properties.backgroundColor,
475
+ this.canvas.width + 10,
476
+ this.canvas.height + 10
477
+ );
478
+ }
479
+
480
+
481
+
482
+
483
+ // Draw the grid?
484
+ if (properties.backgroundGrid) {
485
+
486
+ // Draw the background grey circles
487
+ if (properties.backgroundGridCircles) {
488
+
489
+ // How many background circles?
490
+ if (typeof properties.backgroundGridCirclesCount === 'number') {
491
+ var count = properties.backgroundGridCirclesCount;
492
+ } else {
493
+ var count = this.value.length + 1;
494
+ }
495
+
496
+ for (var i=0; i<count; i++) {
497
+
498
+ var radius = this.radius - (i * (this.width + (2 * properties.marginInner)));
499
+
500
+ this.path(
501
+ 'b a % % % 0 6.29 false s %',
502
+ this.centerx, this.centery, radius,
503
+ properties.backgroundGridColor
504
+ );
505
+ }
506
+
507
+
508
+
509
+
510
+
511
+
512
+ //
513
+ // Draw the background lines that go from the center outwards
514
+ //
515
+ if (properties.backgroundGridRadials) {
516
+
517
+ var angle = (RGraph.TWOPI / properties.backgroundGridRadialsCount);
518
+
519
+ for (var i=0; i<=properties.backgroundGridRadialsCount; ++i) {
520
+
521
+ // Radius must be greater than 0 for Opera to work
522
+ this.path(
523
+ 'b a % % % % % % a % % % % % % s %',
524
+ this.centerx, this.centery, radius, (i * angle) - RGraph.HALFPI, (i * angle) - RGraph.HALFPI, false,
525
+ this.centerx, this.centery, this.radius, (i * angle) - RGraph.HALFPI, (i * angle) - RGraph.HALFPI, false,
526
+ properties.backgroundGridColor
527
+ );
528
+ }
529
+ }
530
+ }
531
+ }
532
+ };
533
+
534
+
535
+
536
+
537
+
538
+
539
+
540
+
541
+ //
542
+ // Draws the meter
543
+ //
544
+ this.drawMeter = function ()
545
+ {
546
+ var color;
547
+
548
+
549
+ // This is the maximum radius of the outer ring
550
+ var r = (this.radius - properties.marginInner);
551
+
552
+
553
+ // Draw the background rings if enabled
554
+ if (properties.backgroundRings) {
555
+ //
556
+ // Loop through the values and draw the background rings
557
+ //
558
+ this.context.globalAlpha = properties.backgroundRingsAlpha;
559
+
560
+ for (var i=0; i<this.value.length; ++i) {
561
+
562
+ // Determine the color
563
+ if (RGraph.isArray(properties.backgroundRingsColors) && typeof properties.backgroundRingsColors[i] === 'string') {
564
+ color = properties.backgroundRingsColors[i];
565
+ } else {
566
+ color = properties.colors[i];
567
+ }
568
+
569
+
570
+ this.path(
571
+ 'b a % % % % % false a % % % % % true f %',
572
+
573
+ this.centerx,
574
+ this.centery,
575
+ r - (i * (properties.marginInner + properties.marginInner + this.width)),
576
+ 0 - RGraph.HALFPI,
577
+ RGraph.TWOPI - RGraph.HALFPI,
578
+
579
+ this.centerx,
580
+ this.centery,
581
+ r - this.width - (i * (properties.marginInner + properties.marginInner + this.width)),
582
+ RGraph.TWOPI - RGraph.HALFPI,
583
+ 0 - RGraph.HALFPI,
584
+
585
+ color
586
+ );
587
+ }
588
+
589
+ // Reset the alpha value
590
+ this.context.globalAlpha = 1;
591
+ }
592
+
593
+
594
+
595
+
596
+
597
+
598
+
599
+
600
+ //
601
+ // Now loop through the values and draw each circle
602
+ //
603
+ for (var i=0; i<this.value.length; ++i) {
604
+
605
+ var radians = ((this.value[i] - this.min) / (this.max - this.min)) * RGraph.TWOPI;
606
+
607
+ this.path(
608
+ 'b a % % % % % false a % % % % % true f %',
609
+
610
+ this.centerx,
611
+ this.centery,
612
+ r - (i * (properties.marginInner + properties.marginInner + this.width)),
613
+ 0 - RGraph.HALFPI,
614
+ radians - RGraph.HALFPI,
615
+
616
+ this.centerx,
617
+ this.centery,
618
+ r - this.width - (i * (properties.marginInner + properties.marginInner + this.width)),
619
+ radians - RGraph.HALFPI,
620
+ 0 - RGraph.HALFPI,
621
+
622
+ properties.colors[i]
623
+ );
624
+
625
+
626
+
627
+
628
+ // Store the coordinates of the ring
629
+ this.angles[i] =
630
+ this.coords[i] = {
631
+ x: this.centerx,
632
+ y: this.centery,
633
+ angleStart: 0 - RGraph.HALFPI,
634
+ angleEnd: radians - RGraph.HALFPI,
635
+ radiusInner: r - this.width - (i * (properties.marginInner + properties.marginInner + this.width)),
636
+ radiusOuter: r - (i * (properties.marginInner + properties.marginInner + this.width)),
637
+ color: properties.colors[i],
638
+ };
639
+ }
640
+
641
+
642
+
643
+
644
+
645
+
646
+
647
+
648
+ //
649
+ // By calling the RGraph.text() function with a blank string the text accessible wrapper DIV
650
+ // will be created and the responsive function will work as expected (ie the css: and parentCss:
651
+ // options).
652
+ //
653
+ RGraph.text({
654
+ object: this,
655
+ x: -10000,
656
+ y: -10000,
657
+ color: 'transparent',
658
+ text: ''
659
+ });
660
+ };
661
+
662
+
663
+
664
+
665
+
666
+
667
+
668
+
669
+ //
670
+ // Draws the center label and the vertical labels if enabled
671
+ //
672
+ this.drawLabels = function ()
673
+ {
674
+ //
675
+ // Draw the label if specified
676
+ //
677
+ if (properties.labelsCenter) {
678
+
679
+ var textConf = RGraph.getTextConf({
680
+ object: this,
681
+ prefix: 'labelsCenter'
682
+ });
683
+
684
+ RGraph.text({
685
+
686
+ object: this,
687
+
688
+ text: String(properties.labelsCenterSpecific ? properties.labelsCenterSpecific : RGraph.numberFormat({
689
+ object: this,
690
+ number: this.value[properties.labelsCenterIndex].toFixed(properties.labelsCenterDecimals),
691
+ unitspre: properties.labelsCenterUnitsPre,
692
+ unitspost: properties.labelsCenterUnitsPost,
693
+ point: properties.labelsCenterPoint,
694
+ thousand: properties.labelsCenterThousand
695
+ })),
696
+
697
+ x: this.centerx + properties.labelsCenterOffsetx,
698
+ y: this.centery + properties.labelsCenterOffsety,
699
+
700
+ halign: 'center',
701
+ valign: 'center',
702
+
703
+ color: textConf.color,
704
+ size: textConf.size,
705
+ font: textConf.font,
706
+ bold: textConf.bold,
707
+ italic: textConf.italic
708
+ });
709
+ }
710
+
711
+
712
+
713
+
714
+
715
+
716
+
717
+
718
+
719
+
720
+
721
+
722
+
723
+
724
+
725
+
726
+
727
+
728
+ var textConf = RGraph.getTextConf({
729
+ object: this,
730
+ prefix: 'labels'
731
+ });
732
+
733
+ if (typeof properties.labels === 'string') {
734
+ properties.labels = RGraph.arrayPad({
735
+ array: [],
736
+ length: this.coords.length,
737
+ value: properties.labels
738
+ });
739
+ }
740
+
741
+
742
+ // Loop thru the labels
743
+ for (var i=0; i<properties.labels.length; ++i) {
744
+
745
+ if ( typeof properties.labels === 'object' && properties.labels.length && typeof properties.labels[i] === 'string' ) {
746
+
747
+ var text = RGraph.labelSubstitution({
748
+ object: this,
749
+ text: properties.labels[i],
750
+ index: i,
751
+ value: this.value[i],
752
+ decimals: properties.labelsFormattedDecimals,
753
+ point: properties.labelsFormattedPoint,
754
+ thousand: properties.labelsFormattedThousand,
755
+ unitsPre: properties.labelsFormattedUnitsPre,
756
+ unitsPost: properties.labelsFormattedUnitsPost,
757
+ });
758
+ }
759
+
760
+
761
+
762
+
763
+
764
+ RGraph.text({
765
+ object: this,
766
+
767
+ text: ( RGraph.isString(properties.labels[i])
768
+ || RGraph.isNumber(properties.labels[i]) ) ? text : '',
769
+
770
+ x: this.coords[i].x - 5 + properties.labelsOffsetx,
771
+ y: this.coords[i].y - this.coords[i].radiusOuter + ((this.coords[i].radiusOuter - this.coords[i].radiusInner) / 2) + properties.labelsOffsety,
772
+
773
+ valign: 'center',
774
+ halign: 'right',
775
+
776
+ bounding: true,
777
+ boundingFill: properties.labelsBackgroundFill,
778
+ boundingStroke: properties.labelsBackgroundStroke,
779
+
780
+ textConfPrefix: 'labels',
781
+
782
+
783
+ });
784
+ }
785
+ };
786
+
787
+
788
+
789
+
790
+
791
+
792
+
793
+
794
+ //
795
+ // Draws the icons at the start of the circles.
796
+ //
797
+ this.drawIcons = function ()
798
+ {
799
+ for (var i=0; i<this.value.length; ++i) {
800
+ if (typeof properties.icons[i] === 'string' && properties.icons[i].length) {
801
+
802
+ this.images[i] = new Image();
803
+ this.images[i].src = properties.icons[i];
804
+ this.images[i].index = i;
805
+ var obj = this;
806
+
807
+ this.images[i].onload = function ()
808
+ {
809
+ // Aids readability
810
+ var img = this;
811
+
812
+ // IMPORTANT:
813
+ //
814
+ // In this callback the 'this' variable is the image object. The
815
+ // 'obj' variable is the chart object.
816
+ //
817
+ var width = img.width;
818
+ var height = width;
819
+
820
+ // Reduce the size of the icon if necessary
821
+ if (width >= obj.width) {
822
+ width -= 10;
823
+ height -= 10;
824
+ }
825
+
826
+ // If a width has been stipulated then use it
827
+ if (typeof properties.iconsWidth === 'number') {
828
+ width = properties.iconsWidth;
829
+ }
830
+
831
+ // If a height has been specified then use it
832
+ if (typeof properties.iconsHeight === 'number') {
833
+ height = properties.iconsHeight;
834
+ }
835
+
836
+ var x = obj.centerx - (width / 3) + ((properties.ends === 'straight' || properties.ends === 'square') ? 15 : 0);
837
+ var y = (obj.centery - obj.coords[this.index].radiusOuter + ((obj.coords[this.index].radiusOuter - obj.coords[this.index].radiusInner) / 2) - (height / 2) );
838
+
839
+ x += properties.iconsOffsetx;
840
+ y += properties.iconsOffsety;
841
+
842
+ obj.context.drawImage(
843
+ this, x, y, width, height
844
+ );
845
+ };
846
+ }
847
+ }
848
+ };
849
+
850
+
851
+
852
+
853
+
854
+
855
+
856
+
857
+ //
858
+ // Draws the rounded ends to the bars
859
+ //
860
+ this.drawEnds = function ()
861
+ {
862
+ if (properties.ends === 'straight' || properties.ends === 'square') {
863
+ return;
864
+ }
865
+
866
+ for (var i=0; i<this.coords.length; ++i) {
867
+
868
+ var x = this.coords[i].x;
869
+ var y = this.coords[i].y - ((this.coords[i].radiusOuter - this.coords[i].radiusInner) / 2) - this.coords[i].radiusInner;
870
+
871
+ this.path(
872
+ 'b a % % % % % false f %',
873
+ x,
874
+ y,
875
+ this.width / 2,
876
+ 0,
877
+ 6.29,
878
+ properties.colors[i]
879
+ );
880
+
881
+
882
+ // cx,cy,angle,radius
883
+ var xy = RGraph.getRadiusEndPoint({
884
+ cx: this.centerx,
885
+ cy: this.centery,
886
+ angle: this.coords[i].angleEnd,
887
+ radius: ((this.coords[i].radiusOuter - this.coords[i].radiusInner) / 2) + this.coords[i].radiusInner
888
+ });
889
+
890
+ this.path(
891
+ 'b a % % % % % false f %',
892
+ xy[0],
893
+ xy[1],
894
+ (this.coords[i].radiusOuter - this.coords[i].radiusInner) / 2,
895
+ 0,
896
+ 6.29,
897
+ properties.colors[i]
898
+ );
899
+ }
900
+ };
901
+
902
+
903
+
904
+
905
+
906
+
907
+
908
+
909
+ //
910
+ // A placeholder function
911
+ //
912
+ // @param object The event object
913
+ //
914
+ this.getShape = function (e)
915
+ {
916
+ var mouseXY = RGraph.getMouseXY(e);
917
+ var mouseX = mouseXY[0];
918
+ var mouseY = mouseXY[1];
919
+
920
+ // Go through the obj.coords array and find the correct index/shape
921
+ for (var i=0; i<this.coords.length; ++i) {
922
+
923
+ if (RGraph.tooltipsHotspotIgnore(this, i)) {
924
+ continue;
925
+ }
926
+
927
+ // Recreate the shape but don't fill/stroke it
928
+ this.path(
929
+ 'b a % % % % % false a % % % % % true',
930
+
931
+ this.coords[i].x,
932
+ this.coords[i].y,
933
+ this.coords[i].radiusOuter,
934
+ this.coords[i].angleStart,
935
+ this.coords[i].angleEnd,
936
+
937
+ this.coords[i].x,
938
+ this.coords[i].y,
939
+ this.coords[i].radiusInner,
940
+ this.coords[i].angleEnd,
941
+ this.coords[i].angleStart
942
+ );
943
+
944
+
945
+
946
+
947
+ //
948
+ // Add the ends to the path if the bars are capped
949
+ //
950
+ if (properties.ends) {
951
+
952
+ this.path(
953
+ 'a % % % % % false',
954
+ this.coords[i].x,
955
+ this.coords[i].y - this.coords[i].radiusInner - (this.width / 2),
956
+ this.width / 2,
957
+ RGraph.HALFPI,
958
+ RGraph.PI + RGraph.HALFPI
959
+ );
960
+
961
+
962
+ // cx,cy,angle,radius of the circle at the end of the bar
963
+ var xy = RGraph.getRadiusEndPoint({
964
+ cx: this.centerx,
965
+ cy: this.centery,
966
+ angle: this.coords[i].angleEnd,
967
+ radius: ((this.coords[i].radiusOuter - this.coords[i].radiusInner) / 2) + this.coords[i].radiusInner
968
+ });
969
+
970
+ this.path(
971
+ 'm % % a % % % % % false',
972
+
973
+ xy[0],
974
+ xy[1],
975
+
976
+ xy[0],
977
+ xy[1],
978
+ (this.coords[i].radiusOuter - this.coords[i].radiusInner) / 2,
979
+ 0,
980
+ 6.29
981
+ );
982
+ }
983
+
984
+
985
+
986
+
987
+ if (this.context.isPointInPath(mouseX, mouseY)) {
988
+
989
+ if (RGraph.parseTooltipText) {
990
+ var tooltip = RGraph.parseTooltipText(properties.tooltips, i);
991
+ }
992
+
993
+ return {
994
+ object: this,
995
+ x: this.coords[i].x,
996
+ y: this.coords[i].y,
997
+ radiusInner: this.coords[i].radiusInner,
998
+ radiusOuter: this.coords[i].radiusOuter,
999
+ angleStart: this.coords[i].angleStart,
1000
+ angleEnd: this.coords[i].angleEnd,
1001
+ tooltip: typeof tooltip === 'string' ? tooltip : null,
1002
+ label: properties.labels && typeof properties.labels[i] === 'string' ? properties.labels[i] : null,
1003
+ dataset: 0,
1004
+ index: i,
1005
+ sequentialIndex: i
1006
+ };
1007
+ }
1008
+ }
1009
+ };
1010
+
1011
+
1012
+
1013
+
1014
+
1015
+
1016
+
1017
+
1018
+ //
1019
+ // This function returns the pertinent value for a particular click (or other mouse event)
1020
+ //
1021
+ // @param obj e The event object
1022
+ //
1023
+ this.getValue = function (e)
1024
+ {
1025
+ var mouseXY = RGraph.getMouseXY(e);
1026
+ var angle = RGraph.getAngleByXY(
1027
+ this.centerx,
1028
+ this.centery,
1029
+ mouseXY[0],
1030
+ mouseXY[1]
1031
+ );
1032
+
1033
+ // Adjust the angle because canvas angles
1034
+ // start at the east axis
1035
+ angle += RGraph.HALFPI;
1036
+ if (angle > RGraph.TWOPI) {
1037
+ angle -= RGraph.TWOPI;
1038
+ }
1039
+
1040
+ // Calculate the value based on the angle and min/max values
1041
+ var value = ((angle / RGraph.TWOPI) * (this.max - this.min)) + this.min;
1042
+
1043
+ // Ensure that the value is in range
1044
+ value = Math.max(value, this.min);
1045
+ value = Math.min(value, this.max);
1046
+
1047
+ return value;
1048
+ };
1049
+
1050
+
1051
+
1052
+
1053
+
1054
+
1055
+
1056
+
1057
+ //
1058
+ // The getObjectByXY() worker method. Don't call this call:
1059
+ //
1060
+ // RGraph.ObjectRegistry.getObjectByXY(e)
1061
+ //
1062
+ // @param object e The event object
1063
+ //
1064
+ this.getObjectByXY = function (e)
1065
+ {
1066
+ var mouseXY = RGraph.getMouseXY(e),
1067
+ width = this.width;
1068
+
1069
+ // Work out the radius
1070
+ var radius = RGraph.getHypLength(
1071
+ this.centerx,
1072
+ this.centery,
1073
+ mouseXY[0],
1074
+ mouseXY[1]
1075
+ );
1076
+
1077
+ if (radius > this.radius || radius < (this.radius * 0.25) ) {
1078
+ return null;
1079
+ }
1080
+
1081
+ return this;
1082
+ };
1083
+
1084
+
1085
+
1086
+
1087
+
1088
+
1089
+
1090
+
1091
+ //
1092
+ // This method handles the adjusting calculation for when the mouse is moved
1093
+ //
1094
+ // @param object e The event object
1095
+ //
1096
+ this.adjusting_mousemove = function (e)
1097
+ {
1098
+ //
1099
+ // Handle adjusting for the Bar
1100
+ //
1101
+ if (properties.adjustable && RGraph.Registry.get('adjusting') && RGraph.Registry.get('adjusting').uid == this.uid) {
1102
+
1103
+ var mouseXY = RGraph.getMouseXY(e);
1104
+
1105
+ var radius = RGraph.getHypLength(
1106
+ this.centerx,
1107
+ this.centery,
1108
+ mouseXY[0],
1109
+ mouseXY[1]
1110
+ );
1111
+
1112
+ var index = this.getIndexByRadius(radius);
1113
+
1114
+ // Store the index in the radius
1115
+ if (typeof RGraph.Registry.get('adjusting.index') !== 'number') {
1116
+ RGraph.Registry.set('adjusting.index', index);
1117
+ RGraph.addCustomEventListener(this, 'onadjustend', function ()
1118
+ {
1119
+ RGraph.Registry.set('adjusting.index', null);
1120
+ });
1121
+ } else {
1122
+ index = RGraph.Registry.get('adjusting.index')
1123
+ }
1124
+
1125
+ if (typeof index === 'number') {
1126
+ this.value[index] = this.getValue(e);
1127
+
1128
+ RGraph.clear(this.canvas);
1129
+ RGraph.redrawCanvas(this.canvas);
1130
+ RGraph.fireCustomEvent(this, 'onadjust');
1131
+ }
1132
+ }
1133
+ };
1134
+
1135
+
1136
+
1137
+
1138
+
1139
+
1140
+
1141
+
1142
+ //
1143
+ // Returns the relevant index of the relevant datapoint.
1144
+ // But only if it's in range.
1145
+ //
1146
+ // @param number radius The radius to check
1147
+ //
1148
+ this.getIndexByRadius = function (radius)
1149
+ {
1150
+ // Loop through the shapes to determine the correct shape
1151
+ for (var i=0; i<this.coords.length; ++i) {
1152
+ if (radius < this.coords[i].radiusOuter && radius > this.coords[i].radiusInner) {
1153
+ return i;
1154
+ }
1155
+ }
1156
+
1157
+ return null;
1158
+ };
1159
+
1160
+
1161
+
1162
+
1163
+
1164
+
1165
+
1166
+
1167
+ //
1168
+ // This method returns the appropriate angle for a value
1169
+ //
1170
+ // @param number value The value
1171
+ //
1172
+ this.getAngle = function (value)
1173
+ {
1174
+ // Higher than max
1175
+ if (value > this.max || value < this.min) {
1176
+ return null;
1177
+ }
1178
+
1179
+ var angle = (((value - this.min) / (this.max - this.min)) * RGraph.TWOPI) - RGraph.HALFPI;
1180
+
1181
+ if (value === this.max) angle -= 0.00001;
1182
+ if (value === this.min) angle += 0.00001;
1183
+
1184
+ return angle;
1185
+ };
1186
+
1187
+
1188
+
1189
+
1190
+
1191
+
1192
+
1193
+
1194
+ //
1195
+ // Each object type has its own Highlight() function which highlights the appropriate shape
1196
+ //
1197
+ // @param object shape The shape to highlight
1198
+ //
1199
+ this.highlight = function (shape)
1200
+ {
1201
+ if (typeof properties.highlightStyle === 'function') {
1202
+
1203
+ if (properties.tooltipsHighlight) {
1204
+ (properties.highlightStyle)(shape);
1205
+ }
1206
+
1207
+
1208
+
1209
+
1210
+ // Highlight all of the rings except this one - essentially an inverted highlight
1211
+ } else if (typeof properties.highlightStyle === 'string' && properties.highlightStyle === 'invert') {
1212
+
1213
+ if (properties.tooltipsHighlight) {
1214
+ this.context.beginPath();
1215
+
1216
+ for (var i=0; i<this.coords.length; ++i) {
1217
+ if (shape.index !== i) {
1218
+ this.pathBar(i);
1219
+ }
1220
+ }
1221
+
1222
+ this.context.fillStyle = properties.highlightFill;
1223
+ this.context.strokeStyle = properties.highlightStroke;
1224
+ this.context.stroke();
1225
+ this.context.fill();
1226
+ }
1227
+
1228
+
1229
+
1230
+
1231
+ // Regular highlighting
1232
+ } else {
1233
+
1234
+ if (properties.tooltipsHighlight) {
1235
+ this.context.beginPath();
1236
+
1237
+ this.pathBar(shape.index);
1238
+
1239
+ this.context.fillStyle = properties.highlightFill;
1240
+ this.context.strokeStyle = properties.highlightStroke;
1241
+ this.context.stroke();
1242
+ this.context.fill();
1243
+ }
1244
+ }
1245
+
1246
+
1247
+
1248
+
1249
+ };
1250
+
1251
+
1252
+
1253
+
1254
+
1255
+
1256
+
1257
+
1258
+ //
1259
+ // Paths a bar given an index but does not:
1260
+ // o stroke
1261
+ // o fill
1262
+ // o issue a beginPath() call
1263
+ // o issue a closePath() call
1264
+ //
1265
+ // Do NOT use when drawing the bars initially - the .coords array
1266
+ // must already be populated.
1267
+ //
1268
+ this.pathBar = function (index)
1269
+ {
1270
+ // Path the outer edge
1271
+ this.path(
1272
+ 'a % % % % % false',
1273
+ this.coords[index].x,
1274
+ this.coords[index].y,
1275
+ this.coords[index].radiusOuter,
1276
+ 0 - RGraph.HALFPI,
1277
+ this.coords[index].angleEnd
1278
+ );
1279
+
1280
+ // Get the center x/y coords of the end of the bar
1281
+ var xy = RGraph.getRadiusEndPoint({
1282
+ cx: this.centerx,
1283
+ cy: this.centery,
1284
+ angle: this.coords[index].angleEnd,
1285
+ radius: this.coords[index].radiusInner + ((this.coords[index].radiusOuter - this.coords[index].radiusInner) / 2)
1286
+ });
1287
+
1288
+ // Path the ending curved end if the ends are round
1289
+ if (properties.ends === 'round') {
1290
+ this.path(
1291
+ 'a % % % % % false',
1292
+ xy[0],
1293
+ xy[1],
1294
+ this.width / 2,
1295
+ this.coords[index].angleEnd,
1296
+ this.coords[index].angleEnd + RGraph.PI
1297
+ );
1298
+ }
1299
+
1300
+ // Path the inner edge
1301
+ this.path(
1302
+ 'a % % % % % true',
1303
+ this.coords[index].x,
1304
+ this.coords[index].y,
1305
+ this.coords[index].radiusInner,
1306
+ this.coords[index].angleEnd,
1307
+ this.coords[index].angleStart
1308
+ );
1309
+
1310
+ // Path the starting curved end if the ends are round
1311
+ if (properties.ends === 'round') {
1312
+ this.path(
1313
+ 'a % % % % % false',
1314
+ this.centerx,
1315
+ this.centery - this.coords[index].radiusInner - ((this.coords[index].radiusOuter - this.coords[index].radiusInner) / 2),
1316
+ this.width / 2,
1317
+ RGraph.HALFPI,
1318
+ RGraph.PI + RGraph.HALFPI
1319
+ );
1320
+ }
1321
+ };
1322
+
1323
+
1324
+
1325
+
1326
+
1327
+
1328
+
1329
+
1330
+ //
1331
+ // A worker function that handles Activity chart specific tooltip substitutions
1332
+ //
1333
+ this.tooltipSubstitutions = function (opt)
1334
+ {
1335
+
1336
+ return {
1337
+ index: opt.index,
1338
+ dataset: 0,
1339
+ sequentialIndex: opt.index,
1340
+ value: this.value[opt.index],
1341
+ values: this.value
1342
+ };
1343
+ };
1344
+
1345
+
1346
+
1347
+
1348
+
1349
+
1350
+
1351
+
1352
+ //
1353
+ // A worker function that returns the correct color/label/value
1354
+ //
1355
+ // @param object specific The indexes that are applicable
1356
+ // @param number index The appropriate index
1357
+ //
1358
+ this.tooltipsFormattedCustom = function (specific, index)
1359
+ {
1360
+ return {
1361
+ label: properties.tooltipsFormattedKeyLabels[index]
1362
+ };
1363
+ };
1364
+
1365
+
1366
+
1367
+
1368
+
1369
+
1370
+
1371
+
1372
+ //
1373
+ // This allows for static tooltip positioning
1374
+ //
1375
+ this.positionTooltipStatic = function (args)
1376
+ {
1377
+ var obj = args.object,
1378
+ e = args.event,
1379
+ tooltip = args.tooltip,
1380
+ index = args.index,
1381
+ canvasXY = RGraph.getCanvasXY(obj.canvas),
1382
+ coords = this.coords[args.index];
1383
+
1384
+ //cx,cy,angle,radius
1385
+ var point = RGraph.getRadiusEndPoint({
1386
+ cx: this.centerx,
1387
+ cy: this.centery,
1388
+ radius: ((coords.radiusOuter - coords.radiusInner) / 2) + coords.radiusInner,
1389
+ angle: ((coords.angleEnd - coords.angleStart) / 2) + (0 - RGraph.HALFPI)
1390
+ });
1391
+
1392
+ // Position the tooltip in the X direction
1393
+ //args.tooltip.style.left = point[0] - (tooltip.offsetWidth / 2) + 'px';
1394
+ args.tooltip.style.left =
1395
+ canvasXY[0]
1396
+ + point[0]
1397
+ - (tooltip.offsetWidth / 2)
1398
+ + obj.properties.tooltipsOffsetx
1399
+ + 'px';
1400
+
1401
+ args.tooltip.style.top =
1402
+ canvasXY[1]
1403
+ + point[1]
1404
+ - tooltip.offsetHeight
1405
+ - 10
1406
+ + obj.properties.tooltipsOffsety
1407
+ + 'px';
1408
+
1409
+ // If the top of the tooltip is off the top of the page
1410
+ // then move the tooltip down
1411
+ if(parseFloat(args.tooltip.style.top) < 0) {
1412
+ args.tooltip.style.top = 5 + 'px';
1413
+ }
1414
+ };
1415
+
1416
+
1417
+
1418
+
1419
+
1420
+
1421
+
1422
+
1423
+ //
1424
+ // This allows for easy specification of gradients
1425
+ //
1426
+ this.parseColors = function ()
1427
+ {
1428
+ // Save the original colors so that they can be restored when the canvas is reset
1429
+ if (this.original_colors.length === 0) {
1430
+ this.original_colors.backgroundColor = RGraph.arrayClone(properties.backgroundColor);
1431
+ this.original_colors.colors = RGraph.arrayClone(properties.colors);
1432
+ }
1433
+
1434
+ // Parse the background color
1435
+ properties.backgroundColor = this.parseSingleColorForGradient(properties.backgroundColor);
1436
+
1437
+
1438
+ // Parse colors
1439
+ var colors = properties.colors;
1440
+
1441
+ if (colors && colors.length) {
1442
+ for (var i=0; i<colors.length; ++i) {
1443
+ colors[i] = this.parseSingleColorForGradient(colors[i]);
1444
+ }
1445
+ }
1446
+ };
1447
+
1448
+
1449
+
1450
+
1451
+
1452
+
1453
+
1454
+
1455
+ //
1456
+ // Use this function to reset the object to the post-constructor state. Eg reset colors if
1457
+ // need be etc
1458
+ //
1459
+ this.reset = function ()
1460
+ {
1461
+ };
1462
+
1463
+
1464
+
1465
+
1466
+
1467
+
1468
+
1469
+
1470
+ //
1471
+ // This parses a single color value
1472
+ //
1473
+ this.parseSingleColorForGradient = function (color)
1474
+ {
1475
+ if (!color || typeof color != 'string') {
1476
+ return color;
1477
+ }
1478
+
1479
+ if (color.match(/^gradient\((.*)\)$/i)) {
1480
+
1481
+ // Allow for JSON gradients
1482
+ if (color.match(/^gradient\(({.*})\)$/i)) {
1483
+ return RGraph.parseJSONGradient({
1484
+ object: this,
1485
+ def: RegExp.$1,
1486
+ radial: true
1487
+ });
1488
+ }
1489
+
1490
+ var parts = RegExp.$1.split(':');
1491
+
1492
+ // Create the gradient
1493
+ var grad = this.context.createLinearGradient(
1494
+ properties.marginLeft,
1495
+ 0,
1496
+ this.canvas.width - properties.marginLeft - properties.marginRight,
1497
+ 0
1498
+ );
1499
+
1500
+ var diff = 1 / (parts.length - 1);
1501
+
1502
+ grad.addColorStop(0, RGraph.trim(parts[0]));
1503
+
1504
+ for (var j=1,len=parts.length; j<len; ++j) {
1505
+ grad.addColorStop(j * diff, RGraph.trim(parts[j]));
1506
+ }
1507
+ }
1508
+
1509
+ return grad ? grad : color;
1510
+ };
1511
+
1512
+
1513
+
1514
+
1515
+
1516
+
1517
+
1518
+
1519
+ //
1520
+ // Using a function to add events makes it easier to facilitate method chaining
1521
+ //
1522
+ // @param string type The type of even to add
1523
+ // @param function func
1524
+ //
1525
+ this.on = function (type, func)
1526
+ {
1527
+ if (type.substr(0,2) !== 'on') {
1528
+ type = 'on' + type;
1529
+ }
1530
+
1531
+ if (typeof this[type] !== 'function') {
1532
+ this[type] = func;
1533
+ } else {
1534
+ RGraph.addCustomEventListener(this, type, func);
1535
+ }
1536
+
1537
+ return this;
1538
+ };
1539
+
1540
+
1541
+
1542
+
1543
+
1544
+
1545
+
1546
+
1547
+ //
1548
+ // This function runs once only
1549
+ // (put at the end of the file (before any effects))
1550
+ //
1551
+ this.firstDrawFunc = function ()
1552
+ {
1553
+ };
1554
+
1555
+
1556
+
1557
+
1558
+
1559
+
1560
+
1561
+
1562
+ //
1563
+ // Meter Grow
1564
+ //
1565
+ // This effect gradually increases the represented value
1566
+ //
1567
+ // @param An object of options - eg: {frames: 60}
1568
+ // @param function An optional callback function
1569
+ //
1570
+ this.grow = function ()
1571
+ {
1572
+ // Cancel any stop request if one is pending
1573
+ this.cancelStopAnimation();
1574
+
1575
+ var obj = this;
1576
+
1577
+ //
1578
+ // Convert the value to an array if its a number
1579
+ //
1580
+ if (typeof this.value === 'number') {
1581
+ this.value = [this.value];
1582
+ }
1583
+
1584
+ //this.currentValue = this.currentValue || obj.min;
1585
+ if (RGraph.isNull(this.currentValue)) {
1586
+
1587
+ this.currentValue=[];
1588
+
1589
+ for (var i=0; i<this.value.length; ++i) {
1590
+ this.currentValue[i] = this.min;
1591
+ }
1592
+ }
1593
+
1594
+ var opt = arguments[0] || {},
1595
+ frames = opt.frames || 30,
1596
+ frame = 0,
1597
+ diff = [],
1598
+ step = [],
1599
+ callback = arguments[1] || function () {},
1600
+ initial = [];
1601
+
1602
+ // Set a few properties too by looping through the data
1603
+ for (var i=0; i<this.value.length; ++i) {
1604
+ diff[i] = this.value[i] - this.currentValue[i];
1605
+ step[i] = diff[i] / frames;
1606
+ initial[i] = this.currentValue[i];
1607
+ }
1608
+
1609
+
1610
+
1611
+ function iterator ()
1612
+ {
1613
+ if (obj.stopAnimationRequested) {
1614
+
1615
+ // Reset the flag
1616
+ obj.stopAnimationRequested = false;
1617
+
1618
+ return;
1619
+ }
1620
+
1621
+
1622
+
1623
+
1624
+ for (var i=0; i<obj.value.length; ++i) {
1625
+ obj.value[i] = initial[i] + (frame * step[i]);
1626
+ }
1627
+
1628
+ // Increment the frame
1629
+ frame++;
1630
+
1631
+ RGraph.clear(obj.canvas);
1632
+ RGraph.redrawCanvas(obj.canvas);
1633
+
1634
+ if (frame <= frames) {
1635
+ RGraph.Effects.updateCanvas(iterator);
1636
+ } else {
1637
+ callback(obj);
1638
+ }
1639
+ }
1640
+
1641
+ iterator();
1642
+
1643
+ return this;
1644
+ };
1645
+
1646
+
1647
+
1648
+
1649
+
1650
+
1651
+
1652
+
1653
+ //
1654
+ // Couple of functions that allow you to control the
1655
+ // animation effect
1656
+ //
1657
+ this.stopAnimation = function ()
1658
+ {
1659
+ this.stopAnimationRequested = true;
1660
+ };
1661
+
1662
+ this.cancelStopAnimation = function ()
1663
+ {
1664
+ this.stopAnimationRequested = false;
1665
+ };
1666
+
1667
+
1668
+
1669
+
1670
+
1671
+
1672
+
1673
+
1674
+ //
1675
+ // Register the object
1676
+ //
1677
+ RGraph.register(this);
1678
+
1679
+
1680
+
1681
+
1682
+
1683
+
1684
+
1685
+
1686
+ //
1687
+ // This is the 'end' of the constructor so if the first argument
1688
+ // contains configuration data - handle that.
1689
+ //
1690
+ RGraph.parseObjectStyleConfig(this, conf.options);
1691
+ };