rgraph-rails 4.62 → 4.64

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