highcharts-rails 5.0.10 → 5.0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (25) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.markdown +48 -0
  3. data/app/assets/javascripts/highcharts.js +2395 -1517
  4. data/app/assets/javascripts/highcharts/highcharts-3d.js +212 -116
  5. data/app/assets/javascripts/highcharts/highcharts-more.js +17 -11
  6. data/app/assets/javascripts/highcharts/modules/accessibility.js +29 -16
  7. data/app/assets/javascripts/highcharts/modules/annotations.js +3 -4
  8. data/app/assets/javascripts/highcharts/modules/boost.js +392 -356
  9. data/app/assets/javascripts/highcharts/modules/broken-axis.js +42 -17
  10. data/app/assets/javascripts/highcharts/modules/data.js +6 -6
  11. data/app/assets/javascripts/highcharts/modules/drilldown.js +54 -27
  12. data/app/assets/javascripts/highcharts/modules/exporting.js +125 -102
  13. data/app/assets/javascripts/highcharts/modules/funnel.js +17 -9
  14. data/app/assets/javascripts/highcharts/modules/grid-axis.js +1 -1
  15. data/app/assets/javascripts/highcharts/modules/heatmap.js +12 -2
  16. data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +1 -1
  17. data/app/assets/javascripts/highcharts/modules/offline-exporting.js +12 -4
  18. data/app/assets/javascripts/highcharts/modules/overlapping-datalabels.js +1 -1
  19. data/app/assets/javascripts/highcharts/modules/series-label.js +1 -1
  20. data/app/assets/javascripts/highcharts/modules/solid-gauge.js +2 -2
  21. data/app/assets/javascripts/highcharts/modules/stock.js +182 -101
  22. data/app/assets/javascripts/highcharts/modules/treemap.js +4 -7
  23. data/app/assets/javascripts/highcharts/modules/xrange-series.js +1 -1
  24. data/lib/highcharts/version.rb +1 -1
  25. metadata +1 -1
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  * Highcharts funnel module
4
4
  *
5
5
  * (c) 2010-2017 Torstein Honsi
@@ -28,6 +28,7 @@
28
28
  var seriesType = Highcharts.seriesType,
29
29
  seriesTypes = Highcharts.seriesTypes,
30
30
  noop = Highcharts.noop,
31
+ pick = Highcharts.pick,
31
32
  each = Highcharts.each;
32
33
 
33
34
 
@@ -115,8 +116,8 @@
115
116
  neckWidth :
116
117
  neckWidth + (width - neckWidth) * (1 - (y - top) / (height - neckHeight));
117
118
  };
