rgraph-rails 4.62 → 4.64

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +3 -4
  3. data/lib/rgraph-rails/version.rb +1 -1
  4. data/vendor/assets/javascripts/RGraph.bar.js +240 -3742
  5. data/vendor/assets/javascripts/RGraph.bipolar.js +165 -2005
  6. data/vendor/assets/javascripts/RGraph.common.annotate.js +35 -395
  7. data/vendor/assets/javascripts/RGraph.common.context.js +30 -595
  8. data/vendor/assets/javascripts/RGraph.common.core.js +418 -5359
  9. data/vendor/assets/javascripts/RGraph.common.csv.js +20 -276
  10. data/vendor/assets/javascripts/RGraph.common.deprecated.js +35 -450
  11. data/vendor/assets/javascripts/RGraph.common.dynamic.js +88 -1395
  12. data/vendor/assets/javascripts/RGraph.common.effects.js +90 -1545
  13. data/vendor/assets/javascripts/RGraph.common.key.js +52 -753
  14. data/vendor/assets/javascripts/RGraph.common.resizing.js +37 -563
  15. data/vendor/assets/javascripts/RGraph.common.sheets.js +29 -352
  16. data/vendor/assets/javascripts/RGraph.common.tooltips.js +32 -450
  17. data/vendor/assets/javascripts/RGraph.common.zoom.js +14 -219
  18. data/vendor/assets/javascripts/RGraph.cornergauge.js +71 -0
  19. data/vendor/assets/javascripts/RGraph.drawing.background.js +34 -570
  20. data/vendor/assets/javascripts/RGraph.drawing.circle.js +33 -544
  21. data/vendor/assets/javascripts/RGraph.drawing.image.js +51 -755
  22. data/vendor/assets/javascripts/RGraph.drawing.marker1.js +37 -645
  23. data/vendor/assets/javascripts/RGraph.drawing.marker2.js +36 -633
  24. data/vendor/assets/javascripts/RGraph.drawing.marker3.js +35 -514
  25. data/vendor/assets/javascripts/RGraph.drawing.poly.js +37 -559
  26. data/vendor/assets/javascripts/RGraph.drawing.rect.js +33 -548
  27. data/vendor/assets/javascripts/RGraph.drawing.text.js +36 -664
  28. data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +50 -812
  29. data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +51 -856
  30. data/vendor/assets/javascripts/RGraph.fuel.js +58 -964
  31. data/vendor/assets/javascripts/RGraph.funnel.js +55 -984
  32. data/vendor/assets/javascripts/RGraph.gantt.js +77 -1354
  33. data/vendor/assets/javascripts/RGraph.gauge.js +85 -1421
  34. data/vendor/assets/javascripts/RGraph.hbar.js +162 -2788
  35. data/vendor/assets/javascripts/RGraph.hprogress.js +80 -1401
  36. data/vendor/assets/javascripts/RGraph.line.js +249 -4248
  37. data/vendor/assets/javascripts/RGraph.meter.js +74 -1280
  38. data/vendor/assets/javascripts/RGraph.modaldialog.js +19 -301
  39. data/vendor/assets/javascripts/RGraph.odo.js +71 -1264
  40. data/vendor/assets/javascripts/RGraph.pie.js +137 -2288
  41. data/vendor/assets/javascripts/RGraph.radar.js +110 -1847
  42. data/vendor/assets/javascripts/RGraph.rose.js +108 -1977
  43. data/vendor/assets/javascripts/RGraph.rscatter.js +80 -1432
  44. data/vendor/assets/javascripts/RGraph.scatter.js +172 -3163
  45. data/vendor/assets/javascripts/RGraph.semicircularprogress.js +60 -1120
  46. data/vendor/assets/javascripts/RGraph.svg.bar.js +66 -1735
  47. data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +21 -246
  48. data/vendor/assets/javascripts/RGraph.svg.common.core.js +255 -3937
  49. data/vendor/assets/javascripts/RGraph.svg.common.csv.js +20 -276
  50. data/vendor/assets/javascripts/RGraph.svg.common.fx.js +68 -1303
  51. data/vendor/assets/javascripts/RGraph.svg.common.key.js +19 -205
  52. data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +29 -352
  53. data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +22 -273
  54. data/vendor/assets/javascripts/RGraph.svg.funnel.js +32 -0
  55. data/vendor/assets/javascripts/RGraph.svg.hbar.js +59 -1400
  56. data/vendor/assets/javascripts/RGraph.svg.line.js +70 -1580
  57. data/vendor/assets/javascripts/RGraph.svg.pie.js +55 -1131
  58. data/vendor/assets/javascripts/RGraph.svg.radar.js +57 -1502
  59. data/vendor/assets/javascripts/RGraph.svg.rose.js +66 -1817
  60. data/vendor/assets/javascripts/RGraph.svg.scatter.js +58 -1261
  61. data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +28 -865
  62. data/vendor/assets/javascripts/RGraph.svg.waterfall.js +45 -1252
  63. data/vendor/assets/javascripts/RGraph.thermometer.js +63 -1136
  64. data/vendor/assets/javascripts/RGraph.vprogress.js +83 -1470
  65. data/vendor/assets/javascripts/RGraph.waterfall.js +83 -1347
  66. metadata +5 -4
  67. data/vendor/assets/javascripts/financial-data.js +0 -1067
@@ -1,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);}};