highcharts-rails 4.2.7 → 5.0.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +34 -0
- data/Gemfile +4 -0
- data/Rakefile +53 -32
- data/app/assets/javascripts/highcharts.js +18775 -17176
- data/app/assets/javascripts/highcharts/highcharts-3d.js +1849 -1563
- data/app/assets/javascripts/highcharts/highcharts-more.js +2162 -1988
- data/app/assets/javascripts/highcharts/modules/accessibility.js +1005 -0
- data/app/assets/javascripts/highcharts/modules/annotations.js +408 -401
- data/app/assets/javascripts/highcharts/modules/boost.js +561 -546
- data/app/assets/javascripts/highcharts/modules/broken-axis.js +330 -324
- data/app/assets/javascripts/highcharts/modules/data.js +973 -965
- data/app/assets/javascripts/highcharts/modules/drilldown.js +783 -723
- data/app/assets/javascripts/highcharts/modules/exporting.js +864 -785
- data/app/assets/javascripts/highcharts/modules/funnel.js +290 -306
- data/app/assets/javascripts/highcharts/modules/heatmap.js +701 -645
- data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +150 -132
- data/app/assets/javascripts/highcharts/modules/offline-exporting.js +414 -355
- data/app/assets/javascripts/highcharts/modules/overlapping-datalabels.js +164 -0
- data/app/assets/javascripts/highcharts/modules/series-label.js +473 -448
- data/app/assets/javascripts/highcharts/modules/solid-gauge.js +279 -271
- data/app/assets/javascripts/highcharts/modules/treemap.js +921 -886
- data/app/assets/javascripts/highcharts/themes/dark-blue.js +307 -244
- data/app/assets/javascripts/highcharts/themes/dark-green.js +303 -244
- data/app/assets/javascripts/highcharts/themes/dark-unica.js +231 -201
- data/app/assets/javascripts/highcharts/themes/gray.js +314 -245
- data/app/assets/javascripts/highcharts/themes/grid-light.js +91 -66
- data/app/assets/javascripts/highcharts/themes/grid.js +124 -96
- data/app/assets/javascripts/highcharts/themes/sand-signika.js +119 -94
- data/app/assets/javascripts/highcharts/themes/skies.js +108 -85
- data/lib/highcharts/version.rb +1 -1
- metadata +13 -14
- data/app/assets/javascripts/highcharts/adapters/standalone-framework.js +0 -1
- data/app/assets/javascripts/highcharts/modules/canvas-tools.js +0 -3115
- data/app/assets/javascripts/highcharts/modules/map.js +0 -2117
@@ -1,895 +1,930 @@
|
|
1
1
|
/**
|
2
|
-
* @license Highcharts JS
|
2
|
+
* @license Highcharts JS v5.0.0 (2016-09-29)
|
3
3
|
*
|
4
4
|
* (c) 2014 Highsoft AS
|
5
5
|
* Authors: Jon Arild Nygard / Oystein Moseng
|
6
6
|
*
|
7
7
|
* License: www.highcharts.com/license
|
8
8
|
*/
|
9
|
+
(function(factory) {
|
10
|
+
if (typeof module === 'object' && module.exports) {
|
11
|
+
module.exports = factory;
|
12
|
+
} else {
|
13
|
+
factory(Highcharts);
|
14
|
+
}
|
15
|
+
}(function(Highcharts) {
|
16
|
+
(function(H) {
|
17
|
+
/**
|
18
|
+
* (c) 2014 Highsoft AS
|
19
|
+
* Authors: Jon Arild Nygard / Oystein Moseng
|
20
|
+
*
|
21
|
+
* License: www.highcharts.com/license
|
22
|
+
*/
|
23
|
+
'use strict';
|
24
|
+
var seriesType = H.seriesType,
|
25
|
+
seriesTypes = H.seriesTypes,
|
26
|
+
map = H.map,
|
27
|
+
merge = H.merge,
|
28
|
+
extend = H.extend,
|
29
|
+
noop = H.noop,
|
30
|
+
each = H.each,
|
31
|
+
grep = H.grep,
|
32
|
+
pick = H.pick,
|
33
|
+
Series = H.Series,
|
34
|
+
stableSort = H.stableSort,
|
35
|
+
color = H.Color,
|
36
|
+
eachObject = function(list, func, context) {
|
37
|
+
var key;
|
38
|
+
context = context || this;
|
39
|
+
for (key in list) {
|
40
|
+
if (list.hasOwnProperty(key)) {
|
41
|
+
func.call(context, list[key], key, list);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
},
|
45
|
+
reduce = function(arr, func, previous, context) {
|
46
|
+
context = context || this;
|
47
|
+
arr = arr || []; // @note should each be able to handle empty values automatically?
|
48
|
+
each(arr, function(current, i) {
|
49
|
+
previous = func.call(context, previous, current, i, arr);
|
50
|
+
});
|
51
|
+
return previous;
|
52
|
+
},
|
53
|
+
// @todo find correct name for this function.
|
54
|
+
// @todo Similar to reduce, this function is likely redundant
|
55
|
+
recursive = function(item, func, context) {
|
56
|
+
var next;
|
57
|
+
context = context || this;
|
58
|
+
next = func.call(context, item);
|
59
|
+
if (next !== false) {
|
60
|
+
recursive(next, func, context);
|
61
|
+
}
|
62
|
+
};
|
9
63
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
var treeAxis = {
|
877
|
-
endOnTick: false,
|
878
|
-
gridLineWidth: 0,
|
879
|
-
lineWidth: 0,
|
880
|
-
min: 0,
|
881
|
-
dataMin: 0,
|
882
|
-
minPadding: 0,
|
883
|
-
max: 100,
|
884
|
-
dataMax: 100,
|
885
|
-
maxPadding: 0,
|
886
|
-
startOnTick: false,
|
887
|
-
title: null,
|
888
|
-
tickPositions: []
|
889
|
-
};
|
890
|
-
Series.prototype.bindAxes.call(this);
|
891
|
-
H.extend(this.yAxis.options, treeAxis);
|
892
|
-
H.extend(this.xAxis.options, treeAxis);
|
893
|
-
}
|
894
|
-
}));
|
64
|
+
// The Treemap series type
|
65
|
+
seriesType('treemap', 'scatter', {
|
66
|
+
showInLegend: false,
|
67
|
+
marker: false,
|
68
|
+
dataLabels: {
|
69
|
+
enabled: true,
|
70
|
+
defer: false,
|
71
|
+
verticalAlign: 'middle',
|
72
|
+
formatter: function() { // #2945
|
73
|
+
return this.point.name || this.point.id;
|
74
|
+
},
|
75
|
+
inside: true
|
76
|
+
},
|
77
|
+
tooltip: {
|
78
|
+
headerFormat: '',
|
79
|
+
pointFormat: '<b>{point.name}</b>: {point.value}</b><br/>'
|
80
|
+
},
|
81
|
+
layoutAlgorithm: 'sliceAndDice',
|
82
|
+
layoutStartingDirection: 'vertical',
|
83
|
+
alternateStartingDirection: false,
|
84
|
+
levelIsConstant: true,
|
85
|
+
drillUpButton: {
|
86
|
+
position: {
|
87
|
+
align: 'right',
|
88
|
+
x: -10,
|
89
|
+
y: 10
|
90
|
+
}
|
91
|
+
},
|
92
|
+
|
93
|
+
// Presentational options
|
94
|
+
borderColor: '#e6e6e6',
|
95
|
+
borderWidth: 1,
|
96
|
+
opacity: 0.15,
|
97
|
+
states: {
|
98
|
+
hover: {
|
99
|
+
borderColor: '#999999',
|
100
|
+
brightness: seriesTypes.heatmap ? 0 : 0.1,
|
101
|
+
opacity: 0.75,
|
102
|
+
shadow: false
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
|
107
|
+
// Prototype members
|
108
|
+
}, {
|
109
|
+
pointArrayMap: ['value'],
|
110
|
+
axisTypes: seriesTypes.heatmap ? ['xAxis', 'yAxis', 'colorAxis'] : ['xAxis', 'yAxis'],
|
111
|
+
optionalAxis: 'colorAxis',
|
112
|
+
getSymbol: noop,
|
113
|
+
parallelArrays: ['x', 'y', 'value', 'colorValue'],
|
114
|
+
colorKey: 'colorValue', // Point color option key
|
115
|
+
translateColors: seriesTypes.heatmap && seriesTypes.heatmap.prototype.translateColors,
|
116
|
+
trackerGroups: ['group', 'dataLabelsGroup'],
|
117
|
+
/**
|
118
|
+
* Creates an object map from parent id to childrens index.
|
119
|
+
* @param {Array} data List of points set in options.
|
120
|
+
* @param {string} data[].parent Parent id of point.
|
121
|
+
* @param {Array} ids List of all point ids.
|
122
|
+
* @return {Object} Map from parent id to children index in data.
|
123
|
+
*/
|
124
|
+
getListOfParents: function(data, ids) {
|
125
|
+
var listOfParents = reduce(data, function(prev, curr, i) {
|
126
|
+
var parent = pick(curr.parent, '');
|
127
|
+
if (prev[parent] === undefined) {
|
128
|
+
prev[parent] = [];
|
129
|
+
}
|
130
|
+
prev[parent].push(i);
|
131
|
+
return prev;
|
132
|
+
}, {});
|
133
|
+
|
134
|
+
// If parent does not exist, hoist parent to root of tree.
|
135
|
+
eachObject(listOfParents, function(children, parent, list) {
|
136
|
+
if ((parent !== '') && (H.inArray(parent, ids) === -1)) {
|
137
|
+
each(children, function(child) {
|
138
|
+
list[''].push(child);
|
139
|
+
});
|
140
|
+
delete list[parent];
|
141
|
+
}
|
142
|
+
});
|
143
|
+
return listOfParents;
|
144
|
+
},
|
145
|
+
/**
|
146
|
+
* Creates a tree structured object from the series points
|
147
|
+
*/
|
148
|
+
getTree: function() {
|
149
|
+
var tree,
|
150
|
+
series = this,
|
151
|
+
allIds = map(this.data, function(d) {
|
152
|
+
return d.id;
|
153
|
+
}),
|
154
|
+
parentList = series.getListOfParents(this.data, allIds);
|
155
|
+
|
156
|
+
series.nodeMap = [];
|
157
|
+
tree = series.buildNode('', -1, 0, parentList, null);
|
158
|
+
// Parents of the root node is by default visible
|
159
|
+
recursive(this.nodeMap[this.rootNode], function(node) {
|
160
|
+
var next = false,
|
161
|
+
p = node.parent;
|
162
|
+
node.visible = true;
|
163
|
+
if (p || p === '') {
|
164
|
+
next = series.nodeMap[p];
|
165
|
+
}
|
166
|
+
return next;
|
167
|
+
});
|
168
|
+
// Children of the root node is by default visible
|
169
|
+
recursive(this.nodeMap[this.rootNode].children, function(children) {
|
170
|
+
var next = false;
|
171
|
+
each(children, function(child) {
|
172
|
+
child.visible = true;
|
173
|
+
if (child.children.length) {
|
174
|
+
next = (next || []).concat(child.children);
|
175
|
+
}
|
176
|
+
});
|
177
|
+
return next;
|
178
|
+
});
|
179
|
+
this.setTreeValues(tree);
|
180
|
+
return tree;
|
181
|
+
},
|
182
|
+
init: function(chart, options) {
|
183
|
+
var series = this;
|
184
|
+
Series.prototype.init.call(series, chart, options);
|
185
|
+
if (series.options.allowDrillToNode) {
|
186
|
+
series.drillTo();
|
187
|
+
}
|
188
|
+
},
|
189
|
+
buildNode: function(id, i, level, list, parent) {
|
190
|
+
var series = this,
|
191
|
+
children = [],
|
192
|
+
point = series.points[i],
|
193
|
+
node,
|
194
|
+
child;
|
195
|
+
|
196
|
+
// Actions
|
197
|
+
each((list[id] || []), function(i) {
|
198
|
+
child = series.buildNode(series.points[i].id, i, (level + 1), list, id);
|
199
|
+
children.push(child);
|
200
|
+
});
|
201
|
+
node = {
|
202
|
+
id: id,
|
203
|
+
i: i,
|
204
|
+
children: children,
|
205
|
+
level: level,
|
206
|
+
parent: parent,
|
207
|
+
visible: false // @todo move this to better location
|
208
|
+
};
|
209
|
+
series.nodeMap[node.id] = node;
|
210
|
+
if (point) {
|
211
|
+
point.node = node;
|
212
|
+
}
|
213
|
+
return node;
|
214
|
+
},
|
215
|
+
setTreeValues: function(tree) {
|
216
|
+
var series = this,
|
217
|
+
options = series.options,
|
218
|
+
childrenTotal = 0,
|
219
|
+
children = [],
|
220
|
+
val,
|
221
|
+
point = series.points[tree.i];
|
222
|
+
|
223
|
+
// First give the children some values
|
224
|
+
each(tree.children, function(child) {
|
225
|
+
child = series.setTreeValues(child);
|
226
|
+
children.push(child);
|
227
|
+
|
228
|
+
if (!child.ignore) {
|
229
|
+
childrenTotal += child.val;
|
230
|
+
} else {
|
231
|
+
// @todo Add predicate to avoid looping already ignored children
|
232
|
+
recursive(child.children, function(children) {
|
233
|
+
var next = false;
|
234
|
+
each(children, function(node) {
|
235
|
+
extend(node, {
|
236
|
+
ignore: true,
|
237
|
+
isLeaf: false,
|
238
|
+
visible: false
|
239
|
+
});
|
240
|
+
if (node.children.length) {
|
241
|
+
next = (next || []).concat(node.children);
|
242
|
+
}
|
243
|
+
});
|
244
|
+
return next;
|
245
|
+
});
|
246
|
+
}
|
247
|
+
});
|
248
|
+
// Sort the children
|
249
|
+
stableSort(children, function(a, b) {
|
250
|
+
return a.sortIndex - b.sortIndex;
|
251
|
+
});
|
252
|
+
// Set the values
|
253
|
+
val = pick(point && point.options.value, childrenTotal);
|
254
|
+
if (point) {
|
255
|
+
point.value = val;
|
256
|
+
}
|
257
|
+
extend(tree, {
|
258
|
+
children: children,
|
259
|
+
childrenTotal: childrenTotal,
|
260
|
+
// Ignore this node if point is not visible
|
261
|
+
ignore: !(pick(point && point.visible, true) && (val > 0)),
|
262
|
+
isLeaf: tree.visible && !childrenTotal,
|
263
|
+
levelDynamic: (options.levelIsConstant ? tree.level : (tree.level - series.nodeMap[series.rootNode].level)),
|
264
|
+
name: pick(point && point.name, ''),
|
265
|
+
sortIndex: pick(point && point.sortIndex, -val),
|
266
|
+
val: val
|
267
|
+
});
|
268
|
+
return tree;
|
269
|
+
},
|
270
|
+
/**
|
271
|
+
* Recursive function which calculates the area for all children of a node.
|
272
|
+
* @param {Object} node The node which is parent to the children.
|
273
|
+
* @param {Object} area The rectangular area of the parent.
|
274
|
+
*/
|
275
|
+
calculateChildrenAreas: function(parent, area) {
|
276
|
+
var series = this,
|
277
|
+
options = series.options,
|
278
|
+
level = this.levelMap[parent.levelDynamic + 1],
|
279
|
+
algorithm = pick((series[level && level.layoutAlgorithm] && level.layoutAlgorithm), options.layoutAlgorithm),
|
280
|
+
alternate = options.alternateStartingDirection,
|
281
|
+
childrenValues = [],
|
282
|
+
children;
|
283
|
+
|
284
|
+
// Collect all children which should be included
|
285
|
+
children = grep(parent.children, function(n) {
|
286
|
+
return !n.ignore;
|
287
|
+
});
|
288
|
+
|
289
|
+
if (level && level.layoutStartingDirection) {
|
290
|
+
area.direction = level.layoutStartingDirection === 'vertical' ? 0 : 1;
|
291
|
+
}
|
292
|
+
childrenValues = series[algorithm](area, children);
|
293
|
+
each(children, function(child, index) {
|
294
|
+
var values = childrenValues[index];
|
295
|
+
child.values = merge(values, {
|
296
|
+
val: child.childrenTotal,
|
297
|
+
direction: (alternate ? 1 - area.direction : area.direction)
|
298
|
+
});
|
299
|
+
child.pointValues = merge(values, {
|
300
|
+
x: (values.x / series.axisRatio),
|
301
|
+
width: (values.width / series.axisRatio)
|
302
|
+
});
|
303
|
+
// If node has children, then call method recursively
|
304
|
+
if (child.children.length) {
|
305
|
+
series.calculateChildrenAreas(child, child.values);
|
306
|
+
}
|
307
|
+
});
|
308
|
+
},
|
309
|
+
setPointValues: function() {
|
310
|
+
var series = this,
|
311
|
+
xAxis = series.xAxis,
|
312
|
+
yAxis = series.yAxis;
|
313
|
+
each(series.points, function(point) {
|
314
|
+
var node = point.node,
|
315
|
+
values = node.pointValues,
|
316
|
+
x1,
|
317
|
+
x2,
|
318
|
+
y1,
|
319
|
+
y2,
|
320
|
+
crispCorr = 0.5; // Assume 1px borderWidth for simplicity
|
321
|
+
|
322
|
+
// Points which is ignored, have no values.
|
323
|
+
if (values && node.visible) {
|
324
|
+
x1 = Math.round(xAxis.translate(values.x, 0, 0, 0, 1)) - crispCorr;
|
325
|
+
x2 = Math.round(xAxis.translate(values.x + values.width, 0, 0, 0, 1)) - crispCorr;
|
326
|
+
y1 = Math.round(yAxis.translate(values.y, 0, 0, 0, 1)) - crispCorr;
|
327
|
+
y2 = Math.round(yAxis.translate(values.y + values.height, 0, 0, 0, 1)) - crispCorr;
|
328
|
+
// Set point values
|
329
|
+
point.shapeType = 'rect';
|
330
|
+
point.shapeArgs = {
|
331
|
+
x: Math.min(x1, x2),
|
332
|
+
y: Math.min(y1, y2),
|
333
|
+
width: Math.abs(x2 - x1),
|
334
|
+
height: Math.abs(y2 - y1)
|
335
|
+
};
|
336
|
+
point.plotX = point.shapeArgs.x + (point.shapeArgs.width / 2);
|
337
|
+
point.plotY = point.shapeArgs.y + (point.shapeArgs.height / 2);
|
338
|
+
} else {
|
339
|
+
// Reset visibility
|
340
|
+
delete point.plotX;
|
341
|
+
delete point.plotY;
|
342
|
+
}
|
343
|
+
});
|
344
|
+
},
|
345
|
+
setColorRecursive: function(node, color, colorIndex) {
|
346
|
+
var series = this,
|
347
|
+
point,
|
348
|
+
level;
|
349
|
+
if (node) {
|
350
|
+
point = series.points[node.i];
|
351
|
+
level = series.levelMap[node.levelDynamic];
|
352
|
+
// Select either point color, level color or inherited color.
|
353
|
+
color = pick(point && point.options.color, level && level.color, color);
|
354
|
+
colorIndex = pick(point && point.options.colorIndex, level && level.colorIndex, colorIndex);
|
355
|
+
if (point) {
|
356
|
+
point.color = color;
|
357
|
+
point.colorIndex = colorIndex;
|
358
|
+
}
|
359
|
+
|
360
|
+
// Do it all again with the children
|
361
|
+
if (node.children.length) {
|
362
|
+
each(node.children, function(child) {
|
363
|
+
series.setColorRecursive(child, color, colorIndex);
|
364
|
+
});
|
365
|
+
}
|
366
|
+
}
|
367
|
+
},
|
368
|
+
algorithmGroup: function(h, w, d, p) {
|
369
|
+
this.height = h;
|
370
|
+
this.width = w;
|
371
|
+
this.plot = p;
|
372
|
+
this.direction = d;
|
373
|
+
this.startDirection = d;
|
374
|
+
this.total = 0;
|
375
|
+
this.nW = 0;
|
376
|
+
this.lW = 0;
|
377
|
+
this.nH = 0;
|
378
|
+
this.lH = 0;
|
379
|
+
this.elArr = [];
|
380
|
+
this.lP = {
|
381
|
+
total: 0,
|
382
|
+
lH: 0,
|
383
|
+
nH: 0,
|
384
|
+
lW: 0,
|
385
|
+
nW: 0,
|
386
|
+
nR: 0,
|
387
|
+
lR: 0,
|
388
|
+
aspectRatio: function(w, h) {
|
389
|
+
return Math.max((w / h), (h / w));
|
390
|
+
}
|
391
|
+
};
|
392
|
+
this.addElement = function(el) {
|
393
|
+
this.lP.total = this.elArr[this.elArr.length - 1];
|
394
|
+
this.total = this.total + el;
|
395
|
+
if (this.direction === 0) {
|
396
|
+
// Calculate last point old aspect ratio
|
397
|
+
this.lW = this.nW;
|
398
|
+
this.lP.lH = this.lP.total / this.lW;
|
399
|
+
this.lP.lR = this.lP.aspectRatio(this.lW, this.lP.lH);
|
400
|
+
// Calculate last point new aspect ratio
|
401
|
+
this.nW = this.total / this.height;
|
402
|
+
this.lP.nH = this.lP.total / this.nW;
|
403
|
+
this.lP.nR = this.lP.aspectRatio(this.nW, this.lP.nH);
|
404
|
+
} else {
|
405
|
+
// Calculate last point old aspect ratio
|
406
|
+
this.lH = this.nH;
|
407
|
+
this.lP.lW = this.lP.total / this.lH;
|
408
|
+
this.lP.lR = this.lP.aspectRatio(this.lP.lW, this.lH);
|
409
|
+
// Calculate last point new aspect ratio
|
410
|
+
this.nH = this.total / this.width;
|
411
|
+
this.lP.nW = this.lP.total / this.nH;
|
412
|
+
this.lP.nR = this.lP.aspectRatio(this.lP.nW, this.nH);
|
413
|
+
}
|
414
|
+
this.elArr.push(el);
|
415
|
+
};
|
416
|
+
this.reset = function() {
|
417
|
+
this.nW = 0;
|
418
|
+
this.lW = 0;
|
419
|
+
this.elArr = [];
|
420
|
+
this.total = 0;
|
421
|
+
};
|
422
|
+
},
|
423
|
+
algorithmCalcPoints: function(directionChange, last, group, childrenArea) {
|
424
|
+
var pX,
|
425
|
+
pY,
|
426
|
+
pW,
|
427
|
+
pH,
|
428
|
+
gW = group.lW,
|
429
|
+
gH = group.lH,
|
430
|
+
plot = group.plot,
|
431
|
+
keep,
|
432
|
+
i = 0,
|
433
|
+
end = group.elArr.length - 1;
|
434
|
+
if (last) {
|
435
|
+
gW = group.nW;
|
436
|
+
gH = group.nH;
|
437
|
+
} else {
|
438
|
+
keep = group.elArr[group.elArr.length - 1];
|
439
|
+
}
|
440
|
+
each(group.elArr, function(p) {
|
441
|
+
if (last || (i < end)) {
|
442
|
+
if (group.direction === 0) {
|
443
|
+
pX = plot.x;
|
444
|
+
pY = plot.y;
|
445
|
+
pW = gW;
|
446
|
+
pH = p / pW;
|
447
|
+
} else {
|
448
|
+
pX = plot.x;
|
449
|
+
pY = plot.y;
|
450
|
+
pH = gH;
|
451
|
+
pW = p / pH;
|
452
|
+
}
|
453
|
+
childrenArea.push({
|
454
|
+
x: pX,
|
455
|
+
y: pY,
|
456
|
+
width: pW,
|
457
|
+
height: pH
|
458
|
+
});
|
459
|
+
if (group.direction === 0) {
|
460
|
+
plot.y = plot.y + pH;
|
461
|
+
} else {
|
462
|
+
plot.x = plot.x + pW;
|
463
|
+
}
|
464
|
+
}
|
465
|
+
i = i + 1;
|
466
|
+
});
|
467
|
+
// Reset variables
|
468
|
+
group.reset();
|
469
|
+
if (group.direction === 0) {
|
470
|
+
group.width = group.width - gW;
|
471
|
+
} else {
|
472
|
+
group.height = group.height - gH;
|
473
|
+
}
|
474
|
+
plot.y = plot.parent.y + (plot.parent.height - group.height);
|
475
|
+
plot.x = plot.parent.x + (plot.parent.width - group.width);
|
476
|
+
if (directionChange) {
|
477
|
+
group.direction = 1 - group.direction;
|
478
|
+
}
|
479
|
+
// If not last, then add uncalculated element
|
480
|
+
if (!last) {
|
481
|
+
group.addElement(keep);
|
482
|
+
}
|
483
|
+
},
|
484
|
+
algorithmLowAspectRatio: function(directionChange, parent, children) {
|
485
|
+
var childrenArea = [],
|
486
|
+
series = this,
|
487
|
+
pTot,
|
488
|
+
plot = {
|
489
|
+
x: parent.x,
|
490
|
+
y: parent.y,
|
491
|
+
parent: parent
|
492
|
+
},
|
493
|
+
direction = parent.direction,
|
494
|
+
i = 0,
|
495
|
+
end = children.length - 1,
|
496
|
+
group = new this.algorithmGroup(parent.height, parent.width, direction, plot); // eslint-disable-line new-cap
|
497
|
+
// Loop through and calculate all areas
|
498
|
+
each(children, function(child) {
|
499
|
+
pTot = (parent.width * parent.height) * (child.val / parent.val);
|
500
|
+
group.addElement(pTot);
|
501
|
+
if (group.lP.nR > group.lP.lR) {
|
502
|
+
series.algorithmCalcPoints(directionChange, false, group, childrenArea, plot);
|
503
|
+
}
|
504
|
+
// If last child, then calculate all remaining areas
|
505
|
+
if (i === end) {
|
506
|
+
series.algorithmCalcPoints(directionChange, true, group, childrenArea, plot);
|
507
|
+
}
|
508
|
+
i = i + 1;
|
509
|
+
});
|
510
|
+
return childrenArea;
|
511
|
+
},
|
512
|
+
algorithmFill: function(directionChange, parent, children) {
|
513
|
+
var childrenArea = [],
|
514
|
+
pTot,
|
515
|
+
direction = parent.direction,
|
516
|
+
x = parent.x,
|
517
|
+
y = parent.y,
|
518
|
+
width = parent.width,
|
519
|
+
height = parent.height,
|
520
|
+
pX,
|
521
|
+
pY,
|
522
|
+
pW,
|
523
|
+
pH;
|
524
|
+
each(children, function(child) {
|
525
|
+
pTot = (parent.width * parent.height) * (child.val / parent.val);
|
526
|
+
pX = x;
|
527
|
+
pY = y;
|
528
|
+
if (direction === 0) {
|
529
|
+
pH = height;
|
530
|
+
pW = pTot / pH;
|
531
|
+
width = width - pW;
|
532
|
+
x = x + pW;
|
533
|
+
} else {
|
534
|
+
pW = width;
|
535
|
+
pH = pTot / pW;
|
536
|
+
height = height - pH;
|
537
|
+
y = y + pH;
|
538
|
+
}
|
539
|
+
childrenArea.push({
|
540
|
+
x: pX,
|
541
|
+
y: pY,
|
542
|
+
width: pW,
|
543
|
+
height: pH
|
544
|
+
});
|
545
|
+
if (directionChange) {
|
546
|
+
direction = 1 - direction;
|
547
|
+
}
|
548
|
+
});
|
549
|
+
return childrenArea;
|
550
|
+
},
|
551
|
+
strip: function(parent, children) {
|
552
|
+
return this.algorithmLowAspectRatio(false, parent, children);
|
553
|
+
},
|
554
|
+
squarified: function(parent, children) {
|
555
|
+
return this.algorithmLowAspectRatio(true, parent, children);
|
556
|
+
},
|
557
|
+
sliceAndDice: function(parent, children) {
|
558
|
+
return this.algorithmFill(true, parent, children);
|
559
|
+
},
|
560
|
+
stripes: function(parent, children) {
|
561
|
+
return this.algorithmFill(false, parent, children);
|
562
|
+
},
|
563
|
+
translate: function() {
|
564
|
+
var pointValues,
|
565
|
+
seriesArea,
|
566
|
+
tree,
|
567
|
+
val;
|
568
|
+
|
569
|
+
// Call prototype function
|
570
|
+
Series.prototype.translate.call(this);
|
571
|
+
|
572
|
+
// Assign variables
|
573
|
+
this.rootNode = pick(this.options.rootId, '');
|
574
|
+
// Create a object map from level to options
|
575
|
+
this.levelMap = reduce(this.options.levels, function(arr, item) {
|
576
|
+
arr[item.level] = item;
|
577
|
+
return arr;
|
578
|
+
}, {});
|
579
|
+
tree = this.tree = this.getTree(); // @todo Only if series.isDirtyData is true
|
580
|
+
|
581
|
+
// Calculate plotting values.
|
582
|
+
this.axisRatio = (this.xAxis.len / this.yAxis.len);
|
583
|
+
this.nodeMap[''].pointValues = pointValues = {
|
584
|
+
x: 0,
|
585
|
+
y: 0,
|
586
|
+
width: 100,
|
587
|
+
height: 100
|
588
|
+
};
|
589
|
+
this.nodeMap[''].values = seriesArea = merge(pointValues, {
|
590
|
+
width: (pointValues.width * this.axisRatio),
|
591
|
+
direction: (this.options.layoutStartingDirection === 'vertical' ? 0 : 1),
|
592
|
+
val: tree.val
|
593
|
+
});
|
594
|
+
this.calculateChildrenAreas(tree, seriesArea);
|
595
|
+
|
596
|
+
// Logic for point colors
|
597
|
+
if (this.colorAxis) {
|
598
|
+
this.translateColors();
|
599
|
+
} else if (!this.options.colorByPoint) {
|
600
|
+
this.setColorRecursive(this.tree);
|
601
|
+
}
|
602
|
+
|
603
|
+
// Update axis extremes according to the root node.
|
604
|
+
if (this.options.allowDrillToNode) {
|
605
|
+
val = this.nodeMap[this.rootNode].pointValues;
|
606
|
+
this.xAxis.setExtremes(val.x, val.x + val.width, false);
|
607
|
+
this.yAxis.setExtremes(val.y, val.y + val.height, false);
|
608
|
+
this.xAxis.setScale();
|
609
|
+
this.yAxis.setScale();
|
610
|
+
}
|
611
|
+
|
612
|
+
// Assign values to points.
|
613
|
+
this.setPointValues();
|
614
|
+
},
|
615
|
+
/**
|
616
|
+
* Extend drawDataLabels with logic to handle custom options related to the treemap series:
|
617
|
+
* - Points which is not a leaf node, has dataLabels disabled by default.
|
618
|
+
* - Options set on series.levels is merged in.
|
619
|
+
* - Width of the dataLabel is set to match the width of the point shape.
|
620
|
+
*/
|
621
|
+
drawDataLabels: function() {
|
622
|
+
var series = this,
|
623
|
+
points = grep(series.points, function(n) {
|
624
|
+
return n.node.visible;
|
625
|
+
}),
|
626
|
+
options,
|
627
|
+
level;
|
628
|
+
each(points, function(point) {
|
629
|
+
level = series.levelMap[point.node.levelDynamic];
|
630
|
+
// Set options to new object to avoid problems with scope
|
631
|
+
options = {
|
632
|
+
style: {}
|
633
|
+
};
|
634
|
+
|
635
|
+
// If not a leaf, then label should be disabled as default
|
636
|
+
if (!point.node.isLeaf) {
|
637
|
+
options.enabled = false;
|
638
|
+
}
|
639
|
+
|
640
|
+
// If options for level exists, include them as well
|
641
|
+
if (level && level.dataLabels) {
|
642
|
+
options = merge(options, level.dataLabels);
|
643
|
+
series._hasPointLabels = true;
|
644
|
+
}
|
645
|
+
|
646
|
+
// Set dataLabel width to the width of the point shape.
|
647
|
+
if (point.shapeArgs) {
|
648
|
+
options.style.width = point.shapeArgs.width;
|
649
|
+
if (point.dataLabel) {
|
650
|
+
point.dataLabel.css({
|
651
|
+
width: point.shapeArgs.width + 'px'
|
652
|
+
});
|
653
|
+
}
|
654
|
+
}
|
655
|
+
|
656
|
+
// Merge custom options with point options
|
657
|
+
point.dlOptions = merge(options, point.options.dataLabels);
|
658
|
+
});
|
659
|
+
Series.prototype.drawDataLabels.call(this);
|
660
|
+
},
|
661
|
+
|
662
|
+
/**
|
663
|
+
* Over the alignment method by setting z index
|
664
|
+
*/
|
665
|
+
alignDataLabel: function(point) {
|
666
|
+
seriesTypes.column.prototype.alignDataLabel.apply(this, arguments);
|
667
|
+
if (point.dataLabel) {
|
668
|
+
point.dataLabel.attr({
|
669
|
+
zIndex: point.node.zIndex + 1
|
670
|
+
});
|
671
|
+
}
|
672
|
+
},
|
673
|
+
|
674
|
+
|
675
|
+
/**
|
676
|
+
* Get presentational attributes
|
677
|
+
*/
|
678
|
+
pointAttribs: function(point, state) {
|
679
|
+
var level = this.levelMap[point.node.levelDynamic] || {},
|
680
|
+
options = this.options,
|
681
|
+
attr,
|
682
|
+
stateOptions = (state && options.states[state]) || {},
|
683
|
+
className = point.getClassName(),
|
684
|
+
opacity;
|
685
|
+
|
686
|
+
// Set attributes by precedence. Point trumps level trumps series. Stroke width uses pick
|
687
|
+
// because it can be 0.
|
688
|
+
attr = {
|
689
|
+
'stroke': point.borderColor || level.borderColor || stateOptions.borderColor || options.borderColor,
|
690
|
+
'stroke-width': pick(point.borderWidth, level.borderWidth, stateOptions.borderWidth, options.borderWidth),
|
691
|
+
'dashstyle': point.borderDashStyle || level.borderDashStyle || stateOptions.borderDashStyle || options.borderDashStyle,
|
692
|
+
'fill': point.color || this.color
|
693
|
+
};
|
694
|
+
|
695
|
+
// Hide levels above the current view
|
696
|
+
if (className.indexOf('highcharts-above-level') !== -1) {
|
697
|
+
attr.fill = 'none';
|
698
|
+
attr['stroke-width'] = 0;
|
699
|
+
|
700
|
+
// Nodes with children that accept interaction
|
701
|
+
} else if (className.indexOf('highcharts-internal-node-interactive') !== -1) {
|
702
|
+
opacity = pick(stateOptions.opacity, options.opacity);
|
703
|
+
attr.fill = color(attr.fill).setOpacity(opacity).get();
|
704
|
+
attr.cursor = 'pointer';
|
705
|
+
// Hide nodes that have children
|
706
|
+
} else if (className.indexOf('highcharts-internal-node') !== -1) {
|
707
|
+
attr.fill = 'none';
|
708
|
+
|
709
|
+
} else if (state) {
|
710
|
+
// Brighten and hoist the hover nodes
|
711
|
+
attr.fill = color(attr.fill).brighten(stateOptions.brightness).get();
|
712
|
+
}
|
713
|
+
return attr;
|
714
|
+
},
|
715
|
+
|
716
|
+
|
717
|
+
/**
|
718
|
+
* Extending ColumnSeries drawPoints
|
719
|
+
*/
|
720
|
+
drawPoints: function() {
|
721
|
+
var series = this,
|
722
|
+
points = grep(series.points, function(n) {
|
723
|
+
return n.node.visible;
|
724
|
+
});
|
725
|
+
|
726
|
+
each(points, function(point) {
|
727
|
+
var groupKey = 'levelGroup-' + point.node.levelDynamic;
|
728
|
+
if (!series[groupKey]) {
|
729
|
+
series[groupKey] = series.chart.renderer.g(groupKey)
|
730
|
+
.attr({
|
731
|
+
zIndex: 1000 - point.node.levelDynamic // @todo Set the zIndex based upon the number of levels, instead of using 1000
|
732
|
+
})
|
733
|
+
.add(series.group);
|
734
|
+
}
|
735
|
+
point.group = series[groupKey];
|
736
|
+
|
737
|
+
});
|
738
|
+
// Call standard drawPoints
|
739
|
+
seriesTypes.column.prototype.drawPoints.call(this);
|
740
|
+
|
741
|
+
// If drillToNode is allowed, set a point cursor on clickables & add drillId to point
|
742
|
+
if (series.options.allowDrillToNode) {
|
743
|
+
each(points, function(point) {
|
744
|
+
if (point.graphic) {
|
745
|
+
point.drillId = series.options.interactByLeaf ? series.drillToByLeaf(point) : series.drillToByGroup(point);
|
746
|
+
}
|
747
|
+
});
|
748
|
+
}
|
749
|
+
},
|
750
|
+
/**
|
751
|
+
* Add drilling on the suitable points
|
752
|
+
*/
|
753
|
+
drillTo: function() {
|
754
|
+
var series = this;
|
755
|
+
H.addEvent(series, 'click', function(event) {
|
756
|
+
var point = event.point,
|
757
|
+
drillId = point.drillId,
|
758
|
+
drillName;
|
759
|
+
// If a drill id is returned, add click event and cursor.
|
760
|
+
if (drillId) {
|
761
|
+
drillName = series.nodeMap[series.rootNode].name || series.rootNode;
|
762
|
+
point.setState(''); // Remove hover
|
763
|
+
series.drillToNode(drillId);
|
764
|
+
series.showDrillUpButton(drillName);
|
765
|
+
}
|
766
|
+
});
|
767
|
+
},
|
768
|
+
/**
|
769
|
+
* Finds the drill id for a parent node.
|
770
|
+
* Returns false if point should not have a click event
|
771
|
+
* @param {Object} point
|
772
|
+
* @return {string || boolean} Drill to id or false when point should not have a click event
|
773
|
+
*/
|
774
|
+
drillToByGroup: function(point) {
|
775
|
+
var series = this,
|
776
|
+
drillId = false;
|
777
|
+
if ((point.node.level - series.nodeMap[series.rootNode].level) === 1 && !point.node.isLeaf) {
|
778
|
+
drillId = point.id;
|
779
|
+
}
|
780
|
+
return drillId;
|
781
|
+
},
|
782
|
+
/**
|
783
|
+
* Finds the drill id for a leaf node.
|
784
|
+
* Returns false if point should not have a click event
|
785
|
+
* @param {Object} point
|
786
|
+
* @return {string || boolean} Drill to id or false when point should not have a click event
|
787
|
+
*/
|
788
|
+
drillToByLeaf: function(point) {
|
789
|
+
var series = this,
|
790
|
+
drillId = false,
|
791
|
+
nodeParent;
|
792
|
+
if ((point.node.parent !== series.rootNode) && (point.node.isLeaf)) {
|
793
|
+
nodeParent = point.node;
|
794
|
+
while (!drillId) {
|
795
|
+
nodeParent = series.nodeMap[nodeParent.parent];
|
796
|
+
if (nodeParent.parent === series.rootNode) {
|
797
|
+
drillId = nodeParent.id;
|
798
|
+
}
|
799
|
+
}
|
800
|
+
}
|
801
|
+
return drillId;
|
802
|
+
},
|
803
|
+
drillUp: function() {
|
804
|
+
var drillPoint = null,
|
805
|
+
node,
|
806
|
+
parent;
|
807
|
+
if (this.rootNode) {
|
808
|
+
node = this.nodeMap[this.rootNode];
|
809
|
+
if (node.parent !== null) {
|
810
|
+
drillPoint = this.nodeMap[node.parent];
|
811
|
+
} else {
|
812
|
+
drillPoint = this.nodeMap[''];
|
813
|
+
}
|
814
|
+
}
|
815
|
+
|
816
|
+
if (drillPoint !== null) {
|
817
|
+
this.drillToNode(drillPoint.id);
|
818
|
+
if (drillPoint.id === '') {
|
819
|
+
this.drillUpButton = this.drillUpButton.destroy();
|
820
|
+
} else {
|
821
|
+
parent = this.nodeMap[drillPoint.parent];
|
822
|
+
this.showDrillUpButton((parent.name || parent.id));
|
823
|
+
}
|
824
|
+
}
|
825
|
+
},
|
826
|
+
drillToNode: function(id) {
|
827
|
+
this.options.rootId = id;
|
828
|
+
this.isDirty = true; // Force redraw
|
829
|
+
this.chart.redraw();
|
830
|
+
},
|
831
|
+
showDrillUpButton: function(name) {
|
832
|
+
var series = this,
|
833
|
+
backText = (name || '< Back'),
|
834
|
+
buttonOptions = series.options.drillUpButton,
|
835
|
+
attr,
|
836
|
+
states;
|
837
|
+
|
838
|
+
if (buttonOptions.text) {
|
839
|
+
backText = buttonOptions.text;
|
840
|
+
}
|
841
|
+
if (!this.drillUpButton) {
|
842
|
+
attr = buttonOptions.theme;
|
843
|
+
states = attr && attr.states;
|
844
|
+
|
845
|
+
this.drillUpButton = this.chart.renderer.button(
|
846
|
+
backText,
|
847
|
+
null,
|
848
|
+
null,
|
849
|
+
function() {
|
850
|
+
series.drillUp();
|
851
|
+
},
|
852
|
+
attr,
|
853
|
+
states && states.hover,
|
854
|
+
states && states.select
|
855
|
+
)
|
856
|
+
.attr({
|
857
|
+
align: buttonOptions.position.align,
|
858
|
+
zIndex: 7
|
859
|
+
})
|
860
|
+
.add()
|
861
|
+
.align(buttonOptions.position, false, buttonOptions.relativeTo || 'plotBox');
|
862
|
+
} else {
|
863
|
+
this.drillUpButton.attr({
|
864
|
+
text: backText
|
865
|
+
})
|
866
|
+
.align();
|
867
|
+
}
|
868
|
+
},
|
869
|
+
buildKDTree: noop,
|
870
|
+
drawLegendSymbol: H.LegendSymbolMixin.drawRectangle,
|
871
|
+
getExtremes: function() {
|
872
|
+
// Get the extremes from the value data
|
873
|
+
Series.prototype.getExtremes.call(this, this.colorValueData);
|
874
|
+
this.valueMin = this.dataMin;
|
875
|
+
this.valueMax = this.dataMax;
|
876
|
+
|
877
|
+
// Get the extremes from the y data
|
878
|
+
Series.prototype.getExtremes.call(this);
|
879
|
+
},
|
880
|
+
getExtremesFromAll: true,
|
881
|
+
bindAxes: function() {
|
882
|
+
var treeAxis = {
|
883
|
+
endOnTick: false,
|
884
|
+
gridLineWidth: 0,
|
885
|
+
lineWidth: 0,
|
886
|
+
min: 0,
|
887
|
+
dataMin: 0,
|
888
|
+
minPadding: 0,
|
889
|
+
max: 100,
|
890
|
+
dataMax: 100,
|
891
|
+
maxPadding: 0,
|
892
|
+
startOnTick: false,
|
893
|
+
title: null,
|
894
|
+
tickPositions: []
|
895
|
+
};
|
896
|
+
Series.prototype.bindAxes.call(this);
|
897
|
+
H.extend(this.yAxis.options, treeAxis);
|
898
|
+
H.extend(this.xAxis.options, treeAxis);
|
899
|
+
}
|
900
|
+
|
901
|
+
// Point class
|
902
|
+
}, {
|
903
|
+
getClassName: function() {
|
904
|
+
var className = H.Point.prototype.getClassName.call(this),
|
905
|
+
series = this.series,
|
906
|
+
options = series.options;
|
907
|
+
|
908
|
+
// Above the current level
|
909
|
+
if (this.node.level <= series.nodeMap[series.rootNode].level) {
|
910
|
+
className += ' highcharts-above-level';
|
911
|
+
|
912
|
+
} else if (!this.node.isLeaf && !pick(options.interactByLeaf, !options.allowDrillToNode)) {
|
913
|
+
className += ' highcharts-internal-node-interactive';
|
914
|
+
|
915
|
+
} else if (!this.node.isLeaf) {
|
916
|
+
className += ' highcharts-internal-node';
|
917
|
+
}
|
918
|
+
return className;
|
919
|
+
},
|
920
|
+
setState: function(state) {
|
921
|
+
H.Point.prototype.setState.call(this, state);
|
922
|
+
this.graphic.attr({
|
923
|
+
zIndex: state === 'hover' ? 1 : 0
|
924
|
+
});
|
925
|
+
},
|
926
|
+
setVisible: seriesTypes.pie.prototype.pointClass.prototype.setVisible
|
927
|
+
});
|
928
|
+
|
929
|
+
}(Highcharts));
|
895
930
|
}));
|