highcharts-rails 6.0.1 → 6.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.markdown +16 -0
  3. data/app/assets/javascripts/highcharts.js +188 -51
  4. data/app/assets/javascripts/highcharts/highcharts-3d.js +3 -4
  5. data/app/assets/javascripts/highcharts/highcharts-more.js +21 -5
  6. data/app/assets/javascripts/highcharts/modules/accessibility.js +4 -2
  7. data/app/assets/javascripts/highcharts/modules/annotations.js +2 -2
  8. data/app/assets/javascripts/highcharts/modules/boost-canvas.js +50 -195
  9. data/app/assets/javascripts/highcharts/modules/boost.js +202 -135
  10. data/app/assets/javascripts/highcharts/modules/broken-axis.js +1 -1
  11. data/app/assets/javascripts/highcharts/modules/bullet.js +1 -1
  12. data/app/assets/javascripts/highcharts/modules/data.js +88 -59
  13. data/app/assets/javascripts/highcharts/modules/drag-panes.js +1 -1
  14. data/app/assets/javascripts/highcharts/modules/drilldown.js +25 -2
  15. data/app/assets/javascripts/highcharts/modules/export-data.js +6 -2
  16. data/app/assets/javascripts/highcharts/modules/exporting.js +1 -1
  17. data/app/assets/javascripts/highcharts/modules/funnel.js +1 -1
  18. data/app/assets/javascripts/highcharts/modules/gantt.js +2 -2
  19. data/app/assets/javascripts/highcharts/modules/grid-axis.js +1 -1
  20. data/app/assets/javascripts/highcharts/modules/heatmap.js +826 -820
  21. data/app/assets/javascripts/highcharts/modules/histogram-bellcurve.js +1 -1
  22. data/app/assets/javascripts/highcharts/modules/item-series.js +1 -1
  23. data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +1 -1
  24. data/app/assets/javascripts/highcharts/modules/offline-exporting.js +2 -2
  25. data/app/assets/javascripts/highcharts/modules/oldie.js +16 -2
  26. data/app/assets/javascripts/highcharts/modules/overlapping-datalabels.js +1 -1
  27. data/app/assets/javascripts/highcharts/modules/parallel-coordinates.js +1 -1
  28. data/app/assets/javascripts/highcharts/modules/pareto.js +1 -1
  29. data/app/assets/javascripts/highcharts/modules/sankey.js +39 -9
  30. data/app/assets/javascripts/highcharts/modules/series-label.js +8 -3
  31. data/app/assets/javascripts/highcharts/modules/solid-gauge.js +1 -1
  32. data/app/assets/javascripts/highcharts/modules/static-scale.js +6 -2
  33. data/app/assets/javascripts/highcharts/modules/stock.js +19 -47
  34. data/app/assets/javascripts/highcharts/modules/streamgraph.js +1 -1
  35. data/app/assets/javascripts/highcharts/modules/sunburst.js +40 -15
  36. data/app/assets/javascripts/highcharts/modules/tilemap.js +7 -6
  37. data/app/assets/javascripts/highcharts/modules/treemap.js +13 -3
  38. data/app/assets/javascripts/highcharts/modules/variable-pie.js +1 -1
  39. data/app/assets/javascripts/highcharts/modules/variwide.js +1 -1
  40. data/app/assets/javascripts/highcharts/modules/vector.js +1 -1
  41. data/app/assets/javascripts/highcharts/modules/windbarb.js +1 -1
  42. data/app/assets/javascripts/highcharts/modules/wordcloud.js +130 -37
  43. data/app/assets/javascripts/highcharts/modules/xrange.js +2 -2
  44. data/app/assets/javascripts/highcharts/themes/avocado.js +1 -1
  45. data/app/assets/javascripts/highcharts/themes/dark-blue.js +1 -1
  46. data/app/assets/javascripts/highcharts/themes/dark-green.js +1 -1
  47. data/app/assets/javascripts/highcharts/themes/dark-unica.js +1 -1
  48. data/app/assets/javascripts/highcharts/themes/gray.js +1 -1
  49. data/app/assets/javascripts/highcharts/themes/grid-light.js +1 -1
  50. data/app/assets/javascripts/highcharts/themes/grid.js +1 -1
  51. data/app/assets/javascripts/highcharts/themes/sand-signika.js +1 -1
  52. data/app/assets/javascripts/highcharts/themes/skies.js +1 -1
  53. data/app/assets/javascripts/highcharts/themes/sunset.js +1 -1
  54. data/lib/highcharts/version.rb +1 -1
  55. metadata +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v6.0.1 (2017-10-05)
2
+ * @license Highcharts JS v6.0.2 (2017-10-20)
3
3
  *
4
4
  * (c) 2009-2017 Torstein Honsi
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v6.0.1 (2017-10-05)
2
+ * @license Highcharts JS v6.0.2 (2017-10-20)
3
3
  *
4
4
  * Bullet graph series type for Highcharts
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v6.0.1 (2017-10-05)
2
+ * @license Highcharts JS v6.0.2 (2017-10-20)
3
3
  * Data module
4
4
  *
5
5
  * (c) 2012-2017 Torstein Honsi
@@ -495,7 +495,7 @@
495
495
  */
496
496
  parseCSV: function(inOptions) {
497
497
  var self = this,
498
- options = this.options || inOptions,
498
+ options = inOptions || this.options,
499
499
  csv = options.csv,
500
500
  columns,
501
501
  startRow = options.startRow || 0,
@@ -515,7 +515,7 @@
515
515
  '\t': 0
516
516
  };
517
517
 
518
- columns = this.columns = this.columns || [];
518
+ columns = this.columns = [];
519
519
 
520
520
  /*
521
521
  This implementation is quite verbose. It will be shortened once
@@ -562,6 +562,7 @@
562
562
  cl = '',
563
563
  cn = '',
564
564
  token = '',
565
+ actualColumn = 0,
565
566
  column = 0;
566
567
 
567
568
  function read(j) {
@@ -580,8 +581,10 @@
580
581
  }
581
582
 
582
583
  function push() {
583
- if (startColumn > column || column > endColumn) {
584
- // Skip this column
584
+ if (startColumn > actualColumn || actualColumn > endColumn) {
585
+ // Skip this column, but increment the column count (#7272)
586
+ ++actualColumn;
587
+ token = '';
585
588
  return;
586
589
  }
587
590
 
@@ -595,16 +598,20 @@
595
598
  pushType('string');
596
599
  }
597
600
 
601
+
598
602
  if (columns.length < column + 1) {
599
603
  columns.push([]);
600
604
  }
601
605
 
602
606
  if (!noAdd) {
603
- columns[column].push(token);
607
+ // Don't push - if there's a varrying amount of columns
608
+ // for each row, pushing will skew everything down n slots
609
+ columns[column][rowNumber] = token;
604
610
  }
605
611
 
606
612
  token = '';
607
613
  ++column;
614
+ ++actualColumn;
608
615
  }
609
616
 
610
617
  if (!columnStr.trim().length) {
@@ -621,6 +628,7 @@
621
628
  // Quoted string
622
629
  if (c === '#') {
623
630
  // The rest of the row is a comment
631
+ push();
624
632
  return;
625
633
  } else if (c === '"') {
626
634
  read(++i);
@@ -655,66 +663,87 @@
655
663
 
656
664
  push();
657
665
 
658
- if (column < columns.length) {
659
- // There might be an issue.
660
- // This set is either
661
-
662
- // Fill in
663
- if (!noAdd) {
664
- for (var z = column; z < columns.length; z++) {
665
- columns[z].push(0);
666
- }
667
- }
668
- }
669
666
  }
670
667
 
671
668
  // Attempt to guess the delimiter
669
+ // We do a separate parse pass here because we need
670
+ // to count potential delimiters softly without making any assumptions.
672
671
  function guessDelimiter(lines) {
673
672
  var points = 0,
674
673
  commas = 0,
675
- guessed = false,
676
- handler = function(c, token) {
674
+ guessed = false;
675
+
676
+ some(lines, function(columnStr, i) {
677
+ var inStr = false,
678
+ c,
679
+ cn,
680
+ cl,
681
+ token = '';
682
+
683
+
684
+ // We should be able to detect dateformats within 13 rows
685
+ if (i > 13) {
686
+ return true;
687
+ }
688
+
689
+ for (var j = 0; j < columnStr.length; j++) {
690
+ c = columnStr[j];
691
+ cn = columnStr[j + 1];
692
+ cl = columnStr[j - 1];
693
+
694
+ if (c === '#') {
695
+ // Skip the rest of the line - it's a comment
696
+ return;
697
+ } else if (c === '"') {
698
+ if (inStr) {
699
+ if (cl !== '"' && cn !== '"') {
700
+ while (cn === ' ' && j < columnStr.length) {
701
+ cn = columnStr[++j];
702
+ }
703
+
704
+ // After parsing a string, the next non-blank
705
+ // should be a delimiter if the CSV is properly
706
+ // formed.
707
+
708
+ if (typeof potDelimiters[cn] !== 'undefined') {
709
+ potDelimiters[cn]++;
710
+ }
711
+
712
+ inStr = false;
713
+ }
714
+ } else {
715
+ inStr = true;
716
+ }
717
+ } else if (typeof potDelimiters[c] !== 'undefined') {
718
+
719
+ token = token.trim();
720
+
721
+ if (!isNaN(Date.parse(token))) {
722
+ potDelimiters[c]++;
723
+ } else if (isNaN(token) || !isFinite(token)) {
724
+ potDelimiters[c]++;
725
+ }
726
+
727
+ token = '';
728
+
729
+ } else {
730
+ token += c;
731
+ }
732
+
677
733
  if (c === ',') {
678
734
  commas++;
679
735
  }
736
+
680
737
  if (c === '.') {
681
738
  points++;
682
739
  }
683
-
684
- if (typeof potDelimiters[c] !== 'undefined') {
685
- // Check what we have in token now
686
-
687
- if (
688
- // We can't make a deduction when token is a number,
689
- // since the decimal delimiter may interfere.
690
- (isNaN(parseFloat(token)) || !isFinite(token)) &&
691
- (
692
- // Highcharts.isString(token) ||
693
- !isNaN(Date.parse(token))
694
- )
695
- ) {
696
- potDelimiters[c]++;
697
- return true;
698
- }
699
- }
700
- },
701
- callbacks = {
702
- ';': handler,
703
- ',': handler,
704
- '\t': handler
705
- };
706
-
707
- some(lines, function(columnStr, i) {
708
- // We should be able to detect dateformats within 13 rows
709
- if (i > 13) {
710
- return true;
711
740
  }
712
- parseRow(columnStr, i, true, callbacks);
713
741
  });
714
742
 
715
743
  // Count the potential delimiters.
716
744
  // This could be improved by checking if the number of delimiters
717
745
  // equals the number of columns - 1
746
+
718
747
  if (potDelimiters[';'] > potDelimiters[',']) {
719
748
  guessed = ';';
720
749
  } else if (potDelimiters[','] > potDelimiters[';']) {
@@ -868,8 +897,8 @@
868
897
  startRow = 0;
869
898
  }
870
899
 
871
- if (!endRow || endRow > lines.length) {
872
- endRow = lines.length;
900
+ if (!endRow || endRow >= lines.length) {
901
+ endRow = lines.length - 1;
873
902
  }
874
903
 
875
904
  if (options.itemDelimiter) {
@@ -879,8 +908,14 @@
879
908
  itemDelimiter = guessDelimiter(lines);
880
909
  }
881
910
 
882
- for (rowIt = startRow; rowIt < endRow; rowIt++) {
883
- parseRow(lines[rowIt], rowIt);
911
+ var offset = 0;
912
+
913
+ for (rowIt = startRow; rowIt <= endRow; rowIt++) {
914
+ if (lines[rowIt][0] === '#') {
915
+ offset++;
916
+ } else {
917
+ parseRow(lines[rowIt], rowIt - startRow - offset);
918
+ }
884
919
  }
885
920
 
886
921
  // //Make sure that there's header columns for everything
@@ -1191,13 +1226,7 @@
1191
1226
  */
