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,1433 +1,81 @@
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 chart constuctor
17
- *
18
- * @param object canvas
19
- * @param array data
20
- */
21
- RGraph.RScatter =
22
- RGraph.Rscatter = function (conf)
23
- {
24
- /**
25
- * Allow for object config style
26
- */
27
- if ( typeof conf === 'object'
28
- && typeof conf.data === 'object'
29
- && typeof conf.id === 'string') {
30
-
31
- var parseConfObjectForOptions = true; // Set this so the config is parsed (at the end of the constructor)
32
-
33
- this.data = new Array(conf.data.length);
34
-
35
- // Store the data set(s)
36
- this.data = RGraph.arrayClone(conf.data);
37
-
38
-
39
- // Account for just one dataset being given
40
- if (typeof conf.data === 'object' && typeof conf.data[0] === 'object' && typeof conf.data[0][0] === 'number') {
41
- var tmp = RGraph.arrayClone(conf.data);
42
- conf.data = new Array();
43
- conf.data[0] = RGraph.arrayClone(tmp);
44
-
45
- this.data = RGraph.arrayClone(conf.data);
46
- }
47
-
48
- } else {
49
-
50
- var conf = {id: conf};
51
- conf.data = arguments[1];
52
-
53
-
54
- this.data = [];
55
-
56
- // Handle multiple datasets being given as one argument
57
- if (arguments[1][0] && arguments[1][0][0] && typeof arguments[1][0][0] == 'object') {
58
- // Store the data set(s)
59
- for (var i=0; i<arguments[1].length; ++i) {
60
- this.data[i] = arguments[1][i];
61
- }
62
-
63
- // Handle multiple data sets being supplied as seperate arguments
64
- } else {
65
-
66
- // Store the data set(s)
67
- for (var i=1; i<arguments.length; ++i) {
68
- this.data[i - 1] = RGraph.arrayClone(arguments[i]);
69
- }
70
- }
71
- }
72
-
73
-
74
-
75
-
76
- this.id = conf.id
77
- this.canvas = document.getElementById(this.id)
78
- this.context = this.canvas.getContext ? this.canvas.getContext("2d") : null;
79
- this.canvas.__object__ = this;
80
- this.type = 'rscatter';
81
- this.hasTooltips = false;
82
- this.isRGraph = true;
83
- this.uid = RGraph.CreateUID();
84
- this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.CreateUID();
85
- this.colorsParsed = false;
86
- this.coordsText = [];
87
- this.original_colors = [];
88
- this.firstDraw = true; // After the first draw this will be false
89
-
90
-
91
- this.centerx = 0;
92
- this.centery = 0;
93
- this.radius = 0;
94
- this.max = 0;
95
-
96
- // Convert all of the data pieces to numbers
97
- for (var i=0; i<this.data.length; ++i) {
98
- for (var j=0; j<this.data[i].length; ++j) {
99
- if (typeof this.data[i][j][0] === 'string') {
100
- this.data[i][j][0] = parseFloat(this.data[i][j][0]);
101
- }
102
-
103
- if (typeof this.data[i][j][1] === 'string') {
104
- this.data[i][j][1] = parseFloat(this.data[i][j][1]);
105
- }
106
- }
107
- }
108
-
109
-
110
- this.properties =
111
- {
112
- 'chart.background.color': 'transparent',
113
- 'chart.background.grid': true,
114
- 'chart.background.grid.diagonals': true,
115
- 'chart.background.grid.diagonals.count': null,
116
- 'chart.background.grid.radials': true,
117
- 'chart.background.grid.radials.count': null,
118
- 'chart.background.grid.linewidth': 1,
119
- 'chart.background.grid.color': '#ccc',
120
- 'chart.radius': null,
121
- 'chart.colors': [], // This is used internally for the key
122
- 'chart.colors.default': 'black',
123
- 'chart.gutter.left': 25,
124
- 'chart.gutter.right': 25,
125
- 'chart.gutter.top': 25,
126
- 'chart.gutter.bottom': 25,
127
- 'chart.title': '',
128
- 'chart.title.background': null,
129
- 'chart.title.hpos': null,
130
- 'chart.title.vpos': null,
131
- 'chart.title.bold': true,
132
- 'chart.title.font': null,
133
- 'chart.title.x': null,
134
- 'chart.title.y': null,
135
- 'chart.title.halign': null,
136
- 'chart.title.valign': null,
137
- 'chart.labels': null,
138
- 'chart.labels.color': null,
139
- 'chart.labels.axes': 'nsew',
140
- 'chart.labels.axes.background': 'rgba(255,255,255,0.8)',
141
- 'chart.labels.count': 5,
142
- 'chart.text.color': 'black',
143
- 'chart.text.font': 'Segoe UI, Arial, Verdana, sans-serif',
144
- 'chart.text.size': 12,
145
- 'chart.text.accessible': true,
146
- 'chart.text.accessible.overflow': 'visible',
147
- 'chart.text.accessible.pointerevents': true,
148
- 'chart.key': null,
149
- 'chart.key.background': 'white',
150
- 'chart.key.position': 'graph',
151
- 'chart.key.halign': 'right',
152
- 'chart.key.shadow': false,
153
- 'chart.key.shadow.color': '#666',
154
- 'chart.key.shadow.blur': 3,
155
- 'chart.key.shadow.offsetx': 2,
156
- 'chart.key.shadow.offsety': 2,
157
- 'chart.key.position.gutter.boxed':false,
158
- 'chart.key.position.x': null,
159
- 'chart.key.position.y': null,
160
- 'chart.key.color.shape': 'square',
161
- 'chart.key.rounded': true,
162
- 'chart.key.linewidth': 1,
163
- 'chart.key.colors': null,
164
- 'chart.key.interactive': false,
165
- 'chart.key.interactive.highlight.chart.fill':'rgba(255,0,0,0.9)',
166
- 'chart.key.interactive.highlight.label':'rgba(255,0,0,0.2)',
167
- 'chart.key.text.color': 'black',
168
- 'chart.contextmenu': null,
169
- 'chart.tooltips': null,
170
- 'chart.tooltips.event': 'onmousemove',
171
- 'chart.tooltips.effect': 'fade',
172
- 'chart.tooltips.css.class': 'RGraph_tooltip',
173
- 'chart.tooltips.highlight': true,
174
- 'chart.tooltips.hotspot': 3,
175
- 'chart.tooltips.coords.page': false,
176
- 'chart.annotatable': false,
177
- 'chart.annotate.color': 'black',
178
- 'chart.zoom.factor': 1.5,
179
- 'chart.zoom.fade.in': true,
180
- 'chart.zoom.fade.out': true,
181
- 'chart.zoom.hdir': 'right',
182
- 'chart.zoom.vdir': 'down',
183
- 'chart.zoom.frames': 25,
184
- 'chart.zoom.delay': 16.666,
185
- 'chart.zoom.shadow': true,
186
- 'chart.zoom.background': true,
187
- 'chart.zoom.action': 'zoom',
188
- 'chart.resizable': false,
189
- 'chart.resize.handle.background': null,
190
- 'chart.ymax': null,
191
- 'chart.ymin': 0,
192
- 'chart.tickmarks': 'cross',
193
- 'chart.ticksize': 3,
194
- 'chart.scale.decimals': null,
195
- 'chart.scale.point': '.',
196
- 'chart.scale.thousand': ',',
197
- 'chart.scale.round': false,
198
- 'chart.scale.zerostart': true,
199
- 'chart.units.pre': '',
200
- 'chart.units.post': '',
201
- 'chart.events.mousemove': null,
202
- 'chart.events.click': null,
203
- 'chart.highlight.stroke': 'transparent',
204
- 'chart.highlight.fill': 'rgba(255,255,255,0.7)',
205
- 'chart.highlight.point.radius': 3,
206
- 'chart.axes.color': 'black',
207
- 'chart.axes.numticks': null,
208
- 'chart.axes.caps': true,
209
- 'chart.segment.highlight': false,
210
- 'chart.segment.highlight.count': null,
211
- 'chart.segment.highlight.fill': 'rgba(0,255,0,0.5)',
212
- 'chart.segment.highlight.stroke':'rgba(0,0,0,0)',
213
- 'chart.line': false,
214
- 'chart.line.close': false,
215
- 'chart.line.linewidth': 1,
216
- 'chart.line.colors': ['black'],
217
- 'chart.line.shadow': false,
218
- 'chart.line.shadow.color': 'black',
219
- 'chart.line.shadow.blur': 2,
220
- 'chart.line.shadow.offsetx': 3,
221
- 'chart.line.shadow.offsety': 3,
222
- 'chart.clearto': 'rgba(0,0,0,0)'
223
- }
224
-
225
-
226
-
227
-
228
- /**
229
- * Create the $ objects so that functions can be added to them
230
- */
231
-
232
- for (var i=0,idx=0; i<this.data.length; ++i) {
233
- for (var j=0,len=this.data[i].length; j<len; j+=1,idx+=1) {
234
- this['$' + idx] = {}
235
- }
236
- }
237
-
238
-
239
-
240
-
241
-
242
- /**
243
- * Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
244
- * done already
245
- */
246
- if (!this.canvas.__rgraph_aa_translated__) {
247
- this.context.translate(0.5,0.5);
248
-
249
- this.canvas.__rgraph_aa_translated__ = true;
250
- }
251
-
252
-
253
-
254
- // Short variable names
255
- var RG = RGraph,
256
- ca = this.canvas,
257
- co = ca.getContext('2d'),
258
- prop = this.properties,
259
- pa2 = RG.path2,
260
- win = window,
261
- doc = document,
262
- ma = Math
263
-
264
-
265
-
266
- /**
267
- * "Decorate" the object with the generic effects if the effects library has been included
268
- */
269
- if (RG.Effects && typeof RG.Effects.decorate === 'function') {
270
- RG.Effects.decorate(this);
271
- }
272
-
273
-
274
-
275
-
276
- /**
277
- * A simple setter
278
- *
279
- * @param string name The name of the property to set
280
- * @param string value The value of the property
281
- */
282
- this.set =
283
- this.Set = function (name, value)
284
- {
285
- var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
286
-
287
- /**
288
- * the number of arguments is only one and it's an
289
- * object - parse it for configuration data and return.
290
- */
291
- if (arguments.length === 1 && typeof name === 'object') {
292
- RG.parseObjectStyleConfig(this, name);
293
- return this;
294
- }
295
-
296
-
297
-
298
- /**
299
- * This should be done first - prepend the property name with "chart." if necessary
300
- */
301
- if (name.substr(0,6) != 'chart.') {
302
- name = 'chart.' + name;
303
- }
304
-
305
-
306
-
307
-
308
- // Convert uppercase letters to dot+lower case letter
309
- while(name.match(/([A-Z])/)) {
310
- name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
311
- }
312
-
313
-
314
-
315
-
316
-
317
-
318
-
319
- //
320
- // Change chart.segments.highlight* to chart.segment.highlight (no plural)
321
- //
322
- if (name === 'chart.segments.highlight') name = 'chart.segment.highlight';
323
- if (name === 'chart.segments.highlight.count') name = 'chart.segment.highlight.count';
324
- if (name === 'chart.segments.highlight.fill') name = 'chart.segment.highlight.fill';
325
- if (name === 'chart.segments.highlight.stroke') name = 'chart.segment.highlight.stroke';
326
-
327
- prop[name.toLowerCase()] = value;
328
-
329
- return this;
330
- };
331
-
332
-
333
-
334
-
335
- /**
336
- * A simple getter
337
- *
338
- * @param string name The name of the property to get
339
- */
340
- this.get =
341
- this.Get = function (name)
342
- {
343
- /**
344
- * This should be done first - prepend the property name with "chart." if necessary
345
- */
346
- if (name.substr(0,6) != 'chart.') {
347
- name = 'chart.' + name;
348
- }
349
-
350
- // Convert uppercase letters to dot+lower case letter
351
- while(name.match(/([A-Z])/)) {
352
- name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
353
- }
354
-
355
- return prop[name.toLowerCase()];
356
- };
357
-
358
-
359
-
360
-
361
- /**
362
- * This method draws the rose chart
363
- */
364
- this.draw =
365
- this.Draw = function ()
366
- {
367
- /**
368
- * Fire the onbeforedraw event
369
- */
370
- RG.FireCustomEvent(this, 'onbeforedraw');
371
-
372
-
373
- /**
374
- * This doesn't affect the chart, but is used for compatibility
375
- */
376
- this.gutterLeft = prop['chart.gutter.left'];
377
- this.gutterRight = prop['chart.gutter.right'];
378
- this.gutterTop = prop['chart.gutter.top'];
379
- this.gutterBottom = prop['chart.gutter.bottom'];
380
-
381
- // Calculate the radius
382
- this.radius = (Math.min(ca.width - this.gutterLeft - this.gutterRight, ca.height - this.gutterTop - this.gutterBottom) / 2);
383
- this.centerx = ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
384
- this.centery = ((ca.height - this.gutterTop - this.gutterBottom) / 2) + this.gutterTop;
385
- this.coords = [];
386
- this.coords2 = [];
387
-
388
-
389
-
390
- /**
391
- * Stop this growing uncontrollably
392
- */
393
- this.coordsText = [];
394
-
395
-
396
-
397
-
398
- /**
399
- * If there's a user specified radius/centerx/centery, use them
400
- */
401
- if (typeof(prop['chart.centerx']) == 'number') this.centerx = prop['chart.centerx'];
402
- if (typeof(prop['chart.centery']) == 'number') this.centery = prop['chart.centery'];
403
- if (typeof(prop['chart.radius']) == 'number') this.radius = prop['chart.radius'];
404
-
405
-
406
-
407
- /**
408
- * Parse the colors for gradients. Its down here so that the center X/Y can be used
409
- */
410
- if (!this.colorsParsed) {
411
-
412
- this.parseColors();
413
-
414
- // Don't want to do this again
415
- this.colorsParsed = true;
416
- }
417
-
418
-
419
- /**
420
- * Work out the scale
421
- */
422
- var max = prop['chart.ymax'];
423
- var min = prop['chart.ymin'];
424
-
425
- if (typeof(max) == 'number') {
426
- this.max = max;
427
- this.scale2 = RG.getScale2(this, {
428
- 'max':max,
429
- 'min':min,
430
- 'strict':true,
431
- 'scale.decimals':Number(prop['chart.scale.decimals']),
432
- 'scale.point':prop['chart.scale.point'],
433
- 'scale.thousand':prop['chart.scale.thousand'],
434
- 'scale.round':prop['chart.scale.round'],
435
- 'units.pre':prop['chart.units.pre'],
436
- 'units.post':prop['chart.units.post'],
437
- 'ylabels.count':prop['chart.labels.count']
438
- });
439
- } else {
440
-
441
- for (var i=0; i<this.data.length; i+=1) {
442
- for (var j=0,len=this.data[i].length; j<len; j+=1) {
443
- this.max = Math.max(this.max, this.data[i][j][1]);
444
- }
445
- }
446
-
447
- this.min = prop['chart.ymin'];
448
-
449
- this.scale2 = RG.getScale2(this, {
450
- 'max':this.max,
451
- 'min':min,
452
- 'scale.decimals':Number(prop['chart.scale.decimals']),
453
- 'scale.point':prop['chart.scale.point'],
454
- 'scale.thousand':prop['chart.scale.thousand'],
455
- 'scale.round':prop['chart.scale.round'],
456
- 'units.pre':prop['chart.units.pre'],
457
- 'units.post':prop['chart.units.post'],
458
- 'ylabels.count':prop['chart.labels.count']
459
- });
460
- this.max = this.scale2.max;
461
- }
462
-
463
- /**
464
- * Change the centerx marginally if the key is defined
465
- */
466
- if (prop['chart.key'] && prop['chart.key'].length > 0 && prop['chart.key'].length >= 3) {
467
- this.centerx = this.centerx - prop['chart.gutter.right'] + 5;
468
- }
469
-
470
- /**
471
- * Populate the colors array for the purposes of generating the key
472
- */
473
- if (typeof(prop['chart.key']) == 'object' && RG.is_array(prop['chart.key']) && prop['chart.key'][0]) {
474
-
475
- // Reset the colors array
476
- prop['chart.colors'] = [];
477
-
478
- for (var i=0; i<this.data.length; i+=1) {
479
- for (var j=0,len=this.data[i].length; j<len; j+=1) {
480
- if (typeof this.data[i][j][2] == 'string') {
481
- prop['chart.colors'].push(this.data[i][j][2]);
482
- }
483
- }
484
- }
485
- }
486
-
487
-
488
-
489
-
490
- /**
491
- * Populate the chart.tooltips array
492
- */
493
- this.Set('chart.tooltips', []);
494
-
495
- for (var i=0; i<this.data.length; i+=1) {
496
- for (var j=0,len=this.data[i].length; j<len; j+=1) {
497
- if (typeof this.data[i][j][3] == 'string') {
498
- prop['chart.tooltips'].push(this.data[i][j][3]);
499
- }
500
- }
501
- }
502
-
503
-
504
-
505
- // This resets the chart drawing state
506
- co.beginPath();
507
-
508
- this.DrawBackground();
509
- this.DrawRscatter();
510
- this.DrawLabels();
511
-
512
- /**
513
- * Setup the context menu if required
514
- */
515
- if (prop['chart.contextmenu']) {
516
- RG.ShowContext(this);
517
- }
518
-
519
-
520
-
521
- // Draw the title if any has been set
522
- if (prop['chart.title']) {
523
- RG.DrawTitle(
524
- this,
525
- prop['chart.title'],
526
- this.centery - this.radius - 10,
527
- this.centerx,
528
- prop['chart.title.size'] ? prop['chart.title.size'] : prop['chart.text.size'] + 2
529
- );
530
- }
531
-
532
-
533
- /**
534
- * This function enables resizing
535
- */
536
- if (prop['chart.resizable']) {
537
- RG.AllowResizing(this);
538
- }
539
-
540
-
541
- /**
542
- * This installs the event listeners
543
- */
544
- RG.InstallEventListeners(this);
545
-
546
-
547
-
548
-
549
-
550
-
551
- //
552
- // Allow the segments to be highlighted
553
- //
554
- if (prop['chart.segment.highlight']) {
555
- RG.allowSegmentHighlight({
556
- object: this,
557
-
558
- // This is duplicated in the drawBackground function
559
- count: typeof prop['chart.segment.highlight.count'] === 'number' ? prop['chart.segment.highlight.count'] : ((prop['chart.background.grid.diagonals.count'] ? prop['chart.background.grid.diagonals.count'] : (prop['chart.labels'] ? prop['chart.labels'].length : 8))),
560
-
561
- fill: prop['chart.segment.highlight.fill'],
562
- stroke: prop['chart.segment.highlight.stroke']
563
- });
564
- }
565
-
566
-
567
-
568
-
569
- /**
570
- * Fire the onfirstdraw event
571
- */
572
- if (this.firstDraw) {
573
- RG.fireCustomEvent(this, 'onfirstdraw');
574
- this.firstDraw = false;
575
- this.firstDrawFunc();
576
- }
577
-
578
-
579
-
580
-
581
- /**
582
- * Fire the RGraph ondraw event
583
- */
584
- RG.FireCustomEvent(this, 'ondraw');
585
-
586
-
587
-
588
-
589
- return this;
590
- };
591
-
592
-
593
-
594
-
595
- /**
596
- * This method draws the rscatter charts background
597
- */
598
- this.drawBackground =
599
- this.DrawBackground = function ()
600
- {
601
- //
602
- // Draw the background color first
603
- //
604
- if (prop['chart.background.color'] != 'transparent') {
605
- pa2(co, ['b','a', this.centerx, this.centery, this.radius, 0, 2 * ma.PI, -1, 'f', prop['chart.background.color']]);
606
- }
607
-
608
-
609
- var gridEnabled = prop['chart.background.grid'];
610
-
611
-
612
- if (gridEnabled) {
613
- co.lineWidth = prop['chart.background.grid.linewidth'];
614
-
615
-
616
-
617
- // Draw the background grey circles
618
- if (prop['chart.background.grid.radials']) {
619
-
620
- co.strokeStyle = prop['chart.background.grid.color'];
621
-
622
- if (RG.isNull(prop['chart.background.grid.radials.count'])) {
623
- prop['chart.background.grid.radials.count'] = prop['chart.labels.count'];
624
- }
625
-
626
- // Radius must be greater than 0 for Opera to work
627
-
628
- var r = this.radius / prop['chart.background.grid.radials.count'];
629
-
630
- for (var i=0,len=this.radius; i<=len; i+=r) {
631
-
632
- // Radius must be greater than 0 for Opera to work
633
- co.arc(this.centerx, this.centery, i, 0, RG.TWOPI, 0);
634
- }
635
- co.stroke();
636
- }
637
-
638
-
639
-
640
-
641
-
642
-
643
-
644
- // Draw the background lines that go from the center outwards
645
- if (prop['chart.background.grid.diagonals']) {
646
-
647
- co.strokeStyle = prop['chart.background.grid.color'];
648
-
649
- co.beginPath();
650
-
651
- // This is duplicated in the allowSegmentHighlight call
652
- var inc = 360 / ((prop['chart.background.grid.diagonals.count'] ? prop['chart.background.grid.diagonals.count'] : (prop['chart.labels'] ? prop['chart.labels'].length : 8)));
653
-
654
-
655
- for (var i=inc; i<360; i+=inc) {
656
-
657
- // Radius must be greater than 0 for Opera to work
658
- co.arc(
659
- this.centerx,
660
- this.centery,
661
- this.radius,
662
- (i / (180 / RG.PI)) - RG.HALFPI,
663
- ((i + 0.01) / (180 / RG.PI)) - RG.HALFPI,
664
- 0
665
- );
666
-
667
- co.lineTo(this.centerx, this.centery);
668
- }
669
- co.stroke();
670
- }
671
- }
672
-
673
- // Reset the linewidth
674
- co.lineWidth = 1;
675
-
676
-
677
-
678
-
679
-
680
-
681
-
682
-
683
-
684
-
685
-
686
-
687
-
688
- co.beginPath();
689
- co.strokeStyle = prop['chart.axes.color'];
690
-
691
- // Draw the X axis
692
- co.moveTo(this.centerx - this.radius, Math.round(this.centery));
693
- co.lineTo(this.centerx + this.radius, Math.round(this.centery));
694
-
695
- // Draw the X ends
696
- if (prop['chart.axes.caps']) {
697
- co.moveTo(ma.round(this.centerx - this.radius), this.centery - 5);
698
- co.lineTo(ma.round(this.centerx - this.radius), this.centery + 5);
699
- co.moveTo(ma.round(this.centerx + this.radius), this.centery - 5);
700
- co.lineTo(ma.round(this.centerx + this.radius), this.centery + 5);
701
- }
702
-
703
-
704
-
705
- if (!RG.isNull(prop['chart.axes.numticks'])) {
706
- var numticks = prop['chart.axes.numticks']
707
- } else {
708
- var numticks = prop['chart.labels.count'];
709
- }
710
-
711
- var caps = prop['chart.axes.caps'];
712
-
713
- if (numticks) {
714
- // Draw the X check marks
715
- for (var i=(this.centerx - this.radius); i<(this.centerx + this.radius); i+=(this.radius / numticks)) {
716
- co.moveTo(ma.round(i), this.centery - 3);
717
- co.lineTo(ma.round(i), this.centery + 3);
718
- }
719
-
720
- // Draw the Y check marks
721
- for (var i=(this.centery - this.radius); i<(this.centery + this.radius); i+=(this.radius / numticks)) {
722
- co.moveTo(this.centerx - 3, ma.round(i));
723
- co.lineTo(this.centerx + 3, ma.round(i));
724
- }
725
- }
726
-
727
- // Draw the Y axis
728
- co.moveTo(ma.round(this.centerx), this.centery - this.radius);
729
- co.lineTo(ma.round(this.centerx), this.centery + this.radius);
730
-
731
- // Draw the Y ends
732
- if (prop['chart.axes.caps']) {
733
- co.moveTo(this.centerx - 5, ma.round(this.centery - this.radius));
734
- co.lineTo(this.centerx + 5, ma.round(this.centery - this.radius));
735
-
736
- co.moveTo(this.centerx - 5, ma.round(this.centery + this.radius));
737
- co.lineTo(this.centerx + 5, ma.round(this.centery + this.radius));
738
- }
739
-
740
- // Stroke it
741
- co.closePath();
742
- co.stroke();
743
- };
744
-
745
-
746
-
747
-
748
- /**
749
- * This method draws a set of data on the graph
750
- */
751
- this.drawRscatter =
752
- this.DrawRscatter = function ()
753
- {
754
- for (var dataset=0; dataset<this.data.length; dataset+=1) {
755
-
756
- var data = this.data[dataset];
757
-
758
- // Don't do this
759
- // this.coords = [];
760
-
761
- this.coords2[dataset] = [];
762
-
763
- var drawPoints = function (obj)
764
- {
765
- for (var i=0; i<data.length; ++i) {
766
-
767
- var d1 = data[i][0],
768
- d2 = data[i][1],
769
- a = d1 / (180 / RG.PI), // RADIANS
770
- r = ( (d2 - prop['chart.ymin']) / (obj.scale2.max - obj.scale2.min) ) * obj.radius,
771
- x = ma.sin(a) * r,
772
- y = ma.cos(a) * r,
773
- color = data[i][2] ? data[i][2] : prop['chart.colors.default'],
774
- tooltip = data[i][3] ? data[i][3] : null
775
-
776
- if (tooltip && String(tooltip).length) {
777
- obj.hasTooltips = true;
778
- }
779
-
780
- /**
781
- * Account for the correct quadrant
782
- */
783
- x = x + obj.centerx;
784
- y = obj.centery - y;
785
-
786
-
787
- obj.drawTick(x, y, color);
788
-
789
- // Populate the coords array with the coordinates and the tooltip
790
-
791
- obj.coords.push([x, y, color, tooltip]);
792
- obj.coords2[dataset].push([x, y, color, tooltip]);
793
- }
794
- }
795
-
796
- drawPoints(this);
797
-
798
- if (prop['chart.line']) {
799
- this.drawLine(dataset);
800
- }
801
-
802
- // Causes tooltips not to appear sometimes on this demo page:
803
- // /demos/rscatter-multiple-datasets-single-array.html
804
- //
805
- //drawPoints(this);
806
- }
807
- };
808
-
809
-
810
-
811
-
812
- /*
813
- * Draws a connecting line through the points if requested
814
- *
815
- * @param object opt The options to the line
816
- */
817
- this.drawLine = function (idx)
818
- {
819
- var opt = {
820
- dataset: idx,
821
- coords: this.coords2[idx],
822
- color: prop['chart.line.colors'][idx],
823
- shadow: prop['chart.line.shadow'],
824
- shadowColor: prop['chart.line.shadow.color'],
825
- shadowOffsetX: prop['chart.line.shadow.offsetx'],
826
- shadowOffsetY: prop['chart.line.shadow.offsety'],
827
- shadowBlur: prop['chart.line.shadow.blur'],
828
- linewidth: prop['chart.line.linewidth']
829
- };
830
-
831
- co.beginPath();
832
-
833
- co.strokeStyle = this.parseSingleColorForGradient(opt.color);
834
- co.lineWidth = typeof prop['chart.line.linewidth'] === 'object' ? prop['chart.line.linewidth'][idx] : prop['chart.line.linewidth'];
835
- co.lineCap = 'round';
836
-
837
- if (opt.shadow) {
838
- RG.setShadow(
839
- this,
840
- opt.shadowColor,
841
- opt.shadowOffsetX,
842
- opt.shadowOffsetY,
843
- opt.shadowBlur
844
- );
845
- }
846
-
847
- for (var i=0; i<this.coords2[idx].length; ++i) {
848
- if (i === 0) {
849
- co.moveTo(this.coords2[idx][i][0], this.coords2[idx][i][1]);
850
-
851
- var startCoords = RG.arrayClone(this.coords2[idx]);
852
-
853
- } else {
854
- co.lineTo(this.coords2[idx][i][0], this.coords2[idx][i][1]);
855
- }
856
- }
857
-
858
- // Draw the line back to the start?
859
- if (
860
- (typeof prop['chart.line.close'] === 'boolean' && prop['chart.line.close'])
861
- || (typeof prop['chart.line.close'] === 'object' && prop['chart.line.close'][idx])
862
- ) {
863
- co.lineTo(this.coords2[idx][0][0], this.coords2[idx][0][1]);
864
- }
865
-
866
- co.stroke();
867
-
868
- RG.noShadow(this);
869
- };
870
-
871
-
872
-
873
-
874
- /**
875
- * Unsuprisingly, draws the labels
876
- */
877
- this.drawLabels =
878
- this.DrawLabels = function ()
879
- {
880
- co.lineWidth = 1;
881
-
882
- // Default the color to black
883
- co.fillStyle = 'black';
884
- co.strokeStyle = 'black';
885
-
886
- var key = prop['chart.key'];
887
- var r = this.radius;
888
- var axesColor = prop['chart.axes.color'];
889
- var color = prop['chart.text.color'];
890
- var font = prop['chart.text.font'];
891
- var size = prop['chart.text.size'];
892
- var axes = prop['chart.labels.axes'].toLowerCase();
893
- var units_pre = prop['chart.units.pre'];
894
- var units_post = prop['chart.units.post'];
895
- var decimals = prop['chart.scale.decimals'];
896
- var centerx = this.centerx;
897
- var centery = this.centery;
898
-
899
- co.fillStyle = prop['chart.text.color'];
900
-
901
- // Draw any labels
902
- if (typeof prop['chart.labels'] == 'object' && prop['chart.labels']) {
903
- this.DrawCircularLabels(co, prop['chart.labels'], font , size, r);
904
- }
905
-
906
-
907
- //
908
- // If the axes are transparent - then the labels should have no offset,
909
- // otherwise it defaults to true. Similarly the labels can or can't be
910
- // centered if there's no axes
911
- //
912
- var offset = 10;
913
- var centered = false;
914
-
915
- if ( axesColor === 'rgba(0,0,0,0)'
916
- || axesColor === 'rgb(0,0,0)'
917
- || axesColor === 'transparent') {
918
-
919
- offset = 0;
920
- centered = true;
921
- }
922
-
923
- // Draw the axis labels
924
- for (var i=0,len=this.scale2.labels.length; i<len; ++i) {
925
- if (axes.indexOf('n') > -1) RG.text2(this, {'tag': 'scale','font':font,'size':size,'x':centerx - offset,'y':centery - (r * ((i+1) / len)),'text':this.scale2.labels[i],'valign':'center','halign':centered ? 'center' : 'right',bounding: true, boundingFill: prop['chart.labels.axes.background'], boundingStroke: 'rgba(0,0,0,0)'});
926
- if (axes.indexOf('s') > -1) RG.text2(this, {'tag': 'scale','font':font,'size':size,'x':centerx - offset,'y':centery + (r * ((i+1) / len)),'text':this.scale2.labels[i],'valign':'center','halign':centered ? 'center' : 'right',bounding: true, boundingFill: prop['chart.labels.axes.background'], boundingStroke: 'rgba(0,0,0,0)'});
927
- if (axes.indexOf('e') > -1) RG.text2(this, {'tag': 'scale','font':font,'size':size,'x':centerx + (r * ((i+1) / len)),'y':centery + offset,'text':this.scale2.labels[i],'valign':centered ? 'center' : 'top','halign':'center',bounding: true, boundingFill: prop['chart.labels.axes.background'], boundingStroke: 'rgba(0,0,0,0)'});
928
- if (axes.indexOf('w') > -1) RG.text2(this, {'tag': 'scale','font':font,'size':size,'x':centerx - (r * ((i+1) / len)),'y':centery + offset,'text':this.scale2.labels[i],'valign':centered ? 'center' : 'top','halign':'center',bounding: true, boundingFill: prop['chart.labels.axes.background'], boundingStroke: 'rgba(0,0,0,0)'});
929
- }
930
-
931
- // Draw the center minimum value (but only if there's at least one axes labels stipulated)
932
- if (prop['chart.labels.axes'].length > 0 && prop['chart.scale.zerostart']) {
933
- RG.text2(this, {
934
- 'font':font,
935
- 'size':size,
936
- 'x':centerx,
937
- 'y':centery,
938
- 'text':RG.numberFormat(this, Number(this.scale2.min).toFixed(this.scale2.decimals), this.scale2.units_pre, this.scale2.units_post),
939
- 'valign':'center',
940
- 'halign':'center',
941
- 'bounding':true,
942
- 'boundingFill': prop['chart.labels.axes.background'],
943
- 'boundingStroke': 'rgba(0,0,0,0)',
944
- 'tag': 'scale'
945
- });
946
- }
947
-
948
- /**
949
- * Draw the key
950
- */
951
- if (key && key.length) {
952
- RG.drawKey(this, key, prop['chart.colors']);
953
- }
954
- };
955
-
956
-
957
-
958
-
959
- /**
960
- * Draws the circular labels that go around the charts
961
- *
962
- * @param labels array The labels that go around the chart
963
- */
964
- this.drawCircularLabels =
965
- this.DrawCircularLabels = function (context, labels, font_face, font_size, r)
966
- {
967
- var r = r + 10,
968
- color = prop['chart.labels.color'];
969
-
970
- for (var i=0; i<labels.length; ++i) {
971
-
972
- var a = (360 / labels.length) * (i + 1) - (360 / (labels.length * 2));
973
- var a = a - 90 + (prop['chart.labels.position'] == 'edge' ? ((360 / labels.length) / 2) : 0);
974
-
975
- var x = ma.cos(a / (180/RG.PI) ) * r;
976
- var y = ma.sin(a / (180/RG.PI)) * r;
977
-
978
- RG.Text2(this, {
979
- 'color': color,
980
- 'font':font_face,
981
- 'size':font_size,
982
- 'x':this.centerx + x,
983
- 'y':this.centery + y,
984
- 'text':String(labels[i]),
985
- 'valign':'center',
986
- 'halign':( (this.centerx + x) > this.centerx) ? 'left' : 'right',
987
- 'tag': 'labels'
988
- });
989
- }
990
- };
991
-
992
-
993
-
994
-
995
- /**
996
- * Draws a single tickmark
997
- */
998
- this.drawTick =
999
- this.DrawTick = function (x, y, color)
1000
- {
1001
- var tickmarks = prop['chart.tickmarks'];
1002
- var ticksize = prop['chart.ticksize'];
1003
-
1004
- co.strokeStyle = color;
1005
- co.fillStyle = color;
1006
-
1007
- // Set the linewidth for the tickmark to 1
1008
- var prevLinewidth = co.lineWidth;
1009
- co.lineWidth = 1;
1010
-
1011
- // Cross
1012
- if (tickmarks == 'cross') {
1013
-
1014
- co.beginPath();
1015
- co.moveTo(x + ticksize, y + ticksize);
1016
- co.lineTo(x - ticksize, y - ticksize);
1017
- co.stroke();
1018
-
1019
- co.beginPath();
1020
- co.moveTo(x - ticksize, y + ticksize);
1021
- co.lineTo(x + ticksize, y - ticksize);
1022
- co.stroke();
1023
-
1024
- // Circle
1025
- } else if (tickmarks == 'circle') {
1026
-
1027
- co.beginPath();
1028
- co.arc(x, y, ticksize, 0, 6.2830, false);
1029
- co.fill();
1030
-
1031
- // Square
1032
- } else if (tickmarks == 'square') {
1033
-
1034
- co.beginPath();
1035
- co.fillRect(x - ticksize, y - ticksize, 2 * ticksize, 2 * ticksize);
1036
- co.fill();
1037
-
1038
- // Diamond shape tickmarks
1039
- } else if (tickmarks == 'diamond') {
1040
-
1041
- co.beginPath();
1042
- co.moveTo(x, y - ticksize);
1043
- co.lineTo(x + ticksize, y);
1044
- co.lineTo(x, y + ticksize);
1045
- co.lineTo(x - ticksize, y);
1046
- co.closePath();
1047
- co.fill();
1048
-
1049
- // Plus style tickmarks
1050
- } else if (tickmarks == 'plus') {
1051
-
1052
- co.lineWidth = 1;
1053
-
1054
- co.beginPath();
1055
- co.moveTo(x, y - ticksize);
1056
- co.lineTo(x, y + ticksize);
1057
- co.moveTo(x - ticksize, y);
1058
- co.lineTo(x + ticksize, y);
1059
- co.stroke();
1060
- }
1061
-
1062
-
1063
- co.lineWidth = prevLinewidth;
1064
- };
1065
-
1066
-
1067
-
1068
-
1069
- /**
1070
- * This function makes it much easier to get the (if any) point that is currently being hovered over.
1071
- *
1072
- * @param object e The event object
1073
- */
1074
- this.getShape =
1075
- this.getPoint = function (e)
1076
- {
1077
- var mouseXY = RG.getMouseXY(e);
1078
- var mouseX = mouseXY[0];
1079
- var mouseY = mouseXY[1];
1080
- var overHotspot = false;
1081
- var offset = prop['chart.tooltips.hotspot']; // This is how far the hotspot extends
1082
-
1083
- for (var i=0,len=this.coords.length; i<len; ++i) {
1084
-
1085
- var x = this.coords[i][0];
1086
- var y = this.coords[i][1];
1087
- var tooltip = this.coords[i][3];
1088
-
1089
- if (
1090
- mouseX < (x + offset) &&
1091
- mouseX > (x - offset) &&
1092
- mouseY < (y + offset) &&
1093
- mouseY > (y - offset)
1094
- ) {
1095
-
1096
- var tooltip = RG.parseTooltipText(prop['chart.tooltips'], i);
1097
-
1098
- return {0:this,1:x,2:y,3:i,'object':this, 'x':x, 'y':y, 'index':i, 'tooltip': tooltip};
1099
- }
1100
- }
1101
- };
1102
-
1103
-
1104
-
1105
-
1106
- /**
1107
- * This function facilitates the installation of tooltip event listeners if
1108
- * tooltips are defined.
1109
- */
1110
- this.allowTooltips =
1111
- this.AllowTooltips = function ()
1112
- {
1113
- // Preload any tooltip images that are used in the tooltips
1114
- RG.PreLoadTooltipImages(this);
1115
-
1116
-
1117
- /**
1118
- * This installs the window mousedown event listener that lears any
1119
- * highlight that may be visible.
1120
- */
1121
- RG.InstallWindowMousedownTooltipListener(this);
1122
-
1123
-
1124
- /**
1125
- * This installs the canvas mousemove event listener. This function
1126
- * controls the pointer shape.
1127
- */
1128
- RG.InstallCanvasMousemoveTooltipListener(this);
1129
-
1130
-
1131
- /**
1132
- * This installs the canvas mouseup event listener. This is the
1133
- * function that actually shows the appropriate tooltip (if any).
1134
- */
1135
- RG.InstallCanvasMouseupTooltipListener(this);
1136
- };
1137
-
1138
-
1139
-
1140
-
1141
- /**
1142
- * Each object type has its own Highlight() function which highlights the appropriate shape
1143
- *
1144
- * @param object shape The shape to highlight
1145
- */
1146
- this.highlight =
1147
- this.Highlight = function (shape)
1148
- {
1149
- if (typeof prop['chart.highlight.style'] === 'function') {
1150
- (prop['chart.highlight.style'])(shape);
1151
- } else {
1152
- RG.Highlight.Point(this, shape);
1153
- }
1154
- };
1155
-
1156
-
1157
-
1158
-
1159
- /**
1160
- * The getObjectByXY() worker method. Don't call this call:
1161
- *
1162
- * RGraph.ObjectRegistry.getObjectByXY(e)
1163
- *
1164
- * @param object e The event object
1165
- */
1166
- this.getObjectByXY = function (e)
1167
- {
1168
- var mouseXY = RG.getMouseXY(e);
1169
- var mouseX = mouseXY[0];
1170
- var mouseY = mouseXY[1];
1171
- var centerx = this.centerx;
1172
- var centery = this.centery;
1173
- var radius = this.radius;
1174
-
1175
- if (
1176
- mouseX > (centerx - radius)
1177
- && mouseX < (centerx + radius)
1178
- && mouseY > (centery - radius)
1179
- && mouseY < (centery + radius)
1180
- ) {
1181
-
1182
- return this;
1183
- }
1184
- };
1185
-
1186
-
1187
-
1188
-
1189
- /**
1190
- * This function positions a tooltip when it is displayed
1191
- *
1192
- * @param obj object The chart object
1193
- * @param int x The X coordinate specified for the tooltip
1194
- * @param int y The Y coordinate specified for the tooltip
1195
- * @param objec tooltip The tooltips DIV element
1196
- *
1197
- this.positionTooltip = function (obj, x, y, tooltip, idx)
1198
- {
1199
- var coordX = obj.coords[tooltip.__index__][0];
1200
- var coordY = obj.coords[tooltip.__index__][1];
1201
- var canvasXY = RG.getCanvasXY(obj.canvas);
1202
- var mouseXY = RG.getMouseXY(window.event);
1203
- var gutterLeft = obj.gutterLeft;
1204
- var gutterTop = obj.gutterTop;
1205
- var width = tooltip.offsetWidth;
1206
- var height = tooltip.offsetHeight;
1207
-
1208
- // Set the top position
1209
- tooltip.style.left = 0;
1210
- tooltip.style.top = window.event.pageY - height - 5 + 'px';
1211
-
1212
- // By default any overflow is hidden
1213
- tooltip.style.overflow = '';
1214
-
1215
- // Reposition the tooltip if at the edges:
1216
-
1217
- // LEFT edge
1218
- if (canvasXY[0] + mouseXY[0] - (width / 2) < 0) {
1219
- tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.1) + 'px';
1220
-
1221
- // RIGHT edge
1222
- } else if (canvasXY[0] + mouseXY[0] + (width / 2) > doc.body.offsetWidth) {
1223
- tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.9) + 'px';
1224
-
1225
- // Default positioning - CENTERED
1226
- } else {
1227
- tooltip.style.left = canvasXY[0] + mouseXY[0] - (width / 2) + 'px';
1228
- }
1229
- };*/
1230
-
1231
-
1232
-
1233
-
1234
- /**
1235
- * This function returns the radius (ie the distance from the center) for a particular
1236
- * value.
1237
- *
1238
- * @param number value The value you want the radius for
1239
- */
1240
- this.getRadius = function (value)
1241
- {
1242
- var max = this.max;
1243
-
1244
- if (value < 0 || value > max) {
1245
- return null;
1246
- }
1247
-
1248
- var r = (value / max) * this.radius;
1249
-
1250
- return r;
1251
- };
1252
-
1253
-
1254
-
1255
-
1256
- /**
1257
- * This allows for easy specification of gradients
1258
- */
1259
- this.parseColors = function ()
1260
- {
1261
- // Save the original colors so that they can be restored when the canvas is reset
1262
- if (this.original_colors.length === 0) {
1263
- this.original_colors['data'] = RG.array_clone(this.data);
1264
- this.original_colors['chart.highlight.stroke'] = RG.arrayClone(prop['chart.highlight.stroke']);
1265
- this.original_colors['chart.highlight.fill'] = RG.arrayClone(prop['chart.highlight.fill']);
1266
- this.original_colors['chart.colors.default'] = RG.arrayClone(prop['chart.colors.default']);
1267
- this.original_colors['chart.background.grid.color'] = RG.arrayClone(prop['chart.background.grid.color']);
1268
- this.original_colors['chart.background.color'] = RG.arrayClone(prop['chart.background.color']);
1269
- this.original_colors['chart.segment.highlight.stroke'] = RG.arrayClone(prop['chart.segment.highlight.stroke']);
1270
- this.original_colors['chart.segment.highlight.fill'] = RG.arrayClone(prop['chart.segment.highlight.fill']);
1271
- }
1272
-
1273
-
1274
-
1275
-
1276
-
1277
-
1278
- // Go through the data
1279
- for (var i=0; i<this.data.length; i+=1) {
1280
- for (var j=0,len=this.data[i].length; j<len; j+=1) {
1281
- this.data[i][j][2] = this.parseSingleColorForGradient(this.data[i][j][2]);
1282
- }
1283
- }
1284
-
1285
- prop['chart.highlight.stroke'] = this.parseSingleColorForGradient(prop['chart.highlight.stroke']);
1286
- prop['chart.highlight.fill'] = this.parseSingleColorForGradient(prop['chart.highlight.fill']);
1287
- prop['chart.colors.default'] = this.parseSingleColorForGradient(prop['chart.colors.default']);
1288
- prop['chart.background.grid.color'] = this.parseSingleColorForGradient(prop['chart.background.grid.color']);
1289
- prop['chart.background.color'] = this.parseSingleColorForGradient(prop['chart.background.color']);
1290
- prop['chart.segment.highlight.stroke'] = this.parseSingleColorForGradient(prop['chart.segment.highlight.stroke']);
1291
- prop['chart.segment.highlight.fill'] = this.parseSingleColorForGradient(prop['chart.segment.highlight.fill']);
1292
- };
1293
-
1294
-
1295
-
1296
-
1297
- /**
1298
- * Use this function to reset the object to the post-constructor state. Eg reset colors if
1299
- * need be etc
1300
- */
1301
- this.reset = function ()
1302
- {
1303
- };
1304
-
1305
-
1306
-
1307
-
1308
- /**
1309
- * This parses a single color value
1310
- */
1311
- this.parseSingleColorForGradient = function (color)
1312
- {
1313
- if (!color || typeof color != 'string') {
1314
- return color;
1315
- }
1316
-
1317
- if (color.match(/^gradient\((.*)\)$/i)) {
1318
-
1319
- var parts = RegExp.$1.split(':');
1320
-
1321
- // Create the gradient
1322
- var grad = co.createRadialGradient(this.centerx, this.centery, 0, this.centerx, this.centery, this.radius);
1323
-
1324
- var diff = 1 / (parts.length - 1);
1325
-
1326
- grad.addColorStop(0, RG.trim(parts[0]));
1327
-
1328
- for (var j=1; j<parts.length; ++j) {
1329
- grad.addColorStop(j * diff, RG.trim(parts[j]));
1330
- }
1331
- }
1332
-
1333
- return grad ? grad : color;
1334
- };
1335
-
1336
-
1337
-
1338
-
1339
- /**
1340
- * This function handles highlighting an entire data-series for the interactive
1341
- * key
1342
- *
1343
- * @param int index The index of the data series to be highlighted
1344
- */
1345
- this.interactiveKeyHighlight = function (index)
1346
- {
1347
- if (this.coords2 && this.coords2[index] && this.coords2[index].length) {
1348
- this.coords2[index].forEach(function (value, idx, arr)
1349
- {
1350
- co.beginPath();
1351
- co.fillStyle = prop['chart.key.interactive.highlight.chart.fill'];
1352
- co.arc(value[0], value[1], prop['chart.ticksize'] + 2, 0, RG.TWOPI, false);
1353
- co.fill();
1354
- });
1355
- }
1356
- };
1357
-
1358
-
1359
-
1360
-
1361
- /**
1362
- * Using a function to add events makes it easier to facilitate method chaining
1363
- *
1364
- * @param string type The type of even to add
1365
- * @param function func
1366
- */
1367
- this.on = function (type, func)
1368
- {
1369
- if (type.substr(0,2) !== 'on') {
1370
- type = 'on' + type;
1371
- }
1372
-
1373
- if (typeof this[type] !== 'function') {
1374
- this[type] = func;
1375
- } else {
1376
- RG.addCustomEventListener(this, type, func);
1377
- }
1378
-
1379
- return this;
1380
- };
1381
-
1382
-
1383
-
1384
-
1385
- /**
1386
- * This helps the Gantt reset colors when the reset function is called.
1387
- * It handles going through the data and resetting the colors.
1388
- */
1389
- this.resetColorsToOriginalValues = function ()
1390
- {
1391
- /**
1392
- * Copy the original colors over for single-event-per-line data
1393
- */
1394
- for (var i=0,len=this.original_colors['data'].length; i<len; ++i) {
1395
- for (var j=0,len2=this.original_colors['data'][i].length; j<len2;++j) {
1396
- this.data[i][j][2] = RG.array_clone(this.original_colors['data'][i][j][2]);
1397
- }
1398
- }
1399
- };
1400
-
1401
-
1402
-
1403
-
1404
- /**
1405
- * This function runs once only
1406
- * (put at the end of the file (before any effects))
1407
- */
1408
- this.firstDrawFunc = function ()
1409
- {
1410
- };
1411
-
1412
-
1413
- RG.att(ca);
1414
-
1415
-
1416
-
1417
-
1418
- /**
1419
- * Register the object
1420
- */
1421
- RG.Register(this);
1422
-
1423
-
1424
-
1425
-
1426
- /**
1427
- * This is the 'end' of the constructor so if the first argument
1428
- * contains configuration data - handle that.
1429
- */
1430
- if (parseConfObjectForOptions) {
1431
- RG.parseObjectStyleConfig(this, conf.options);
1432
- }
1433
- };
2
+ RGraph=window.RGraph||{isRGraph:true};RGraph.RScatter=RGraph.Rscatter=function(conf)
3
+ {if(typeof conf==='object'&&typeof conf.data==='object'&&typeof conf.id==='string'){var parseConfObjectForOptions=true;this.data=new Array(conf.data.length);this.data=RGraph.arrayClone(conf.data);if(typeof conf.data==='object'&&typeof conf.data[0]==='object'&&typeof conf.data[0][0]==='number'){var tmp=RGraph.arrayClone(conf.data);conf.data=new Array();conf.data[0]=RGraph.arrayClone(tmp);this.data=RGraph.arrayClone(conf.data);}}else{var conf={id:conf};conf.data=arguments[1];this.data=[];if(arguments[1][0]&&arguments[1][0][0]&&typeof arguments[1][0][0]=='object'){for(var i=0;i<arguments[1].length;++i){this.data[i]=arguments[1][i];}}else{for(var i=1;i<arguments.length;++i){this.data[i-1]=RGraph.arrayClone(arguments[i]);}}}
4
+ this.id=conf.id
5
+ this.canvas=document.getElementById(this.id)
6
+ this.context=this.canvas.getContext?this.canvas.getContext("2d"):null;this.canvas.__object__=this;this.type='rscatter';this.hasTooltips=false;this.isRGraph=true;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.centerx=0;this.centery=0;this.radius=0;this.max=0;for(var i=0;i<this.data.length;++i){for(var j=0;j<this.data[i].length;++j){if(typeof this.data[i][j][0]==='string'){this.data[i][j][0]=parseFloat(this.data[i][j][0]);}
7
+ if(typeof this.data[i][j][1]==='string'){this.data[i][j][1]=parseFloat(this.data[i][j][1]);}}}
8
+ this.properties={'chart.background.color':'transparent','chart.background.grid':true,'chart.background.grid.diagonals':true,'chart.background.grid.diagonals.count':null,'chart.background.grid.radials':true,'chart.background.grid.radials.count':null,'chart.background.grid.linewidth':1,'chart.background.grid.color':'#ccc','chart.radius':null,'chart.colors':[],'chart.colors.default':'black','chart.gutter.left':25,'chart.gutter.right':25,'chart.gutter.top':25,'chart.gutter.bottom':25,'chart.title':'','chart.title.background':null,'chart.title.hpos':null,'chart.title.vpos':null,'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.labels':null,'chart.labels.color':null,'chart.labels.axes':'nsew','chart.labels.axes.background':'rgba(255,255,255,0.8)','chart.labels.count':5,'chart.text.color':'black','chart.text.font':'Segoe UI, Arial, Verdana, sans-serif','chart.text.size':12,'chart.text.accessible':true,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':true,'chart.key':null,'chart.key.background':'white','chart.key.position':'graph','chart.key.halign':'right','chart.key.shadow':false,'chart.key.shadow.color':'#666','chart.key.shadow.blur':3,'chart.key.shadow.offsetx':2,'chart.key.shadow.offsety':2,'chart.key.position.gutter.boxed':false,'chart.key.position.x':null,'chart.key.position.y':null,'chart.key.color.shape':'square','chart.key.rounded':true,'chart.key.linewidth':1,'chart.key.colors':null,'chart.key.interactive':false,'chart.key.interactive.highlight.chart.fill':'rgba(255,0,0,0.9)','chart.key.interactive.highlight.label':'rgba(255,0,0,0.2)','chart.key.text.color':'black','chart.contextmenu':null,'chart.tooltips':null,'chart.tooltips.event':'onmousemove','chart.tooltips.effect':'fade','chart.tooltips.css.class':'RGraph_tooltip','chart.tooltips.highlight':true,'chart.tooltips.hotspot':3,'chart.tooltips.coords.page':false,'chart.annotatable':false,'chart.annotate.color':'black','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.resizable':false,'chart.resize.handle.background':null,'chart.ymax':null,'chart.ymin':0,'chart.tickmarks':'cross','chart.ticksize':3,'chart.scale.decimals':null,'chart.scale.point':'.','chart.scale.thousand':',','chart.scale.round':false,'chart.scale.zerostart':true,'chart.units.pre':'','chart.units.post':'','chart.events.mousemove':null,'chart.events.click':null,'chart.highlight.stroke':'transparent','chart.highlight.fill':'rgba(255,255,255,0.7)','chart.highlight.point.radius':3,'chart.axes.color':'black','chart.axes.numticks':null,'chart.axes.caps':true,'chart.segment.highlight':false,'chart.segment.highlight.count':null,'chart.segment.highlight.fill':'rgba(0,255,0,0.5)','chart.segment.highlight.stroke':'rgba(0,0,0,0)','chart.line':false,'chart.line.close':false,'chart.line.linewidth':1,'chart.line.colors':['black'],'chart.line.shadow':false,'chart.line.shadow.color':'black','chart.line.shadow.blur':2,'chart.line.shadow.offsetx':3,'chart.line.shadow.offsety':3,'chart.clearto':'rgba(0,0,0,0)'}
9
+ for(var i=0,idx=0;i<this.data.length;++i){for(var j=0,len=this.data[i].length;j<len;j+=1,idx+=1){this['$'+idx]={}}}
10
+ if(!this.canvas.__rgraph_aa_translated__){this.context.translate(0.5,0.5);this.canvas.__rgraph_aa_translated__=true;}
11
+ var RG=RGraph,ca=this.canvas,co=ca.getContext('2d'),prop=this.properties,pa2=RG.path2,win=window,doc=document,ma=Math
12
+ if(RG.Effects&&typeof RG.Effects.decorate==='function'){RG.Effects.decorate(this);}
13
+ this.set=this.Set=function(name,value)
14
+ {var value=typeof arguments[1]==='undefined'?null:arguments[1];if(arguments.length===1&&typeof name==='object'){RG.parseObjectStyleConfig(this,name);return this;}
15
+ if(name.substr(0,6)!='chart.'){name='chart.'+name;}
16
+ while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
17
+ if(name==='chart.segments.highlight')name='chart.segment.highlight';if(name==='chart.segments.highlight.count')name='chart.segment.highlight.count';if(name==='chart.segments.highlight.fill')name='chart.segment.highlight.fill';if(name==='chart.segments.highlight.stroke')name='chart.segment.highlight.stroke';prop[name.toLowerCase()]=value;return this;};this.get=this.Get=function(name)
18
+ {if(name.substr(0,6)!='chart.'){name='chart.'+name;}
19
+ while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
20
+ return prop[name.toLowerCase()];};this.draw=this.Draw=function()
21
+ {RG.FireCustomEvent(this,'onbeforedraw');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.radius=(Math.min(ca.width-this.gutterLeft-this.gutterRight,ca.height-this.gutterTop-this.gutterBottom)/2);this.centerx=((ca.width-this.gutterLeft-this.gutterRight)/2)+this.gutterLeft;this.centery=((ca.height-this.gutterTop-this.gutterBottom)/2)+this.gutterTop;this.coords=[];this.coords2=[];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;}
22
+ var max=prop['chart.ymax'];var min=prop['chart.ymin'];if(typeof(max)=='number'){this.max=max;this.scale2=RG.getScale2(this,{'max':max,'min':min,'strict':true,'scale.decimals':Number(prop['chart.scale.decimals']),'scale.point':prop['chart.scale.point'],'scale.thousand':prop['chart.scale.thousand'],'scale.round':prop['chart.scale.round'],'units.pre':prop['chart.units.pre'],'units.post':prop['chart.units.post'],'ylabels.count':prop['chart.labels.count']});}else{for(var i=0;i<this.data.length;i+=1){for(var j=0,len=this.data[i].length;j<len;j+=1){this.max=Math.max(this.max,this.data[i][j][1]);}}
23
+ this.min=prop['chart.ymin'];this.scale2=RG.getScale2(this,{'max':this.max,'min':min,'scale.decimals':Number(prop['chart.scale.decimals']),'scale.point':prop['chart.scale.point'],'scale.thousand':prop['chart.scale.thousand'],'scale.round':prop['chart.scale.round'],'units.pre':prop['chart.units.pre'],'units.post':prop['chart.units.post'],'ylabels.count':prop['chart.labels.count']});this.max=this.scale2.max;}
24
+ if(prop['chart.key']&&prop['chart.key'].length>0&&prop['chart.key'].length>=3){this.centerx=this.centerx-prop['chart.gutter.right']+5;}
25
+ if(typeof(prop['chart.key'])=='object'&&RG.is_array(prop['chart.key'])&&prop['chart.key'][0]){prop['chart.colors']=[];for(var i=0;i<this.data.length;i+=1){for(var j=0,len=this.data[i].length;j<len;j+=1){if(typeof this.data[i][j][2]=='string'){prop['chart.colors'].push(this.data[i][j][2]);}}}}
26
+ this.Set('chart.tooltips',[]);for(var i=0;i<this.data.length;i+=1){for(var j=0,len=this.data[i].length;j<len;j+=1){if(typeof this.data[i][j][3]=='string'){prop['chart.tooltips'].push(this.data[i][j][3]);}}}
27
+ co.beginPath();this.DrawBackground();this.DrawRscatter();this.DrawLabels();if(prop['chart.contextmenu']){RG.ShowContext(this);}
28
+ if(prop['chart.title']){RG.DrawTitle(this,prop['chart.title'],this.centery-this.radius-10,this.centerx,prop['chart.title.size']?prop['chart.title.size']:prop['chart.text.size']+2);}
29
+ if(prop['chart.resizable']){RG.AllowResizing(this);}
30
+ RG.InstallEventListeners(this);if(prop['chart.segment.highlight']){RG.allowSegmentHighlight({object:this,count:typeof prop['chart.segment.highlight.count']==='number'?prop['chart.segment.highlight.count']:((prop['chart.background.grid.diagonals.count']?prop['chart.background.grid.diagonals.count']:(prop['chart.labels']?prop['chart.labels'].length:8))),fill:prop['chart.segment.highlight.fill'],stroke:prop['chart.segment.highlight.stroke']});}
31
+ if(this.firstDraw){this.firstDraw=false;RG.fireCustomEvent(this,'onfirstdraw');this.firstDrawFunc();}
32
+ RG.FireCustomEvent(this,'ondraw');return this;};this.drawBackground=this.DrawBackground=function()
33
+ {if(prop['chart.background.color']!='transparent'){pa2(co,['b','a',this.centerx,this.centery,this.radius,0,2*ma.PI,-1,'f',prop['chart.background.color']]);}
34
+ var gridEnabled=prop['chart.background.grid'];if(gridEnabled){co.lineWidth=prop['chart.background.grid.linewidth'];if(prop['chart.background.grid.radials']){co.strokeStyle=prop['chart.background.grid.color'];if(RG.isNull(prop['chart.background.grid.radials.count'])){prop['chart.background.grid.radials.count']=prop['chart.labels.count'];}
35
+ var r=this.radius/prop['chart.background.grid.radials.count'];for(var i=0,len=this.radius;i<=len;i+=r){co.arc(this.centerx,this.centery,i,0,RG.TWOPI,0);}
36
+ co.stroke();}
37
+ if(prop['chart.background.grid.diagonals']){co.strokeStyle=prop['chart.background.grid.color'];co.beginPath();var inc=360/((prop['chart.background.grid.diagonals.count']?prop['chart.background.grid.diagonals.count']:(prop['chart.labels']?prop['chart.labels'].length:8)));for(var i=inc;i<360;i+=inc){co.arc(this.centerx,this.centery,this.radius,(i/(180/RG.PI))-RG.HALFPI,((i+0.01)/(180/RG.PI))-RG.HALFPI,0);co.lineTo(this.centerx,this.centery);}
38
+ co.stroke();}}
39
+ co.lineWidth=1;co.beginPath();co.strokeStyle=prop['chart.axes.color'];co.moveTo(this.centerx-this.radius,Math.round(this.centery));co.lineTo(this.centerx+this.radius,Math.round(this.centery));if(prop['chart.axes.caps']){co.moveTo(ma.round(this.centerx-this.radius),this.centery-5);co.lineTo(ma.round(this.centerx-this.radius),this.centery+5);co.moveTo(ma.round(this.centerx+this.radius),this.centery-5);co.lineTo(ma.round(this.centerx+this.radius),this.centery+5);}
40
+ if(!RG.isNull(prop['chart.axes.numticks'])){var numticks=prop['chart.axes.numticks']}else{var numticks=prop['chart.labels.count'];}
41
+ var caps=prop['chart.axes.caps'];if(numticks){for(var i=(this.centerx-this.radius);i<(this.centerx+this.radius);i+=(this.radius/numticks)){co.moveTo(ma.round(i),this.centery-3);co.lineTo(ma.round(i),this.centery+3);}
42
+ for(var i=(this.centery-this.radius);i<(this.centery+this.radius);i+=(this.radius/numticks)){co.moveTo(this.centerx-3,ma.round(i));co.lineTo(this.centerx+3,ma.round(i));}}
43
+ co.moveTo(ma.round(this.centerx),this.centery-this.radius);co.lineTo(ma.round(this.centerx),this.centery+this.radius);if(prop['chart.axes.caps']){co.moveTo(this.centerx-5,ma.round(this.centery-this.radius));co.lineTo(this.centerx+5,ma.round(this.centery-this.radius));co.moveTo(this.centerx-5,ma.round(this.centery+this.radius));co.lineTo(this.centerx+5,ma.round(this.centery+this.radius));}
44
+ co.closePath();co.stroke();};this.drawRscatter=this.DrawRscatter=function()
45
+ {for(var dataset=0;dataset<this.data.length;dataset+=1){var data=this.data[dataset];this.coords2[dataset]=[];var drawPoints=function(obj)
46
+ {for(var i=0;i<data.length;++i){var d1=data[i][0],d2=data[i][1],a=d1/(180/RG.PI),r=((d2-prop['chart.ymin'])/(obj.scale2.max-obj.scale2.min))*obj.radius,x=ma.sin(a)*r,y=ma.cos(a)*r,color=data[i][2]?data[i][2]:prop['chart.colors.default'],tooltip=data[i][3]?data[i][3]:null
47
+ if(tooltip&&String(tooltip).length){obj.hasTooltips=true;}
48
+ x=x+obj.centerx;y=obj.centery-y;obj.drawTick(x,y,color);obj.coords.push([x,y,color,tooltip]);obj.coords2[dataset].push([x,y,color,tooltip]);}}
49
+ drawPoints(this);if(prop['chart.line']){this.drawLine(dataset);}}};this.drawLine=function(idx)
50
+ {var opt={dataset:idx,coords:this.coords2[idx],color:prop['chart.line.colors'][idx],shadow:prop['chart.line.shadow'],shadowColor:prop['chart.line.shadow.color'],shadowOffsetX:prop['chart.line.shadow.offsetx'],shadowOffsetY:prop['chart.line.shadow.offsety'],shadowBlur:prop['chart.line.shadow.blur'],linewidth:prop['chart.line.linewidth']};co.beginPath();co.strokeStyle=this.parseSingleColorForGradient(opt.color);co.lineWidth=typeof prop['chart.line.linewidth']==='object'?prop['chart.line.linewidth'][idx]:prop['chart.line.linewidth'];co.lineCap='round';if(opt.shadow){RG.setShadow(this,opt.shadowColor,opt.shadowOffsetX,opt.shadowOffsetY,opt.shadowBlur);}
51
+ for(var i=0;i<this.coords2[idx].length;++i){if(i===0){co.moveTo(this.coords2[idx][i][0],this.coords2[idx][i][1]);var startCoords=RG.arrayClone(this.coords2[idx]);}else{co.lineTo(this.coords2[idx][i][0],this.coords2[idx][i][1]);}}
52
+ if((typeof prop['chart.line.close']==='boolean'&&prop['chart.line.close'])||(typeof prop['chart.line.close']==='object'&&prop['chart.line.close'][idx])){co.lineTo(this.coords2[idx][0][0],this.coords2[idx][0][1]);}
53
+ co.stroke();RG.noShadow(this);};this.drawLabels=this.DrawLabels=function()
54
+ {co.lineWidth=1;co.fillStyle='black';co.strokeStyle='black';var key=prop['chart.key'];var r=this.radius;var axesColor=prop['chart.axes.color'];var color=prop['chart.text.color'];var font=prop['chart.text.font'];var size=prop['chart.text.size'];var axes=prop['chart.labels.axes'].toLowerCase();var units_pre=prop['chart.units.pre'];var units_post=prop['chart.units.post'];var decimals=prop['chart.scale.decimals'];var centerx=this.centerx;var centery=this.centery;co.fillStyle=prop['chart.text.color'];if(typeof prop['chart.labels']=='object'&&prop['chart.labels']){this.DrawCircularLabels(co,prop['chart.labels'],font,size,r);}
55
+ var offset=10;var centered=false;if(axesColor==='rgba(0,0,0,0)'||axesColor==='rgb(0,0,0)'||axesColor==='transparent'){offset=0;centered=true;}
56
+ for(var i=0,len=this.scale2.labels.length;i<len;++i){if(axes.indexOf('n')>-1)RG.text2(this,{'tag':'scale','font':font,'size':size,'x':centerx-offset,'y':centery-(r*((i+1)/len)),'text':this.scale2.labels[i],'valign':'center','halign':centered?'center':'right',bounding:true,boundingFill:prop['chart.labels.axes.background'],boundingStroke:'rgba(0,0,0,0)'});if(axes.indexOf('s')>-1)RG.text2(this,{'tag':'scale','font':font,'size':size,'x':centerx-offset,'y':centery+(r*((i+1)/len)),'text':this.scale2.labels[i],'valign':'center','halign':centered?'center':'right',bounding:true,boundingFill:prop['chart.labels.axes.background'],boundingStroke:'rgba(0,0,0,0)'});if(axes.indexOf('e')>-1)RG.text2(this,{'tag':'scale','font':font,'size':size,'x':centerx+(r*((i+1)/len)),'y':centery+offset,'text':this.scale2.labels[i],'valign':centered?'center':'top','halign':'center',bounding:true,boundingFill:prop['chart.labels.axes.background'],boundingStroke:'rgba(0,0,0,0)'});if(axes.indexOf('w')>-1)RG.text2(this,{'tag':'scale','font':font,'size':size,'x':centerx-(r*((i+1)/len)),'y':centery+offset,'text':this.scale2.labels[i],'valign':centered?'center':'top','halign':'center',bounding:true,boundingFill:prop['chart.labels.axes.background'],boundingStroke:'rgba(0,0,0,0)'});}
57
+ if(prop['chart.labels.axes'].length>0&&prop['chart.scale.zerostart']){RG.text2(this,{'font':font,'size':size,'x':centerx,'y':centery,'text':RG.numberFormat(this,Number(this.scale2.min).toFixed(this.scale2.decimals),this.scale2.units_pre,this.scale2.units_post),'valign':'center','halign':'center','bounding':true,'boundingFill':prop['chart.labels.axes.background'],'boundingStroke':'rgba(0,0,0,0)','tag':'scale'});}
58
+ if(key&&key.length){RG.drawKey(this,key,prop['chart.colors']);}};this.drawCircularLabels=this.DrawCircularLabels=function(context,labels,font_face,font_size,r)
59
+ {var r=r+10,color=prop['chart.labels.color'];for(var i=0;i<labels.length;++i){var a=(360/labels.length)*(i+1)-(360/(labels.length*2));var a=a-90+(prop['chart.labels.position']=='edge'?((360/labels.length)/2):0);var x=ma.cos(a/(180/RG.PI))*r;var y=ma.sin(a/(180/RG.PI))*r;RG.Text2(this,{'color':color,'font':font_face,'size':font_size,'x':this.centerx+x,'y':this.centery+y,'text':String(labels[i]),'valign':'center','halign':((this.centerx+x)>this.centerx)?'left':'right','tag':'labels'});}};this.drawTick=this.DrawTick=function(x,y,color)
60
+ {var tickmarks=prop['chart.tickmarks'];var ticksize=prop['chart.ticksize'];co.strokeStyle=color;co.fillStyle=color;var prevLinewidth=co.lineWidth;co.lineWidth=1;if(tickmarks=='cross'){co.beginPath();co.moveTo(x+ticksize,y+ticksize);co.lineTo(x-ticksize,y-ticksize);co.stroke();co.beginPath();co.moveTo(x-ticksize,y+ticksize);co.lineTo(x+ticksize,y-ticksize);co.stroke();}else if(tickmarks=='circle'){co.beginPath();co.arc(x,y,ticksize,0,6.2830,false);co.fill();}else if(tickmarks=='square'){co.beginPath();co.fillRect(x-ticksize,y-ticksize,2*ticksize,2*ticksize);co.fill();}else if(tickmarks=='diamond'){co.beginPath();co.moveTo(x,y-ticksize);co.lineTo(x+ticksize,y);co.lineTo(x,y+ticksize);co.lineTo(x-ticksize,y);co.closePath();co.fill();}else if(tickmarks=='plus'){co.lineWidth=1;co.beginPath();co.moveTo(x,y-ticksize);co.lineTo(x,y+ticksize);co.moveTo(x-ticksize,y);co.lineTo(x+ticksize,y);co.stroke();}
61
+ co.lineWidth=prevLinewidth;};this.getShape=this.getPoint=function(e)
62
+ {var mouseXY=RG.getMouseXY(e);var mouseX=mouseXY[0];var mouseY=mouseXY[1];var overHotspot=false;var offset=prop['chart.tooltips.hotspot'];for(var i=0,len=this.coords.length;i<len;++i){var x=this.coords[i][0];var y=this.coords[i][1];var tooltip=this.coords[i][3];if(mouseX<(x+offset)&&mouseX>(x-offset)&&mouseY<(y+offset)&&mouseY>(y-offset)){var tooltip=RG.parseTooltipText(prop['chart.tooltips'],i);return{0:this,1:x,2:y,3:i,'object':this,'x':x,'y':y,'index':i,'tooltip':tooltip};}}};this.allowTooltips=this.AllowTooltips=function()
63
+ {RG.PreLoadTooltipImages(this);RG.InstallWindowMousedownTooltipListener(this);RG.InstallCanvasMousemoveTooltipListener(this);RG.InstallCanvasMouseupTooltipListener(this);};this.highlight=this.Highlight=function(shape)
64
+ {if(typeof prop['chart.highlight.style']==='function'){(prop['chart.highlight.style'])(shape);}else{RG.Highlight.Point(this,shape);}};this.getObjectByXY=function(e)
65
+ {var mouseXY=RG.getMouseXY(e);var mouseX=mouseXY[0];var mouseY=mouseXY[1];var centerx=this.centerx;var centery=this.centery;var radius=this.radius;if(mouseX>(centerx-radius)&&mouseX<(centerx+radius)&&mouseY>(centery-radius)&&mouseY<(centery+radius)){return this;}};this.getRadius=function(value)
66
+ {var max=this.max;if(value<0||value>max){return null;}
67
+ var r=(value/max)*this.radius;return r;};this.parseColors=function()
68
+ {if(this.original_colors.length===0){this.original_colors['data']=RG.array_clone(this.data);this.original_colors['chart.highlight.stroke']=RG.arrayClone(prop['chart.highlight.stroke']);this.original_colors['chart.highlight.fill']=RG.arrayClone(prop['chart.highlight.fill']);this.original_colors['chart.colors.default']=RG.arrayClone(prop['chart.colors.default']);this.original_colors['chart.background.grid.color']=RG.arrayClone(prop['chart.background.grid.color']);this.original_colors['chart.background.color']=RG.arrayClone(prop['chart.background.color']);this.original_colors['chart.segment.highlight.stroke']=RG.arrayClone(prop['chart.segment.highlight.stroke']);this.original_colors['chart.segment.highlight.fill']=RG.arrayClone(prop['chart.segment.highlight.fill']);}
69
+ for(var i=0;i<this.data.length;i+=1){for(var j=0,len=this.data[i].length;j<len;j+=1){this.data[i][j][2]=this.parseSingleColorForGradient(this.data[i][j][2]);}}
70
+ prop['chart.highlight.stroke']=this.parseSingleColorForGradient(prop['chart.highlight.stroke']);prop['chart.highlight.fill']=this.parseSingleColorForGradient(prop['chart.highlight.fill']);prop['chart.colors.default']=this.parseSingleColorForGradient(prop['chart.colors.default']);prop['chart.background.grid.color']=this.parseSingleColorForGradient(prop['chart.background.grid.color']);prop['chart.background.color']=this.parseSingleColorForGradient(prop['chart.background.color']);prop['chart.segment.highlight.stroke']=this.parseSingleColorForGradient(prop['chart.segment.highlight.stroke']);prop['chart.segment.highlight.fill']=this.parseSingleColorForGradient(prop['chart.segment.highlight.fill']);};this.reset=function()
71
+ {};this.parseSingleColorForGradient=function(color)
72
+ {if(!color||typeof color!='string'){return color;}
73
+ if(color.match(/^gradient\((.*)\)$/i)){var parts=RegExp.$1.split(':');var grad=co.createRadialGradient(this.centerx,this.centery,0,this.centerx,this.centery,this.radius);var diff=1/(parts.length-1);grad.addColorStop(0,RG.trim(parts[0]));for(var j=1;j<parts.length;++j){grad.addColorStop(j*diff,RG.trim(parts[j]));}}
74
+ return grad?grad:color;};this.interactiveKeyHighlight=function(index)
75
+ {if(this.coords2&&this.coords2[index]&&this.coords2[index].length){this.coords2[index].forEach(function(value,idx,arr)
76
+ {co.beginPath();co.fillStyle=prop['chart.key.interactive.highlight.chart.fill'];co.arc(value[0],value[1],prop['chart.ticksize']+2,0,RG.TWOPI,false);co.fill();});}};this.on=function(type,func)
77
+ {if(type.substr(0,2)!=='on'){type='on'+type;}
78
+ if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
79
+ return this;};this.resetColorsToOriginalValues=function()
80
+ {for(var i=0,len=this.original_colors['data'].length;i<len;++i){for(var j=0,len2=this.original_colors['data'][i].length;j<len2;++j){this.data[i][j][2]=RG.array_clone(this.original_colors['data'][i][j][2]);}}};this.firstDrawFunc=function()
81
+ {};RG.att(ca);RG.Register(this);if(parseConfObjectForOptions){RG.parseObjectStyleConfig(this,conf.options);}};