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,1818 +1,67 @@
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.Rose = 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
-
55
- } else {
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
-
78
-
79
- this.id = conf.id;
80
- this.uid = RG.SVG.createUID();
81
- this.container = document.getElementById(this.id);
82
- this.svg = RG.SVG.createSVG({container: this.container});
83
- this.isRGraph = true;
84
- this.width = Number(this.svg.getAttribute('width'));
85
- this.height = Number(this.svg.getAttribute('height'));
86
- this.data = RG.SVG.arrayClone(conf.data);
87
- this.originalData = RG.SVG.arrayClone(conf.data);
88
- this.type = 'rose';
89
- this.angles = [];
90
- this.angles2 = [];
91
- this.colorsParsed = false;
92
- this.originalColors = {};
93
- this.gradientCounter = 1;
94
- this.nodes = [];
95
- this.shadowNodes = [];
96
- this.max = 0;
97
- this.redraw = false;
98
- this.highlight_node = null;
99
-
100
- // Add this object to the ObjectRegistry
101
- RG.SVG.OR.add(this);
102
-
103
- // Set the DIV container to be inline-block
104
- this.container.style.display = 'inline-block';
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
- this.properties =
113
- {
114
- centerx: null,
115
- centery: null,
116
- radius: null,
117
-
118
- gutterLeft: 35,
119
- gutterRight: 35,
120
- gutterTop: 35,
121
- gutterBottom: 35,
122
-
123
- backgroundGrid: true,
124
- backgroundGridColor: '#ddd',
125
- backgroundGridRadialsCount: null,
126
- backgroundGridRadialsAngleOffset: 0,
127
- backgroundGridConcentricsCount: 5,
128
- backgroundGridLinewidth: 1,
129
-
130
- strokestyle: 'white',
131
- colors: [
132
- 'red', 'black', 'orange', 'green', '#6ff', '#ccc',
133
- 'pink', 'orange', 'cyan', 'maroon', 'olive', 'teal'
134
- ],
135
- colorsOpacity: 1,
136
-
137
- textColor: 'black',
138
- textFont: 'sans-serif',
139
- textSize: 12,
140
- textBold: false,
141
- textItalic: false,
142
-
143
- labels: [],
144
- labelsFont: null,
145
- labelsSize: null,
146
- labelsColor: null,
147
- labelsBold: null,
148
- labelsItalic: null,
149
- labelsRadialMargin: 10,
150
- labelsAngleOffset: 0,
151
-
152
- scaleVisible: true,
153
- scaleUnitsPre: '',
154
- scaleUnitsPost: '',
155
- scaleMax: null,
156
- scaleMin: 0,
157
- scalePoint: '.',
158
- scaleThousand: ',',
159
- scaleRound: false,
160
- scaleDecimals: 0,
161
- scaleFormatter: null,
162
- scaleBold: null,
163
- scaleItalic: null,
164
- scaleColor: null,
165
- scaleSize: null,
166
- scaleFont: null,
167
- scaleLabelsCount: 5,
168
-
169
- linewidth: 1,
170
-
171
- tooltips: null,
172
- tooltipsOverride: null,
173
- tooltipsEffect: 'fade',
174
- tooltipsCssClass: 'RGraph_tooltip',
175
- tooltipsEvent: 'click',
176
-
177
- highlightStroke: 'rgba(0,0,0,0)',
178
- highlightFill: 'rgba(255,255,255,0.7)',
179
- highlightLinewidth: 1,
180
-
181
- title: '',
182
- titleSize: 16,
183
- titleX: null,
184
- titleY: null,
185
- titleHalign: 'center',
186
- titleValign: null,
187
- titleColor: 'black',
188
- titleFont: null,
189
- titleBold: false,
190
- titleItalic: false,
191
-
192
- titleSubtitle: '',
193
- titleSubtitleSize: 10,
194
- titleSubtitleX: null,
195
- titleSubtitleY: null,
196
- titleSubtitleHalign: 'center',
197
- titleSubtitleValign: null,
198
- titleSubtitleColor: '#aaa',
199
- titleSubtitleFont: null,
200
- titleSubtitleBold: false,
201
- titleSubtitleItalic: false,
202
-
203
- shadow: false,
204
- shadowOffsetx: 2,
205
- shadowOffsety: 2,
206
- shadowBlur: 2,
207
- shadowOpacity: 0.25,
208
-
209
- margin: 0,
210
- exploded: 0,
211
-
212
-
213
- key: null,
214
- keyColors: null,
215
- keyOffsetx: 0,
216
- keyOffsety: 0,
217
- keyTextOffsetx: 0,
218
- keyTextOffsety: -1,
219
- keyTextSize: null,
220
- keyTextBold: null,
221
- keyTextItalic: null,
222
-
223
- attribution: true,
224
- attributionX: null,
225
- attributionY: null,
226
- attributionHref: null,// Default is set in RGraph.svg.common.core.js
227
- attributionHalign: 'right',
228
- attributionValign: 'bottom',
229
- attributionSize: 7,
230
- attributionColor: 'gray',
231
- attributionFont: 'sans-serif',
232
- attributionItalic: false,
233
- attributionBold: false,
234
-
235
- segmentsAngleOffset: 0,
236
- variant: 'normal'
237
- };
238
-
239
-
240
-
241
-
242
-
243
-
244
- /**
245
- * "Decorate" the object with the generic effects if the effects library has been included
246
- */
247
- if (RG.SVG.FX && typeof RG.SVG.FX.decorate === 'function') {
248
- RG.SVG.FX.decorate(this);
249
- }
250
-
251
-
252
-
253
-
254
- var prop = this.properties;
255
-
256
-
257
-
258
-
259
-
260
-
261
-
262
-
263
- //
264
- // The draw method draws the Bar chart
265
- //
266
- this.draw = function ()
267
- {
268
- // Fire the beforedraw event
269
- RG.SVG.fireCustomEvent(this, 'onbeforedraw');
270
-
271
-
272
-
273
- // Reset the data back to the original values
274
- this.data = RG.SVG.arrayClone(this.originalData);
275
-
276
-
277
-
278
- // Reset the angles array to stop it growing
279
- this.angles = [];
280
-
281
-
282
- // Create the arrays in the angles2 array based on
283
- // the data that we've been passed
284
- for (var i=0; i<this.data.length; ++i) {
285
- this.angles2[i] = [];
286
- }
287
-
288
-
289
-
290
-
291
-
292
- // Create the defs tag if necessary
293
- RG.SVG.createDefs(this);
294
-
295
-
296
-
297
-
298
- this.graphWidth = this.width - prop.gutterLeft - prop.gutterRight;
299
- this.graphHeight = this.height - prop.gutterTop - prop.gutterBottom;
300
-
301
-
302
-
303
- // Work out the center point
304
- this.centerx = (this.graphWidth / 2) + prop.gutterLeft;
305
- this.centery = (this.graphHeight / 2) + prop.gutterTop;
306
- this.radius = ma.min(this.graphWidth, this.graphHeight) / 2;
307
-
308
-
309
-
310
- // Allow the user to override the calculated centerx/y/radius
311
- this.centerx = typeof prop.centerx === 'number' ? prop.centerx : this.centerx;
312
- this.centery = typeof prop.centery === 'number' ? prop.centery : this.centery;
313
- this.radius = typeof prop.radius === 'number' ? prop.radius : this.radius;
314
-
315
- //
316
- // Allow the centerx/centery/radius to be a plus/minus
317
- //
318
- if (typeof prop.radius === 'string' && prop.radius.match(/^\+|-\d+$/) ) this.radius += parseFloat(prop.radius);
319
- if (typeof prop.centerx === 'string' && prop.centerx.match(/^\+|-\d+$/) ) this.centery += parseFloat(prop.centerx);
320
- if (typeof prop.centery === 'string' && prop.centery.match(/^\+|-\d+$/) ) this.centerx += parseFloat(prop.centery);
321
-
322
-
323
-
324
-
325
-
326
- //
327
- // Convert the nargin from strings to a number
328
- //
329
- if (typeof prop.margin === 'string' && prop.margin.match(/([0-9.]+)deg/)) {
330
- prop.margin = RegExp.$1 / (180 / ma.PI);
331
- }
332
-
333
-
334
-
335
-
336
- /**
337
- * Add the data to the .originalData array and work out the max value
338
- *
339
- * 2/5/14 Now also use this loop to ensure that the data pieces
340
- * are numbers
341
- *
342
- * **Is this necessary **
343
- */
344
- //if (RG.SVG.isArray(this.data) && (typeof this.data[0] === 'number' || typeof this.data[0] === 'string')) {
345
- // this.data = [this.data];
346
- //}
347
-
348
- // Convert strings to numbers
349
- for (var i=0; i<this.data.length; ++i) {
350
- if (typeof this.data[i] === 'object') {
351
- for (var j=0; j<this.data[i].length; ++j) {
352
- if (typeof this.data[i][j] === 'string') {
353
- this.data[i][j] = RG.SVG.stringsToNumbers(this.data[i][j]);
354
- }
355
- }
356
- } else if (typeof this.data[i] === 'string') {
357
- this.data[i] = RG.SVG.stringsToNumbers(this.data[i]);
358
- }
359
- }
360
-
361
-
362
-
363
-
364
-
365
-
366
-
367
-
368
-
369
- // Get the max value. This sets the maximum value on the
370
- // this.max variable
371
- this.getMaxValue();
372
-
373
-
374
-
375
-
376
-
377
-
378
-
379
- // Parse the colors for gradients
380
- RG.SVG.resetColorsToOriginalValues({object:this});
381
- this.parseColors();
382
-
383
- //
384
- // Get the scale
385
- //
386
-
387
- this.scale = RG.SVG.getScale({
388
- object: this,
389
- numlabels: typeof prop.scaleLabelsCount === 'number' ? prop.scaleLabelsCount : prop.backgroundGridConcentricCount,
390
- unitsPre: prop.scaleUnitsPre,
391
- unitsPost: prop.scaleUnitsPost,
392
- max: typeof prop.scaleMax === 'number' ? prop.scaleMax : this.max,
393
- min: prop.scaleMin,
394
- point: prop.scalePoint,
395
- round: prop.scaleRound,
396
- thousand: prop.scaleThousand,
397
- decimals: prop.scaleDecimals,
398
- strict: typeof prop.scaleMax === 'number',
399
- formatter: prop.scaleFormatter
400
- });
401
-
402
- this.max = this.scale.max;
403
-
404
-
405
-
406
- // Draw the background 'grid'
407
- this.drawBackground();
408
-
409
-
410
-
411
- // Draw the chart
412
- this.drawRose();
413
-
414
-
415
-
416
-
417
-
418
-
419
- // Draw the labels
420
- this.drawLabels();
421
-
422
-
423
-
424
- // Draw the title and subtitle
425
- RG.SVG.drawTitle(this);
426
-
427
-
428
-
429
-
430
-
431
-
432
- // Draw the key
433
- if (typeof prop.key !== null && RG.SVG.drawKey) {
434
- RG.SVG.drawKey(this);
435
- } else if (!RGraph.SVG.isNull(prop.key)) {
436
- alert('The drawKey() function does not exist - have you forgotten to include the key library?');
437
- }
438
-
439
-
440
-
441
-
442
-
443
- // Add the attribution link. If you're adding this elsewhere on your page/site
444
- // and you don't want it displayed then there are options available to not
445
- // show it.
446
- RG.SVG.attribution(this);
447
-
448
- // Create the shadow definition if needed
449
- if (prop.shadow) {
450
- RG.SVG.setShadow({
451
- object: this,
452
- offsetx: prop.shadowOffsetx,
453
- offsety: prop.shadowOffsety,
454
- blur: prop.shadowBlur,
455
- opacity: prop.shadowOpacity,
456
- id: 'dropShadow'
457
- });
458
- }
459
-
460
-
461
-
462
- // Add the event listener that clears the highlight if
463
- // there is any. Must be MOUSEDOWN (ie before the click event)
464
- var obj = this;
465
- doc.body.addEventListener('mousedown', function (e)
466
- {
467
- obj.hideHighlight(obj);
468
- }, false);
469
-
470
-
471
-
472
- // Fire the draw event
473
- RG.SVG.fireCustomEvent(this, 'ondraw');
474
-
475
-
476
-
477
- return this;
478
- };
479
-
480
-
481
-
482
-
483
-
484
-
485
-
486
-
487
- //
488
- // Draw the background grid
489
- //
490
- this.drawBackground = function ()
491
- {
492
- if (prop.backgroundGrid) {
493
-
494
- // Create the background grid group tag
495
- var grid = RG.SVG.create({
496
- svg: this.svg,
497
- parent: this.svg.all,
498
- type: 'g',
499
- attr: {
500
- className: 'rgraph_radar_grid',
501
- fill: 'rgba(0,0,0,0)',
502
- stroke: prop.backgroundGridColor
503
- }
504
- });
505
-
506
- // Draw the concentric "rings" grid lines that are
507
- // arranged around the centerx/centery along with
508
- // the radials that eminate from the center outwards
509
-
510
- var origin = 0 - (RG.SVG.TRIG.PI / 2),
511
- radials = (typeof prop.backgroundGridRadialsCount === 'number' ? prop.backgroundGridRadialsCount : this.data.length),
512
- concentrics = prop.backgroundGridConcentricsCount,
513
- step = RG.SVG.TRIG.TWOPI / radials;
514
-
515
-
516
-
517
-
518
-
519
- // First draw the radial lines that emanate from the
520
- // center outwards
521
- if (radials > 0) {
522
- // This draws the radials for the non-equi-angular ONLY
523
- if (prop.variant === 'non-equi-angular') {
524
-
525
-
526
-
527
-
528
-
529
-
530
-
531
-
532
-
533
-
534
-
535
-
536
-
537
-
538
- // Number of radials always matches the number of data pieces
539
- var radials = this.data.length;
540
-
541
- // Work out the total of the second part of each data bit
542
- for (var i=0,total=0; i<this.data.length; ++i) {
543
- total += this.data[i][1];
544
- }
545
-
546
- for (var i=0,sum=0; i<this.data.length; ++i) {
547
-
548
- var coords = RG.SVG.TRIG.toCartesian({
549
- cx: this.centerx,
550
- cy: this.centery,
551
- r: this.radius,
552
- angle: origin + ( (sum / total) * RG.SVG.TRIG.TWOPI) + prop.backgroundGridRadialsAngleOffset
553
- });
554
-
555
- var str = 'M {1} {2} L {3} {4}'.format(
556
- this.centerx,
557
- this.centery,
558
- coords.x,
559
- coords.y
560
- );
561
-
562
- RG.SVG.create({
563
- svg: this.svg,
564
- type: 'path',
565
- parent: grid,
566
- attr: {
567
- d: str,
568
- stroke: prop.backgroundGridColor,
569
- 'stroke-width': prop.backgroundGridLinewidth
570
- }
571
- });
572
-
573
- sum += this.data[i][1];
574
- }
575
-
576
-
577
-
578
-
579
-
580
-
581
-
582
-
583
-
584
-
585
-
586
-
587
- // This draws the radials for normal and STACKED Rose charts
588
- } else {
589
- for (var i=0,len=radials; i<len; ++i) {
590
-
591
- var coords = RG.SVG.TRIG.toCartesian({
592
- cx: this.centerx,
593
- cy: this.centery,
594
- r: this.radius,
595
- angle: origin + (i * step) + prop.backgroundGridRadialsAngleOffset
596
- });
597
-
598
- var str = 'M {1} {2} L {3} {4}'.format(
599
- this.centerx,
600
- this.centery,
601
- coords.x,
602
- coords.y
603
- );
604
-
605
- RG.SVG.create({
606
- svg: this.svg,
607
- type: 'path',
608
- parent: grid,
609
- attr: {
610
- d: str,
611
- stroke: prop.backgroundGridColor,
612
- 'stroke-width': prop.backgroundGridLinewidth
613
- }
614
- });
615
- }
616
- }
617
- }
618
-
619
-
620
-
621
-
622
-
623
- // Draw the concentrics
624
- if (concentrics > 0) {
625
-
626
- for (var j=1; j<=concentrics; j++) {
627
-
628
- // Add circle to the scene
629
- RG.SVG.create({
630
- svg: this.svg,
631
- type: 'circle',
632
- parent: grid,
633
- attr: {
634
- cx: this.centerx,
635
- cy: this.centery,
636
- r: this.radius * (j/concentrics),
637
- fill: 'transparent',
638
- stroke: prop.backgroundGridColor,
639
- 'stroke-width': prop.backgroundGridLinewidth
640
- }
641
- });
642
- }
643
- }
644
- }
645
- };
646
-
647
-
648
-
649
-
650
-
651
-
652
-
653
-
654
- //
655
- // Draws the radar
656
- //
657
- this.drawRose = function (opt)
658
- {
659
- // Jump to another function if we're drawing a non-equi-angular chart
660
- if (prop.variant === 'non-equi-angular') {
661
- return this.drawRoseNonEquiAngular(opt);
662
- }
663
-
664
-
665
-
666
-
667
-
668
-
669
- var radians = RG.SVG.TRIG.TWOPI / this.data.length;
670
-
671
- var group = RG.SVG.create({
672
- svg: this.svg,
673
- type:'g',
674
- parent: this.svg.all,
675
- attr: {
676
- id: 'rgraph_rose_segments_' + this.id
677
- }
678
- });
679
-
680
-
681
- // Now loop thru the data
682
- for (var i=0,seq=0; i<this.data.length; ++i,++seq) {
683
-
684
- var radius = (this.data[i] / this.scale.max) * this.radius,
685
- start = (i / this.data.length) * RG.SVG.TRIG.TWOPI,
686
- end = ((i / this.data.length) * RG.SVG.TRIG.TWOPI) + radians;
687
-
688
- // Get the exploded distance
689
- var explosion = this.getExploded({
690
- index: i,
691
- start: start - RG.SVG.TRIG.HALFPI,
692
- end: end - RG.SVG.TRIG.HALFPI
693
- });
694
-
695
-
696
-
697
-
698
-
699
-
700
-
701
-
702
-
703
-
704
-
705
-
706
-
707
-
708
-
709
-
710
-
711
-
712
-
713
- // Is the data piece an array or a number?
714
- if (typeof this.data[i] === 'object' && !RG.SVG.isNull(this.data[i])) {
715
-
716
- // Create a group for the parts of this segment
717
- var segment_group = RG.SVG.create({
718
- svg: this.svg,
719
- type: 'g',
720
- parent: group,
721
- attr: {
722
- id: 'rose_' + this.id + '_segment_group_' + i
723
- }
724
- });
725
-
726
- for (var j=0,sum=0,accRadius=0; j<this.data[i].length; ++j,++seq) {
727
-
728
- sum += this.data[i][j];
729
-
730
- var radius = (sum / this.scale.max) * this.radius;
731
-
732
- // This (I think is the OUTER curve in the segment
733
- var arcPath = RG.SVG.TRIG.getArcPath2({
734
- cx: this.centerx + explosion[0],
735
- cy: this.centery + explosion[1],
736
- r: radius,
737
- start: start + prop.margin + prop.segmentsAngleOffset,
738
- end: end - prop.margin + prop.segmentsAngleOffset,
739
- anticlockwise: false
740
- });
741
-
742
- // The inner most segment
743
- if (j === 0) {
744
- arcPath = '{1} z'.format(
745
- arcPath
746
- );
747
- } else {
748
-
749
- var arcPath2 = RG.SVG.TRIG.getArcPath2({
750
- cx: this.centerx + explosion[0],
751
- cy: this.centery + explosion[1],
752
- r: prevRadius,
753
- start: end - prop.margin + prop.segmentsAngleOffset,
754
- end: start + prop.margin + prop.segmentsAngleOffset,
755
- anticlockwise: true
756
- });
757
- arcPath = '{1} L {2} {3} {4}'.format(
758
- arcPath,
759
- this.centerx + explosion[0],
760
- this.centery + explosion[1],
761
- arcPath2
762
- );
763
- }
764
-
765
- var path = RG.SVG.create({
766
- svg: this.svg,
767
- type: 'path',
768
- parent: segment_group,
769
- attr: {
770
- d: arcPath,
771
- fill: prop.colorsSequential ? prop.colors[seq] : prop.colors[j],
772
- 'fill-opacity': prop.colorsOpacity,
773
- stroke: prop.strokestyle,
774
- 'stroke-width': prop.linewidth,
775
-
776
- 'data-tooltip': (!RG.SVG.isNull(prop.tooltips) && prop.tooltips.length) ? prop.tooltips[seq] : '',
777
- 'data-index': i,
778
- 'data-centerx': this.centerx + explosion[0],
779
- 'data-centery': this.centery + explosion[1],
780
- 'data-group': i,
781
- 'data-subindex': j,
782
- 'data-value': this.data[i][j],
783
- 'data-start-angle': start,
784
- 'data-end-angle': end,
785
- 'data-radius': radius,
786
- 'data-radius-inner': typeof prevRadius === 'number' ? prevRadius : 0,
787
- 'data-sequential-index': seq
788
- }
789
- });
790
-
791
-
792
- // Install the tooltip listener
793
- if (prop.tooltips && prop.tooltips[seq]) {
794
-
795
- // Make the tooltipsEvent default to click
796
- if (prop.tooltipsEvent !== 'mousemove') {
797
- prop.tooltipsEvent = 'click';
798
- }
799
-
800
- (function (index, group, seq, obj)
801
- {
802
- path.addEventListener(prop.tooltipsEvent, function (e)
803
- {
804
- obj.removeHighlight();
805
-
806
- // Show the tooltip
807
- RG.SVG.tooltip({
808
- object: obj,
809
- group: group,
810
- index: index,
811
- sequentialIndex: seq,
812
- text: prop.tooltips[seq],
813
- event: e
814
- });
815
-
816
- // Highlight the rect that has been clicked on
817
- obj.highlight(e.target);
818
-
819
- var highlight = RG.SVG.REG.get('highlight');
820
-
821
- if (prop.tooltipsEvent === 'mousemove') {
822
- highlight.style.cursor = 'pointer';
823
- }
824
-
825
- }, false);
826
-
827
- // Install the event listener that changes the
828
- // cursor if necessary
829
- if (prop.tooltipsEvent === 'click') {
830
- path.addEventListener('mousemove', function (e)
831
- {
832
- e.target.style.cursor = 'pointer';
833
- }, false);
834
- }
835
-
836
- }(j, i, seq, this));
837
- }
838
-
839
- // Add the segment to the angles and angles2 array
840
- this.angles.push({
841
- object: path,
842
- index: seq,
843
- cx: this.centerx + explosion[0],
844
- cy: this.centery + explosion[1],
845
- start: start,
846
- end: end,
847
- radius: radius,
848
- 'radius-inner': prevRadius,
849
- value: this.data[i][j]
850
- });
851
-
852
- this.angles2[i].push({
853
- object: path,
854
- index: seq,
855
- cx: this.centerx + explosion[0],
856
- cy: this.centery + explosion[1],
857
- start: start,
858
- end: end,
859
- radius: radius,
860
- 'radius-inner': prevRadius,
861
- value: this.data[i][j]
862
- });
863
-
864
- var prevRadius = radius;
865
- }
866
-
867
-
868
-
869
-
870
-
871
-
872
-
873
-
874
-
875
-
876
- seq--;
877
-
878
-
879
-
880
-
881
-
882
-
883
-
884
-
885
-
886
-
887
-
888
-
889
-
890
- // A regular number
891
- } else {
892
-
893
- var arcPath = RG.SVG.TRIG.getArcPath2({
894
- cx: this.centerx + explosion[0],
895
- cy: this.centery + explosion[1],
896
- r: radius,
897
- start: start + prop.margin + prop.segmentsAngleOffset,
898
- end: end - prop.margin + prop.segmentsAngleOffset,
899
- anticlockwise: false
900
- });
901
-
902
- var path = RG.SVG.create({
903
- svg: this.svg,
904
- type: 'path',
905
- parent: group,
906
- attr: {
907
- d: '{1} z'.format(
908
- arcPath
909
- ),
910
- fill: prop.colorsSequential ? prop.colors[i] : prop.colors[0],
911
- 'fill-opacity': prop.colorsOpacity,
912
- stroke: prop.strokestyle,
913
- 'stroke-width': prop.linewidth,
914
-
915
- 'data-tooltip': (!RG.SVG.isNull(prop.tooltips) && prop.tooltips.length) ? prop.tooltips[i] : '',
916
- 'data-index': i,
917
- 'data-centerx': this.centerx + explosion[0],
918
- 'data-centery': this.centery + explosion[1],
919
- 'data-value': this.data[i],
920
- 'data-start-angle': start,
921
- 'data-end-angle': end,
922
- 'data-radius': radius,
923
- 'data-sequential': seq
924
- }
925
- });
926
-
927
- // Add the segment to the angles array
928
- this.angles.push({
929
- object: path,
930
- index: i,
931
- cx: this.centerx + explosion[0],
932
- cy: this.centery + explosion[1],
933
- start: start,
934
- end: end,
935
- radius: radius,
936
- value: this.data[i]
937
- });
938
-
939
- this.angles2[i].push({
940
- object: path,
941
- index: seq,
942
- cx: this.centerx + explosion[0],
943
- cy: this.centery + explosion[1],
944
- start: start,
945
- end: end,
946
- radius: radius,
947
- 'radius-inner': prevRadius,
948
- value: this.data[i][j]
949
- });
950
-
951
-
952
-
953
-
954
- if (prop.tooltips && prop.tooltips[i]) {
955
-
956
- // Make the tooltipsEvent default to click
957
- if (prop.tooltipsEvent !== 'mousemove') {
958
- prop.tooltipsEvent = 'click';
959
- }
960
-
961
- (function (index, obj)
962
- {
963
- path.addEventListener(prop.tooltipsEvent, function (e)
964
- {
965
- obj.removeHighlight();
966
-
967
- // Show the tooltip
968
- RG.SVG.tooltip({
969
- object: obj,
970
- index: index,
971
- group: index,
972
- sequentialIndex: index,
973
- text: prop.tooltips[index],
974
- event: e
975
- });
976
-
977
- // Highlight the rect that has been clicked on
978
- obj.highlight(e.target);
979
-
980
- var highlight = RG.SVG.REG.get('highlight');
981
-
982
- if (prop.tooltipsEvent === 'mousemove') {
983
- highlight.style.cursor = 'pointer';
984
- }
985
-
986
- }, false);
987
-
988
- // Install the event listener that changes the
989
- // cursor if necessary
990
- if (prop.tooltipsEvent === 'click') {
991
- path.addEventListener('mousemove', function (e)
992
- {
993
- e.target.style.cursor = 'pointer';
994
- }, false);
995
- }
996
-
997
- }(i, this));
998
- }
999
- }
1000
- }
1001
- };
1002
-
1003
-
1004
-
1005
-
1006
-
1007
-
1008
-
1009
-
1010
- //
1011
- // Draws the radar, but only the non-equi-angular variant
1012
- //
1013
- this.drawRoseNonEquiAngular = function (opt)
1014
- {
1015
- var group = RG.SVG.create({
1016
- svg: this.svg,
1017
- type:'g',
1018
- parent: this.svg.all,
1019
- attr: {
1020
- id: 'rgraph_rose_segments_' + this.id
1021
- }
1022
- });
1023
-
1024
- //Loop through the data summing the second data-pieces
1025
- for (var i=0,total=0; i<this.data.length; ++i) {
1026
- total += parseFloat(this.data[i][1]);
1027
- }
1028
-
1029
-
1030
-
1031
-
1032
-
1033
-
1034
-
1035
-
1036
-
1037
-
1038
-
1039
- // The initial angles
1040
- var start = 0;
1041
-
1042
-
1043
-
1044
-
1045
- // Now loop thru the data
1046
- for (var i=0,seq=0; i<this.data.length; ++i,++seq) {
1047
-
1048
- var radians = (this.data[i][1] / total) * RG.SVG.TRIG.TWOPI,
1049
- end = start + radians;
1050
-
1051
- // Get the exploded distance
1052
- var explosion = this.getExploded({
1053
- index: i,
1054
- start: start - RG.SVG.TRIG.HALFPI,
1055
- end: end - RG.SVG.TRIG.HALFPI
1056
- });
1057
-
1058
-
1059
-
1060
-
1061
-
1062
-
1063
-
1064
-
1065
-
1066
-
1067
-
1068
-
1069
-
1070
-
1071
-
1072
- // A stacked non-equi-angular segment
1073
- if (typeof this.data[i][0] === 'object' && !RG.SVG.isNull(this.data[i][0])) {
1074
-
1075
-
1076
-
1077
- // Loop thru the set of values for this segment
1078
- for (var j=0,sum=0; j<this.data[i][0].length; ++j,++seq) {
1079
-
1080
- sum += this.data[i][0][j];
1081
-
1082
- // First segment in the stack or not?
1083
- if (j === 0) {
1084
-
1085
- var prevRadius = 0,
1086
- radius = (sum / this.scale.max) * this.radius;
1087
-
1088
- var arcPath = RG.SVG.TRIG.getArcPath2({
1089
- cx: this.centerx + explosion[0],
1090
- cy: this.centery + explosion[1],
1091
- r: radius,
1092
- start: start + prop.margin + prop.segmentsAngleOffset,
1093
- end: end - prop.margin + prop.segmentsAngleOffset,
1094
- anticlockwise: false
1095
- });
1096
-
1097
- var arcPath2 = '';
1098
-
1099
- } else {
1100
-
1101
- var prevRadius = radius, // The previous iterations radius
1102
- radius = (sum / this.scale.max) * this.radius;
1103
-
1104
- var arcPath = RG.SVG.TRIG.getArcPath2({
1105
- cx: this.centerx + explosion[0],
1106
- cy: this.centery + explosion[1],
1107
- r: radius,
1108
- start: start + prop.margin + prop.segmentsAngleOffset,
1109
- end: end - prop.margin + prop.segmentsAngleOffset,
1110
- anticlockwise: false
1111
- });
1112
-
1113
- var arcPath2 = RG.SVG.TRIG.getArcPath2({
1114
- cx: this.centerx + explosion[0],
1115
- cy: this.centery + explosion[1],
1116
- r: prevRadius,
1117
- start: end - prop.margin + prop.segmentsAngleOffset,
1118
- end: start + prop.margin + prop.segmentsAngleOffset,
1119
- anticlockwise: true
1120
- });
1121
- }
1122
-
1123
- var path = RG.SVG.create({
1124
- svg: this.svg,
1125
- type: 'path',
1126
- parent: group,
1127
- attr: {
1128
- d: '{1} {2} z'.format(
1129
- arcPath,
1130
- arcPath2
1131
- ),
1132
- fill: prop.colorsSequential ? prop.colors[seq] : prop.colors[j],
1133
- 'fill-opacity': prop.colorsOpacity,
1134
- stroke: prop.strokestyle,
1135
- 'stroke-width': prop.linewidth,
1136
- 'data-tooltip': (!RG.SVG.isNull(prop.tooltips) && prop.tooltips.length) ? prop.tooltips[i] : '',
1137
- 'data-centerx': this.centerx + explosion[0],
1138
- 'data-centery': this.centery + explosion[1],
1139
- 'data-index': '[{1},{2}]'.format(i, j),
1140
- 'data-value': this.data[i][0][j],
1141
- 'data-start-angle': start,
1142
- 'data-end-angle': end,
1143
- 'data-radius': radius,
1144
- 'data-radius-inner': prevRadius,
1145
- 'data-sequential': seq
1146
- }
1147
- });
1148
-
1149
-
1150
-
1151
- // Add the segment to the angles array
1152
- this.angles.push({
1153
- object: path,
1154
- index: i,
1155
- cx: this.centerx + explosion[0],
1156
- cy: this.centery + explosion[1],
1157
- start: start,
1158
- end: end,
1159
- radius: radius,
1160
- 'radius-inner': prevRadius,
1161
- value: this.data[i][0]
1162
- });
1163
-
1164
- this.angles2[i].push({
1165
- object: path,
1166
- index: seq,
1167
- cx: this.centerx + explosion[0],
1168
- cy: this.centery + explosion[1],
1169
- start: start,
1170
- end: end,
1171
- radius: radius,
1172
- 'radius-inner': prevRadius,
1173
- value: this.data[i][j]
1174
- });
1175
-
1176
-
1177
-
1178
-
1179
- // Install tooltips listeners
1180
- if (prop.tooltips && prop.tooltips[seq]) {
1181
-
1182
- // Make the tooltipsEvent default to click
1183
- if (prop.tooltipsEvent !== 'mousemove') {
1184
- prop.tooltipsEvent = 'click';
1185
- }
1186
-
1187
- (function (index,group,seq,obj)
1188
- {
1189
- path.addEventListener(prop.tooltipsEvent, function (e)
1190
- {
1191
- obj.removeHighlight();
1192
-
1193
- // Show the tooltip
1194
- RG.SVG.tooltip({
1195
- object: obj,
1196
- index: index,
1197
- group: group,
1198
- sequentialIndex: seq,
1199
- text: prop.tooltips[seq],
1200
- event: e
1201
- });
1202
-
1203
- // Highlight the rect that has been clicked on
1204
- obj.highlight(e.target);
1205
-
1206
- var highlight = RG.SVG.REG.get('highlight');
1207
-
1208
- if (prop.tooltipsEvent === 'mousemove') {
1209
- highlight.style.cursor = 'pointer';
1210
- }
1211
-
1212
- }, false);
1213
-
1214
- // Install the event listener that changes the
1215
- // cursor if necessary
1216
- if (prop.tooltipsEvent === 'click') {
1217
- path.addEventListener('mousemove', function (e)
1218
- {
1219
- e.target.style.cursor = 'pointer';
1220
- }, false);
1221
- }
1222
-
1223
- }(j, i, seq, this));
1224
- }
1225
- var prevRadius = radius;
1226
- }
1227
- seq--
1228
-
1229
-
1230
-
1231
-
1232
-
1233
-
1234
-
1235
-
1236
-
1237
-
1238
-
1239
-
1240
-
1241
-
1242
-
1243
-
1244
-
1245
-
1246
-
1247
-
1248
- // A regular non-equi-angular segment
1249
- } else {
1250
- var radius = (this.data[i][0] / this.scale.max) * this.radius;
1251
-
1252
- var arcPath = RG.SVG.TRIG.getArcPath2({
1253
- cx: this.centerx + explosion[0],
1254
- cy: this.centery + explosion[1],
1255
- r: radius,
1256
- start: start + prop.margin + prop.segmentsAngleOffset,
1257
- end: end - prop.margin + prop.segmentsAngleOffset,
1258
- anticlockwise: false
1259
- });
1260
-
1261
- var path = RG.SVG.create({
1262
- svg: this.svg,
1263
- type: 'path',
1264
- parent: group,
1265
- attr: {
1266
- d: '{1} z'.format(
1267
- arcPath
1268
- ),
1269
- fill: prop.colorsSequential ? prop.colors[i] : prop.colors[0],
1270
- 'fill-opacity': prop.colorsOpacity,
1271
- stroke: prop.strokestyle,
1272
- 'stroke-width': prop.linewidth,
1273
-
1274
- 'data-tooltip': (!RG.SVG.isNull(prop.tooltips) && prop.tooltips.length) ? prop.tooltips[i] : '',
1275
- 'data-centerx': this.centerx + explosion[0],
1276
- 'data-centery': this.centery + explosion[1],
1277
- 'data-index': i,
1278
- 'data-value': this.data[i],
1279
- 'data-start-angle': start,
1280
- 'data-end-angle': end,
1281
- 'data-radius': radius,
1282
- 'data-sequential': seq
1283
- }
1284
- });
1285
-
1286
- // Add the segment to the angles array
1287
- this.angles.push({
1288
- object: path,
1289
- index: i,
1290
- cx: this.centerx + explosion[0],
1291
- cy: this.centery + explosion[1],
1292
- start: start,
1293
- end: end,
1294
- radius: radius,
1295
- value: this.data[i][0]
1296
- });
1297
-
1298
- this.angles2[i].push({
1299
- object: path,
1300
- index: seq,
1301
- cx: this.centerx + explosion[0],
1302
- cy: this.centery + explosion[1],
1303
- start: start,
1304
- end: end,
1305
- radius: radius,
1306
- 'radius-inner': 0,
1307
- value: this.data[i][j]
1308
- });
1309
-
1310
-
1311
-
1312
-
1313
- if (prop.tooltips && prop.tooltips[i]) {
1314
-
1315
- // Make the tooltipsEvent default to click
1316
- if (prop.tooltipsEvent !== 'mousemove') {
1317
- prop.tooltipsEvent = 'click';
1318
- }
1319
-
1320
- (function (index, group, seq, obj)
1321
- {
1322
- path.addEventListener(prop.tooltipsEvent, function (e)
1323
- {
1324
- obj.removeHighlight();
1325
-
1326
- // Show the tooltip
1327
- RG.SVG.tooltip({
1328
- object: obj,
1329
- index: index,
1330
- group: index,
1331
- sequentialIndex: seq,
1332
- text: prop.tooltips[index],
1333
- event: e
1334
- });
1335
-
1336
- // Highlight the rect that has been clicked on
1337
- obj.highlight(e.target);
1338
-
1339
- var highlight = RG.SVG.REG.get('highlight');
1340
-
1341
- if (prop.tooltipsEvent === 'mousemove') {
1342
- highlight.style.cursor = 'pointer';
1343
- }
1344
-
1345
- }, false);
1346
-
1347
- // Install the event listener that changes the
1348
- // cursor if necessary
1349
- if (prop.tooltipsEvent === 'click') {
1350
- path.addEventListener('mousemove', function (e)
1351
- {
1352
- e.target.style.cursor = 'pointer';
1353
- }, false);
1354
- }
1355
-
1356
- }(i, i, seq, this));
1357
- }
1358
- }
1359
-
1360
-
1361
- // Increment the start angle for the next iteration of the loop
1362
- start += radians;
1363
- }
1364
- };
1365
-
1366
-
1367
-
1368
-
1369
-
1370
-
1371
-
1372
-
1373
- //
1374
- // Redraws the chart if required
1375
- //
1376
- this.redrawRose = function ()
1377
- {
1378
- };
1379
-
1380
-
1381
-
1382
-
1383
-
1384
-
1385
-
1386
-
1387
- //
1388
- // Draw the labels
1389
- //
1390
- this.drawLabels = function ()
1391
- {
1392
- // Draw the scale if required
1393
- if (prop.scaleVisible) {
1394
- for (var i=0; i<this.scale.labels.length; ++i) {
1395
-
1396
- var x = this.centerx;
1397
- var y = this.centery - (this.radius / this.scale.labels.length * (i+1) );
1398
-
1399
-
1400
- RG.SVG.text({
1401
- object: this,
1402
- svg: this.svg,
1403
- parent: this.svg.all,
1404
- text: this.scale.labels[i],
1405
- size: prop.scaleSize || prop.textSize - 2,
1406
- x: x,
1407
- y: y,
1408
- halign: 'center',
1409
- valign: 'center',
1410
- background: 'rgba(255,255,255,0.7)',
1411
- padding:2,
1412
- color: prop.scaleColor || prop.textColor,
1413
- bold: typeof prop.scaleBold === 'boolean' ? prop.scaleBold : prop.textBold,
1414
- italic: typeof prop.scaleItalic === 'boolean' ? prop.scaleItalic : prop.textItalic,
1415
- font: prop.scaleFont || prop.textFont
1416
- });
1417
- }
1418
-
1419
- // Draw the zero label
1420
- var str = RG.SVG.numberFormat({
1421
- object: this,
1422
- num: this.scale.min.toFixed(prop.scaleDecimals),
1423
- prepend: prop.scaleUnitsPre,
1424
- append: prop.scaleUnitsPost,
1425
- point: prop.scalePoint,
1426
- thousand: prop.scaleThousand,
1427
- formatter: prop.scaleFormatter
1428
- });
1429
-
1430
-
1431
- RG.SVG.text({
1432
- object: this,
1433
- svg: this.svg,
1434
- parent: this.svg.all,
1435
- text: str,
1436
- size: prop.scaleSize || prop.textSize - 2,
1437
- x: this.centerx,
1438
- y: this.centery,
1439
- halign: 'center',
1440
- valign: 'center',
1441
- background: 'rgba(255,255,255,0.7)',
1442
- padding:2,
1443
- color: prop.scaleColor || prop.textColor,
1444
- bold: typeof prop.scaleBold === 'boolean' ? prop.scaleBold : prop.textBold,
1445
- italic: typeof prop.scaleItalic === 'boolean' ? prop.scaleItalic : prop.textItalic,
1446
- font: prop.scaleFont || prop.textFont
1447
- });
1448
- }
1449
-
1450
-
1451
-
1452
-
1453
-
1454
-
1455
-
1456
- // Used further down
1457
- var halign;
1458
-
1459
- // Set a default size for the labels
1460
- if (typeof prop.labelsSize !== 'number') {
1461
- prop.labelsSize = prop.textSize + 4;
1462
- }
1463
-
1464
-
1465
-
1466
- // Draw the circular labels if necessary
1467
- for (var i=0; i<prop.labels.length; ++i) {
1468
-
1469
- if (prop.variant === 'non-equi-angular') {
1470
- var angle = ((this.angles2[i][0].end - this.angles2[i][0].start) / 2) + this.angles2[i][0].start - RG.SVG.TRIG.HALFPI;
1471
- } else {
1472
- var angle = (((RG.SVG.TRIG.TWOPI / prop.labels.length)) * i) - RG.SVG.TRIG.HALFPI + prop.labelsAngleOffset + ((this.angles2[i][0].end - this.angles2[i][0].start) / 2);
1473
- }
1474
-
1475
- var endpoint = RG.SVG.TRIG.getRadiusEndPoint({
1476
- r: this.radius + prop.labelsRadialMargin,
1477
- angle: angle
1478
- });
1479
-
1480
- // Accommodate the explosion for the label
1481
- var explosion = this.getExploded({
1482
- index: i,
1483
- start: this.angles2[i][0].start - RG.SVG.TRIG.HALFPI,
1484
- end: this.angles2[i][0].end - RG.SVG.TRIG.HALFPI
1485
- });
1486
-
1487
- endpoint[0] += this.centerx + explosion[0];
1488
- endpoint[1] += this.centery + explosion[1];
1489
-
1490
-
1491
- // Do the alignment based on which quadrant the label is in
1492
- if (ma.round(endpoint[0]) > this.centerx) {
1493
- halign = 'left';
1494
- } else if (ma.round(endpoint[0]) === this.centerx) {
1495
- halign = 'center';
1496
- } else {
1497
- halign = 'right';
1498
- }
1499
-
1500
-
1501
-
1502
-
1503
-
1504
- RG.SVG.text({
1505
- object: this,
1506
- svg: this.svg,
1507
- parent: this.svg.all,
1508
- text: typeof prop.labels[i] === 'string' ? prop.labels[i] : '',
1509
- size: prop.labelsSize,
1510
- x: endpoint[0],
1511
- y: endpoint[1],
1512
- halign: halign,
1513
- valign: 'center',
1514
- background: 'rgba(255,255,255,0.7)',
1515
- padding:2,
1516
- color: prop.labelsColor || prop.textColor,
1517
- bold: typeof prop.labelsBold === 'boolean' ? prop.labelsBold : prop.textBold,
1518
- italic: typeof prop.labelsItalic === 'boolean' ? prop.labelsItalic : prop.textItalic,
1519
- font: prop.labelsFont || prop.textFont
1520
- });
1521
- }
1522
- };
1523
-
1524
-
1525
-
1526
-
1527
-
1528
-
1529
-
1530
-
1531
- /**
1532
- * This function can be used to highlight a segment on the chart
1533
- *
1534
- * @param object circle The circle to highlight
1535
- */
1536
- this.highlight = function (path)
1537
- {
1538
- var path = path.getAttribute('d');
1539
-
1540
- var highlight = RG.SVG.create({
1541
- svg: this.svg,
1542
- parent: this.svg.all,
1543
- type: 'path',
1544
- attr: {
1545
- d: path,
1546
- fill: prop.highlightFill,
1547
- stroke: prop.highlightStroke,
1548
- 'stroke-width': prop.highlightLinewidth
1549
- }
1550
- });
1551
-
1552
-
1553
- if (prop.tooltipsEvent === 'mousemove') {
1554
- highlight.addEventListener('mouseout', function (e)
1555
- {
1556
- highlight.parentNode.removeChild(highlight);
1557
- RG.SVG.hideTooltip();
1558
-
1559
- RG.SVG.REG.set('highlight', null);
1560
- }, false);
1561
- }
1562
-
1563
-
1564
- // Store the highlight rect in the registry so
1565
- // it can be cleared later
1566
- RG.SVG.REG.set('highlight', highlight);
1567
- };
1568
-
1569
-
1570
-
1571
-
1572
-
1573
-
1574
-
1575
-
1576
- /**
1577
- * This allows for easy specification of gradients
1578
- */
1579
- this.parseColors = function ()
1580
- {
1581
- // Save the original colors so that they can be restored when the canvas is reset
1582
- if (!Object.keys(this.originalColors).length) {
1583
- this.originalColors = {
1584
- colors: RG.SVG.arrayClone(prop.colors),
1585
- highlightFill: RG.SVG.arrayClone(prop.highlightFill)
1586
- }
1587
- }
1588
-
1589
-
1590
- // colors
1591
- var colors = prop.colors;
1592
-
1593
- if (colors) {
1594
- for (var i=0; i<colors.length; ++i) {
1595
- colors[i] = RG.SVG.parseColorRadial({
1596
- object: this,
1597
- color: colors[i]
1598
- });
1599
- }
1600
- }
1601
-
1602
- // Highlight fill
1603
- prop.highlightFill = RG.SVG.parseColorRadial({
1604
- object: this,
1605
- color: prop.highlightFill
1606
- });
1607
- };
1608
-
1609
-
1610
-
1611
-
1612
-
1613
-
1614
-
1615
-
1616
- //
1617
- // Get the maximum value
1618
- //
1619
- this.getMaxValue = function ()
1620
- {
1621
- var max = 0;
1622
-
1623
- if (prop.variant === 'non-equi-angular') {
1624
- for (var i=0; i<this.data.length; ++i) {
1625
- if (!RG.SVG.isNull(this.data[i])) {
1626
- if (typeof this.data[i][0] === 'number') {
1627
- max = ma.max(max, this.data[i][0]);
1628
- } else if (typeof this.data[i][0] === 'object'){
1629
- max = ma.max(max, RG.SVG.arraySum(this.data[i][0]));
1630
- }
1631
- }
1632
- }
1633
- } else {
1634
- for (var i=0; i<this.data.length; ++i) {
1635
- if (!RG.SVG.isNull(this.data[i])) {
1636
- if (typeof this.data[i] === 'number') {
1637
- max = ma.max(max, this.data[i]);
1638
- } else if (typeof this.data[i] === 'object') {
1639
- max = ma.max(max, RG.SVG.arraySum(this.data[i]));
1640
- }
1641
- }
1642
- }
1643
- }
1644
-
1645
- this.max = max;
1646
- };
1647
-
1648
-
1649
-
1650
-
1651
-
1652
-
1653
-
1654
-
1655
- //
1656
- // Gets the radius of a value
1657
- //
1658
- //@param number The value to get the radius for
1659
- //
1660
- this.getRadius = function (value)
1661
- {
1662
- return ( (value - prop.scaleMin) / (this.scale.max - prop.scaleMin) ) * this.radius;
1663
- };
1664
-
1665
-
1666
-
1667
-
1668
-
1669
-
1670
-
1671
-
1672
- //
1673
- // A roundRobin effect for the Pie chart
1674
- //
1675
- // @param object Options for the effect
1676
- // @param function An optional callback function to call when
1677
- // the effect is complete
1678
- //
1679
- this.roundRobin = function ()
1680
- {
1681
- };
1682
-
1683
-
1684
-
1685
-
1686
-
1687
-
1688
-
1689
-
1690
- /**
1691
- * Using a function to add events makes it easier to facilitate method
1692
- * chaining
1693
- *
1694
- * @param string type The type of even to add
1695
- * @param function func
1696
- */
1697
- this.on = function (type, func)
1698
- {
1699
- if (type.substr(0,2) !== 'on') {
1700
- type = 'on' + type;
1701
- }
1702
-
1703
- RG.SVG.addCustomEventListener(this, type, func);
1704
-
1705
- return this;
1706
- };
1707
-
1708
-
1709
-
1710
-
1711
-
1712
-
1713
-
1714
-
1715
- //
1716
- // Used in chaining. Runs a function there and then - not waiting for
1717
- // the events to fire (eg the onbeforedraw event)
1718
- //
1719
- // @param function func The function to execute
1720
- //
1721
- this.exec = function (func)
1722
- {
1723
- func(this);
1724
-
1725
- return this;
1726
- };
1727
-
1728
-
1729
-
1730
-
1731
-
1732
-
1733
-
1734
-
1735
- //
1736
- // Removes the tooltip highlight from the chart
1737
- //
1738
- this.removeHighlight =
1739
- this.hideHighlight = function ()
1740
- {
1741
- var highlight = RG.SVG.REG.get('highlight');
1742
-
1743
- if (highlight && this.highlight_node) {
1744
- this.highlight_node.setAttribute('fill','transparent');
1745
- this.highlight_node.setAttribute('stroke','transparent');
1746
-
1747
- RG.SVG.REG.set('highlight', null);
1748
- }
1749
- };
1750
-
1751
-
1752
-
1753
-
1754
-
1755
-
1756
-
1757
-
1758
- //
1759
- // Returns the exploded X/Y for a given explosion
1760
- //
1761
- //TODO Needs updating to current coding style, including converting
1762
- // arguments to an object
1763
- //
1764
- this.getExploded = function (opt)
1765
- {
1766
- var index = opt.index,
1767
- start = opt.start,
1768
- end = opt.end,
1769
- exploded = prop.exploded,
1770
- explodedX,
1771
- explodedY;
1772
-
1773
- /**
1774
- * Retrieve any exploded - the exploded can be an array of numbers or a single number
1775
- * (which is applied to all segments)
1776
- */
1777
- if (typeof exploded === 'object' && typeof exploded[index] === 'number') {
1778
- explodedX = ma.cos(((end - start) / 2) + start) * exploded[index];
1779
- explodedY = (ma.sin(((end - start) / 2) + start) * exploded[index]);
1780
-
1781
- } else if (typeof exploded === 'number') {
1782
- explodedX = ma.cos(((end - start) / 2) + start) * exploded;
1783
- explodedY = ma.sin(((end - start) / 2) + start) * exploded;
1784
-
1785
- } else {
1786
- explodedX = 0;
1787
- explodedY = 0;
1788
- }
1789
-
1790
- return [explodedX, explodedY];
1791
- };
1792
-
1793
-
1794
-
1795
-
1796
-
1797
-
1798
-
1799
-
1800
- //
1801
- // Set the options that the user has provided
1802
- //
1803
- for (i in conf.options) {
1804
- if (typeof i === 'string') {
1805
- this.set(i, conf.options[i]);
1806
- }
1807
- }
1808
- };
1809
-
1810
-
1811
-
1812
- return this;
1813
-
1814
-
1815
-
1816
-
1817
- // End module pattern
1818
- })(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.Rose=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=RG.SVG.arrayClone(conf.data);this.originalData=RG.SVG.arrayClone(conf.data);this.type='rose';this.angles=[];this.angles2=[];this.colorsParsed=false;this.originalColors={};this.gradientCounter=1;this.nodes=[];this.shadowNodes=[];this.max=0;this.redraw=false;this.highlight_node=null;RG.SVG.OR.add(this);this.container.style.display='inline-block';this.properties={centerx:null,centery:null,radius:null,gutterLeft:35,gutterRight:35,gutterTop:35,gutterBottom:35,backgroundGrid:true,backgroundGridColor:'#ddd',backgroundGridRadialsCount:null,backgroundGridRadialsAngleOffset:0,backgroundGridConcentricsCount:5,backgroundGridLinewidth:1,strokestyle:'white',colors:['red','black','orange','green','#6ff','#ccc','pink','orange','cyan','maroon','olive','teal'],colorsOpacity:1,textColor:'black',textFont:'sans-serif',textSize:12,textBold:false,textItalic:false,labels:[],labelsFont:null,labelsSize:null,labelsColor:null,labelsBold:null,labelsItalic:null,labelsRadialMargin:10,labelsAngleOffset:0,scaleVisible:true,scaleUnitsPre:'',scaleUnitsPost:'',scaleMax:null,scaleMin:0,scalePoint:'.',scaleThousand:',',scaleRound:false,scaleDecimals:0,scaleFormatter:null,scaleBold:null,scaleItalic:null,scaleColor:null,scaleSize:null,scaleFont:null,scaleLabelsCount:5,linewidth:1,tooltips:null,tooltipsOverride:null,tooltipsEffect:'fade',tooltipsCssClass:'RGraph_tooltip',tooltipsEvent:'click',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,shadow:false,shadowOffsetx:2,shadowOffsety:2,shadowBlur:2,shadowOpacity:0.25,margin:0,exploded:0,key:null,keyColors:null,keyOffsetx:0,keyOffsety:0,keyTextOffsetx:0,keyTextOffsety:-1,keyTextSize:null,keyTextBold:null,keyTextItalic:null,segmentsAngleOffset:0,variant:'normal'};RG.SVG.getGlobals(this);if(RG.SVG.FX&&typeof RG.SVG.FX.decorate==='function'){RG.SVG.FX.decorate(this);}
7
+ var prop=this.properties;this.draw=function()
8
+ {RG.SVG.fireCustomEvent(this,'onbeforedraw');this.data=RG.SVG.arrayClone(this.originalData);this.angles=[];for(var i=0;i<this.data.length;++i){this.angles2[i]=[];}
9
+ RG.SVG.createDefs(this);this.graphWidth=this.width-prop.gutterLeft-prop.gutterRight;this.graphHeight=this.height-prop.gutterTop-prop.gutterBottom;this.centerx=(this.graphWidth/2)+prop.gutterLeft;this.centery=(this.graphHeight/2)+prop.gutterTop;this.radius=ma.min(this.graphWidth,this.graphHeight)/2;this.centerx=typeof prop.centerx==='number'?prop.centerx:this.centerx;this.centery=typeof prop.centery==='number'?prop.centery:this.centery;this.radius=typeof prop.radius==='number'?prop.radius:this.radius;if(typeof prop.radius==='string'&&prop.radius.match(/^\+|-\d+$/))this.radius+=parseFloat(prop.radius);if(typeof prop.centerx==='string'&&prop.centerx.match(/^\+|-\d+$/))this.centery+=parseFloat(prop.centerx);if(typeof prop.centery==='string'&&prop.centery.match(/^\+|-\d+$/))this.centerx+=parseFloat(prop.centery);if(typeof prop.margin==='string'&&prop.margin.match(/([0-9.]+)deg/)){prop.margin=RegExp.$1/(180/ma.PI);}
10
+ for(var i=0;i<this.data.length;++i){if(typeof this.data[i]==='object'){for(var j=0;j<this.data[i].length;++j){if(typeof this.data[i][j]==='string'){this.data[i][j]=RG.SVG.stringsToNumbers(this.data[i][j]);}}}else if(typeof this.data[i]==='string'){this.data[i]=RG.SVG.stringsToNumbers(this.data[i]);}}
11
+ this.getMaxValue();RG.SVG.resetColorsToOriginalValues({object:this});this.parseColors();this.scale=RG.SVG.getScale({object:this,numlabels:typeof prop.scaleLabelsCount==='number'?prop.scaleLabelsCount:prop.backgroundGridConcentricCount,unitsPre:prop.scaleUnitsPre,unitsPost:prop.scaleUnitsPost,max:typeof prop.scaleMax==='number'?prop.scaleMax:this.max,min:prop.scaleMin,point:prop.scalePoint,round:prop.scaleRound,thousand:prop.scaleThousand,decimals:prop.scaleDecimals,strict:typeof prop.scaleMax==='number',formatter:prop.scaleFormatter});this.max=this.scale.max;this.drawBackground();this.drawRose();this.drawLabels();RG.SVG.drawTitle(this);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?');}
12
+ RG.SVG.attribution(this);if(prop.shadow){RG.SVG.setShadow({object:this,offsetx:prop.shadowOffsetx,offsety:prop.shadowOffsety,blur:prop.shadowBlur,opacity:prop.shadowOpacity,id:'dropShadow'});}
13
+ var obj=this;doc.body.addEventListener('mousedown',function(e)
14
+ {obj.hideHighlight(obj);},false);RG.SVG.fireCustomEvent(this,'ondraw');return this;};this.drawBackground=function()
15
+ {if(prop.backgroundGrid){var grid=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'g',attr:{className:'rgraph_radar_grid',fill:'rgba(0,0,0,0)',stroke:prop.backgroundGridColor}});var origin=0-(RG.SVG.TRIG.PI/2),radials=(typeof prop.backgroundGridRadialsCount==='number'?prop.backgroundGridRadialsCount:this.data.length),concentrics=prop.backgroundGridConcentricsCount,step=RG.SVG.TRIG.TWOPI/radials;if(radials>0){if(prop.variant==='non-equi-angular'){var radials=this.data.length;for(var i=0,total=0;i<this.data.length;++i){total+=this.data[i][1];}
16
+ for(var i=0,sum=0;i<this.data.length;++i){var coords=RG.SVG.TRIG.toCartesian({cx:this.centerx,cy:this.centery,r:this.radius,angle:origin+((sum/total)*RG.SVG.TRIG.TWOPI)+prop.backgroundGridRadialsAngleOffset});var str='M {1} {2} L {3} {4}'.format(this.centerx,this.centery,coords.x,coords.y);RG.SVG.create({svg:this.svg,type:'path',parent:grid,attr:{d:str,stroke:prop.backgroundGridColor,'stroke-width':prop.backgroundGridLinewidth}});sum+=this.data[i][1];}}else{for(var i=0,len=radials;i<len;++i){var coords=RG.SVG.TRIG.toCartesian({cx:this.centerx,cy:this.centery,r:this.radius,angle:origin+(i*step)+prop.backgroundGridRadialsAngleOffset});var str='M {1} {2} L {3} {4}'.format(this.centerx,this.centery,coords.x,coords.y);RG.SVG.create({svg:this.svg,type:'path',parent:grid,attr:{d:str,stroke:prop.backgroundGridColor,'stroke-width':prop.backgroundGridLinewidth}});}}}
17
+ if(concentrics>0){for(var j=1;j<=concentrics;j++){RG.SVG.create({svg:this.svg,type:'circle',parent:grid,attr:{cx:this.centerx,cy:this.centery,r:this.radius*(j/concentrics),fill:'transparent',stroke:prop.backgroundGridColor,'stroke-width':prop.backgroundGridLinewidth}});}}}};this.drawRose=function(opt)
18
+ {if(prop.variant==='non-equi-angular'){return this.drawRoseNonEquiAngular(opt);}
19
+ var radians=RG.SVG.TRIG.TWOPI/this.data.length;var group=RG.SVG.create({svg:this.svg,type:'g',parent:this.svg.all,attr:{id:'rgraph_rose_segments_'+this.id}});for(var i=0,seq=0;i<this.data.length;++i,++seq){var radius=(this.data[i]/this.scale.max)*this.radius,start=(i/this.data.length)*RG.SVG.TRIG.TWOPI,end=((i/this.data.length)*RG.SVG.TRIG.TWOPI)+radians;var explosion=this.getExploded({index:i,start:start-RG.SVG.TRIG.HALFPI,end:end-RG.SVG.TRIG.HALFPI});if(typeof this.data[i]==='object'&&!RG.SVG.isNull(this.data[i])){var segment_group=RG.SVG.create({svg:this.svg,type:'g',parent:group,attr:{id:'rose_'+this.id+'_segment_group_'+i}});for(var j=0,sum=0,accRadius=0;j<this.data[i].length;++j,++seq){sum+=this.data[i][j];var radius=(sum/this.scale.max)*this.radius;var arcPath=RG.SVG.TRIG.getArcPath2({cx:this.centerx+explosion[0],cy:this.centery+explosion[1],r:radius,start:start+prop.margin+prop.segmentsAngleOffset,end:end-prop.margin+prop.segmentsAngleOffset,anticlockwise:false});if(j===0){arcPath='{1} z'.format(arcPath);}else{var arcPath2=RG.SVG.TRIG.getArcPath2({cx:this.centerx+explosion[0],cy:this.centery+explosion[1],r:prevRadius,start:end-prop.margin+prop.segmentsAngleOffset,end:start+prop.margin+prop.segmentsAngleOffset,anticlockwise:true});arcPath='{1} L {2} {3} {4}'.format(arcPath,this.centerx+explosion[0],this.centery+explosion[1],arcPath2);}
20
+ var path=RG.SVG.create({svg:this.svg,type:'path',parent:segment_group,attr:{d:arcPath,fill:prop.colorsSequential?prop.colors[seq]:prop.colors[j],'fill-opacity':prop.colorsOpacity,stroke:prop.strokestyle,'stroke-width':prop.linewidth,'data-tooltip':(!RG.SVG.isNull(prop.tooltips)&&prop.tooltips.length)?prop.tooltips[seq]:'','data-index':i,'data-centerx':this.centerx+explosion[0],'data-centery':this.centery+explosion[1],'data-group':i,'data-subindex':j,'data-value':this.data[i][j],'data-start-angle':start,'data-end-angle':end,'data-radius':radius,'data-radius-inner':typeof prevRadius==='number'?prevRadius:0,'data-sequential-index':seq}});if(prop.tooltips&&prop.tooltips[seq]){if(prop.tooltipsEvent!=='mousemove'){prop.tooltipsEvent='click';}
21
+ (function(index,group,seq,obj)
22
+ {path.addEventListener(prop.tooltipsEvent,function(e)
23
+ {obj.removeHighlight();RG.SVG.tooltip({object:obj,group:group,index:index,sequentialIndex:seq,text:prop.tooltips[seq],event:e});obj.highlight(e.target);var highlight=RG.SVG.REG.get('highlight');if(prop.tooltipsEvent==='mousemove'){highlight.style.cursor='pointer';}},false);if(prop.tooltipsEvent==='click'){path.addEventListener('mousemove',function(e)
24
+ {e.target.style.cursor='pointer';},false);}}(j,i,seq,this));}
25
+ this.angles.push({object:path,index:seq,cx:this.centerx+explosion[0],cy:this.centery+explosion[1],start:start,end:end,radius:radius,'radius-inner':prevRadius,value:this.data[i][j]});this.angles2[i].push({object:path,index:seq,cx:this.centerx+explosion[0],cy:this.centery+explosion[1],start:start,end:end,radius:radius,'radius-inner':prevRadius,value:this.data[i][j]});var prevRadius=radius;}
26
+ seq--;}else{var arcPath=RG.SVG.TRIG.getArcPath2({cx:this.centerx+explosion[0],cy:this.centery+explosion[1],r:radius,start:start+prop.margin+prop.segmentsAngleOffset,end:end-prop.margin+prop.segmentsAngleOffset,anticlockwise:false});var path=RG.SVG.create({svg:this.svg,type:'path',parent:group,attr:{d:'{1} z'.format(arcPath),fill:prop.colorsSequential?prop.colors[i]:prop.colors[0],'fill-opacity':prop.colorsOpacity,stroke:prop.strokestyle,'stroke-width':prop.linewidth,'data-tooltip':(!RG.SVG.isNull(prop.tooltips)&&prop.tooltips.length)?prop.tooltips[i]:'','data-index':i,'data-centerx':this.centerx+explosion[0],'data-centery':this.centery+explosion[1],'data-value':this.data[i],'data-start-angle':start,'data-end-angle':end,'data-radius':radius,'data-sequential':seq}});this.angles.push({object:path,index:i,cx:this.centerx+explosion[0],cy:this.centery+explosion[1],start:start,end:end,radius:radius,value:this.data[i]});this.angles2[i].push({object:path,index:seq,cx:this.centerx+explosion[0],cy:this.centery+explosion[1],start:start,end:end,radius:radius,'radius-inner':prevRadius,value:this.data[i][j]});if(prop.tooltips&&prop.tooltips[i]){if(prop.tooltipsEvent!=='mousemove'){prop.tooltipsEvent='click';}
27
+ (function(index,obj)
28
+ {path.addEventListener(prop.tooltipsEvent,function(e)
29
+ {obj.removeHighlight();RG.SVG.tooltip({object:obj,index:index,group:index,sequentialIndex:index,text:prop.tooltips[index],event:e});obj.highlight(e.target);var highlight=RG.SVG.REG.get('highlight');if(prop.tooltipsEvent==='mousemove'){highlight.style.cursor='pointer';}},false);if(prop.tooltipsEvent==='click'){path.addEventListener('mousemove',function(e)
30
+ {e.target.style.cursor='pointer';},false);}}(i,this));}}}};this.drawRoseNonEquiAngular=function(opt)
31
+ {var group=RG.SVG.create({svg:this.svg,type:'g',parent:this.svg.all,attr:{id:'rgraph_rose_segments_'+this.id}});for(var i=0,total=0;i<this.data.length;++i){total+=parseFloat(this.data[i][1]);}
32
+ var start=0;for(var i=0,seq=0;i<this.data.length;++i,++seq){var radians=(this.data[i][1]/total)*RG.SVG.TRIG.TWOPI,end=start+radians;var explosion=this.getExploded({index:i,start:start-RG.SVG.TRIG.HALFPI,end:end-RG.SVG.TRIG.HALFPI});if(typeof this.data[i][0]==='object'&&!RG.SVG.isNull(this.data[i][0])){for(var j=0,sum=0;j<this.data[i][0].length;++j,++seq){sum+=this.data[i][0][j];if(j===0){var prevRadius=0,radius=(sum/this.scale.max)*this.radius;var arcPath=RG.SVG.TRIG.getArcPath2({cx:this.centerx+explosion[0],cy:this.centery+explosion[1],r:radius,start:start+prop.margin+prop.segmentsAngleOffset,end:end-prop.margin+prop.segmentsAngleOffset,anticlockwise:false});var arcPath2='';}else{var prevRadius=radius,radius=(sum/this.scale.max)*this.radius;var arcPath=RG.SVG.TRIG.getArcPath2({cx:this.centerx+explosion[0],cy:this.centery+explosion[1],r:radius,start:start+prop.margin+prop.segmentsAngleOffset,end:end-prop.margin+prop.segmentsAngleOffset,anticlockwise:false});var arcPath2=RG.SVG.TRIG.getArcPath2({cx:this.centerx+explosion[0],cy:this.centery+explosion[1],r:prevRadius,start:end-prop.margin+prop.segmentsAngleOffset,end:start+prop.margin+prop.segmentsAngleOffset,anticlockwise:true});}
33
+ var path=RG.SVG.create({svg:this.svg,type:'path',parent:group,attr:{d:'{1} {2} z'.format(arcPath,arcPath2),fill:prop.colorsSequential?prop.colors[seq]:prop.colors[j],'fill-opacity':prop.colorsOpacity,stroke:prop.strokestyle,'stroke-width':prop.linewidth,'data-tooltip':(!RG.SVG.isNull(prop.tooltips)&&prop.tooltips.length)?prop.tooltips[i]:'','data-centerx':this.centerx+explosion[0],'data-centery':this.centery+explosion[1],'data-index':'[{1},{2}]'.format(i,j),'data-value':this.data[i][0][j],'data-start-angle':start,'data-end-angle':end,'data-radius':radius,'data-radius-inner':prevRadius,'data-sequential':seq}});this.angles.push({object:path,index:i,cx:this.centerx+explosion[0],cy:this.centery+explosion[1],start:start,end:end,radius:radius,'radius-inner':prevRadius,value:this.data[i][0]});this.angles2[i].push({object:path,index:seq,cx:this.centerx+explosion[0],cy:this.centery+explosion[1],start:start,end:end,radius:radius,'radius-inner':prevRadius,value:this.data[i][j]});if(prop.tooltips&&prop.tooltips[seq]){if(prop.tooltipsEvent!=='mousemove'){prop.tooltipsEvent='click';}
34
+ (function(index,group,seq,obj)
35
+ {path.addEventListener(prop.tooltipsEvent,function(e)
36
+ {obj.removeHighlight();RG.SVG.tooltip({object:obj,index:index,group:group,sequentialIndex:seq,text:prop.tooltips[seq],event:e});obj.highlight(e.target);var highlight=RG.SVG.REG.get('highlight');if(prop.tooltipsEvent==='mousemove'){highlight.style.cursor='pointer';}},false);if(prop.tooltipsEvent==='click'){path.addEventListener('mousemove',function(e)
37
+ {e.target.style.cursor='pointer';},false);}}(j,i,seq,this));}
38
+ var prevRadius=radius;}
39
+ seq--}else{var radius=(this.data[i][0]/this.scale.max)*this.radius;var arcPath=RG.SVG.TRIG.getArcPath2({cx:this.centerx+explosion[0],cy:this.centery+explosion[1],r:radius,start:start+prop.margin+prop.segmentsAngleOffset,end:end-prop.margin+prop.segmentsAngleOffset,anticlockwise:false});var path=RG.SVG.create({svg:this.svg,type:'path',parent:group,attr:{d:'{1} z'.format(arcPath),fill:prop.colorsSequential?prop.colors[i]:prop.colors[0],'fill-opacity':prop.colorsOpacity,stroke:prop.strokestyle,'stroke-width':prop.linewidth,'data-tooltip':(!RG.SVG.isNull(prop.tooltips)&&prop.tooltips.length)?prop.tooltips[i]:'','data-centerx':this.centerx+explosion[0],'data-centery':this.centery+explosion[1],'data-index':i,'data-value':this.data[i],'data-start-angle':start,'data-end-angle':end,'data-radius':radius,'data-sequential':seq}});this.angles.push({object:path,index:i,cx:this.centerx+explosion[0],cy:this.centery+explosion[1],start:start,end:end,radius:radius,value:this.data[i][0]});this.angles2[i].push({object:path,index:seq,cx:this.centerx+explosion[0],cy:this.centery+explosion[1],start:start,end:end,radius:radius,'radius-inner':0,value:this.data[i][j]});if(prop.tooltips&&prop.tooltips[i]){if(prop.tooltipsEvent!=='mousemove'){prop.tooltipsEvent='click';}
40
+ (function(index,group,seq,obj)
41
+ {path.addEventListener(prop.tooltipsEvent,function(e)
42
+ {obj.removeHighlight();RG.SVG.tooltip({object:obj,index:index,group:index,sequentialIndex:seq,text:prop.tooltips[index],event:e});obj.highlight(e.target);var highlight=RG.SVG.REG.get('highlight');if(prop.tooltipsEvent==='mousemove'){highlight.style.cursor='pointer';}},false);if(prop.tooltipsEvent==='click'){path.addEventListener('mousemove',function(e)
43
+ {e.target.style.cursor='pointer';},false);}}(i,i,seq,this));}}
44
+ start+=radians;}};this.redrawRose=function()
45
+ {};this.drawLabels=function()
46
+ {if(prop.scaleVisible){for(var i=0;i<this.scale.labels.length;++i){var x=this.centerx;var y=this.centery-(this.radius/this.scale.labels.length*(i+1));RG.SVG.text({object:this,svg:this.svg,parent:this.svg.all,text:this.scale.labels[i],size:prop.scaleSize||prop.textSize-2,x:x,y:y,halign:'center',valign:'center',background:'rgba(255,255,255,0.7)',padding:2,color:prop.scaleColor||prop.textColor,bold:typeof prop.scaleBold==='boolean'?prop.scaleBold:prop.textBold,italic:typeof prop.scaleItalic==='boolean'?prop.scaleItalic:prop.textItalic,font:prop.scaleFont||prop.textFont});}
47
+ var str=RG.SVG.numberFormat({object:this,num:this.scale.min.toFixed(prop.scaleDecimals),prepend:prop.scaleUnitsPre,append:prop.scaleUnitsPost,point:prop.scalePoint,thousand:prop.scaleThousand,formatter:prop.scaleFormatter});RG.SVG.text({object:this,svg:this.svg,parent:this.svg.all,text:str,size:prop.scaleSize||prop.textSize-2,x:this.centerx,y:this.centery,halign:'center',valign:'center',background:'rgba(255,255,255,0.7)',padding:2,color:prop.scaleColor||prop.textColor,bold:typeof prop.scaleBold==='boolean'?prop.scaleBold:prop.textBold,italic:typeof prop.scaleItalic==='boolean'?prop.scaleItalic:prop.textItalic,font:prop.scaleFont||prop.textFont});}
48
+ var halign;if(typeof prop.labelsSize!=='number'){prop.labelsSize=prop.textSize+4;}
49
+ for(var i=0;i<prop.labels.length;++i){if(prop.variant==='non-equi-angular'){var angle=((this.angles2[i][0].end-this.angles2[i][0].start)/2)+this.angles2[i][0].start-RG.SVG.TRIG.HALFPI;}else{var angle=(((RG.SVG.TRIG.TWOPI/prop.labels.length))*i)-RG.SVG.TRIG.HALFPI+prop.labelsAngleOffset+((this.angles2[i][0].end-this.angles2[i][0].start)/2);}
50
+ var endpoint=RG.SVG.TRIG.getRadiusEndPoint({r:this.radius+prop.labelsRadialMargin,angle:angle});var explosion=this.getExploded({index:i,start:this.angles2[i][0].start-RG.SVG.TRIG.HALFPI,end:this.angles2[i][0].end-RG.SVG.TRIG.HALFPI});endpoint[0]+=this.centerx+explosion[0];endpoint[1]+=this.centery+explosion[1];if(ma.round(endpoint[0])>this.centerx){halign='left';}else if(ma.round(endpoint[0])===this.centerx){halign='center';}else{halign='right';}
51
+ RG.SVG.text({object:this,svg:this.svg,parent:this.svg.all,text:typeof prop.labels[i]==='string'?prop.labels[i]:'',size:prop.labelsSize,x:endpoint[0],y:endpoint[1],halign:halign,valign:'center',background:'rgba(255,255,255,0.7)',padding:2,color:prop.labelsColor||prop.textColor,bold:typeof prop.labelsBold==='boolean'?prop.labelsBold:prop.textBold,italic:typeof prop.labelsItalic==='boolean'?prop.labelsItalic:prop.textItalic,font:prop.labelsFont||prop.textFont});}};this.highlight=function(path)
52
+ {var path=path.getAttribute('d');var highlight=RG.SVG.create({svg:this.svg,parent:this.svg.all,type:'path',attr:{d:path,fill:prop.highlightFill,stroke:prop.highlightStroke,'stroke-width':prop.highlightLinewidth}});if(prop.tooltipsEvent==='mousemove'){highlight.addEventListener('mouseout',function(e)
53
+ {highlight.parentNode.removeChild(highlight);RG.SVG.hideTooltip();RG.SVG.REG.set('highlight',null);},false);}
54
+ RG.SVG.REG.set('highlight',highlight);};this.parseColors=function()
55
+ {if(!Object.keys(this.originalColors).length){this.originalColors={colors:RG.SVG.arrayClone(prop.colors),highlightFill:RG.SVG.arrayClone(prop.highlightFill)}}
56
+ var colors=prop.colors;if(colors){for(var i=0;i<colors.length;++i){colors[i]=RG.SVG.parseColorRadial({object:this,color:colors[i]});}}
57
+ prop.highlightFill=RG.SVG.parseColorRadial({object:this,color:prop.highlightFill});};this.getMaxValue=function()
58
+ {var max=0;if(prop.variant==='non-equi-angular'){for(var i=0;i<this.data.length;++i){if(!RG.SVG.isNull(this.data[i])){if(typeof this.data[i][0]==='number'){max=ma.max(max,this.data[i][0]);}else if(typeof this.data[i][0]==='object'){max=ma.max(max,RG.SVG.arraySum(this.data[i][0]));}}}}else{for(var i=0;i<this.data.length;++i){if(!RG.SVG.isNull(this.data[i])){if(typeof this.data[i]==='number'){max=ma.max(max,this.data[i]);}else if(typeof this.data[i]==='object'){max=ma.max(max,RG.SVG.arraySum(this.data[i]));}}}}
59
+ this.max=max;};this.getRadius=function(value)
60
+ {return((value-prop.scaleMin)/(this.scale.max-prop.scaleMin))*this.radius;};this.roundRobin=function()
61
+ {};this.on=function(type,func)
62
+ {if(type.substr(0,2)!=='on'){type='on'+type;}
63
+ RG.SVG.addCustomEventListener(this,type,func);return this;};this.exec=function(func)
64
+ {func(this);return this;};this.removeHighlight=this.hideHighlight=function()
65
+ {var highlight=RG.SVG.REG.get('highlight');if(highlight&&this.highlight_node){this.highlight_node.setAttribute('fill','transparent');this.highlight_node.setAttribute('stroke','transparent');RG.SVG.REG.set('highlight',null);}};this.getExploded=function(opt)
66
+ {var index=opt.index,start=opt.start,end=opt.end,exploded=prop.exploded,explodedX,explodedY;if(typeof exploded==='object'&&typeof exploded[index]==='number'){explodedX=ma.cos(((end-start)/2)+start)*exploded[index];explodedY=(ma.sin(((end-start)/2)+start)*exploded[index]);}else if(typeof exploded==='number'){explodedX=ma.cos(((end-start)/2)+start)*exploded;explodedY=ma.sin(((end-start)/2)+start)*exploded;}else{explodedX=0;explodedY=0;}
67
+ return[explodedX,explodedY];};for(i in conf.options){if(typeof i==='string'){this.set(i,conf.options[i]);}}};return this;})(window,document);