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,1262 +1,59 @@
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
- RGraph.SVG = RGraph.SVG || {};
15
-
16
- // Module pattern
17
- (function (win, doc, undefined)
18
- {
19
- var RG = RGraph,
20
- ua = navigator.userAgent,
21
- ma = Math,
22
- win = window,
23
- doc = document;
24
-
25
-
26
-
27
- RG.SVG.Scatter = function (conf)
28
- {
29
- //
30
- // A setter that the constructor uses (at the end)
31
- // to set all of the properties
32
- //
33
- // @param string name The name of the property to set
34
- // @param string value The value to set the property to
35
- //
36
- this.set = function (name, value)
37
- {
38
- if (arguments.length === 1 && typeof name === 'object') {
39
- for (i in arguments[0]) {
40
- if (typeof i === 'string') {
41
-
42
- var ret = RG.SVG.commonSetter({
43
- object: this,
44
- name: i,
45
- value: arguments[0][i]
46
- });
47
-
48
- name = ret.name;
49
- value = ret.value;
50
-
51
- this.set(name, value);
52
- }
53
- }
54
- } else {
55
-
56
-
57
- var ret = RG.SVG.commonSetter({
58
- object: this,
59
- name: name,
60
- value: value
61
- });
62
-
63
- name = ret.name;
64
- value = ret.value;
65
-
66
- this.properties[name] = value;
67
- }
68
-
69
- return this;
70
- };
71
-
72
-
73
-
74
-
75
-
76
-
77
- this.id = conf.id;
78
- this.uid = RG.SVG.createUID();
79
- this.container = document.getElementById(this.id);
80
- this.svg = RG.SVG.createSVG({container: this.container});
81
- this.isRGraph = true;
82
- this.width = Number(this.svg.getAttribute('width'));
83
- this.height = Number(this.svg.getAttribute('height'));
84
- this.data = conf.data;
85
- this.type = 'scatter';
86
- this.coords = [];
87
- this.colorsParsed = false;
88
- this.originalColors = {};
89
- this.gradientCounter = 1;
90
- this.sequential = 0;
91
-
92
- // Add this object to the ObjectRegistry
93
- RG.SVG.OR.add(this);
94
-
95
- this.container.style.display = 'inline-block';
96
-
97
- this.properties =
98
- {
99
- gutterLeft: 35,
100
- gutterRight: 35,
101
- gutterTop: 35,
102
- gutterBottom: 35,
103
-
104
- backgroundColor: null,
105
- backgroundImage: null,
106
- backgroundImageAspect: 'none',
107
- backgroundImageStretch: true,
108
- backgroundImageOpacity: null,
109
- backgroundImageX: null,
110
- backgroundImageY: null,
111
- backgroundImageW: null,
112
- backgroundImageH: null,
113
- backgroundGrid: true,
114
- backgroundGridColor: '#ddd',
115
- backgroundGridLinewidth: 1,
116
- backgroundGridHlines: true,
117
- backgroundGridHlinesCount: null,
118
- backgroundGridVlines: true,
119
- backgroundGridVlinesCount: null,
120
- backgroundGridBorder: true,
121
-
122
- xmax: 0,
123
- tickmarksStyle: 'cross',
124
- tickmarksSize: 7,
125
- colors: ['black'],
126
-
127
- line: false,
128
- lineColors: 1,
129
- lineLinewidth: 'black',
130
-
131
- yaxis: true,
132
- yaxisTickmarks: true,
133
- yaxisTickmarksLength: 3,
134
- yaxisColor: 'black',
135
- yaxisScale: true,
136
- yaxisLabels: null,
137
- yaxisLabelsOffsetx: 0,
138
- yaxisLabelsOffsety: 0,
139
- yaxisLabelsCount: 5,
140
- yaxisUnitsPre: '',
141
- yaxisUnitsPost: '',
142
- yaxisStrict: false,
143
- yaxisDecimals: 0,
144
- yaxisPoint: '.',
145
- yaxisThousand: ',',
146
- yaxisRound: false,
147
- yaxisMax: null,
148
- yaxisMin: 0,
149
- yaxisFormatter: null,
150
-
151
- xaxis: true,
152
- xaxisTickmarks: true,
153
- xaxisTickmarksLength: 5,
154
- xaxisLabels: null,
155
- xaxisLabelsPosition: 'section',
156
- xaxisLabelsPositionEdgeTickmarksCount: null,
157
- xaxisColor: 'black',
158
- xaxisLabelsOffsetx: 0,
159
- xaxisLabelsOffsety: 0,
160
- xaxisMin: 0,
161
- xaxisMax: null,
162
-
163
- textColor: 'black',
164
- textFont: 'sans-serif',
165
- textSize: 12,
166
- textBold: false,
167
- textItalic: false,
168
-
169
- tooltipsOverride: null,
170
- tooltipsEffect: 'fade',
171
- tooltipsCssClass: 'RGraph_tooltip',
172
- tooltipsEvent: 'mousemove',
173
-
174
- highlightStroke: 'rgba(0,0,0,0)',
175
- highlightFill: 'rgba(255,255,255,0.7)',
176
- highlightLinewidth: 1,
177
-
178
- title: '',
179
- titleSize: 16,
180
- titleX: null,
181
- titleY: null,
182
- titleHalign: 'center',
183
- titleValign: null,
184
- titleColor: 'black',
185
- titleFont: null,
186
- titleBold: false,
187
- titleItalic: false,
188
-
189
- titleSubtitle: '',
190
- titleSubtitleSize: 10,
191
- titleSubtitleX: null,
192
- titleSubtitleY: null,
193
- titleSubtitleHalign: 'center',
194
- titleSubtitleValign: null,
195
- titleSubtitleColor: '#aaa',
196
- titleSubtitleFont: null,
197
- titleSubtitleBold: false,
198
- titleSubtitleItalic: false,
199
-
200
- key: null,
201
- keyColors: null,
202
- keyOffsetx: 0,
203
- keyOffsety: 0,
204
- keyTextOffsetx: 0,
205
- keyTextOffsety: -1,
206
- keyTextSize: null,
207
- keyTextBold: null,
208
- keyTextItalic: null,
209
-
210
- attribution: true,
211
- attributionX: null,
212
- attributionY: null,
213
- attributionHref: null,// Default is set in RGraph.svg.common.core.js
214
- attributionHalign: 'right',
215
- attributionValign: 'bottom',
216
- attributionSize: 7,
217
- attributionColor: 'gray',
218
- attributionFont: 'sans-serif',
219
- attributionItalic: false,
220
- attributionBold: false
221
- };
222
-
223
-
224
-
225
-
226
-
227
- //
228
- // Set the options that the user has provided
229
- //
230
- for (i in conf.options) {
231
- if (typeof i === 'string') {
232
- this.set(i, conf.options[i]);
233
- }
234
- }
235
-
236
-
237
-
238
-
239
-
240
- // Handles the data that was supplied to the object. If only one dataset
241
- // was given, convert it into into a multiple dataset style array
242
- if (this.data[0] && !RG.SVG.isArray(this.data[0])) {
243
- this.data = [];
244
- this.data[0] = conf.data;
245
- }
246
-
247
-
248
-
249
-
250
-
251
- /**
252
- * "Decorate" the object with the generic effects if the effects library has been included
253
- */
254
- if (RG.SVG.FX && typeof RG.SVG.FX.decorate === 'function') {
255
- RG.SVG.FX.decorate(this);
256
- }
257
-
258
-
259
-
260
-
261
- var prop = this.properties;
262
-
263
-
264
- //
265
- // Convert string X values to timestamps
266
- //
267
- if (typeof prop.xaxisMin === 'string') {
268
- prop.xaxisMin = RG.SVG.parseDate(prop.xaxisMin);
269
- }
270
-
271
- if (typeof prop.xaxisMax === 'string') {
272
- prop.xaxisMax = RG.SVG.parseDate(prop.xaxisMax);
273
- }
274
-
275
- for (var i=0; i<this.data.length; ++i) {
276
- for (var j=0; j<this.data[i].length; ++j) {
277
- if (typeof this.data[i][j].x === 'string') {
278
- this.data[i][j].x = RG.SVG.parseDate(this.data[i][j].x);
279
- }
280
- }
281
- }
282
-
283
-
284
-
285
-
286
-
287
-
288
-
289
-
290
- //
291
- // The draw method draws the Bar chart
292
- //
293
- this.draw = function ()
294
- {
295
- // Fire the beforedraw event
296
- RG.SVG.fireCustomEvent(this, 'onbeforedraw');
297
-
298
-
299
-
300
-
301
- // Create the defs tag if necessary
302
- RG.SVG.createDefs(this);
303
-
304
-
305
-
306
-
307
-
308
- this.graphWidth = this.width - prop.gutterLeft - prop.gutterRight;
309
- this.graphHeight = this.height - prop.gutterTop - prop.gutterBottom;
310
-
311
-
312
-
313
-
314
- // Parse the colors for gradients
315
- RG.SVG.resetColorsToOriginalValues({object:this});
316
- this.parseColors();
317
-
318
-
319
-
320
-
321
- // Work out the maximum value
322
- for (var ds=0,max=0; ds<this.data.length; ++ds) { // Datasets
323
- for (var dp=0; dp<this.data[ds].length; ++dp) { // Datapoints
324
- max = ma.max(max, this.data[ds][dp].y);
325
- }
326
- }
327
-
328
-
329
-
330
-
331
-
332
-
333
- // A custom, user-specified maximum value
334
- if (typeof prop.yaxisMax === 'number') {
335
- max = prop.yaxisMax;
336
- }
337
-
338
- // Set the ymin to zero if it's set mirror
339
- if (prop.yaxisMin === 'mirror' || prop.yaxisMin === 'middle' || prop.yaxisMin === 'center') {
340
- var mirrorScale = true;
341
- prop.yaxisMin = 0;
342
- }
343
-
344
-
345
- //
346
- // Generate an appropiate scale
347
- //
348
- this.scale = RG.SVG.getScale({
349
- object: this,
350
- numlabels: prop.yaxisLabelsCount,
351
- unitsPre: prop.yaxisUnitsPre,
352
- unitsPost: prop.yaxisUnitsPost,
353
- max: max,
354
- min: prop.yaxisMin,
355
- point: prop.yaxisPoint,
356
- round: prop.yaxisRound,
357
- thousand: prop.yaxisThousand,
358
- decimals: prop.yaxisDecimals,
359
- strict: typeof prop.yaxisMax === 'number',
360
- formatter: prop.yaxisFormatter
361
- });
362
-
363
-
364
-
365
- //
366
- // Get the scale a second time if the ymin should be mirored
367
- //
368
- // Set the ymin to zero if it's set mirror
369
- if (mirrorScale) {
370
- this.scale = RG.SVG.getScale({
371
- object: this,
372
- numlabels: prop.yaxisLabelsCount,
373
- unitsPre: prop.yaxisUnitsPre,
374
- unitsPost: prop.yaxisUnitsPost,
375
- max: this.scale.max,
376
- min: this.scale.max * -1,
377
- point: prop.yaxisPoint,
378
- round: false,
379
- thousand: prop.yaxisThousand,
380
- decimals: prop.yaxisDecimals,
381
- strict: typeof prop.yaxisMax === 'number',
382
- formatter: prop.yaxisFormatter
383
- });
384
- }
385
-
386
- // Now the scale has been generated adopt its max value
387
- this.max = this.scale.max;
388
- this.min = this.scale.min;
389
- prop.yaxisMax = this.scale.max;
390
- prop.yaxisMin = this.scale.min;
391
-
392
-
393
-
394
-
395
- // Draw the background first
396
- RG.SVG.drawBackground(this);
397
-
398
-
399
-
400
-
401
-
402
-
403
-
404
- // Draw the axes under the points
405
- RG.SVG.drawXAxis(this);
406
- RG.SVG.drawYAxis(this);
407
-
408
-
409
-
410
-
411
-
412
-
413
- // Create a group for all of the datasets
414
- var dataset_group = RGraph.SVG.create({
415
- svg: this.svg,
416
- type: 'g',
417
- parent: this.svg.all,
418
- attr: {
419
- className: 'scatter_datasets_' + this.uid
420
- }
421
- });
422
-
423
- // Draw the points for all of the datasets
424
- for (var i=0; i<this.data.length; ++i) {
425
-
426
- this.drawPoints({
427
- index: i,
428
- data: this.data[i],
429
- group: dataset_group
430
- });
431
-
432
- if (prop.line == true || (typeof prop.line === 'object' && prop.line[i] == true)) {
433
- this.drawLine({
434
- index: i,
435
- coords: this.coords[i]
436
- });
437
- }
438
- }
439
-
440
-
441
-
442
- // Draw the key
443
- if (typeof prop.key !== null && RG.SVG.drawKey) {
444
- RG.SVG.drawKey(this);
445
- } else if (!RGraph.SVG.isNull(prop.key)) {
446
- alert('The drawKey() function does not exist - have you forgotten to include the key library?');
447
- }
448
-
449
-
450
-
451
-
452
- // Add the attribution link. If you're adding this elsewhere on your page/site
453
- // and you don't want it displayed then there are options available to not
454
- // show it.
455
- RG.SVG.attribution(this);
456
-
457
-
458
-
459
-
460
- // Add the event listener that clears the highlight rect if
461
- // there is any. Must be MOUSEDOWN (ie before the click event)
462
- //var obj = this;
463
- //doc.body.addEventListener('mousedown', function (e)
464
- //{
465
- //RG.SVG.removeHighlight(obj);
466
-
467
- //}, false);
468
-
469
-
470
-
471
- // Fire the draw event
472
- RG.SVG.fireCustomEvent(this, 'ondraw');
473
-
474
-
475
-
476
-
477
- return this;
478
- };
479
-
480
-
481
-
482
-
483
-
484
-
485
-
486
-
487
- //
488
- // Draws the Points
489
- //
490
- // @param opt object Options to the function which can consist of:
491
- // o index: The numerical index of the DATASET
492
- // o dataset: The dataset.
493
- //
494
- this.drawPoints = function (opt)
495
- {
496
- var index = opt.index,
497
- data = opt.data,
498
- group = opt.group;
499
-
500
- // Initialise the array for coordinates
501
- this.coords[index] = [];
502
-
503
- //
504
- // Create the <g> tag that the datapoints are added to
505
- //
506
- var group = RG.SVG.create({
507
- svg: this.svg,
508
- type: 'g',
509
- parent: group,
510
- attr: {
511
- className: 'scatter_dataset_' + index + '_' + this.uid
512
- }
513
- });
514
-
515
- // Loop through the data
516
- for (var i=0; i<data.length; ++i) {
517
-
518
- var point = data[i];
519
-
520
- if (typeof point.x === 'number'&& typeof point.y === 'number') {
521
- var ret = this.drawSinglePoint({
522
- dataset: data,
523
- datasetIdx: index,
524
- point: point,
525
- index: i,
526
- group: group, // The SVG <g> tag the the points are added to
527
- sequential: this.sequential++
528
- });
529
-
530
- this.coords[index][i] = [ret.x, ret.y];
531
- }
532
-
533
-
534
-
535
-
536
-
537
-
538
-
539
-
540
-
541
-
542
-
543
-
544
-
545
- //
546
- // Add tooltip highlight to the point
547
- //
548
- if ( (typeof data[i].tooltip === 'string' && data[i].tooltip) || (typeof data[i].tooltip === 'number') ) {
549
-
550
- // Convert the tooltip to a string
551
- data[i].tooltip = String(data[i].tooltip);
552
-
553
- // Make the tooltipsEvent default to click
554
- if (prop.tooltipsEvent !== 'mousemove') {
555
- prop.tooltipsEvent = 'click';
556
- }
557
-
558
- if (!group_tooltip_hotspots) {
559
- var group_tooltip_hotspots = RG.SVG.create({
560
- svg: this.svg,
561
- parent: this.svg.all,
562
- type: 'g',
563
- attr: {
564
- className: 'rgraph-scatter-tooltip-hotspots'
565
- }
566
- });
567
- }
568
-
569
- var rect = RG.SVG.create({
570
- svg: this.svg,
571
- parent: this.svg.all,
572
- type: 'rect',
573
- parent: group_tooltip_hotspots,
574
- attr: {
575
- x: ret.x - (ret.size / 2),
576
- y: ret.y - (ret.size / 2),
577
- width: ret.size,
578
- height: ret.size,
579
- fill: 'transparent',
580
- stroke: 'transparent',
581
- 'stroke-width': 0
582
- },
583
- style: {
584
- cursor: 'pointer'
585
- }
586
- });
587
-
588
- // Add the hotspot to the original tickmark
589
- ret.mark.hotspot = rect;
590
-
591
- (function (dataset, index, seq, obj)
592
- {
593
- rect.addEventListener(prop.tooltipsEvent, function (e)
594
- {
595
- var tooltip = RG.SVG.REG.get('tooltip');
596
-
597
- if (tooltip && tooltip.__dataset__ === dataset && tooltip.__index__ === index) {
598
- return;
599
- }
600
-
601
- obj.removeHighlight();
602
-
603
- // Show the tooltip
604
- RG.SVG.tooltip({
605
- object: obj,
606
- dataset: dataset,
607
- index: index,
608
- sequentialIndex: seq,
609
- text: obj.data[dataset][index].tooltip,
610
- event: e
611
- });
612
-
613
-
614
- // Highlight the shape that has been clicked on
615
- if (RG.SVG.REG.get('tooltip')) {
616
- obj.highlight(this);
617
- }
618
-
619
- }, false);
620
-
621
- // Install the event listener that changes the
622
- // cursor if necessary
623
- if (prop.tooltipsEvent === 'click') {
624
- rect.addEventListener('mousemove', function (e)
625
- {
626
- e.target.style.cursor = 'pointer';
627
- }, false);
628
- }
629
-
630
- }(index, i, this.sequential - 1, this));
631
- }
632
- }
633
- };
634
-
635
-
636
-
637
-
638
-
639
-
640
-
641
-
642
- //
643
- // Draws a single point on the chart
644
- //
645
- this.drawSinglePoint = function (opt)
646
- {
647
- var dataset = opt.dataset,
648
- datasetIdx = opt.datasetIdx,
649
- seq = opt.sequential,
650
- point = opt.point,
651
- index = opt.index,
652
- valueX = opt.point.x,
653
- valueY = opt.point.y,
654
- conf = opt.point || {},
655
- group = opt.group,
656
- coordX = opt.coordx = this.getXCoord(valueX),
657
- coordY = opt.coordy = this.getYCoord(valueY);
658
-
659
-
660
-
661
-
662
-
663
-
664
-
665
-
666
-
667
-
668
-
669
- // Allow shape to be synonym for type
670
- if (typeof conf.type === 'undefined' && typeof conf.shape !== 'undefined') {
671
- conf.type = conf.shape;
672
- }
673
-
674
-
675
-
676
-
677
-
678
-
679
- // set the type to the default if its not set
680
- if (typeof conf.type === 'string') {
681
- // nada
682
- } else if (typeof prop.tickmarksStyle === 'string') {
683
- conf.type = prop.tickmarksStyle;
684
- } else if (typeof prop.tickmarksStyle === 'object' && typeof prop.tickmarksStyle[datasetIdx] === 'string') {
685
- conf.type = prop.tickmarksStyle[datasetIdx];
686
- }
687
-
688
-
689
-
690
-
691
-
692
-
693
-
694
-
695
-
696
-
697
-
698
-
699
- // set the size to the default if its not set
700
- if (typeof conf.size !== 'number' && typeof prop.tickmarksSize === 'number') {
701
- conf.size = prop.tickmarksSize;
702
- } else if (typeof conf.size !== 'number' && typeof prop.tickmarksSize === 'object' && typeof prop.tickmarksSize[datasetIdx] === 'number') {
703
- conf.size = prop.tickmarksSize[datasetIdx];
704
- }
705
-
706
-
707
-
708
-
709
-
710
-
711
-
712
- // Set the color to the default if its not set and then blacck if thats not set either
713
- if (typeof conf.color === 'string') {
714
- // nada
715
- } else if (typeof prop.colors[datasetIdx] === 'string') {
716
- conf.color = prop.colors[datasetIdx];
717
- } else {
718
- conf.color = 'black';
719
- }
720
-
721
-
722
-
723
-
724
-
725
-
726
-
727
- // Set the opacity of this point
728
- if (typeof conf.opacity === 'undefined') {
729
- conf.opacity = 1;
730
- } else if (typeof conf.opacity === 'number') {
731
- // nada
732
- }
733
-
734
-
735
-
736
-
737
-
738
-
739
-
740
-
741
-
742
-
743
-
744
-
745
-
746
-
747
-
748
-
749
-
750
-
751
-
752
- // Bubble charts are drawn by their own function
753
- if (prop.bubble) {
754
- return this.drawBubble(opt, conf);
755
- }
756
-
757
-
758
-
759
-
760
-
761
-
762
-
763
-
764
-
765
-
766
-
767
-
768
-
769
-
770
-
771
-
772
-
773
-
774
-
775
-
776
-
777
- // Handle the various shapes for tickmarks here
778
- switch (conf.type) {
779
- case 'image:' + conf.type.substr(6):
780
-
781
- var src = conf.type.substr(6);
782
-
783
- var img = new Image();
784
- img.src = src;
785
-
786
- var mark = RG.SVG.create({
787
- svg: this.svg,
788
- type: 'image',
789
- parent: group,
790
- attr: {
791
- preserveAspectRatio: 'xMidYMid meet',
792
- 'xlink:href': src
793
- }
794
- });
795
-
796
- // Once the image has loaded the x/y/width/height can be set
797
- // (both the image and it's hotspot)
798
- img.onload = function ()
799
- {
800
- var x = coordX - (img.width / 2),
801
- y = coordY - (img.height / 2),
802
- w = img.width,
803
- h = img.height;
804
-
805
- mark.setAttribute('x', x);
806
- mark.setAttribute('y', y);
807
- mark.setAttribute('width', w);
808
- mark.setAttribute('height', h);
809
-
810
- if (mark && mark.hotspot) {
811
- mark.hotspot.setAttribute('x', x);
812
- mark.hotspot.setAttribute('y', y);
813
- mark.hotspot.setAttribute('width', w);
814
- mark.hotspot.setAttribute('height', h);
815
- }
816
- };
817
-
818
- break;
819
-
820
- case 'triangle':
821
- var mark = RG.SVG.create({
822
- svg: this.svg,
823
- type: 'path',
824
- parent: group,
825
- attr: {
826
- d: 'M {1} {2} L {3} {4} L {5} {6}'.format(
827
- coordX - (conf.size / 2),
828
- coordY + (conf.size / 2),
829
- coordX,
830
- coordY - (conf.size / 2),
831
- coordX + (conf.size / 2),
832
- coordY + (conf.size / 2)
833
- ),
834
- fill: conf.color,
835
- 'fill-opacity': conf.opacity
836
- }
837
- });
838
- break;
839
-
840
- case 'plus':
841
- var mark = RG.SVG.create({
842
- svg: this.svg,
843
- type: 'path',
844
- parent: group,
845
- attr: {
846
- d: 'M {1} {2} L {3} {4} M {5} {6} L {7} {8}'.format(
847
- coordX - (conf.size / 2),
848
- coordY,
849
- coordX + (conf.size / 2),
850
- coordY,
851
- coordX,
852
- coordY - (conf.size / 2),
853
- coordX,
854
- coordY + (conf.size / 2)
855
- ),
856
- stroke: conf.color,
857
- 'stroke-opacity': conf.opacity
858
- }
859
- });
860
- break;
861
-
862
- case 'square':
863
- case 'rect':
864
- var mark = RG.SVG.create({
865
- svg: this.svg,
866
- type: 'rect',
867
- parent: group,
868
- attr: {
869
- x: coordX - (conf.size / 2),
870
- y: coordY - (conf.size / 2),
871
- width: conf.size,
872
- height: conf.size,
873
- fill: conf.color,
874
- 'fill-opacity': conf.opacity
875
- }
876
- });
877
- break;
878
-
879
-
880
-
881
- case 'dot':
882
- case 'circle':
883
- var mark = RG.SVG.create({
884
- svg: this.svg,
885
- type: 'circle',
886
- parent: group,
887
- attr: {
888
- cx: coordX,
889
- cy: coordY,
890
- r: conf.size / 2,
891
- fill: conf.color,
892
- 'fill-opacity': conf.opacity
893
- }
894
- });
895
- break;
896
-
897
-
898
-
899
- case 'cross':
900
- default:
901
- var mark = RG.SVG.create({
902
- svg: this.svg,
903
- type: 'path',
904
- parent: group,
905
- attr: {
906
- d: 'M {1} {2} L {3} {4} M {5} {6} L {7} {8}'.format(
907
- coordX - (conf.size / 2), coordY - (conf.size / 2),
908
- coordX + (conf.size / 2), coordY + (conf.size / 2),
909
- coordX - (conf.size / 2), coordY + (conf.size / 2),
910
- coordX + (conf.size / 2), coordY - (conf.size / 2)
911
- ),
912
- stroke: conf.color,
913
- 'stroke-opacity': conf.opacity
914
- }
915
- });
916
- break;
917
- }
918
-
919
- // Add some data attributes that save various values
920
- mark.setAttribute('data-index', index);
921
- mark.setAttribute('data-dataset', datasetIdx);
922
- mark.setAttribute('data-original-opacity', conf.opacity);
923
- mark.setAttribute('data-original-color', conf.color);
924
- mark.setAttribute('data-original-coordx', coordX);
925
- mark.setAttribute('data-original-coordy', coordY);
926
- mark.setAttribute('data-size', conf.size);
927
- mark.setAttribute('data-sequential', seq);
928
- mark.setAttribute('data-type', conf.type);
929
-
930
- return {
931
- x: coordX,
932
- y: coordY,
933
- size: conf.type.substr(0,6) === 'image:' ? img.width : conf.size,
934
- mark: mark,
935
- type: conf.type
936
- };
937
- };
938
-
939
-
940
-
941
-
942
-
943
-
944
-
945
- // Draw a bubble on a bubble chart
946
- this.drawBubble = function (opt, conf)
947
- {
948
- var size = (conf.z / prop.bubbleMaxValue) * prop.bubbleMaxRadius;
949
-
950
- var color = RG.SVG.parseColorRadial({
951
- object: this,
952
- color: prop.bubbleColorsSolid ? conf.color : 'Gradient(white:' + conf.color + ')',
953
- cx: opt.coordx + (size / 4),
954
- cy: opt.coordy - (size / 4),
955
- fx: opt.coordx + (size / 4),
956
- fy: opt.coordy - (size / 4),
957
- r: size * 1.5
958
- });
959
-
960
- var circle = RG.SVG.create({
961
- svg: this.svg,
962
- type: 'circle',
963
- attr: {
964
- cx: opt.coordx,
965
- cy: opt.coordy,
966
- r: size,
967
- fill: color,
968
- 'fill-opacity': conf.opacity
969
- }
970
- });
971
-
972
- // Add some data attributes that save various values
973
- circle.setAttribute('data-index', opt.index);
974
- circle.setAttribute('data-dataset', opt.datasetIdx);
975
- circle.setAttribute('data-original-opacity', conf.opacity);
976
- circle.setAttribute('data-original-color', conf.color);
977
- circle.setAttribute('data-original-coordx', opt.coordx);
978
- circle.setAttribute('data-original-coordy', opt.coordy);
979
- circle.setAttribute('data-size', size);
980
- circle.setAttribute('data-sequential', opt.sequential);
981
- circle.setAttribute('data-type', 'bubble');
982
-
983
- return {
984
- x: opt.coordx,
985
- y: opt.coordy,
986
- z: opt.coordz
987
- };
988
- };
989
-
990
-
991
-
992
-
993
-
994
-
995
-
996
-
997
- //
998
- // This functions draws a line if required
999
- //
1000
- this.drawLine = function (opt)
1001
- {
1002
- var linewidth = 1,
1003
- color = 'black';
1004
-
1005
-
1006
-
1007
- // Calculate the linewidth
1008
- if (typeof prop.lineLinewidth === 'object' && typeof prop.lineLinewidth[opt.index] === 'number') {
1009
- linewidth = prop.lineLinewidth[opt.index];
1010
- } else if (typeof prop.lineLinewidth === 'number') {
1011
- linewidth = prop.lineLinewidth;
1012
- } else {
1013
- linewidth = 1;
1014
- }
1015
-
1016
-
1017
-
1018
-
1019
-
1020
-
1021
- // Determine the color
1022
- if (typeof prop.lineColors === 'object' && prop.lineColors[opt.index]) {
1023
- color = prop.lineColors[opt.index];
1024
- } else if (prop.colors[opt.index] === 'string') {
1025
- color = prop.colors[opt.index];
1026
- } else {
1027
- color = 'black';
1028
- }
1029
-
1030
-
1031
-
1032
-
1033
-
1034
- for (var i=0,path=''; i<this.coords[opt.index].length; ++i) {
1035
- path += '{1} {2} {3} '.format(
1036
- i === 0 ? 'M' : 'L',
1037
- this.coords[opt.index][i][0],
1038
- this.coords[opt.index][i][1]
1039
- );
1040
- }
1041
-
1042
- RG.SVG.create({
1043
- svg: this.svg,
1044
- type: 'path',
1045
- parent: this.svg.all,
1046
- attr: {
1047
- d: path,
1048
- fill: 'transparent',
1049
- stroke: color,
1050
- 'stroke-width': linewidth,
1051
- 'stroke-linecap': 'round',
1052
- 'stroke-linejoin': 'round'
1053
- }
1054
- });
1055
- };
1056
-
1057
-
1058
-
1059
-
1060
-
1061
-
1062
-
1063
-
1064
- /**
1065
- * This function can be used to retrieve the relevant X coordinate for a
1066
- * particular value.
1067
- *
1068
- * @param int value The value to get the X coordinate for
1069
- */
1070
- this.getXCoord = function (value)
1071
- {
1072
- var x;
1073
-
1074
- if (value > prop.xaxisMax) {
1075
- return null;
1076
- }
1077
-
1078
- if (value < prop.xaxisMin) {
1079
- return null;
1080
- }
1081
-
1082
- x = ((value - prop.xaxisMin) / (prop.xaxisMax - prop.xaxisMin));
1083
- x *= (this.width - prop.gutterLeft - prop.gutterRight);
1084
-
1085
- x = prop.gutterLeft + x;
1086
-
1087
- return x;
1088
- };
1089
-
1090
-
1091
-
1092
-
1093
-
1094
-
1095
-
1096
-
1097
- /**
1098
- * This function can be used to retrieve the relevant Y coordinate for a
1099
- * particular value.
1100
- *
1101
- * @param int value The value to get the Y coordinate for
1102
- */
1103
- this.getYCoord = function (value)
1104
- {
1105
- var prop = this.properties;
1106
-
1107
- if (value > this.scale.max) {
1108
- return null;
1109
- }
1110
-
1111
- var y, xaxispos = prop.xaxispos;
1112
-
1113
- if (value < this.scale.min) {
1114
- return null;
1115
- }
1116
-
1117
- y = ((value - this.scale.min) / (this.scale.max - this.scale.min));
1118
- y *= (this.height - prop.gutterTop - prop.gutterBottom);
1119
-
1120
- y = this.height - prop.gutterBottom - y;
1121
-
1122
- return y;
1123
- };
1124
-
1125
-
1126
-
1127
-
1128
-
1129
-
1130
-
1131
-
1132
- /**
1133
- * This function can be used to highlight a bar on the chart
1134
- *
1135
- * @param object rect The rectangle to highlight
1136
- */
1137
- this.highlight = function (rect)
1138
- {
1139
- rect.setAttribute('fill', prop.highlightFill);
1140
-
1141
- // Store the highlight rect in the registry so
1142
- // it can be reset later
1143
- RG.SVG.REG.set('highlight', rect);
1144
- };
1145
-
1146
-
1147
-
1148
-
1149
-
1150
-
1151
-
1152
-
1153
- /**
1154
- * This allows for easy specification of gradients
1155
- */
1156
- this.parseColors = function ()
1157
- {
1158
-
1159
- // TODO Loop thru the data parsing the color for gradients too
1160
-
1161
- // Save the original colors so that they can be restored when
1162
- // the canvas is cleared
1163
- if (!Object.keys(this.originalColors).length) {
1164
- this.originalColors = {
1165
- colors: RG.SVG.arrayClone(prop.colors),
1166
- backgroundGridColor: RG.SVG.arrayClone(prop.backgroundGridColor),
1167
- highlightFill: RG.SVG.arrayClone(prop.highlightFill),
1168
- backgroundColor: RG.SVG.arrayClone(prop.backgroundColor)
1169
- }
1170
- }
1171
-
1172
-
1173
- // colors
1174
- var colors = prop.colors;
1175
-
1176
- // IMPORTANT: Bubble chart gradients are parse in the drawBubble()
1177
- // function below
1178
- if (colors && !prop.bubble) {
1179
- for (var i=0; i<colors.length; ++i) {
1180
- colors[i] = RG.SVG.parseColorLinear({
1181
- object: this,
1182
- color: colors[i]
1183
- });
1184
- }
1185
- }
1186
-
1187
- prop.backgroundGridColor = RG.SVG.parseColorLinear({object: this, color: prop.backgroundGridColor});
1188
- prop.highlightFill = RG.SVG.parseColorLinear({object: this, color: prop.highlightFill});
1189
- prop.backgroundColor = RG.SVG.parseColorLinear({object: this, color: prop.backgroundColor});
1190
- };
1191
-
1192
-
1193
-
1194
-
1195
-
1196
-
1197
-
1198
-
1199
- /**
1200
- * Using a function to add events makes it easier to facilitate method
1201
- * chaining
1202
- *
1203
- * @param string type The type of even to add
1204
- * @param function func
1205
- */
1206
- this.on = function (type, func)
1207
- {
1208
- if (type.substr(0,2) !== 'on') {
1209
- type = 'on' + type;
1210
- }
1211
-
1212
- RG.SVG.addCustomEventListener(this, type, func);
1213
-
1214
- return this;
1215
- };
1216
-
1217
-
1218
-
1219
-
1220
-
1221
-
1222
-
1223
-
1224
- //
1225
- // Used in chaining. Runs a function there and then - not waiting for
1226
- // the events to fire (eg the onbeforedraw event)
1227
- //
1228
- // @param function func The function to execute
1229
- //
1230
- this.exec = function (func)
1231
- {
1232
- func(this);
1233
-
1234
- return this;
1235
- };
1236
-
1237
-
1238
-
1239
-
1240
-
1241
-
1242
-
1243
-
1244
- //
1245
- // Remove highlight from the chart (tooltips)
1246
- //
1247
- this.removeHighlight = function ()
1248
- {
1249
- var highlight = RG.SVG.REG.get('highlight');
1250
-
1251
- if (highlight) {
1252
- highlight.setAttribute('fill', 'transparent');
1253
- RG.SVG.REG.set('highlight', null);
1254
- }
1255
- };
1256
-
1257
- };
1258
-
1259
- return this;
1260
-
1261
- // End module pattern
1262
- })(window, document);
2
+ RGraph=window.RGraph||{isRGraph:true};RGraph.SVG=RGraph.SVG||{};(function(win,doc,undefined)
3
+ {var RG=RGraph,ua=navigator.userAgent,ma=Math,win=window,doc=document;RG.SVG.Scatter=function(conf)
4
+ {this.set=function(name,value)
5
+ {if(arguments.length===1&&typeof name==='object'){for(i in arguments[0]){if(typeof i==='string'){var ret=RG.SVG.commonSetter({object:this,name:i,value:arguments[0][i]});name=ret.name;value=ret.value;this.set(name,value);}}}else{var ret=RG.SVG.commonSetter({object:this,name:name,value:value});name=ret.name;value=ret.value;this.properties[name]=value;if(name==='colors'){this.originalColors=RG.SVG.arrayClone(value);this.colorsParsed=false;}}
6
+ return this;};this.id=conf.id;this.uid=RG.SVG.createUID();this.container=document.getElementById(this.id);this.layers={};this.svg=RG.SVG.createSVG({object:this,container:this.container});this.isRGraph=true;this.width=Number(this.svg.getAttribute('width'));this.height=Number(this.svg.getAttribute('height'));this.data=conf.data;this.type='scatter';this.coords=[];this.colorsParsed=false;this.originalColors={};this.gradientCounter=1;this.sequential=0;RG.SVG.OR.add(this);this.container.style.display='inline-block';this.properties={gutterLeft:35,gutterRight:35,gutterTop:35,gutterBottom:35,backgroundColor:null,backgroundImage:null,backgroundImageAspect:'none',backgroundImageStretch:true,backgroundImageOpacity:null,backgroundImageX:null,backgroundImageY:null,backgroundImageW:null,backgroundImageH:null,backgroundGrid:true,backgroundGridColor:'#ddd',backgroundGridLinewidth:1,backgroundGridHlines:true,backgroundGridHlinesCount:null,backgroundGridVlines:true,backgroundGridVlinesCount:null,backgroundGridBorder:true,backgroundGridDashed:false,backgroundGridDotted:false,backgroundGridDashArray:null,xmax:0,tickmarksStyle:'cross',tickmarksSize:7,colors:['black'],line:false,lineColors:1,lineLinewidth:'black',yaxis:true,yaxisTickmarks:true,yaxisTickmarksLength:3,yaxisColor:'black',yaxisScale:true,yaxisLabels:null,yaxisLabelsOffsetx:0,yaxisLabelsOffsety:0,yaxisLabelsCount:5,yaxisUnitsPre:'',yaxisUnitsPost:'',yaxisStrict:false,yaxisDecimals:0,yaxisPoint:'.',yaxisThousand:',',yaxisRound:false,yaxisMax:null,yaxisMin:0,yaxisFormatter:null,xaxis:true,xaxisTickmarks:true,xaxisTickmarksLength:5,xaxisLabels:null,xaxisLabelsPosition:'section',xaxisLabelsPositionEdgeTickmarksCount:null,xaxisColor:'black',xaxisLabelsOffsetx:0,xaxisLabelsOffsety:0,xaxisMin:0,xaxisMax:null,textColor:'black',textFont:'sans-serif',textSize:12,textBold:false,textItalic:false,labelsAboveFont:null,labelsAboveSize:null,labelsAboveBold:null,labelsAboveItalic:null,labelsAboveColor:null,labelsAboveBackground:'rgba(255,255,255,0.7)',labelsAboveBackgroundPadding:2,labelsAboveXUnitsPre:null,labelsAboveXUnitsPost:null,labelsAboveXPoint:null,labelsAboveXThousand:null,labelsAboveXFormatter:null,labelsAboveXDecimals:null,labelsAboveXDecimalsTrim:null,labelsAboveYUnitsPre:null,labelsAboveYUnitsPost:null,labelsAboveYPoint:null,labelsAboveYThousand:null,labelsAboveYFormatter:null,labelsAboveYDecimals:null,labelsAboveOffsetx:0,labelsAboveOffsety:-10,labelsAboveHalign:'center',labelsAboveValign:'bottom',labelsAboveSeperator:',',tooltipsOverride:null,tooltipsEffect:'fade',tooltipsCssClass:'RGraph_tooltip',tooltipsEvent:'mousemove',highlightStroke:'rgba(0,0,0,0)',highlightFill:'rgba(255,255,255,0.7)',highlightLinewidth:1,title:'',titleSize:16,titleX:null,titleY:null,titleHalign:'center',titleValign:null,titleColor:'black',titleFont:null,titleBold:false,titleItalic:false,titleSubtitle:'',titleSubtitleSize:10,titleSubtitleX:null,titleSubtitleY:null,titleSubtitleHalign:'center',titleSubtitleValign:null,titleSubtitleColor:'#aaa',titleSubtitleFont:null,titleSubtitleBold:false,titleSubtitleItalic:false,key:null,keyColors:null,keyOffsetx:0,keyOffsety:0,keyTextOffsetx:0,keyTextOffsety:-1,keyTextSize:null,keyTextBold:null,keyTextItalic:null};RG.SVG.getGlobals(this);for(i in conf.options){if(typeof i==='string'){this.set(i,conf.options[i]);}}
7
+ if(this.data[0]&&!RG.SVG.isArray(this.data[0])){this.data=[];this.data[0]=conf.data;}
8
+ if(RG.SVG.FX&&typeof RG.SVG.FX.decorate==='function'){RG.SVG.FX.decorate(this);}
9
+ var prop=this.properties;if(typeof prop.xaxisMin==='string'){prop.xaxisMin=RG.SVG.parseDate(prop.xaxisMin);}
10
+ if(typeof prop.xaxisMax==='string'){prop.xaxisMax=RG.SVG.parseDate(prop.xaxisMax);}
11
+ 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].x==='string'){this.data[i][j].x=RG.SVG.parseDate(this.data[i][j].x);}}}
12
+ this.draw=function()
13
+ {RG.SVG.fireCustomEvent(this,'onbeforedraw');RG.SVG.createDefs(this);this.graphWidth=this.width-prop.gutterLeft-prop.gutterRight;this.graphHeight=this.height-prop.gutterTop-prop.gutterBottom;RG.SVG.resetColorsToOriginalValues({object:this});this.parseColors();for(var ds=0,max=0;ds<this.data.length;++ds){for(var dp=0;dp<this.data[ds].length;++dp){max=ma.max(max,this.data[ds][dp].y);}}
14
+ if(typeof prop.yaxisMax==='number'){max=prop.yaxisMax;}
15
+ if(prop.yaxisMin==='mirror'||prop.yaxisMin==='middle'||prop.yaxisMin==='center'){var mirrorScale=true;prop.yaxisMin=0;}
16
+ this.scale=RG.SVG.getScale({object:this,numlabels:prop.yaxisLabelsCount,unitsPre:prop.yaxisUnitsPre,unitsPost:prop.yaxisUnitsPost,max:max,min:prop.yaxisMin,point:prop.yaxisPoint,round:prop.yaxisRound,thousand:prop.yaxisThousand,decimals:prop.yaxisDecimals,strict:typeof prop.yaxisMax==='number',formatter:prop.yaxisFormatter});if(mirrorScale){this.scale=RG.SVG.getScale({object:this,numlabels:prop.yaxisLabelsCount,unitsPre:prop.yaxisUnitsPre,unitsPost:prop.yaxisUnitsPost,max:this.scale.max,min:this.scale.max* -1,point:prop.yaxisPoint,round:false,thousand:prop.yaxisThousand,decimals:prop.yaxisDecimals,strict:typeof prop.yaxisMax==='number',formatter:prop.yaxisFormatter});}
17
+ this.max=this.scale.max;this.min=this.scale.min;prop.yaxisMax=this.scale.max;prop.yaxisMin=this.scale.min;RG.SVG.drawBackground(this);RG.SVG.drawXAxis(this);RG.SVG.drawYAxis(this);var dataset_group=RGraph.SVG.create({svg:this.svg,type:'g',parent:this.svg.all,attr:{className:'scatter_datasets_'+this.uid}});for(var i=0;i<this.data.length;++i){this.drawPoints({index:i,data:this.data[i],group:dataset_group});if(prop.line==true||(typeof prop.line==='object'&&prop.line[i]==true)){this.drawLine({index:i,coords:this.coords[i]});}}
18
+ if(typeof prop.key!==null&&RG.SVG.drawKey){RG.SVG.drawKey(this);}else if(!RGraph.SVG.isNull(prop.key)){alert('The drawKey() function does not exist - have you forgotten to include the key library?');}
19
+ RG.SVG.fireCustomEvent(this,'ondraw');return this;};this.drawPoints=function(opt)
20
+ {var index=opt.index,data=opt.data,group=opt.group;this.coords[index]=[];var group=RG.SVG.create({svg:this.svg,type:'g',parent:group,attr:{className:'scatter_dataset_'+index+'_'+this.uid}});for(var i=0;i<data.length;++i){var point=data[i];if(typeof point.x==='number'&&typeof point.y==='number'){var ret=this.drawSinglePoint({dataset:data,datasetIdx:index,point:point,index:i,group:group,sequential:this.sequential++});this.coords[index][i]=[ret.x,ret.y];}
21
+ if((typeof data[i].tooltip==='string'&&data[i].tooltip)||(typeof data[i].tooltip==='number')){data[i].tooltip=String(data[i].tooltip);if(prop.tooltipsEvent!=='mousemove'){prop.tooltipsEvent='click';}
22
+ if(!group_tooltip_hotspots){var group_tooltip_hotspots=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'g',attr:{className:'rgraph-scatter-tooltip-hotspots'}});}
23
+ var rect=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'rect',parent:group_tooltip_hotspots,attr:{x:ret.x-(ret.size/2),y:ret.y-(ret.size/2),width:ret.size,height:ret.size,fill:'transparent',stroke:'transparent','stroke-width':0},style:{cursor:'pointer'}});ret.mark.hotspot=rect;(function(dataset,index,seq,obj)
24
+ {rect.addEventListener(prop.tooltipsEvent,function(e)
25
+ {var tooltip=RG.SVG.REG.get('tooltip');if(tooltip&&tooltip.__dataset__===dataset&&tooltip.__index__===index){return;}
26
+ obj.removeHighlight();RG.SVG.tooltip({object:obj,dataset:dataset,index:index,sequentialIndex:seq,text:obj.data[dataset][index].tooltip,event:e});if(RG.SVG.REG.get('tooltip')){obj.highlight(this);}},false);if(prop.tooltipsEvent==='click'){rect.addEventListener('mousemove',function(e)
27
+ {e.target.style.cursor='pointer';},false);}}(index,i,this.sequential-1,this));}}};this.drawSinglePoint=function(opt)
28
+ {var dataset=opt.dataset,datasetIdx=opt.datasetIdx,seq=opt.sequential,point=opt.point,index=opt.index,valueX=opt.point.x,valueY=opt.point.y,conf=opt.point||{},group=opt.group,coordX=opt.coordx=this.getXCoord(valueX),coordY=opt.coordy=this.getYCoord(valueY);if(conf.labelsAbove){var above=true;}else if(conf.labelAbove){var above=true;}else if(conf.above){var above=true;}
29
+ if(typeof conf.type==='undefined'&&typeof conf.shape!=='undefined'){conf.type=conf.shape;}
30
+ if(typeof conf.type==='string'){}else if(typeof prop.tickmarksStyle==='string'){conf.type=prop.tickmarksStyle;}else if(typeof prop.tickmarksStyle==='object'&&typeof prop.tickmarksStyle[datasetIdx]==='string'){conf.type=prop.tickmarksStyle[datasetIdx];}
31
+ if(typeof conf.size!=='number'&&typeof prop.tickmarksSize==='number'){conf.size=prop.tickmarksSize;}else if(typeof conf.size!=='number'&&typeof prop.tickmarksSize==='object'&&typeof prop.tickmarksSize[datasetIdx]==='number'){conf.size=prop.tickmarksSize[datasetIdx];}
32
+ if(typeof conf.color==='string'){}else if(typeof prop.colors[datasetIdx]==='string'){conf.color=prop.colors[datasetIdx];}else{conf.color='black';}
33
+ if(typeof conf.opacity==='undefined'){conf.opacity=1;}else if(typeof conf.opacity==='number'){}
34
+ if(prop.bubble){return this.drawBubble(opt,conf);}
35
+ switch(conf.type){case'image:'+conf.type.substr(6):var src=conf.type.substr(6);var img=new Image();img.src=src;var mark=RG.SVG.create({svg:this.svg,type:'image',parent:group,attr:{preserveAspectRatio:'xMidYMid meet','xlink:href':src}});img.onload=function()
36
+ {var x=coordX-(img.width/2),y=coordY-(img.height/2),w=img.width,h=img.height;mark.setAttribute('x',x);mark.setAttribute('y',y);mark.setAttribute('width',w);mark.setAttribute('height',h);if(mark&&mark.hotspot){mark.hotspot.setAttribute('x',x);mark.hotspot.setAttribute('y',y);mark.hotspot.setAttribute('width',w);mark.hotspot.setAttribute('height',h);}};break;case'triangle':var mark=RG.SVG.create({svg:this.svg,type:'path',parent:group,attr:{d:'M {1} {2} L {3} {4} L {5} {6}'.format(coordX-(conf.size/2),coordY+(conf.size/2),coordX,coordY-(conf.size/2),coordX+(conf.size/2),coordY+(conf.size/2)),fill:conf.color,'fill-opacity':conf.opacity}});break;case'plus':var mark=RG.SVG.create({svg:this.svg,type:'path',parent:group,attr:{d:'M {1} {2} L {3} {4} M {5} {6} L {7} {8}'.format(coordX-(conf.size/2),coordY,coordX+(conf.size/2),coordY,coordX,coordY-(conf.size/2),coordX,coordY+(conf.size/2)),stroke:conf.color,'stroke-opacity':conf.opacity}});break;case'square':case'rect':var mark=RG.SVG.create({svg:this.svg,type:'rect',parent:group,attr:{x:coordX-(conf.size/2),y:coordY-(conf.size/2),width:conf.size,height:conf.size,fill:conf.color,'fill-opacity':conf.opacity}});break;case'dot':case'circle':var mark=RG.SVG.create({svg:this.svg,type:'circle',parent:group,attr:{cx:coordX,cy:coordY,r:conf.size/2,fill:conf.color,'fill-opacity':conf.opacity}});break;case'cross':default:var mark=RG.SVG.create({svg:this.svg,type:'path',parent:group,attr:{d:'M {1} {2} L {3} {4} M {5} {6} L {7} {8}'.format(coordX-(conf.size/2),coordY-(conf.size/2),coordX+(conf.size/2),coordY+(conf.size/2),coordX-(conf.size/2),coordY+(conf.size/2),coordX+(conf.size/2),coordY-(conf.size/2)),stroke:conf.color,'stroke-opacity':conf.opacity}});break;}
37
+ if(typeof conf.above==='string'||(typeof conf.above!=='string'&&conf.above)){this.drawLabelsAbove({point:conf,coordX:coordX,coordY:coordY});}
38
+ mark.setAttribute('data-index',index);mark.setAttribute('data-dataset',datasetIdx);mark.setAttribute('data-original-opacity',conf.opacity);mark.setAttribute('data-original-color',conf.color);mark.setAttribute('data-original-coordx',coordX);mark.setAttribute('data-original-coordy',coordY);mark.setAttribute('data-size',conf.size);mark.setAttribute('data-sequential',seq);mark.setAttribute('data-type',conf.type);return{x:coordX,y:coordY,size:conf.type.substr(0,6)==='image:'?img.width:conf.size,mark:mark,type:conf.type};};this.drawBubble=function(opt,conf)
39
+ {var size=(conf.z/prop.bubbleMaxValue)*prop.bubbleMaxRadius;var color=RG.SVG.parseColorRadial({object:this,color:prop.bubbleColorsSolid?conf.color:'Gradient(white:'+conf.color+')',cx:opt.coordx+(size/4),cy:opt.coordy-(size/4),fx:opt.coordx+(size/4),fy:opt.coordy-(size/4),r:size*1.5});var circle=RG.SVG.create({svg:this.svg,type:'circle',attr:{cx:opt.coordx,cy:opt.coordy,r:size,fill:color,'fill-opacity':conf.opacity}});circle.setAttribute('data-index',opt.index);circle.setAttribute('data-dataset',opt.datasetIdx);circle.setAttribute('data-original-opacity',conf.opacity);circle.setAttribute('data-original-color',conf.color);circle.setAttribute('data-original-coordx',opt.coordx);circle.setAttribute('data-original-coordy',opt.coordy);circle.setAttribute('data-size',size);circle.setAttribute('data-sequential',opt.sequential);circle.setAttribute('data-type','bubble');return{x:opt.coordx,y:opt.coordy,z:opt.coordz};};this.drawLine=function(opt)
40
+ {var linewidth=1,color='black';if(typeof prop.lineLinewidth==='object'&&typeof prop.lineLinewidth[opt.index]==='number'){linewidth=prop.lineLinewidth[opt.index];}else if(typeof prop.lineLinewidth==='number'){linewidth=prop.lineLinewidth;}else{linewidth=1;}
41
+ if(typeof prop.lineColors==='object'&&prop.lineColors[opt.index]){color=prop.lineColors[opt.index];}else if(prop.colors[opt.index]==='string'){color=prop.colors[opt.index];}else{color='black';}
42
+ for(var i=0,path='';i<this.coords[opt.index].length;++i){path+='{1} {2} {3} '.format(i===0?'M':'L',this.coords[opt.index][i][0],this.coords[opt.index][i][1]);}
43
+ RG.SVG.create({svg:this.svg,type:'path',parent:this.svg.all,attr:{d:path,fill:'transparent',stroke:color,'stroke-width':linewidth,'stroke-linecap':'round','stroke-linejoin':'round'}});};this.getXCoord=function(value)
44
+ {var x;if(value>prop.xaxisMax){return null;}
45
+ if(value<prop.xaxisMin){return null;}
46
+ x=((value-prop.xaxisMin)/(prop.xaxisMax-prop.xaxisMin));x*=(this.width-prop.gutterLeft-prop.gutterRight);x=prop.gutterLeft+x;return x;};this.getYCoord=function(value)
47
+ {var prop=this.properties;if(value>this.scale.max){return null;}
48
+ var y,xaxispos=prop.xaxispos;if(value<this.scale.min){return null;}
49
+ y=((value-this.scale.min)/(this.scale.max-this.scale.min));y*=(this.height-prop.gutterTop-prop.gutterBottom);y=this.height-prop.gutterBottom-y;return y;};this.highlight=function(rect)
50
+ {rect.setAttribute('fill',prop.highlightFill);RG.SVG.REG.set('highlight',rect);};this.drawLabelsAbove=function(opt)
51
+ {var conf=opt.point,coordX=opt.coordX,coordY=opt.coordY;if(typeof conf.above==='string'){var str=conf.above;}else{conf.x=RG.SVG.numberFormat({object:this,num:conf.x.toFixed(prop.labelsAboveXDecimals),prepend:typeof prop.labelsAboveXUnitsPre==='string'?prop.labelsAboveXUnitsPre:null,append:typeof prop.labelsAboveXUnitsPost==='string'?prop.labelsAboveXUnitsPost:null,point:typeof prop.labelsAboveXPoint==='string'?prop.labelsAboveXPoint:null,thousand:typeof prop.labelsAboveXThousand==='string'?prop.labelsAboveXThousand:null,formatter:typeof prop.labelsAboveXFormatter==='function'?prop.labelsAboveXFormatter:null,decimals_trim:prop.labelsAboveXDecimalsTrim});conf.y=RG.SVG.numberFormat({object:this,num:conf.y.toFixed(prop.labelsAboveYDecimals),prepend:typeof prop.labelsAboveYUnitsPre==='string'?prop.labelsAboveYUnitsPre:null,append:typeof prop.labelsAboveYUnitsPost==='string'?prop.labelsAboveYUnitsPost:null,point:typeof prop.labelsAboveYPoint==='string'?prop.labelsAboveYPoint:null,thousand:typeof prop.labelsAboveYThousand==='string'?prop.labelsAboveYThousand:null,formatter:typeof prop.labelsAboveYFormatter==='function'?prop.labelsAboveYFormatter:null,decimals_trim:prop.labelsAboveYDecimalsTrim});var str='{1}{2}{3}'.format(conf.x,prop.labelsAboveSeperator,conf.y);}
52
+ RG.SVG.text({object:this,parent:this.svg.all,text:str,x:parseFloat(coordX)+prop.labelsAboveOffsetx,y:parseFloat(coordY)+prop.labelsAboveOffsety,halign:prop.labelsAboveHalign,valign:prop.labelsAboveValign,font:prop.labelsAboveFont||prop.textFont,size:prop.labelsAboveSize||prop.textSize,bold:prop.labelsAboveBold||prop.textBold,italic:prop.labelsAboveItalic||prop.textItalic,color:prop.labelsAboveColor||prop.textColor,background:prop.labelsAboveBackground||null,padding:prop.labelsAboveBackgroundPadding||0});};this.parseColors=function()
53
+ {if(!Object.keys(this.originalColors).length){this.originalColors={colors:RG.SVG.arrayClone(prop.colors),backgroundGridColor:RG.SVG.arrayClone(prop.backgroundGridColor),highlightFill:RG.SVG.arrayClone(prop.highlightFill),backgroundColor:RG.SVG.arrayClone(prop.backgroundColor)}}
54
+ var colors=prop.colors;if(colors&&!prop.bubble){for(var i=0;i<colors.length;++i){colors[i]=RG.SVG.parseColorLinear({object:this,color:colors[i]});}}
55
+ prop.backgroundGridColor=RG.SVG.parseColorLinear({object:this,color:prop.backgroundGridColor});prop.highlightFill=RG.SVG.parseColorLinear({object:this,color:prop.highlightFill});prop.backgroundColor=RG.SVG.parseColorLinear({object:this,color:prop.backgroundColor});};this.on=function(type,func)
56
+ {if(type.substr(0,2)!=='on'){type='on'+type;}
57
+ RG.SVG.addCustomEventListener(this,type,func);return this;};this.exec=function(func)
58
+ {func(this);return this;};this.removeHighlight=function()
59
+ {var highlight=RG.SVG.REG.get('highlight');if(highlight){highlight.setAttribute('fill','transparent');RG.SVG.REG.set('highlight',null);}};};return this;})(window,document);