118
- series.getX = function(y, half) {
119
- return centerX + (half ? -1 : 1) * ((getWidthAt(reversed ? 2 * centerY - y : y) / 2) + options.dataLabels.distance);
119
+ series.getX = function(y, half, point) {
120
+ return centerX + (half ? -1 : 1) * ((getWidthAt(reversed ? 2 * centerY - y : y) / 2) + point.labelDistance);
120
121
  };
121
122
 
122
123
  // Expose
@@ -250,8 +251,9 @@
250
251
  * Extend the pie data label method
251
252
  */
252
253
  drawDataLabels: function() {
253
- var data = this.data,
254
- labelDistance = this.options.dataLabels.distance,
254
+ var series = this,
255
+ data = series.data,
256
+ labelDistance = series.options.dataLabels.distance,
255
257
  leftSide,
256
258
  sign,
257
259
  point,
@@ -262,7 +264,7 @@
262
264
  // In the original pie label anticollision logic, the slots are distributed
263
265
  // from one labelDistance above to one labelDistance below the pie. In funnels
264
266
  // we don't want this.
265
- this.center[2] -= 2 * labelDistance;
267
+ series.center[2] -= 2 * labelDistance;
266
268
 
267
269
  // Set the label position array for each point.
268
270
  while (i--) {
@@ -270,15 +272,21 @@
270
272
  leftSide = point.half;
271
273
  sign = leftSide ? 1 : -1;
272
274
  y = point.plotY;
273
- x = this.getX(y, leftSide);
275
+ point.labelDistance = pick(
276
+ point.options.dataLabels && point.options.dataLabels.distance,
277
+ labelDistance
278
+ );
279
+
280
+ series.maxLabelDistance = Math.max(point.labelDistance, series.maxLabelDistance || 0);
281
+ x = series.getX(y, leftSide, point);
274
282
 
275
283
  // set the anchor point for data labels
276
284
  point.labelPos = [
277
285
  0, // first break of connector
278
286
  y, // a/a
279
- x + (labelDistance - 5) * sign, // second break, right outside point shape
287
+ x + (point.labelDistance - 5) * sign, // second break, right outside point shape
280
288
  y, // a/a
281
- x + labelDistance * sign, // landing point for connector
289
+ x + point.labelDistance * sign, // landing point for connector
282
290
  y, // a/a
283
291
  leftSide ? 'right' : 'left', // alignment
284
292
  0 // center angle
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  * GridAxis
4
4
  *
5
5
  * (c) 2016 Lars A. V. Cabrera
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  *
4
4
  * (c) 2009-2017 Torstein Honsi
5
5
  *
@@ -440,7 +440,7 @@
440
440
  // When updating data classes, destroy old items and make sure new ones are created (#3207)
441
441
  if (newOptions.dataClasses && legend.allItems) {
442
442
  each(legend.allItems, function(item) {
443
- if (item.isDataClass) {
443
+ if (item.isDataClass && item.legendGroup) {
444
444
  item.legendGroup.destroy();
445
445
  }
446
446
  });
@@ -458,6 +458,16 @@
458
458
  }
459
459
  },
460
460
 
461
+ /**
462
+ * Extend basic axis remove by also removing the legend item.
463
+ */
464
+ remove: function() {
465
+ if (this.legendItem) {
466
+ this.chart.legend.destroyItem(this);
467
+ }
468
+ Axis.prototype.remove.call(this);
469
+ },
470
+
461
471
  /**
462
472
  * Get the legend item symbols for data classes
463
473
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  * Plugin for displaying a message when there is no data visible in chart.
4
4
  *
5
5
  * (c) 2010-2017 Highsoft AS
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  * Client side exporting module
4
4
  *
5
5
  * (c) 2015 Torstein Honsi / Oystein Moseng
@@ -109,7 +109,6 @@
109
109
  if (a.download !== undefined) {
110
110
  a.href = dataURL;
111
111
  a.download = filename; // HTML5 download attribute
112
- a.target = '_blank';
113
112
  doc.body.appendChild(a);
114
113
  a.click();
115
114
  doc.body.removeChild(a);
@@ -443,7 +442,16 @@
443
442
  };
444
443
 
445
444
  /**
446
- * Add a new method to the Chart object to perform a local download
445
+ * Exporting and offline-exporting modules required. Export a chart to an image
446
+ * locally in the user's browser.
447
+ *
448
+ * @param {Object} exportingOptions
449
+ * Exporting options, the same as in {@link
450
+ * Highcharts.Chart#exportChart}.
451
+ * @param {Options} chartOptions
452
+ * Additional chart options for the exported chart. For example a
453
+ * different background color can be added here, or `dataLabels`
454
+ * for export only.
447
455
  */
448
456
  Highcharts.Chart.prototype.exportChartLocal = function(exportingOptions, chartOptions) {
449
457
  var chart = this,
@@ -500,7 +508,7 @@
500
508
 
501
509
  // Extend the default options to use the local exporter logic
502
510
  merge(true, Highcharts.getOptions().exporting, {
503
- libURL: 'https://code.highcharts.com/5.0.10/lib/',
511
+ libURL: 'https://code.highcharts.com/5.0.11/lib/',
504
512
  buttons: {
505
513
  contextButton: {
506
514
  menuItems: [{
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  *
4
4
  * (c) 2009-2017 Torstein Honsi
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  *
4
4
  * (c) 2009-2017 Torstein Honsi
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  * Solid angular gauge module
4
4
  *
5
5
  * (c) 2010-2017 Torstein Honsi
@@ -313,7 +313,7 @@
313
313
  }
314
314
  } else {
315
315
  point.graphic = renderer.arc(shapeArgs)
316
- .addClass('highcharts-point')
316
+ .addClass(point.getClassName(), true)
317
317
  .attr({
318
318
  fill: toColor,
319
319
  'sweep-flag': 0
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.10 (2017-03-31)
2
+ * @license Highcharts JS v5.0.11 (2017-05-04)
3
3
  * Highstock as a plugin for Highcharts
4
4
  *
5
5
  * (c) 2017 Torstein Honsi
@@ -687,37 +687,6 @@
687
687
  }
688
688
  });
689
689
 
690
-
691
-
692
- /**
693
- * Extend getGraphPath by identifying gaps in the ordinal data so that we can draw a gap in the
694
- * line or area
695
- */
696
- Series.prototype.gappedPath = function() {
697
- var gapSize = this.options.gapSize,
698
- points = this.points.slice(),
699
- i = points.length - 1;
700
-
701
- if (gapSize && i > 0) { // #5008
702
-
703
- // extension for ordinal breaks
704
- while (i--) {
705
- if (points[i + 1].x - points[i].x > this.closestPointRange * gapSize) {
706
- points.splice( // insert after this one
707
- i + 1,
708
- 0, {
709
- isNull: true
710
- }
711
- );
712
- }
713
- }
714
- }
715
-
716
- // Call base method
717
- //return proceed.call(this, points, a, b);
718
- return this.getGraphPath(points);
719
- };
720
-
721
690
  /* ****************************************************************************
722
691
  * End ordinal axis logic *
723
692
  *****************************************************************************/
@@ -879,17 +848,14 @@
879
848
  length = 0,
880
849
  inBrk,
881
850
  repeat,
882
- brk,
883
851
  min = axis.userMin || axis.min,
884
852
  max = axis.userMax || axis.max,
885
853
  pointRangePadding = pick(axis.pointRangePadding, 0),
886
854
  start,
887
- i,
888
- j;
855
+ i;
889
856
 
890
857
  // Min & max check (#4247)
891
- for (i in breaks) {
892
- brk = breaks[i];
858
+ each(breaks, function(brk) {
893
859
  repeat = brk.repeat || Infinity;
894
860
  if (axis.isInBreak(brk, min)) {
895
861
  min += (brk.to % repeat) - (min % repeat);
@@ -897,11 +863,10 @@
897
863
  if (axis.isInBreak(brk, max)) {
898
864
  max -= (max % repeat) - (brk.from % repeat);
899
865
  }
900
- }
866
+ });
901
867
 
902
868
  // Construct an array holding all breaks in the axis
903
- for (i in breaks) {
904
- brk = breaks[i];
869
+ each(breaks, function(brk) {
905
870
  start = brk.from;
906
871
  repeat = brk.repeat || Infinity;
907
872
 
@@ -912,18 +877,18 @@
912
877
  start += repeat;
913
878
  }
914
879
 
915
- for (j = start; j < max; j += repeat) {
880
+ for (i = start; i < max; i += repeat) {
916
881
  breakArrayT.push({
917
- value: j,
882
+ value: i,
918
883
  move: 'in'
919
884
  });
920
885
  breakArrayT.push({
921
- value: j + (brk.to - brk.from),
886
+ value: i + (brk.to - brk.from),
922
887
  move: 'out',
923
888
  size: brk.breakSize
924
889
  });
925
890
  }
926
- }
891
+ });
927
892
 
928
893
  breakArrayT.sort(function(a, b) {
929
894
  var ret;
@@ -939,8 +904,7 @@
939
904
  inBrk = 0;
940
905
  start = min;
941
906
 
942
- for (i in breakArrayT) {
943
- brk = breakArrayT[i];
907
+ each(breakArrayT, function(brk) {
944
908
  inBrk += (brk.move === 'in' ? 1 : -1);
945
909
 
946
910
  if (inBrk === 1 && brk.move === 'in') {
@@ -954,7 +918,7 @@
954
918
  });
955
919
  length += brk.value - start - (brk.size || 0);
956
920
  }
957
- }
921
+ });
958
922
 
959
923
  axis.breakArray = breakArray;
960
924
 
@@ -966,7 +930,7 @@
966
930
 
967
931
  if (axis.options.staticScale) {
968
932
  axis.transA = axis.options.staticScale;
969
- } else {
933
+ } else if (axis.unitLength) {
970
934
  axis.transA *= (max - axis.min + pointRangePadding) /
971
935
  axis.unitLength;
972
936
  }
@@ -1053,6 +1017,36 @@
1053
1017
  });
1054
1018
  };
1055
1019
 
1020
+
1021
+ /**
1022
+ * Extend getGraphPath by identifying gaps in the data so that we can draw a gap
1023
+ * in the line or area. This was moved from ordinal axis module to broken axis
1024
+ * module as of #5045.
1025
+ */
1026
+ H.Series.prototype.gappedPath = function() {
1027
+ var gapSize = this.options.gapSize,
1028
+ points = this.points.slice(),
1029
+ i = points.length - 1;
1030
+
1031
+ if (gapSize && i > 0) { // #5008
1032
+
1033
+ // extension for ordinal breaks
1034
+ while (i--) {
1035
+ if (points[i + 1].x - points[i].x > this.closestPointRange * gapSize) {
1036
+ points.splice( // insert after this one
1037
+ i + 1,
1038
+ 0, {
1039
+ isNull: true
1040
+ }
1041
+ );
1042
+ }
1043
+ }
1044
+ }
1045
+
1046
+ // Call base method
1047
+ return this.getGraphPath(points);
1048
+ };
1049
+
1056
1050
  wrap(H.seriesTypes.column.prototype, 'drawPoints', drawPointsWrapped);
1057
1051
  wrap(H.Series.prototype, 'drawPoints', drawPointsWrapped);
1058
1052
 
@@ -1173,9 +1167,10 @@
1173
1167
 
1174
1168
 
1175
1169
  /**
1176
- * Define the available approximation types. The data grouping approximations takes an array
1177
- * or numbers as the first parameter. In case of ohlc, four arrays are sent in as four parameters.
1178
- * Each array consists only of numbers. In case null values belong to the group, the property
1170
+ * Define the available approximation types. The data grouping
1171
+ * approximations takes an array or numbers as the first parameter. In case
1172
+ * of ohlc, four arrays are sent in as four parameters. Each array consists
1173
+ * only of numbers. In case null values belong to the group, the property
1179
1174
  * .hasNulls will be set to true on the array.
1180
1175
  */
1181
1176
  approximations = {
@@ -1202,14 +1197,25 @@
1202
1197
  var len = arr.length,
1203
1198
  ret = approximations.sum(arr);
1204
1199
 
1205
- // If we have a number, return it divided by the length. If not, return
1206
- // null or undefined based on what the sum method finds.
1200
+ // If we have a number, return it divided by the length. If not,
1201
+ // return null or undefined based on what the sum method finds.
1207
1202
  if (isNumber(ret) && len) {
1208
1203
  ret = ret / len;
1209
1204
  }
1210
1205
 
1211
1206
  return ret;
1212
1207
  },
1208
+ // The same as average, but for series with multiple values, like area
1209
+ // ranges.
1210
+ averages: function() { // #5479
1211
+ var ret = [];
1212
+
1213
+ each(arguments, function(arr) {
1214
+ ret.push(approximations.average(arr));
1215
+ });
1216
+
1217
+ return ret;
1218
+ },
1213
1219
  open: function(arr) {
1214
1220
  return arr.length ? arr[0] : (arr.hasNulls ? null : undefined);
1215
1221
  },
@@ -1247,8 +1253,8 @@
1247
1253
 
1248
1254
 
1249
1255
  /**
1250
- * Takes parallel arrays of x and y data and groups the data into intervals defined by groupPositions, a collection
1251
- * of starting x values for each group.
1256
+ * Takes parallel arrays of x and y data and groups the data into intervals
1257
+ * defined by groupPositions, a collection of starting x values for each group.
1252
1258
  */
1253
1259
  seriesProto.groupData = function(xData, yData, groupPositions, approximation) {
1254
1260
  var series = this,
@@ -1261,19 +1267,35 @@
1261
1267
  pointX,
1262
1268
  pointY,
1263
1269
  groupedY,
1264
- handleYData = !!yData, // when grouping the fake extended axis for panning, we don't need to consider y
1265
- values = [
1266
- [],
1267
- [],
1268
- [],
1269
- []
1270
- ],
1271
- approximationFn = typeof approximation === 'function' ? approximation : approximations[approximation],
1270
+ // when grouping the fake extended axis for panning,
1271
+ // we don't need to consider y
1272
+ handleYData = !!yData,
1273
+ values = [],
1274
+ approximationFn = typeof approximation === 'function' ?
1275
+ approximation :
1276
+ approximations[approximation] ||
1277
+ // if the approximation is not found use default series type
1278
+ // approximation (#2914)
1279
+ (
1280
+ specificOptions[series.type] &&
1281
+ approximations[specificOptions[series.type].approximation]
1282
+ ) || approximations[commonOptions.approximation],
1272
1283
  pointArrayMap = series.pointArrayMap,
1273
1284
  pointArrayMapLength = pointArrayMap && pointArrayMap.length,
1274
- i,
1275
1285
  pos = 0,
1276
- start = 0;
1286
+ start = 0,
1287
+ valuesLen,
1288
+ i, j;
1289
+
1290
+ // Calculate values array size from pointArrayMap length
1291
+ if (pointArrayMapLength) {
1292
+ each(pointArrayMap, function() {
1293
+ values.push([]);
1294
+ });
1295
+ } else {
1296
+ values.push([]);
1297
+ }
1298
+ valuesLen = pointArrayMapLength || 1;
1277
1299
 
1278
1300
  // Start with the first point within the X axis range (#2696)
1279
1301
  for (i = 0; i <= dataLength; i++) {
@@ -1284,9 +1306,12 @@
1284
1306
 
1285
1307
  for (i; i <= dataLength; i++) {
1286
1308
 
1287
- // when a new group is entered, summarize and initiate the previous group
1288
- while ((groupPositions[pos + 1] !== undefined && xData[i] >= groupPositions[pos + 1]) ||
1289
- i === dataLength) { // get the last group
1309
+ // when a new group is entered, summarize and initiate
1310
+ // the previous group
1311
+ while ((
1312
+ groupPositions[pos + 1] !== undefined &&
1313
+ xData[i] >= groupPositions[pos + 1]
1314
+ ) || i === dataLength) { // get the last group
1290
1315
 
1291
1316
  // get group x and y
1292
1317
  pointX = groupPositions[pos];
@@ -1305,10 +1330,10 @@
1305
1330
 
1306
1331
  // reset the aggregate arrays
1307
1332
  start = i;
1308
- values[0] = [];
1309
- values[1] = [];
1310
- values[2] = [];
1311
- values[3] = [];
1333
+ for (j = 0; j < valuesLen; j++) {
1334
+ values[j].length = 0; // faster than values[j] = []
1335
+ values[j].hasNulls = false;
1336
+ }
1312
1337
 
1313
1338
  // Advance on the group positions
1314
1339
  pos += 1;
@@ -1324,14 +1349,15 @@
1324
1349
  break;
1325
1350
  }
1326
1351
 
1327
- // for each raw data point, push it to an array that contains all values for this specific group
1352
+ // for each raw data point, push it to an array that contains all values
1353
+ // for this specific group
1328
1354
  if (pointArrayMap) {
1329
1355
 
1330
1356
  var index = series.cropStart + i,
1331
- point = (data && data[index]) || series.pointClass.prototype.applyOptions.apply({
1357
+ point = (data && data[index]) ||
1358
+ series.pointClass.prototype.applyOptions.apply({
1332
1359
  series: series
1333
1360
  }, [dataOptions[index]]),
1334
- j,
1335
1361
  val;
1336
1362
 
1337
1363
  for (j = 0; j < pointArrayMapLength; j++) {
@@ -1738,7 +1764,7 @@
1738
1764
  toYData: function(point) { // return a plain array for speedy calculation
1739
1765
  return [point.open, point.high, point.low, point.close];
1740
1766
  },
1741
- pointValKey: 'high',
1767
+ pointValKey: 'close',
1742
1768
 
1743
1769
 
1744
1770
  pointAttrToOptions: {
@@ -1791,6 +1817,10 @@
1791
1817
  point[translated[i]] = yAxis.toPixels(value, true);
1792
1818
  }
1793
1819
  });
1820
+
1821
+ // Align the tooltip to the high value to avoid covering the point
1822
+ point.tooltipPos[1] =
1823
+ point.plotHigh + yAxis.pos - series.chart.plotTop;
1794
1824
  });
1795
1825
  },
1796
1826
 
@@ -1835,7 +1865,7 @@
1835
1865
  'M',
1836
1866
  crispX, Math.round(point.yBottom),
1837
1867
  'L',
1838
- crispX, Math.round(point.plotY)
1868
+ crispX, Math.round(point.plotHigh)
1839
1869
  ];
1840
1870
 
1841
1871
  // open
@@ -2005,7 +2035,7 @@
2005
2035
  topBox = Math.min(plotOpen, plotClose);
2006
2036
  bottomBox = Math.max(plotOpen, plotClose);
2007
2037
  halfWidth = Math.round(point.shapeArgs.width / 2);
2008
- hasTopWhisker = Math.round(topBox) !== Math.round(point.plotY);
2038
+ hasTopWhisker = Math.round(topBox) !== Math.round(point.plotHigh);
2009
2039
  hasBottomWhisker = bottomBox !== point.yBottom;
2010
2040
  topBox = Math.round(topBox) + crispCorr;
2011
2041
  bottomBox = Math.round(bottomBox) + crispCorr;
@@ -2028,7 +2058,7 @@
2028
2058
  'M',
2029
2059
  crispX, topBox,
2030
2060
  'L',
2031
- crispX, hasTopWhisker ? Math.round(point.plotY) : topBox, // #460, #2094
2061
+ crispX, hasTopWhisker ? Math.round(point.plotHigh) : topBox, // #460, #2094
2032
2062
  'M',
2033
2063
  crispX, bottomBox,
2034
2064
  'L',
@@ -3052,7 +3082,7 @@
3052
3082
  each(this._events, function(args) {
3053
3083
  removeEvent.apply(null, args);
3054
3084
  });
3055
- this._events = undefined;
3085
+ this._events.length = 0;
3056
3086
  },
3057
3087
 
3058
3088
  /**
@@ -3124,6 +3154,7 @@
3124
3154
  scrollMin = Math.min(pick(axis.options.min, axis.min), axis.min, axis.dataMin),
3125
3155
  scrollMax = Math.max(pick(axis.options.max, axis.max), axis.max, axis.dataMax),
3126
3156
  scrollbar = axis.scrollbar,
3157
+ titleOffset = axis.titleOffset || 0,
3127
3158
  offsetsIndex,
3128
3159
  from,
3129
3160
  to;
@@ -3136,7 +3167,10 @@
3136
3167
  scrollbar.position(
3137
3168
  axis.left,
3138
3169
  axis.top + axis.height + 2 + axis.chart.scrollbarsOffsets[1] +
3139
- (axis.opposite ? 0 : axis.axisTitleMargin + axis.offset),
3170
+ (axis.opposite ?
3171
+ 0 :
3172
+ titleOffset + axis.axisTitleMargin + axis.offset
3173
+ ),
3140
3174
  axis.width,
3141
3175
  axis.height
3142
3176
  );
@@ -3144,7 +3178,10 @@
3144
3178
  } else {
3145
3179
  scrollbar.position(
3146
3180
  axis.left + axis.width + 2 + axis.chart.scrollbarsOffsets[0] +
3147
- (axis.opposite ? axis.axisTitleMargin + axis.offset : 0),
3181
+ (axis.opposite ?
3182
+ titleOffset + axis.axisTitleMargin + axis.offset :
3183
+ 0
3184
+ ),
3148
3185
  axis.top,
3149
3186
  axis.width,
3150
3187
  axis.height
@@ -3645,6 +3682,7 @@
3645
3682
  scrollbarHeight = navigator.scrollbarHeight,
3646
3683
  navigatorSize,
3647
3684
  xAxis = navigator.xAxis,
3685
+ scrollbarXAxis = xAxis.fake ? chart.xAxis[0] : xAxis,
3648
3686
  navigatorEnabled = navigator.navigatorEnabled,
3649
3687
  zoomedMin,
3650
3688
  zoomedMax,
@@ -3745,7 +3783,9 @@
3745
3783
  if (inverted) {
3746
3784
  scrollbarTop = navigator.top - scrollbarHeight;
3747
3785
  scrollbarLeft = navigator.left - scrollbarHeight +
3748
- (navigatorEnabled ? 0 : navigator.height);
3786
+ (navigatorEnabled ? 0 : (scrollbarXAxis.titleOffset || 0) +
3787
+ scrollbarXAxis.axisTitleMargin
3788
+ );
3749
3789
  scrollbarHeight = navigatorSize + 2 * scrollbarHeight;
3750
3790
  } else {
3751
3791
  scrollbarTop = navigator.top +
@@ -5522,15 +5562,15 @@
5522
5562
  * Destroys allocated elements.
5523
5563
  */
5524
5564
  destroy: function() {
5525
- var minInput = this.minInput,
5526
- maxInput = this.maxInput,
5527
- key;
5565
+ var rSelector = this,
5566
+ minInput = rSelector.minInput,
5567
+ maxInput = rSelector.maxInput;
5528
5568
 
5529
- this.unMouseDown();
5530
- this.unResize();
5569
+ rSelector.unMouseDown();
5570
+ rSelector.unResize();
5531
5571
 
5532
5572
  // Destroy elements in collections
5533
- destroyObjectProperties(this.buttons);
5573
+ destroyObjectProperties(rSelector.buttons);
5534
5574
 
5535
5575
  // Clear input element events
5536
5576
  if (minInput) {
@@ -5541,18 +5581,18 @@
5541
5581
  }
5542
5582
 
5543
5583
  // Destroy HTML and SVG elements
5544
- for (key in this) {
5545
- if (this[key] && key !== 'chart') {
5546
- if (this[key].destroy) { // SVGElement
5547
- this[key].destroy();
5548
- } else if (this[key].nodeType) { // HTML element
5584
+ H.objectEach(rSelector, function(val, key) {
5585
+ if (val && key !== 'chart') {
5586
+ if (val.destroy) { // SVGElement
5587
+ val.destroy();
5588
+ } else if (val.nodeType) { // HTML element
5549
5589
  discardElement(this[key]);
5550
5590
  }
5551
5591
  }
5552
- if (this[key] !== RangeSelector.prototype[key]) {
5553
- this[key] = null;
5592
+ if (val !== RangeSelector.prototype[key]) {
5593
+ rSelector[key] = null;
5554
5594
  }
5555
- }
5595
+ }, this);
5556
5596
  }
5557
5597
  };
5558
5598
 
@@ -5606,8 +5646,15 @@
5606
5646
  range,
5607
5647
  // Get the true range from a start date
5608
5648
  getTrueRange = function(base, count) {
5609
- var date = new Date(base);
5610
- date['set' + timeName](date['get' + timeName]() + count);
5649
+ var date = new Date(base),
5650
+ basePeriod = date['get' + timeName]();
5651
+
5652
+ date['set' + timeName](basePeriod + count);
5653
+
5654
+ if (basePeriod === date['get' + timeName]()) {
5655
+ date.setDate(0); // #6537
5656
+ }
5657
+
5611
5658
  return date.getTime() - base;
5612
5659
  };
5613
5660
 
@@ -5715,6 +5762,7 @@
5715
5762
  each = H.each,
5716
5763
  extend = H.extend,
5717
5764
  format = H.format,
5765
+ grep = H.grep,
5718
5766
  inArray = H.inArray,
5719
5767
  isNumber = H.isNumber,
5720
5768
  isString = H.isString,
@@ -5973,7 +6021,13 @@
5973
6021
  // lines (#2796).
5974
6022
  uniqueAxes = axes.length ? [] : [axis.isXAxis ? chart.yAxis[0] : chart.xAxis[0]]; //#3742
5975
6023
  each(axes, function(axis2) {
5976
- if (inArray(axis2, uniqueAxes) === -1) {
6024
+ if (
6025
+ inArray(axis2, uniqueAxes) === -1 &&
6026
+ // Do not draw on axis which overlap completely. #5424
6027
+ !H.find(uniqueAxes, function(unique) {
6028
+ return unique.pos === axis2.pos && unique.len && axis2.len;
6029
+ })
6030
+ ) {
5977
6031
  uniqueAxes.push(axis2);
5978
6032
  }
5979
6033
  });
@@ -6320,7 +6374,7 @@
6320
6374
 
6321
6375
  // find the first value for comparison
6322
6376
  for (i = 0; i < length - 1; i++) {
6323
- compareValue = keyIndex > -1 ?
6377
+ compareValue = processedYData[i] && keyIndex > -1 ?
6324
6378
  processedYData[i][keyIndex] :
6325
6379
  processedYData[i];
6326
6380
  if (isNumber(compareValue) && processedXData[i + 1] >= series.xAxis.min && compareValue !== 0) {
@@ -6416,5 +6470,32 @@
6416
6470
  proceed.call(this);
6417
6471
  });
6418
6472
 
6473
+ wrap(Chart.prototype, 'getSelectedPoints', function(proceed) {
6474
+ var points = proceed.call(this);
6475
+
6476
+ each(this.series, function(serie) {
6477
+ // series.points - for grouped points (#6445)
6478
+ if (serie.hasGroupedData) {
6479
+ points = points.concat(grep(serie.points || [], function(point) {
6480
+ return point.selected;
6481
+ }));
6482
+ }
6483
+ });
6484
+ return points;
6485
+ });
6486
+
6487
+ wrap(Chart.prototype, 'update', function(proceed, options) {
6488
+ // Use case: enabling scrollbar from a disabled state.
6489
+ // Scrollbar needs to be initialized from a controller, Navigator in this
6490
+ // case (#6615)
6491
+ if ('scrollbar' in options && this.navigator) {
6492
+ merge(true, this.options.scrollbar, options.scrollbar);
6493
+ this.navigator.update({}, false);
6494
+ delete options.scrollbar;
6495
+ }
6496
+
6497
+ return proceed.apply(this, Array.prototype.slice.call(arguments, 1));
6498
+ });
6499
+
6419
6500
  }(Highcharts));
6420
6501
  }));