highcharts-rails 6.0.1 → 6.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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