1192
1227
  dateFormats: {
1193
1228
  'YYYY-mm-dd': {
1194
- regex: /^([0-9]{4})[\-\/\.]([0-9]{2})[\-\/\.]([0-9]{2})$/,
1195
- parser: function(match) {
1196
- return Date.UTC(+match[1], match[2] - 1, +match[3]);
1197
- }
1198
- },
1199
- 'YYYY/mm/dd': {
1200
- regex: /^([0-9]{4})[\-\/\.]([0-9]{2})[\-\/\.]([0-9]{2})$/,
1229
+ regex: /^([0-9]{4})[\-\/\.]([0-9]{1,2})[\-\/\.]([0-9]{1,2})$/,
1201
1230
  parser: function(match) {
1202
1231
  return Date.UTC(+match[1], match[2] - 1, +match[3]);
1203
1232
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v6.0.1 (2017-10-05)
2
+ * @license Highcharts JS v6.0.2 (2017-10-20)
3
3
  * Drag-panes module
4
4
  *
5
5
  * (c) 2010-2017 Highsoft AS
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v6.0.1 (2017-10-05)
2
+ * @license Highcharts JS v6.0.2 (2017-10-20)
3
3
  * Highcharts Drilldown module
4
4
  *
5
5
  * Author: Torstein Honsi
@@ -448,7 +448,8 @@
448
448
  xMax: xAxis && xAxis.userMax,
449
449
  yMin: yAxis && yAxis.userMin,
450
450
  yMax: yAxis && yAxis.userMax
451
- }
451
+ },
452
+ resetZoomButton: this.resetZoomButton
452
453
  }, colorProp);
453
454
 
454
455
  // Push it to the lookup array
@@ -490,6 +491,14 @@
490
491
  }
491
492
  });
492
493
  }
494
+
495
+ // We have a reset zoom button. Hide it and detatch it from the chart. It
496
+ // is preserved to the layer config above.
497
+ if (this.resetZoomButton) {
498
+ this.resetZoomButton.hide();
499
+ delete this.resetZoomButton;
500
+ }
501
+
493
502
  this.pointer.reset();
494
503
  this.redraw();
495
504
  this.showDrillUpButton();
@@ -623,6 +632,13 @@
623
632
  newSeries.xAxis.setExtremes(oldExtremes.xMin, oldExtremes.xMax, false);
624
633
  newSeries.yAxis.setExtremes(oldExtremes.yMin, oldExtremes.yMax, false);
625
634
  }
635
+
636
+ // We have a resetZoomButton tucked away for this level. Attatch
637
+ // it to the chart and show it.
638
+ if (level.resetZoomButton) {
639
+ chart.resetZoomButton = level.resetZoomButton;
640
+ chart.resetZoomButton.show();
641
+ }
626
642
  }
627
643
  }
628
644
 
@@ -643,6 +659,13 @@
643
659
  this.ddDupes.length = []; // #3315
644
660
  };
645
661
 
662
+ // Don't show the reset button if we already are displaying the drillUp button.
663
+ wrap(Chart.prototype, 'showResetZoom', function(proceed) {
664
+ if (!this.drillUpButton) {
665
+ proceed.apply(this, Array.prototype.slice.call(arguments, 1));
666
+ }
667
+ });
668
+
646
669
 
647
670
  /**
648
671
  * When drilling up, keep the upper series invisible until the lower series has
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v6.0.1 (2017-10-05)
2
+ * @license Highcharts JS v6.0.2 (2017-10-20)
3
3
  * Exporting module
4
4
  *
5
5
  * (c) 2010-2017 Torstein Honsi
@@ -120,7 +120,11 @@
120
120
  // Add an event listener to handle the showTable option
121
121
  Highcharts.Chart.prototype.callbacks.push(function(chart) {
122
122
  Highcharts.addEvent(chart, 'render', function() {
123
- if (chart.options.exporting.showTable) {
123
+ if (
124
+ chart.options &&
125
+ chart.options.exporting &&
126
+ chart.options.exporting.showTable
127
+ ) {
124
128
  chart.viewData();
125
129
  }
126
130
  });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v6.0.1 (2017-10-05)
2
+ * @license Highcharts JS v6.0.2 (2017-10-20)
3
3
  * Exporting module
4
4
  *
5
5
  * (c) 2010-2017 Torstein Honsi
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v6.0.1 (2017-10-05)
2
+ * @license Highcharts JS v6.0.2 (2017-10-20)
3
3
  * Highcharts funnel module
4
4
  *
5
5
  * (c) 2010-2017 Torstein Honsi
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v6.0.1 (2017-10-05)
2
+ * @license Highcharts JS v6.0.2 (2017-10-20)
3
3
  * Gantt series
4
4
  *
5
5
  * (c) 2016 Lars A. V. Cabrera
@@ -583,7 +583,7 @@
583
583
  * @excluding boostThreshold,crisp,cropThreshold,depth,edgeColor,edgeWidth,
584
584
  * findNearestPointBy,getExtremesFromAll,grouping,groupPadding,
585
585
  * negativeColor,pointInterval,pointIntervalUnit,pointPlacement,
586
- * pointRange,pointStart,softThreshold,stacking,threshold
586
+ * pointRange,pointStart,softThreshold,stacking,threshold,data
587
587
  * @product highcharts
588
588
  * @sample {highcharts} highcharts/demo/x-range/
589
589
  * X-range
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v6.0.1 (2017-10-05)
2
+ * @license Highcharts JS v6.0.2 (2017-10-20)
3
3
  * GridAxis
4
4
  *
5
5
  * (c) 2016 Lars A. V. Cabrera
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v6.0.1 (2017-10-05)
2
+ * @license Highcharts JS v6.0.2 (2017-10-20)
3
3
  *
4
4
  * (c) 2009-2017 Torstein Honsi
5
5
  *
@@ -33,949 +33,954 @@
33
33
  pick = H.pick,
34
34
  wrap = H.wrap;
35
35
 
36
- /**
37
- * The ColorAxis object for inclusion in gradient legends
38
- */
39
- ColorAxis = H.ColorAxis = function() {
40
- this.init.apply(this, arguments);
41
- };
42
- extend(ColorAxis.prototype, Axis.prototype);
43
- extend(ColorAxis.prototype, {
36
+ // If ColorAxis already exists, we may be loading the heatmap module on top of
37
+ // Highmaps.
38
+ if (!H.ColorAxis) {
39
+
44
40
  /**
45
- * A color axis for choropleth maps and heat maps. Visually, the color axis
46
- * will appear as a gradient or as separate items inside the legend,
47
- * depending on whether the axis is scalar or based on data classes.
48
- *
49
- * For supported color formats, see the
50
- * [docs article about colors](http://www.highcharts.com/docs/chart-design-and-style/colors).
51
- *
52
- * A scalar color axis is represented by a gradient. The colors either range
53
- * between the [minColor](#colorAxis.minColor) and the [maxColor](#colorAxis.maxColor),
54
- * or for more fine grained control the colors can be
55
- * defined in [stops](#colorAxis.stops). Often times, the color axis needs
56
- * to be adjusted to get the right color spread for the data. In addition to
57
- * stops, consider using a logarithmic [axis type](#colorAxis.type), or
58
- * setting [min](#colorAxis.min) and [max](#colorAxis.max) to avoid the
59
- * colors being determined by outliers.
60
- *
61
- * When [dataClasses](#colorAxis.dataClasses) are used, the ranges are
62
- * subdivided into separate classes like categories based on their values.
63
- * This can be used for ranges between two values, but also for a true
64
- * category. However, when your data is categorized, it may be as convenient
65
- * to add each category to a separate series.
66
- *
67
- * See [the Axis object](#Axis) for programmatic access to the axis.
68
- * @extends {xAxis}
69
- * @excluding allowDecimals,alternateGridColor,breaks,categories,crosshair,
70
- * dateTimeLabelFormats,lineWidth,linkedTo,maxZoom,minRange,
71
- * minTickInterval,offset,opposite,plotBands,plotLines,showEmpty,
72
- * title
73
- * @product highcharts highmaps
74
- * @optionparent colorAxis
41
+ * The ColorAxis object for inclusion in gradient legends
75
42
  */
76
- defaultColorAxisOptions: {
77
-
43
+ ColorAxis = H.ColorAxis = function() {
44
+ this.init.apply(this, arguments);
45
+ };
46
+ extend(ColorAxis.prototype, Axis.prototype);
47
+ extend(ColorAxis.prototype, {
78
48
  /**
79
- * Whether to allow decimals on the color axis.
80
- * @type {Boolean}
81
- * @default true
49
+ * A color axis for choropleth maps and heat maps. Visually, the color axis
50
+ * will appear as a gradient or as separate items inside the legend,
51
+ * depending on whether the axis is scalar or based on data classes.
52
+ *
53
+ * For supported color formats, see the
54
+ * [docs article about colors](http://www.highcharts.com/docs/chart-design-and-style/colors).
55
+ *
56
+ * A scalar color axis is represented by a gradient. The colors either range
57
+ * between the [minColor](#colorAxis.minColor) and the [maxColor](#colorAxis.maxColor),
58
+ * or for more fine grained control the colors can be
59
+ * defined in [stops](#colorAxis.stops). Often times, the color axis needs
60
+ * to be adjusted to get the right color spread for the data. In addition to
61
+ * stops, consider using a logarithmic [axis type](#colorAxis.type), or
62
+ * setting [min](#colorAxis.min) and [max](#colorAxis.max) to avoid the
63
+ * colors being determined by outliers.
64
+ *
65
+ * When [dataClasses](#colorAxis.dataClasses) are used, the ranges are
66
+ * subdivided into separate classes like categories based on their values.
67
+ * This can be used for ranges between two values, but also for a true
68
+ * category. However, when your data is categorized, it may be as convenient
69
+ * to add each category to a separate series.
70
+ *
71
+ * See [the Axis object](#Axis) for programmatic access to the axis.
72
+ * @extends {xAxis}
73
+ * @excluding allowDecimals,alternateGridColor,breaks,categories,crosshair,
74
+ * dateTimeLabelFormats,lineWidth,linkedTo,maxZoom,minRange,
75
+ * minTickInterval,offset,opposite,plotBands,plotLines,showEmpty,
76
+ * title
82
77
  * @product highcharts highmaps
83
- * @apioption colorAxis.allowDecimals
78
+ * @optionparent colorAxis
84
79
  */
80
+ defaultColorAxisOptions: {
85
81
 
86
- /**
87
- * Determines how to set each data class' color if no individual color
88
- * is set. The default value, `tween`, computes intermediate colors
89
- * between `minColor` and `maxColor`. The other possible value, `category`,
90
- * pulls colors from the global or chart specific [colors](#colors)
91
- * array.
92
- *
93
- * @validvalue ["tween", "category"]
94
- * @type {String}
95
- * @sample {highmaps} maps/coloraxis/dataclasscolor/ Category colors
96
- * @default tween
97
- * @product highcharts highmaps
98
- * @apioption colorAxis.dataClassColor
99
- */
82
+ /**
83
+ * Whether to allow decimals on the color axis.
84
+ * @type {Boolean}
85
+ * @default true
86
+ * @product highcharts highmaps
87
+ * @apioption colorAxis.allowDecimals
88
+ */
100
89
 
101
- /**
102
- * An array of data classes or ranges for the choropleth map. If none
103
- * given, the color axis is scalar and values are distributed as a gradient
104
- * between the minimum and maximum colors.
105
- *
106
- * @type {Array<Object>}
107
- * @sample {highmaps} maps/demo/data-class-ranges/ Multiple ranges
108
- * @sample {highmaps} maps/demo/data-class-two-ranges/ Two ranges
109
- * @product highcharts highmaps
110
- * @apioption colorAxis.dataClasses
111
- */
90
+ /**
91
+ * Determines how to set each data class' color if no individual color
92
+ * is set. The default value, `tween`, computes intermediate colors
93
+ * between `minColor` and `maxColor`. The other possible value, `category`,
94
+ * pulls colors from the global or chart specific [colors](#colors)
95
+ * array.
96
+ *
97
+ * @validvalue ["tween", "category"]
98
+ * @type {String}
99
+ * @sample {highmaps} maps/coloraxis/dataclasscolor/ Category colors
100
+ * @default tween
101
+ * @product highcharts highmaps
102
+ * @apioption colorAxis.dataClassColor
103
+ */
112
104
 
113
- /**
114
- * The color of each data class. If not set, the color is pulled from
115
- * the global or chart-specific [colors](#colors) array. In
116
- * styled mode, this option is ignored. Instead, use colors defined in
117
- * CSS.
118
- *
119
- * @type {Color}
120
- * @sample {highmaps} maps/demo/data-class-two-ranges/ Explicit colors
121
- * @product highcharts highmaps
122
- * @apioption colorAxis.dataClasses.color
123
- */
105
+ /**
106
+ * An array of data classes or ranges for the choropleth map. If none
107
+ * given, the color axis is scalar and values are distributed as a gradient
108
+ * between the minimum and maximum colors.
109
+ *
110
+ * @type {Array<Object>}
111
+ * @sample {highmaps} maps/demo/data-class-ranges/ Multiple ranges
112
+ * @sample {highmaps} maps/demo/data-class-two-ranges/ Two ranges
113
+ * @product highcharts highmaps
114
+ * @apioption colorAxis.dataClasses
115
+ */
124
116
 
125
- /**
126
- * The start of the value range that the data class represents, relating
127
- * to the point value.
128
- *
129
- * @type {Number}
130
- * @product highcharts highmaps
131
- * @apioption colorAxis.dataClasses.from
132
- */
117
+ /**
118
+ * The color of each data class. If not set, the color is pulled from
119
+ * the global or chart-specific [colors](#colors) array. In
120
+ * styled mode, this option is ignored. Instead, use colors defined in
121
+ * CSS.
122
+ *
123
+ * @type {Color}
124
+ * @sample {highmaps} maps/demo/data-class-two-ranges/ Explicit colors
125
+ * @product highcharts highmaps
126
+ * @apioption colorAxis.dataClasses.color
127
+ */
133
128
 
134
- /**
135
- * The name of the data class as it appears in the legend. If no name
136
- * is given, it is automatically created based on the `from` and `to`
137
- * values. For full programmatic control, [legend.labelFormatter](#legend.
138
- * labelFormatter) can be used. In the formatter, `this.from` and `this.
139
- * to` can be accessed.
140
- *
141
- * @type {String}
142
- * @sample {highmaps} maps/coloraxis/dataclasses-name/ Named data classes
143
- * @sample {highmaps} maps/coloraxis/dataclasses-labelformatter/ Formatted data classes
144
- * @product highcharts highmaps
145
- * @apioption colorAxis.dataClasses.name
146
- */
129
+ /**
130
+ * The start of the value range that the data class represents, relating
131
+ * to the point value.
132
+ *
133
+ * @type {Number}
134
+ * @product highcharts highmaps
135
+ * @apioption colorAxis.dataClasses.from
136
+ */
147
137
 
148
- /**
149
- * The end of the value range that the data class represents, relating
150
- * to the point value.
151
- *
152
- * @type {Number}
153
- * @product highcharts highmaps
154
- * @apioption colorAxis.dataClasses.to
155
- */
138
+ /**
139
+ * The name of the data class as it appears in the legend. If no name
140
+ * is given, it is automatically created based on the `from` and `to`
141
+ * values. For full programmatic control, [legend.labelFormatter](#legend.
142
+ * labelFormatter) can be used. In the formatter, `this.from` and `this.
143
+ * to` can be accessed.
144
+ *
145
+ * @type {String}
146
+ * @sample {highmaps} maps/coloraxis/dataclasses-name/ Named data classes
147
+ * @sample {highmaps} maps/coloraxis/dataclasses-labelformatter/ Formatted data classes
148
+ * @product highcharts highmaps
149
+ * @apioption colorAxis.dataClasses.name
150
+ */
156
151
 
157
- /** @ignore */
158
- lineWidth: 0,
152
+ /**
153
+ * The end of the value range that the data class represents, relating
154
+ * to the point value.
155
+ *
156
+ * @type {Number}
157
+ * @product highcharts highmaps
158
+ * @apioption colorAxis.dataClasses.to
159
+ */
159
160
 
160
- /**
161
- * Padding of the min value relative to the length of the axis. A
162
- * padding of 0.05 will make a 100px axis 5px longer.
163
- *
164
- * @type {Number}
165
- * @product highcharts highmaps
166
- */
167
- minPadding: 0,
161
+ /** @ignore */
162
+ lineWidth: 0,
168
163
 
169
- /**
170
- * The maximum value of the axis in terms of map point values. If `null`,
171
- * the max value is automatically calculated. If the `endOnTick` option
172
- * is true, the max value might be rounded up.
173
- *
174
- * @type {Number}
175
- * @sample {highmaps} maps/coloraxis/gridlines/
176
- * Explicit min and max to reduce the effect of outliers
177
- * @product highcharts highmaps
178
- * @apioption colorAxis.max
179
- */
164
+ /**
165
+ * Padding of the min value relative to the length of the axis. A
166
+ * padding of 0.05 will make a 100px axis 5px longer.
167
+ *
168
+ * @type {Number}
169
+ * @product highcharts highmaps
170
+ */
171
+ minPadding: 0,
180
172
 
181
- /**
182
- * The minimum value of the axis in terms of map point values. If `null`,
183
- * the min value is automatically calculated. If the `startOnTick`
184
- * option is true, the min value might be rounded down.
185
- *
186
- * @type {Number}
187
- * @sample {highmaps} maps/coloraxis/gridlines/
188
- * Explicit min and max to reduce the effect of outliers
189
- * @product highcharts highmaps
190
- * @apioption colorAxis.min
191
- */
173
+ /**
174
+ * The maximum value of the axis in terms of map point values. If `null`,
175
+ * the max value is automatically calculated. If the `endOnTick` option
176
+ * is true, the max value might be rounded up.
177
+ *
178
+ * @type {Number}
179
+ * @sample {highmaps} maps/coloraxis/gridlines/
180
+ * Explicit min and max to reduce the effect of outliers
181
+ * @product highcharts highmaps
182
+ * @apioption colorAxis.max
183
+ */
192
184
 
193
- /**
194
- * Padding of the max value relative to the length of the axis. A
195
- * padding of 0.05 will make a 100px axis 5px longer.
196
- *
197
- * @type {Number}
198
- * @product highcharts highmaps
199
- */
200
- maxPadding: 0,
185
+ /**
186
+ * The minimum value of the axis in terms of map point values. If `null`,
187
+ * the min value is automatically calculated. If the `startOnTick`
188
+ * option is true, the min value might be rounded down.
189
+ *
190
+ * @type {Number}
191
+ * @sample {highmaps} maps/coloraxis/gridlines/
192
+ * Explicit min and max to reduce the effect of outliers
193
+ * @product highcharts highmaps
194
+ * @apioption colorAxis.min
195
+ */
201
196
 
202
- /**
203
- * Color of the grid lines extending from the axis across the gradient.
204
- *
205
- * @type {Color}
206
- * @sample {highmaps} maps/coloraxis/gridlines/ Grid lines demonstrated
207
- * @default #e6e6e6
208
- * @product highcharts highmaps
209
- * @apioption colorAxis.gridLineColor
210
- */
197
+ /**
198
+ * Padding of the max value relative to the length of the axis. A
199
+ * padding of 0.05 will make a 100px axis 5px longer.
200
+ *
201
+ * @type {Number}
202
+ * @product highcharts highmaps
203
+ */
204
+ maxPadding: 0,
211
205
 
212
- /**
213
- * The width of the grid lines extending from the axis across the
214
- * gradient of a scalar color axis.
215
- *
216
- * @type {Number}
217
- * @sample {highmaps} maps/coloraxis/gridlines/ Grid lines demonstrated
218
- * @default 1
219
- * @product highcharts highmaps
220
- */
221
- gridLineWidth: 1,
206
+ /**
207
+ * Color of the grid lines extending from the axis across the gradient.
208
+ *
209
+ * @type {Color}
210
+ * @sample {highmaps} maps/coloraxis/gridlines/ Grid lines demonstrated
211
+ * @default #e6e6e6
212
+ * @product highcharts highmaps
213
+ * @apioption colorAxis.gridLineColor
214
+ */
222
215
 
223
- /**
224
- * The interval of the tick marks in axis units. When `null`, the tick
225
- * interval is computed to approximately follow the `tickPixelInterval`.
226
- *
227
- * @type {Number}
228
- * @product highcharts highmaps
229
- * @apioption colorAxis.tickInterval
230
- */
216
+ /**
217
+ * The width of the grid lines extending from the axis across the
218
+ * gradient of a scalar color axis.
219
+ *
220
+ * @type {Number}
221
+ * @sample {highmaps} maps/coloraxis/gridlines/ Grid lines demonstrated
222
+ * @default 1
223
+ * @product highcharts highmaps
224
+ */
225
+ gridLineWidth: 1,
231
226
 
232
- /**
233
- * If [tickInterval](#colorAxis.tickInterval) is `null` this option
234
- * sets the approximate pixel interval of the tick marks.
235
- *
236
- * @type {Number}
237
- * @default 72
238
- * @product highcharts highmaps
239
- */
240
- tickPixelInterval: 72,
227
+ /**
228
+ * The interval of the tick marks in axis units. When `null`, the tick
229
+ * interval is computed to approximately follow the `tickPixelInterval`.
230
+ *
231
+ * @type {Number}
232
+ * @product highcharts highmaps
233
+ * @apioption colorAxis.tickInterval
234
+ */
241
235
 
242
- /**
243
- * Whether to force the axis to start on a tick. Use this option with
244
- * the `maxPadding` option to control the axis start.
245
- *
246
- * @type {Boolean}
247
- * @default true
248
- * @product highcharts highmaps
249
- */
250
- startOnTick: true,
236
+ /**
237
+ * If [tickInterval](#colorAxis.tickInterval) is `null` this option
238
+ * sets the approximate pixel interval of the tick marks.
239
+ *
240
+ * @type {Number}
241
+ * @default 72
242
+ * @product highcharts highmaps
243
+ */
244
+ tickPixelInterval: 72,
251
245
 
252
- /**
253
- * Whether to force the axis to end on a tick. Use this option with
254
- * the [maxPadding](#colorAxis.maxPadding) option to control the axis
255
- * end.
256
- *
257
- * @type {Boolean}
258
- * @default true
259
- * @product highcharts highmaps
260
- */
261
- endOnTick: true,
246
+ /**
247
+ * Whether to force the axis to start on a tick. Use this option with
248
+ * the `maxPadding` option to control the axis start.
249
+ *
250
+ * @type {Boolean}
251
+ * @default true
252
+ * @product highcharts highmaps
253
+ */
254
+ startOnTick: true,
262
255
 
263
- /** @ignore */
264
- offset: 0,
256
+ /**
257
+ * Whether to force the axis to end on a tick. Use this option with
258
+ * the [maxPadding](#colorAxis.maxPadding) option to control the axis
259
+ * end.
260
+ *
261
+ * @type {Boolean}
262
+ * @default true
263
+ * @product highcharts highmaps
264
+ */
265
+ endOnTick: true,
265
266
 
266
- /**
267
- * The triangular marker on a scalar color axis that points to the
268
- * value of the hovered area. To disable the marker, set `marker:
269
- * null`.
270
- *
271
- * @type {Object}
272
- * @sample {highmaps} maps/coloraxis/marker/ Black marker
273
- * @product highcharts highmaps
274
- */
275
- marker: {
267
+ /** @ignore */
268
+ offset: 0,
276
269
 
277
270
  /**
278
- * Animation for the marker as it moves between values. Set to `false`
279
- * to disable animation. Defaults to `{ duration: 50 }`.
271
+ * The triangular marker on a scalar color axis that points to the
272
+ * value of the hovered area. To disable the marker, set `marker:
273
+ * null`.
280
274
  *
281
- * @type {Object|Boolean}
275
+ * @type {Object}
276
+ * @sample {highmaps} maps/coloraxis/marker/ Black marker
282
277
  * @product highcharts highmaps
283
278
  */
284
- animation: {
285
- duration: 50
279
+ marker: {
280
+
281
+ /**
282
+ * Animation for the marker as it moves between values. Set to `false`
283
+ * to disable animation. Defaults to `{ duration: 50 }`.
284
+ *
285
+ * @type {Object|Boolean}
286
+ * @product highcharts highmaps
287
+ */
288
+ animation: {
289
+ duration: 50
290
+ },
291
+
292
+ /** @ignore */
293
+ width: 0.01,
294
+
295
+
296
+ /**
297
+ * The color of the marker.
298
+ *
299
+ * @type {Color}
300
+ * @default #999999
301
+ * @product highcharts highmaps
302
+ */
303
+ color: '#999999'
304
+
286
305
  },
287
306
 
288
- /** @ignore */
289
- width: 0.01,
307
+ /**
308
+ * The axis labels show the number for each tick.
309
+ *
310
+ * For more live examples on label options, see [xAxis.labels in the
311
+ * Highcharts API.](/highcharts#xAxis.labels)
312
+ *
313
+ * @type {Object}
314
+ * @extends xAxis.labels
315
+ * @product highcharts highmaps
316
+ */
317
+ labels: {
318
+
319
+ /**
320
+ * How to handle overflowing labels on horizontal color axis. Can be
321
+ * undefined or "justify". If "justify", labels will not render
322
+ * outside the legend area. If there is room to move it, it will be
323
+ * aligned to the edge, else it will be removed.
324
+ *
325
+ * @validvalue [null, "justify"]
326
+ * @type {String}
327
+ * @default justify
328
+ * @product highcharts highmaps
329
+ */
330
+ overflow: 'justify',
331
+
332
+ rotation: 0
333
+ },
290
334
 
335
+ /**
336
+ * The color to represent the minimum of the color axis. Unless [dataClasses](#colorAxis.
337
+ * dataClasses) or [stops](#colorAxis.stops) are set, the gradient
338
+ * starts at this value.
339
+ *
340
+ * If dataClasses are set, the color is based on minColor and maxColor
341
+ * unless a color is set for each data class, or the [dataClassColor](#colorAxis.
342
+ * dataClassColor) is set.
343
+ *
344
+ * @type {Color}
345
+ * @sample {highmaps} maps/coloraxis/mincolor-maxcolor/ Min and max colors on scalar (gradient) axis
346
+ * @sample {highmaps} maps/coloraxis/mincolor-maxcolor-dataclasses/ On data classes
347
+ * @default #e6ebf5
348
+ * @product highcharts highmaps
349
+ */
350
+ minColor: '#e6ebf5',
291
351
 
292
352
  /**
293
- * The color of the marker.
353
+ * The color to represent the maximum of the color axis. Unless [dataClasses](#colorAxis.
354
+ * dataClasses) or [stops](#colorAxis.stops) are set, the gradient
355
+ * ends at this value.
356
+ *
357
+ * If dataClasses are set, the color is based on minColor and maxColor
358
+ * unless a color is set for each data class, or the [dataClassColor](#colorAxis.
359
+ * dataClassColor) is set.
294
360
  *
295
361
  * @type {Color}
296
- * @default #999999
362
+ * @sample {highmaps} maps/coloraxis/mincolor-maxcolor/ Min and max colors on scalar (gradient) axis
363
+ * @sample {highmaps} maps/coloraxis/mincolor-maxcolor-dataclasses/ On data classes
364
+ * @default #003399
297
365
  * @product highcharts highmaps
298
366
  */
299
- color: '#999999'
367
+ maxColor: '#003399',
300
368
 
301
- },
369
+ /**
370
+ * Color stops for the gradient of a scalar color axis. Use this in
371
+ * cases where a linear gradient between a `minColor` and `maxColor`
372
+ * is not sufficient. The stops is an array of tuples, where the first
373
+ * item is a float between 0 and 1 assigning the relative position in
374
+ * the gradient, and the second item is the color.
375
+ *
376
+ * @type {Array<Array>}
377
+ * @sample {highmaps} maps/demo/heatmap/ Heatmap with three color stops
378
+ * @product highcharts highmaps
379
+ * @apioption colorAxis.stops
380
+ */
302
381
 
303
- /**
304
- * The axis labels show the number for each tick.
305
- *
306
- * For more live examples on label options, see [xAxis.labels in the
307
- * Highcharts API.](/highcharts#xAxis.labels)
308
- *
309
- * @type {Object}
310
- * @extends xAxis.labels
311
- * @product highcharts highmaps
312
- */
313
- labels: {
382
+ /**
383
+ * The pixel length of the main tick marks on the color axis.
384
+ */
385
+ tickLength: 5,
314
386
 
315
387
  /**
316
- * How to handle overflowing labels on horizontal color axis. Can be
317
- * undefined or "justify". If "justify", labels will not render
318
- * outside the legend area. If there is room to move it, it will be
319
- * aligned to the edge, else it will be removed.
388
+ * The type of interpolation to use for the color axis. Can be `linear`
389
+ * or `logarithmic`.
320
390
  *
321
- * @validvalue [null, "justify"]
391
+ * @validvalue ["linear", "logarithmic"]
322
392
  * @type {String}
323
- * @default justify
393
+ * @default linear
394
+ * @product highcharts highmaps
395
+ * @apioption colorAxis.type
396
+ */
397
+
398
+ /**
399
+ * Whether to reverse the axis so that the highest number is closest
400
+ * to the origin. Defaults to `false` in a horizontal legend and `true`
401
+ * in a vertical legend, where the smallest value starts on top.
402
+ *
403
+ * @type {Boolean}
324
404
  * @product highcharts highmaps
405
+ * @apioption colorAxis.reversed
325
406
  */
326
- overflow: 'justify',
327
407
 
328
- rotation: 0
408
+ /**
409
+ * Whether to display the colorAxis in the legend.
410
+ *
411
+ * @type {Boolean}
412
+ * @see [heatmap.showInLegend](#series.heatmap.showInLegend)
413
+ * @default true
414
+ * @since 4.2.7
415
+ * @product highcharts highmaps
416
+ */
417
+ showInLegend: true
329
418
  },
330
419
 
331
- /**
332
- * The color to represent the minimum of the color axis. Unless [dataClasses](#colorAxis.
333
- * dataClasses) or [stops](#colorAxis.stops) are set, the gradient
334
- * starts at this value.
335
- *
336
- * If dataClasses are set, the color is based on minColor and maxColor
337
- * unless a color is set for each data class, or the [dataClassColor](#colorAxis.
338
- * dataClassColor) is set.
339
- *
340
- * @type {Color}
341
- * @sample {highmaps} maps/coloraxis/mincolor-maxcolor/ Min and max colors on scalar (gradient) axis
342
- * @sample {highmaps} maps/coloraxis/mincolor-maxcolor-dataclasses/ On data classes
343
- * @default #e6ebf5
344
- * @product highcharts highmaps
345
- */
346
- minColor: '#e6ebf5',
420
+ // Properties to preserve after destroy, for Axis.update (#5881, #6025)
421
+ keepProps: [
422
+ 'legendGroup',
423
+ 'legendItemHeight',
424
+ 'legendItemWidth',
425
+ 'legendItem',
426
+ 'legendSymbol'
427
+ ].concat(Axis.prototype.keepProps),
347
428
 
348
429
  /**
349
- * The color to represent the maximum of the color axis. Unless [dataClasses](#colorAxis.
350
- * dataClasses) or [stops](#colorAxis.stops) are set, the gradient
351
- * ends at this value.
352
- *
353
- * If dataClasses are set, the color is based on minColor and maxColor
354
- * unless a color is set for each data class, or the [dataClassColor](#colorAxis.
355
- * dataClassColor) is set.
356
- *
357
- * @type {Color}
358
- * @sample {highmaps} maps/coloraxis/mincolor-maxcolor/ Min and max colors on scalar (gradient) axis
359
- * @sample {highmaps} maps/coloraxis/mincolor-maxcolor-dataclasses/ On data classes
360
- * @default #003399
361
- * @product highcharts highmaps
430
+ * Initialize the color axis
362
431
  */
363
- maxColor: '#003399',
432
+ init: function(chart, userOptions) {
433
+ var horiz = chart.options.legend.layout !== 'vertical',
434
+ options;
435
+
436
+ this.coll = 'colorAxis';
437
+
438
+ // Build the options
439
+ options = merge(this.defaultColorAxisOptions, {
440
+ side: horiz ? 2 : 1,
441
+ reversed: !horiz
442
+ }, userOptions, {
443
+ opposite: !horiz,
444
+ showEmpty: false,
445
+ title: null
446
+ });
364
447
 
365
- /**
366
- * Color stops for the gradient of a scalar color axis. Use this in
367
- * cases where a linear gradient between a `minColor` and `maxColor`
368
- * is not sufficient. The stops is an array of tuples, where the first
369
- * item is a float between 0 and 1 assigning the relative position in
370
- * the gradient, and the second item is the color.
371
- *
372
- * @type {Array<Array>}
373
- * @sample {highmaps} maps/demo/heatmap/ Heatmap with three color stops
374
- * @product highcharts highmaps
375
- * @apioption colorAxis.stops
376
- */
448
+ Axis.prototype.init.call(this, chart, options);
377
449
 
378
- /**
379
- * The pixel length of the main tick marks on the color axis.
380
- */
381
- tickLength: 5,
450
+ // Base init() pushes it to the xAxis array, now pop it again
451
+ // chart[this.isXAxis ? 'xAxis' : 'yAxis'].pop();
382
452
 
383
- /**
384
- * The type of interpolation to use for the color axis. Can be `linear`
385
- * or `logarithmic`.
386
- *
387
- * @validvalue ["linear", "logarithmic"]
388
- * @type {String}
389
- * @default linear
390
- * @product highcharts highmaps
391
- * @apioption colorAxis.type
392
- */
453
+ // Prepare data classes
454
+ if (userOptions.dataClasses) {
455
+ this.initDataClasses(userOptions);
456
+ }
457
+ this.initStops();
393
458
 
394
- /**
395
- * Whether to reverse the axis so that the highest number is closest
396
- * to the origin. Defaults to `false` in a horizontal legend and `true`
397
- * in a vertical legend, where the smallest value starts on top.
398
- *
399
- * @type {Boolean}
400
- * @product highcharts highmaps
401
- * @apioption colorAxis.reversed
402
- */
459
+ // Override original axis properties
460
+ this.horiz = horiz;
461
+ this.zoomEnabled = false;
403
462
 
404
- /**
405
- * Whether to display the colorAxis in the legend.
406
- *
407
- * @type {Boolean}
408
- * @see [heatmap.showInLegend](#series.heatmap.showInLegend)
409
- * @default true
410
- * @since 4.2.7
411
- * @product highcharts highmaps
412
- */
413
- showInLegend: true
414
- },
463
+ // Add default values
464
+ this.defaultLegendLength = 200;
465
+ },
415
466
 
416
- // Properties to preserve after destroy, for Axis.update (#5881, #6025)
417
- keepProps: [
418
- 'legendGroup',
419
- 'legendItemHeight',
420
- 'legendItemWidth',
421
- 'legendItem',
422
- 'legendSymbol'
423
- ].concat(Axis.prototype.keepProps),
467
+ initDataClasses: function(userOptions) {
468
+ var chart = this.chart,
469
+ dataClasses,
470
+ colorCounter = 0,
471
+ colorCount = chart.options.chart.colorCount,
472
+ options = this.options,
473
+ len = userOptions.dataClasses.length;
474
+ this.dataClasses = dataClasses = [];
475
+ this.legendItems = [];
424
476
 
425
- /**
426
- * Initialize the color axis
427
- */
428
- init: function(chart, userOptions) {
429
- var horiz = chart.options.legend.layout !== 'vertical',
430
- options;
431
-
432
- this.coll = 'colorAxis';
433
-
434
- // Build the options
435
- options = merge(this.defaultColorAxisOptions, {
436
- side: horiz ? 2 : 1,
437
- reversed: !horiz
438
- }, userOptions, {
439
- opposite: !horiz,
440
- showEmpty: false,
441
- title: null
442
- });
477
+ each(userOptions.dataClasses, function(dataClass, i) {
478
+ var colors;
443
479
 
444
- Axis.prototype.init.call(this, chart, options);
480
+ dataClass = merge(dataClass);
481
+ dataClasses.push(dataClass);
445
482
 
446
- // Base init() pushes it to the xAxis array, now pop it again
447
- // chart[this.isXAxis ? 'xAxis' : 'yAxis'].pop();
448
483
 
449
- // Prepare data classes
450
- if (userOptions.dataClasses) {
451
- this.initDataClasses(userOptions);
452
- }
453
- this.initStops();
484
+ if (dataClass.color) {
485
+ return;
486
+ }
454
487
 
455
- // Override original axis properties
456
- this.horiz = horiz;
457
- this.zoomEnabled = false;
488
+ if (options.dataClassColor === 'category') {
458
489
 
459
- // Add default values
460
- this.defaultLegendLength = 200;
461
- },
490
+ colors = chart.options.colors;
491
+ colorCount = colors.length;
492
+ dataClass.color = colors[colorCounter];
462
493
 
463
- initDataClasses: function(userOptions) {
464
- var chart = this.chart,
465
- dataClasses,
466
- colorCounter = 0,
467
- colorCount = chart.options.chart.colorCount,
468
- options = this.options,
469
- len = userOptions.dataClasses.length;
470
- this.dataClasses = dataClasses = [];
471
- this.legendItems = [];
494
+ dataClass.colorIndex = colorCounter;
472
495
 
473
- each(userOptions.dataClasses, function(dataClass, i) {
474
- var colors;
496
+ // increase and loop back to zero
497
+ colorCounter++;
498
+ if (colorCounter === colorCount) {
499
+ colorCounter = 0;
500
+ }
501
+ } else {
502
+ dataClass.color = color(options.minColor).tweenTo(
503
+ color(options.maxColor),
504
+ len < 2 ? 0.5 : i / (len - 1) // #3219
505
+ );
506
+ }
507
+ });
508
+ },
475
509
 
476
- dataClass = merge(dataClass);
477
- dataClasses.push(dataClass);
510
+ /**
511
+ * Override so that ticks are not added in data class axes (#6914)
512
+ */
513
+ setTickPositions: function() {
514
+ if (!this.dataClasses) {
515
+ return Axis.prototype.setTickPositions.call(this);
516
+ }
517
+ },
478
518
 
479
519
 
480
- if (dataClass.color) {
481
- return;
482
- }
520
+ initStops: function() {
521
+ this.stops = this.options.stops || [
522
+ [0, this.options.minColor],
523
+ [1, this.options.maxColor]
524
+ ];
525
+ each(this.stops, function(stop) {
526
+ stop.color = color(stop[1]);
527
+ });
528
+ },
483
529
 
484
- if (options.dataClassColor === 'category') {
530
+ /**
531
+ * Extend the setOptions method to process extreme colors and color
532
+ * stops.
533
+ */
534
+ setOptions: function(userOptions) {
535
+ Axis.prototype.setOptions.call(this, userOptions);
536
+
537
+ this.options.crosshair = this.options.marker;
538
+ },
485
539
 
486
- colors = chart.options.colors;
487
- colorCount = colors.length;
488
- dataClass.color = colors[colorCounter];
540
+ setAxisSize: function() {
541
+ var symbol = this.legendSymbol,
542
+ chart = this.chart,
543
+ legendOptions = chart.options.legend || {},
544
+ x,
545
+ y,
546
+ width,
547
+ height;
548
+
549
+ if (symbol) {
550
+ this.left = x = symbol.attr('x');
551
+ this.top = y = symbol.attr('y');
552
+ this.width = width = symbol.attr('width');
553
+ this.height = height = symbol.attr('height');
554
+ this.right = chart.chartWidth - x - width;
555
+ this.bottom = chart.chartHeight - y - height;
556
+
557
+ this.len = this.horiz ? width : height;
558
+ this.pos = this.horiz ? x : y;
559
+ } else {
560
+ // Fake length for disabled legend to avoid tick issues
561
+ // and such (#5205)
562
+ this.len = (
563
+ this.horiz ?
564
+ legendOptions.symbolWidth :
565
+ legendOptions.symbolHeight
566
+ ) || this.defaultLegendLength;
567
+ }
568
+ },
489
569
 
490
- dataClass.colorIndex = colorCounter;
570
+ normalizedValue: function(value) {
571
+ if (this.isLog) {
572
+ value = this.val2lin(value);
573
+ }
574
+ return 1 - ((this.max - value) / ((this.max - this.min) || 1));
575
+ },
491
576
 
492
- // increase and loop back to zero
493
- colorCounter++;
494
- if (colorCounter === colorCount) {
495
- colorCounter = 0;
577
+ /**
578
+ * Translate from a value to a color
579
+ */
580
+ toColor: function(value, point) {
581
+ var pos,
582
+ stops = this.stops,
583
+ from,
584
+ to,
585
+ color,
586
+ dataClasses = this.dataClasses,
587
+ dataClass,
588
+ i;
589
+
590
+ if (dataClasses) {
591
+ i = dataClasses.length;
592
+ while (i--) {
593
+ dataClass = dataClasses[i];
594
+ from = dataClass.from;
595
+ to = dataClass.to;
596
+ if (
597
+ (from === undefined || value >= from) &&
598
+ (to === undefined || value <= to)
599
+ ) {
600
+
601
+ color = dataClass.color;
602
+
603
+ if (point) {
604
+ point.dataClass = i;
605
+ point.colorIndex = dataClass.colorIndex;
606
+ }
607
+ break;
608
+ }
496
609
  }
610
+
497
611
  } else {
498
- dataClass.color = color(options.minColor).tweenTo(
499
- color(options.maxColor),
500
- len < 2 ? 0.5 : i / (len - 1) // #3219
612
+
613
+ pos = this.normalizedValue(value);
614
+ i = stops.length;
615
+ while (i--) {
616
+ if (pos > stops[i][0]) {
617
+ break;
618
+ }
619
+ }
620
+ from = stops[i] || stops[i + 1];
621
+ to = stops[i + 1] || from;
622
+
623
+ // The position within the gradient
624
+ pos = 1 - (to[0] - pos) / ((to[0] - from[0]) || 1);
625
+
626
+ color = from.color.tweenTo(
627
+ to.color,
628
+ pos
501
629
  );
502
630
  }
503
- });
504
- },
505
-
506
- /**
507
- * Override so that ticks are not added in data class axes (#6914)
508
- */
509
- setTickPositions: function() {
510
- if (!this.dataClasses) {
511
- return Axis.prototype.setTickPositions.call(this);
512
- }
513
- },
631
+ return color;
632
+ },
514
633
 
634
+ /**
635
+ * Override the getOffset method to add the whole axis groups inside
636
+ * the legend.
637
+ */
638
+ getOffset: function() {
639
+ var group = this.legendGroup,
640
+ sideOffset = this.chart.axisOffset[this.side];
515
641
 
516
- initStops: function() {
517
- this.stops = this.options.stops || [
518
- [0, this.options.minColor],
519
- [1, this.options.maxColor]
520
- ];
521
- each(this.stops, function(stop) {
522
- stop.color = color(stop[1]);
523
- });
524
- },
642
+ if (group) {
525
643
 
526
- /**
527
- * Extend the setOptions method to process extreme colors and color
528
- * stops.
529
- */
530
- setOptions: function(userOptions) {
531
- Axis.prototype.setOptions.call(this, userOptions);
644
+ // Hook for the getOffset method to add groups to this parent group
645
+ this.axisParent = group;
532
646
 
533
- this.options.crosshair = this.options.marker;
534
- },
647
+ // Call the base
648
+ Axis.prototype.getOffset.call(this);
535
649
 
536
- setAxisSize: function() {
537
- var symbol = this.legendSymbol,
538
- chart = this.chart,
539
- legendOptions = chart.options.legend || {},
540
- x,
541
- y,
542
- width,
543
- height;
544
-
545
- if (symbol) {
546
- this.left = x = symbol.attr('x');
547
- this.top = y = symbol.attr('y');
548
- this.width = width = symbol.attr('width');
549
- this.height = height = symbol.attr('height');
550
- this.right = chart.chartWidth - x - width;
551
- this.bottom = chart.chartHeight - y - height;
552
-
553
- this.len = this.horiz ? width : height;
554
- this.pos = this.horiz ? x : y;
555
- } else {
556
- // Fake length for disabled legend to avoid tick issues
557
- // and such (#5205)
558
- this.len = (
559
- this.horiz ?
560
- legendOptions.symbolWidth :
561
- legendOptions.symbolHeight
562
- ) || this.defaultLegendLength;
563
- }
564
- },
650
+ // First time only
651
+ if (!this.added) {
565
652
 
566
- normalizedValue: function(value) {
567
- if (this.isLog) {
568
- value = this.val2lin(value);
569
- }
570
- return 1 - ((this.max - value) / ((this.max - this.min) || 1));
571
- },
653
+ this.added = true;
572
654
 
573
- /**
574
- * Translate from a value to a color
575
- */
576
- toColor: function(value, point) {
577
- var pos,
578
- stops = this.stops,
579
- from,
580
- to,
581
- color,
582
- dataClasses = this.dataClasses,
583
- dataClass,
584
- i;
585
-
586
- if (dataClasses) {
587
- i = dataClasses.length;
588
- while (i--) {
589
- dataClass = dataClasses[i];
590
- from = dataClass.from;
591
- to = dataClass.to;
592
- if (
593
- (from === undefined || value >= from) &&
594
- (to === undefined || value <= to)
595
- ) {
596
-
597
- color = dataClass.color;
598
-
599
- if (point) {
600
- point.dataClass = i;
601
- point.colorIndex = dataClass.colorIndex;
602
- }
603
- break;
655
+ this.labelLeft = 0;
656
+ this.labelRight = this.width;
604
657
  }
658
+ // Reset it to avoid color axis reserving space
659
+ this.chart.axisOffset[this.side] = sideOffset;
605
660
  }
661
+ },
662
+
663
+ /**
664
+ * Create the color gradient
665
+ */
666
+ setLegendColor: function() {
667
+ var grad,
668
+ horiz = this.horiz,
669
+ reversed = this.reversed,
670
+ one = reversed ? 1 : 0,
671
+ zero = reversed ? 0 : 1;
672
+
673
+ grad = horiz ? [one, 0, zero, 0] : [0, zero, 0, one]; // #3190
674
+ this.legendColor = {
675
+ linearGradient: {
676
+ x1: grad[0],
677
+ y1: grad[1],
678
+ x2: grad[2],
679
+ y2: grad[3]
680
+ },
681
+ stops: this.stops
682
+ };
683
+ },
684
+
685
+ /**
686
+ * The color axis appears inside the legend and has its own legend symbol
687
+ */
688
+ drawLegendSymbol: function(legend, item) {
689
+ var padding = legend.padding,
690
+ legendOptions = legend.options,
691
+ horiz = this.horiz,
692
+ width = pick(
693
+ legendOptions.symbolWidth,
694
+ horiz ? this.defaultLegendLength : 12
695
+ ),
696
+ height = pick(
697
+ legendOptions.symbolHeight,
698
+ horiz ? 12 : this.defaultLegendLength
699
+ ),
700
+ labelPadding = pick(legendOptions.labelPadding, horiz ? 16 : 30),
701
+ itemDistance = pick(legendOptions.itemDistance, 10);
606
702
 
607
- } else {
703
+ this.setLegendColor();
608
704
 
609
- pos = this.normalizedValue(value);
610
- i = stops.length;
705
+ // Create the gradient
706
+ item.legendSymbol = this.chart.renderer.rect(
707
+ 0,
708
+ legend.baseline - 11,
709
+ width,
710
+ height
711
+ ).attr({
712
+ zIndex: 1
713
+ }).add(item.legendGroup);
714
+
715
+ // Set how much space this legend item takes up
716
+ this.legendItemWidth = width + padding +
717
+ (horiz ? itemDistance : labelPadding);
718
+ this.legendItemHeight = height + padding + (horiz ? labelPadding : 0);
719
+ },
720
+ /**
721
+ * Fool the legend
722
+ */
723
+ setState: noop,
724
+ visible: true,
725
+ setVisible: noop,
726
+ getSeriesExtremes: function() {
727
+ var series = this.series,
728
+ i = series.length;
729
+ this.dataMin = Infinity;
730
+ this.dataMax = -Infinity;
611
731
  while (i--) {
612
- if (pos > stops[i][0]) {
613
- break;
732
+ if (series[i].valueMin !== undefined) {
733
+ this.dataMin = Math.min(this.dataMin, series[i].valueMin);
734
+ this.dataMax = Math.max(this.dataMax, series[i].valueMax);
614
735
  }
615
736
  }
616
- from = stops[i] || stops[i + 1];
617
- to = stops[i + 1] || from;
737
+ },
738
+ drawCrosshair: function(e, point) {
739
+ var plotX = point && point.plotX,
740
+ plotY = point && point.plotY,
741
+ crossPos,
742
+ axisPos = this.pos,
743
+ axisLen = this.len;
744
+
745
+ if (point) {
746
+ crossPos = this.toPixels(point[point.series.colorKey]);
747
+ if (crossPos < axisPos) {
748
+ crossPos = axisPos - 2;
749
+ } else if (crossPos > axisPos + axisLen) {
750
+ crossPos = axisPos + axisLen + 2;
751
+ }
618
752
 
619
- // The position within the gradient
620
- pos = 1 - (to[0] - pos) / ((to[0] - from[0]) || 1);
753
+ point.plotX = crossPos;
754
+ point.plotY = this.len - crossPos;
755
+ Axis.prototype.drawCrosshair.call(this, e, point);
756
+ point.plotX = plotX;
757
+ point.plotY = plotY;
621
758
 
622
- color = from.color.tweenTo(
623
- to.color,
624
- pos
625
- );
626
- }
627
- return color;
628
- },
759
+ if (this.cross) {
760
+ this.cross
761
+ .addClass('highcharts-coloraxis-marker')
762
+ .add(this.legendGroup);
629
763
 
630
- /**
631
- * Override the getOffset method to add the whole axis groups inside
632
- * the legend.
633
- */
634
- getOffset: function() {
635
- var group = this.legendGroup,
636
- sideOffset = this.chart.axisOffset[this.side];
637
764
 
638
- if (group) {
765
+ this.cross.attr({
766
+ fill: this.crosshair.color
767
+ });
639
768
 
640
- // Hook for the getOffset method to add groups to this parent group
641
- this.axisParent = group;
642
769
 
643
- // Call the base
644
- Axis.prototype.getOffset.call(this);
770
+ }
771
+ }
772
+ },
773
+ getPlotLinePath: function(a, b, c, d, pos) {
774
+ // crosshairs only
775
+ return isNumber(pos) ? // pos can be 0 (#3969)
776
+ (
777
+ this.horiz ? [
778
+ 'M',
779
+ pos - 4, this.top - 6,
780
+ 'L',
781
+ pos + 4, this.top - 6,
782
+ pos, this.top,
783
+ 'Z'
784
+ ] : [
785
+ 'M',
786
+ this.left, pos,
787
+ 'L',
788
+ this.left - 6, pos + 6,
789
+ this.left - 6, pos - 6,
790
+ 'Z'
791
+ ]
792
+ ) :
793
+ Axis.prototype.getPlotLinePath.call(this, a, b, c, d);
794
+ },
645
795
 
646
- // First time only
647
- if (!this.added) {
796
+ update: function(newOptions, redraw) {
797
+ var chart = this.chart,
798
+ legend = chart.legend;
648
799
 
649
- this.added = true;
800
+ each(this.series, function(series) {
801
+ // Needed for Axis.update when choropleth colors change
802
+ series.isDirtyData = true;
803
+ });
650
804
 
651
- this.labelLeft = 0;
652
- this.labelRight = this.width;
805
+ // When updating data classes, destroy old items and make sure new ones
806
+ // are created (#3207)
807
+ if (newOptions.dataClasses && legend.allItems) {
808
+ each(legend.allItems, function(item) {
809
+ if (item.isDataClass && item.legendGroup) {
810
+ item.legendGroup.destroy();
811
+ }
812
+ });
813
+ chart.isDirtyLegend = true;
653
814
  }
654
- // Reset it to avoid color axis reserving space
655
- this.chart.axisOffset[this.side] = sideOffset;
656
- }
657
- },
658
815
 
659
- /**
660
- * Create the color gradient
661
- */
662
- setLegendColor: function() {
663
- var grad,
664
- horiz = this.horiz,
665
- reversed = this.reversed,
666
- one = reversed ? 1 : 0,
667
- zero = reversed ? 0 : 1;
668
-
669
- grad = horiz ? [one, 0, zero, 0] : [0, zero, 0, one]; // #3190
670
- this.legendColor = {
671
- linearGradient: {
672
- x1: grad[0],
673
- y1: grad[1],
674
- x2: grad[2],
675
- y2: grad[3]
676
- },
677
- stops: this.stops
678
- };
679
- },
816
+ // Keep the options structure updated for export. Unlike xAxis and
817
+ // yAxis, the colorAxis is not an array. (#3207)
818
+ chart.options[this.coll] = merge(this.userOptions, newOptions);
680
819
 
681
- /**
682
- * The color axis appears inside the legend and has its own legend symbol
683
- */
684
- drawLegendSymbol: function(legend, item) {
685
- var padding = legend.padding,
686
- legendOptions = legend.options,
687
- horiz = this.horiz,
688
- width = pick(
689
- legendOptions.symbolWidth,
690
- horiz ? this.defaultLegendLength : 12
691
- ),
692
- height = pick(
693
- legendOptions.symbolHeight,
694
- horiz ? 12 : this.defaultLegendLength
695
- ),
696
- labelPadding = pick(legendOptions.labelPadding, horiz ? 16 : 30),
697
- itemDistance = pick(legendOptions.itemDistance, 10);
698
-
699
- this.setLegendColor();
700
-
701
- // Create the gradient
702
- item.legendSymbol = this.chart.renderer.rect(
703
- 0,
704
- legend.baseline - 11,
705
- width,
706
- height
707
- ).attr({
708
- zIndex: 1
709
- }).add(item.legendGroup);
710
-
711
- // Set how much space this legend item takes up
712
- this.legendItemWidth = width + padding +
713
- (horiz ? itemDistance : labelPadding);
714
- this.legendItemHeight = height + padding + (horiz ? labelPadding : 0);
715
- },
716
- /**
717
- * Fool the legend
718
- */
719
- setState: noop,
720
- visible: true,
721
- setVisible: noop,
722
- getSeriesExtremes: function() {
723
- var series = this.series,
724
- i = series.length;
725
- this.dataMin = Infinity;
726
- this.dataMax = -Infinity;
727
- while (i--) {
728
- if (series[i].valueMin !== undefined) {
729
- this.dataMin = Math.min(this.dataMin, series[i].valueMin);
730
- this.dataMax = Math.max(this.dataMax, series[i].valueMax);
820
+ Axis.prototype.update.call(this, newOptions, redraw);
821
+ if (this.legendItem) {
822
+ this.setLegendColor();
823
+ legend.colorizeItem(this, true);
731
824
  }
732
- }
733
- },
734
- drawCrosshair: function(e, point) {
735
- var plotX = point && point.plotX,
736
- plotY = point && point.plotY,
737
- crossPos,
738
- axisPos = this.pos,
739
- axisLen = this.len;
740
-
741
- if (point) {
742
- crossPos = this.toPixels(point[point.series.colorKey]);
743
- if (crossPos < axisPos) {
744
- crossPos = axisPos - 2;
745
- } else if (crossPos > axisPos + axisLen) {
746
- crossPos = axisPos + axisLen + 2;
747
- }
748
-
749
- point.plotX = crossPos;
750
- point.plotY = this.len - crossPos;
751
- Axis.prototype.drawCrosshair.call(this, e, point);
752
- point.plotX = plotX;
753
- point.plotY = plotY;
825
+ },
754
826
 
755
- if (this.cross) {
756
- this.cross
757
- .addClass('highcharts-coloraxis-marker')
758
- .add(this.legendGroup);
827
+ /**
828
+ * Extend basic axis remove by also removing the legend item.
829
+ */
830
+ remove: function() {
831
+ if (this.legendItem) {
832
+ this.chart.legend.destroyItem(this);
833
+ }
834
+ Axis.prototype.remove.call(this);
835
+ },
759
836
 
837
+ /**
838
+ * Get the legend item symbols for data classes
839
+ */
840
+ getDataClassLegendSymbols: function() {
841
+ var axis = this,
842
+ chart = this.chart,
843
+ legendItems = this.legendItems,
844
+ legendOptions = chart.options.legend,
845
+ valueDecimals = legendOptions.valueDecimals,
846
+ valueSuffix = legendOptions.valueSuffix || '',
847
+ name;
848
+
849
+ if (!legendItems.length) {
850
+ each(this.dataClasses, function(dataClass, i) {
851
+ var vis = true,
852
+ from = dataClass.from,
853
+ to = dataClass.to;
854
+
855
+ // Assemble the default name. This can be overridden
856
+ // by legend.options.labelFormatter
857
+ name = '';
858
+ if (from === undefined) {
859
+ name = '< ';
860
+ } else if (to === undefined) {
861
+ name = '> ';
862
+ }
863
+ if (from !== undefined) {
864
+ name += H.numberFormat(from, valueDecimals) + valueSuffix;
865
+ }
866
+ if (from !== undefined && to !== undefined) {
867
+ name += ' - ';
868
+ }
869
+ if (to !== undefined) {
870
+ name += H.numberFormat(to, valueDecimals) + valueSuffix;
871
+ }
872
+ // Add a mock object to the legend items
873
+ legendItems.push(extend({
874
+ chart: chart,
875
+ name: name,
876
+ options: {},
877
+ drawLegendSymbol: LegendSymbolMixin.drawRectangle,
878
+ visible: true,
879
+ setState: noop,
880
+ isDataClass: true,
881
+ setVisible: function() {
882
+ vis = this.visible = !vis;
883
+ each(axis.series, function(series) {
884
+ each(series.points, function(point) {
885
+ if (point.dataClass === i) {
886
+ point.setVisible(vis);
887
+ }
888
+ });
889
+ });
760
890
 
761
- this.cross.attr({
762
- fill: this.crosshair.color
891
+ chart.legend.colorizeItem(this, vis);
892
+ }
893
+ }, dataClass));
763
894
  });
764
-
765
-
766
895
  }
767
- }
768
- },
769
- getPlotLinePath: function(a, b, c, d, pos) {
770
- // crosshairs only
771
- return isNumber(pos) ? // pos can be 0 (#3969)
772
- (
773
- this.horiz ? [
774
- 'M',
775
- pos - 4, this.top - 6,
776
- 'L',
777
- pos + 4, this.top - 6,
778
- pos, this.top,
779
- 'Z'
780
- ] : [
781
- 'M',
782
- this.left, pos,
783
- 'L',
784
- this.left - 6, pos + 6,
785
- this.left - 6, pos - 6,
786
- 'Z'
787
- ]
788
- ) :
789
- Axis.prototype.getPlotLinePath.call(this, a, b, c, d);
790
- },
896
+ return legendItems;
897
+ },
898
+ name: '' // Prevents 'undefined' in legend in IE8
899
+ });
791
900
 
792
- update: function(newOptions, redraw) {
793
- var chart = this.chart,
794
- legend = chart.legend;
901
+ /**
902
+ * Handle animation of the color attributes directly
903
+ */
904
+ each(['fill', 'stroke'], function(prop) {
905
+ H.Fx.prototype[prop + 'Setter'] = function() {
906
+ this.elem.attr(
907
+ prop,
908
+ color(this.start).tweenTo(
909
+ color(this.end),
910
+ this.pos
911
+ ),
912
+ null,
913
+ true
914
+ );
915
+ };
916
+ });
795
917
 
796
- each(this.series, function(series) {
797
- // Needed for Axis.update when choropleth colors change
798
- series.isDirtyData = true;
799
- });
918
+ /**
919
+ * Extend the chart getAxes method to also get the color axis
920
+ */
921
+ wrap(Chart.prototype, 'getAxes', function(proceed) {
800
922
 
801
- // When updating data classes, destroy old items and make sure new ones
802
- // are created (#3207)
803
- if (newOptions.dataClasses && legend.allItems) {
804
- each(legend.allItems, function(item) {
805
- if (item.isDataClass && item.legendGroup) {
806
- item.legendGroup.destroy();
807
- }
808
- });
809
- chart.isDirtyLegend = true;
810
- }
923
+ var options = this.options,
924
+ colorAxisOptions = options.colorAxis;
811
925
 
812
- // Keep the options structure updated for export. Unlike xAxis and
813
- // yAxis, the colorAxis is not an array. (#3207)
814
- chart.options[this.coll] = merge(this.userOptions, newOptions);
926
+ proceed.call(this);
815
927
 
816
- Axis.prototype.update.call(this, newOptions, redraw);
817
- if (this.legendItem) {
818
- this.setLegendColor();
819
- legend.colorizeItem(this, true);
928
+ this.colorAxis = [];
929
+ if (colorAxisOptions) {
930
+ new ColorAxis(this, colorAxisOptions); // eslint-disable-line no-new
820
931
  }
821
- },
932
+ });
822
933
 
823
- /**
824
- * Extend basic axis remove by also removing the legend item.
825
- */
826
- remove: function() {
827
- if (this.legendItem) {
828
- this.chart.legend.destroyItem(this);
829
- }
830
- Axis.prototype.remove.call(this);
831
- },
832
934
 
833
935
  /**
834
- * Get the legend item symbols for data classes
936
+ * Wrap the legend getAllItems method to add the color axis. This also removes
937
+ * the axis' own series to prevent them from showing up individually.
835
938
  */
836
- getDataClassLegendSymbols: function() {
837
- var axis = this,
838
- chart = this.chart,
839
- legendItems = this.legendItems,
840
- legendOptions = chart.options.legend,
841
- valueDecimals = legendOptions.valueDecimals,
842
- valueSuffix = legendOptions.valueSuffix || '',
843
- name;
844
-
845
- if (!legendItems.length) {
846
- each(this.dataClasses, function(dataClass, i) {
847
- var vis = true,
848
- from = dataClass.from,
849
- to = dataClass.to;
850
-
851
- // Assemble the default name. This can be overridden
852
- // by legend.options.labelFormatter
853
- name = '';
854
- if (from === undefined) {
855
- name = '< ';
856
- } else if (to === undefined) {
857
- name = '> ';
858
- }
859
- if (from !== undefined) {
860
- name += H.numberFormat(from, valueDecimals) + valueSuffix;
939
+ wrap(Legend.prototype, 'getAllItems', function(proceed) {
940
+ var allItems = [],
941
+ colorAxis = this.chart.colorAxis[0];
942
+
943
+ if (colorAxis && colorAxis.options) {
944
+ if (colorAxis.options.showInLegend) {
945
+ // Data classes
946
+ if (colorAxis.options.dataClasses) {
947
+ allItems = allItems.concat(
948
+ colorAxis.getDataClassLegendSymbols()
949
+ );
950
+ // Gradient legend
951
+ } else {
952
+ // Add this axis on top
953
+ allItems.push(colorAxis);
861
954
  }
862
- if (from !== undefined && to !== undefined) {
863
- name += ' - ';
864
- }
865
- if (to !== undefined) {
866
- name += H.numberFormat(to, valueDecimals) + valueSuffix;
867
- }
868
- // Add a mock object to the legend items
869
- legendItems.push(extend({
870
- chart: chart,
871
- name: name,
872
- options: {},
873
- drawLegendSymbol: LegendSymbolMixin.drawRectangle,
874
- visible: true,
875
- setState: noop,
876
- isDataClass: true,
877
- setVisible: function() {
878
- vis = this.visible = !vis;
879
- each(axis.series, function(series) {
880
- each(series.points, function(point) {
881
- if (point.dataClass === i) {
882
- point.setVisible(vis);
883
- }
884
- });
885
- });
955
+ }
886
956
 
887
- chart.legend.colorizeItem(this, vis);
888
- }
889
- }, dataClass));
957
+ // Don't add the color axis' series
958
+ each(colorAxis.series, function(series) {
959
+ series.options.showInLegend = false;
890
960
  });
891
961
  }
892
- return legendItems;
893
- },
894
- name: '' // Prevents 'undefined' in legend in IE8
895
- });
896
-
897
- /**
898
- * Handle animation of the color attributes directly
899
- */
900
- each(['fill', 'stroke'], function(prop) {
901
- H.Fx.prototype[prop + 'Setter'] = function() {
902
- this.elem.attr(
903
- prop,
904
- color(this.start).tweenTo(
905
- color(this.end),
906
- this.pos
907
- ),
908
- null,
909
- true
910
- );
911
- };
912
- });
913
-
914
- /**
915
- * Extend the chart getAxes method to also get the color axis
916
- */
917
- wrap(Chart.prototype, 'getAxes', function(proceed) {
918
-
919
- var options = this.options,
920
- colorAxisOptions = options.colorAxis;
921
-
922
- proceed.call(this);
923
-
924
- this.colorAxis = [];
925
- if (colorAxisOptions) {
926
- new ColorAxis(this, colorAxisOptions); // eslint-disable-line no-new
927
- }
928
- });
929
962
 
963
+ return allItems.concat(proceed.call(this));
964
+ });
930
965
 
931
- /**
932
- * Wrap the legend getAllItems method to add the color axis. This also removes
933
- * the axis' own series to prevent them from showing up individually.
934
- */
935
- wrap(Legend.prototype, 'getAllItems', function(proceed) {
936
- var allItems = [],
937
- colorAxis = this.chart.colorAxis[0];
938
-
939
- if (colorAxis && colorAxis.options) {
940
- if (colorAxis.options.showInLegend) {
941
- // Data classes
942
- if (colorAxis.options.dataClasses) {
943
- allItems = allItems.concat(
944
- colorAxis.getDataClassLegendSymbols()
945
- );
946
- // Gradient legend
947
- } else {
948
- // Add this axis on top
949
- allItems.push(colorAxis);
950
- }
966
+ wrap(Legend.prototype, 'colorizeItem', function(proceed, item, visible) {
967
+ proceed.call(this, item, visible);
968
+ if (visible && item.legendColor) {
969
+ item.legendSymbol.attr({
970
+ fill: item.legendColor
971
+ });
951
972
  }
973
+ });
952
974
 
953
- // Don't add the color axis' series
954
- each(colorAxis.series, function(series) {
955
- series.options.showInLegend = false;
956
- });
957
- }
958
-
959
- return allItems.concat(proceed.call(this));
960
- });
961
-
962
- wrap(Legend.prototype, 'colorizeItem', function(proceed, item, visible) {
963
- proceed.call(this, item, visible);
964
- if (visible && item.legendColor) {
965
- item.legendSymbol.attr({
966
- fill: item.legendColor
967
- });
968
- }
969
- });
975
+ // Updates in the legend need to be reflected in the color axis (6888)
976
+ wrap(Legend.prototype, 'update', function(proceed) {
977
+ proceed.apply(this, [].slice.call(arguments, 1));
970
978
 
971
- // Updates in the legend need to be reflected in the color axis (6888)
972
- wrap(Legend.prototype, 'update', function(proceed) {
973
- proceed.apply(this, [].slice.call(arguments, 1));
974
-
975
- if (this.chart.colorAxis[0]) {
976
- this.chart.colorAxis[0].update({}, arguments[2]);
977
- }
978
- });
979
+ if (this.chart.colorAxis[0]) {
980
+ this.chart.colorAxis[0].update({}, arguments[2]);
981
+ }
982
+ });
983
+ }
979
984
 
980
985
  }(Highcharts));
981
986
  (function(H) {
@@ -1409,18 +1414,19 @@
1409
1414
  */
1410
1415
 
1411
1416
  /**
1412
- * The x coordinate of the point.
1417
+ * The x value of the point. For datetime axes,
1418
+ * the X value is the timestamp in milliseconds since 1970.
1413
1419
  *
1414
1420
  * @type {Number}
1415
- * @product highmaps
1421
+ * @product highcharts highmaps
1416
1422
  * @apioption series.heatmap.data.x
1417
1423
  */
1418
1424
 
1419
1425
  /**
1420
- * The y coordinate of the point.
1426
+ * The y value of the point.
1421
1427
  *
1422
1428
  * @type {Number}
1423
- * @product highmaps
1429
+ * @product highcharts highmaps
1424
1430
  * @apioption series.heatmap.data.y
1425
1431
  */
1426
1432