highcharts-rails 5.0.9 → 5.0.10

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 +547 -270
  4. data/app/assets/javascripts/highcharts/highcharts-3d.js +13 -11
  5. data/app/assets/javascripts/highcharts/highcharts-more.js +373 -181
  6. data/app/assets/javascripts/highcharts/modules/accessibility.js +3 -3
  7. data/app/assets/javascripts/highcharts/modules/annotations.js +3 -3
  8. data/app/assets/javascripts/highcharts/modules/boost.js +11 -5
  9. data/app/assets/javascripts/highcharts/modules/broken-axis.js +3 -3
  10. data/app/assets/javascripts/highcharts/modules/data.js +3 -3
  11. data/app/assets/javascripts/highcharts/modules/drilldown.js +1 -1
  12. data/app/assets/javascripts/highcharts/modules/exporting.js +70 -28
  13. data/app/assets/javascripts/highcharts/modules/funnel.js +3 -3
  14. data/app/assets/javascripts/highcharts/modules/grid-axis.js +1 -1
  15. data/app/assets/javascripts/highcharts/modules/heatmap.js +5 -5
  16. data/app/assets/javascripts/highcharts/modules/no-data-to-display.js +3 -3
  17. data/app/assets/javascripts/highcharts/modules/offline-exporting.js +2 -2
  18. data/app/assets/javascripts/highcharts/modules/overlapping-datalabels.js +43 -20
  19. data/app/assets/javascripts/highcharts/modules/series-label.js +3 -3
  20. data/app/assets/javascripts/highcharts/modules/solid-gauge.js +3 -3
  21. data/app/assets/javascripts/highcharts/modules/stock.js +83 -42
  22. data/app/assets/javascripts/highcharts/modules/treemap.js +1 -1
  23. data/app/assets/javascripts/highcharts/modules/xrange-series.js +3 -3
  24. data/lib/highcharts/version.rb +1 -1
  25. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a1203f405bffad4bc97bdeb40025f1d32aa9d035
4
- data.tar.gz: 7c4d64d7ccfef934a1d562ba18c28e6e8756f8dd
3
+ metadata.gz: 4d9fce6a4b9deae4055a42cc56e54f4cab837e50
4
+ data.tar.gz: 83880957c3ae435a500132e2b95e5a9d8a5d2ea8
5
5
  SHA512:
6
- metadata.gz: 7487bf84bcb2f7d8d540afc53341be646fce318ba69a48a6517e9f41ed3e2c38f28d0883bb4332a78423297fca542c77b061b69abbff6dca2556e8799508dcbc
7
- data.tar.gz: 4a587287886f11f7d3816f424174b3fea4a0a108655b849b2d4c5fb2fe0d3898dfda781c465c29a80b98a914549357fa90e0937072abc5238db25ca9e2907d8f
6
+ metadata.gz: 9c4eebee732b136ebf348a290b09286ab798f435e65c70a24ead95dbf596d6b1c15a7c80afd6a4e3f1796fa332d3b4b31d80597dd874b23699ad7b74cad1c515
7
+ data.tar.gz: 22bc411c05e562ff3404f8f76e282bc4a8663257abd1719880757c7ea601454f5af680a7e1487cec7a05d5a5e222af1d2b9aeea777931f65f6a22e49bc2b87dd
data/CHANGELOG.markdown CHANGED
@@ -1,3 +1,51 @@
1
+ # 5.0.10 / 2017-11-10
2
+
3
+ * Updated Highcharts to 5.0.10 (2017-03-31)
4
+ * Added !default statement to SASS variables for easier configuration. Closes #6436.
5
+ * Added new option, plotOptions.column.crisp, to allow disabling crisp columns and subsequent rendering issues with densely packed items. Closes #5755.
6
+ * Added new option, findNearestPointBy to declare how the tooltip searches for points. #6231.
7
+ * Refactored the Pane object to keep track of its own backgrounds, more decoupled from Axis.
8
+ * Bug fixes
9
+ * Fixed #3481, title and subtitle were not resizing chart correctly when using useHTML on true.
10
+ * Fixed #3936, colorAxis was not updated through chart.update.
11
+ * Fixed #4964, missing plotband when small range.
12
+ * Fixed #6007, exporting after chart.update() threw errors.
13
+ * Fixed #6144, empty categories caused wrong render of tooltip.
14
+ * Fixed #6191, dead clip path references.
15
+ * Fixed #6203, yAxis extremes were wrong calculated for visible scatter points
16
+ * Fixed #6258, text labels with ellipsis had inconsistent behavior.
17
+ * Fixed #6279, error when hiding series of line polar using data module.
18
+ * Fixed #6359, softMin/softMax didn't work in combination with floor/ceiling.
19
+ * Fixed #6430, areasplinerange polar curve path was wrongly rendered.
20
+ * Fixed #6431, addition to #6476, stickyTracking should default to true when there is a shared tooltip.
21
+ * Fixed #6433, updating Axis with plotBands rendered redundant nodes.
22
+ * Fixed #6437, 3D pie chart disappeared when drilling down after resize.
23
+ * Fixed #6444, exporting the second time failed with axis extremes.
24
+ * Fixed #6449, series with noSharedTooltip was inaccessible with shared tooltip.
25
+ * Fixed #6452, chart.update was not redrawing axes when setting alignTicks to false.
26
+ * Fixed #6456, tooltip didn't show on hovering outside candlestick and OHLC series.
27
+ * Fixed #6458, named color deduction was case sensitive.
28
+ * Fixed #6459, colors of boxplot series points would not update.
29
+ * Fixed #6463, missing closing sign in RegEx caused wrong handling of pseudo attributes.
30
+ * Fixed #6465, first data label in polar charts was not visible.
31
+ * Fixed #6469, series got lost when mixing category data in a dual axis chart.
32
+ * Fixed #6470, exporting failed in IE8 when data labels were enabled.
33
+ * Fixed #6473, wrong text wrapping with textOutline: none.
34
+ * Fixed #6474, custom CSS property was injected into the DOM. Added to blacklist.
35
+ * Fixed #6474, text outlines were not properly cleaned up on resizing.
36
+ * Fixed #6476, shared tooltip with disabled stickyTracking did not work.
37
+ * Fixed #6477, regression on crosshairs with snap in a bubble chart.
38
+ * Fixed #6479, responsive rules didn't apply to panes.
39
+ * Fixed #6481, offline export of pie charts to PDF not working in Firefox and Safari.
40
+ * Fixed #6487, contrast color was not applied for a justified label on a column.
41
+ * Fixed #6497, horizontal legend layout didn't respect spacing setting.
42
+ * Fixed #6499, offline export fails with allowHTML despite no HTML in chart.
43
+ * Fixed #6502, missing chart series and axis in combined logarithmic chart.
44
+ * Fixed #6518, wrong marker positions when hovering after redrawing in boost module.
45
+ * Fixed #6519, empty space caused overlapping in legend.
46
+ * Fixed #6521, missing label for narrow plot band.
47
+ * * Fixed #6089, chart.update not taking effect on panes. Also closes #6438.
48
+
1
49
  # 5.0.9 / 2017-11-10
2
50
 
3
51
  * Updated Highcharts to 5.0.9 (2017-03-08)
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v5.0.9 (2017-03-08)
2
+ * @license Highcharts JS v5.0.10 (2017-03-31)
3
3
  *
4
4
  * (c) 2009-2016 Torstein Honsi
5
5
  *
@@ -17,7 +17,7 @@
17
17
  }(typeof window !== 'undefined' ? window : this, function(win) {
18
18
  var Highcharts = (function() {
19
19
  /**
20
- * (c) 2010-2016 Torstein Honsi
20
+ * (c) 2010-2017 Torstein Honsi
21
21
  *
22
22
  * License: www.highcharts.com/license
23
23
  */
@@ -35,7 +35,7 @@
35
35
 
36
36
  var Highcharts = win.Highcharts ? win.Highcharts.error(16, true) : {
37
37
  product: 'Highcharts',
38
- version: '5.0.9',
38
+ version: '5.0.10',
39
39
  deg2rad: Math.PI * 2 / 360,
40
40
  doc: doc,
41
41
  hasBidiBug: hasBidiBug,
@@ -61,7 +61,7 @@
61
61
  }());
62
62
  (function(H) {
63
63
  /**
64
- * (c) 2010-2016 Torstein Honsi
64
+ * (c) 2010-2017 Torstein Honsi
65
65
  *
66
66
  * License: www.highcharts.com/license
67
67
  */
@@ -2091,7 +2091,7 @@
2091
2091
  }(Highcharts));
2092
2092
  (function(H) {
2093
2093
  /**
2094
- * (c) 2010-2016 Torstein Honsi
2094
+ * (c) 2010-2017 Torstein Honsi
2095
2095
  *
2096
2096
  * License: www.highcharts.com/license
2097
2097
  */
@@ -2139,8 +2139,8 @@
2139
2139
  }
2140
2140
  }],
2141
2141
 
2142
- // Collection of named colors. Can be extended from the outside by adding colors
2143
- // to Highcharts.Color.prototype.names.
2142
+ // Collection of named colors. Can be extended from the outside by adding
2143
+ // colors to Highcharts.Color.prototype.names.
2144
2144
  names: {
2145
2145
  white: '#ffffff',
2146
2146
  black: '#000000'
@@ -2157,7 +2157,11 @@
2157
2157
  parser,
2158
2158
  len;
2159
2159
 
2160
- this.input = input = this.names[input] || input;
2160
+ this.input = input = this.names[
2161
+ input && input.toLowerCase ?
2162
+ input.toLowerCase() :
2163
+ ''
2164
+ ] || input;
2161
2165
 
2162
2166
  // Gradients
2163
2167
  if (input && input.stops) {
@@ -2288,7 +2292,7 @@
2288
2292
  }(Highcharts));
2289
2293
  (function(H) {
2290
2294
  /**
2291
- * (c) 2010-2016 Torstein Honsi
2295
+ * (c) 2010-2017 Torstein Honsi
2292
2296
  *
2293
2297
  * License: www.highcharts.com/license
2294
2298
  */
@@ -2484,10 +2488,10 @@
2484
2488
  value;
2485
2489
 
2486
2490
  // Apply linear or radial gradients
2487
- if (color.linearGradient) {
2488
- gradName = 'linearGradient';
2489
- } else if (color.radialGradient) {
2491
+ if (color.radialGradient) {
2490
2492
  gradName = 'radialGradient';
2493
+ } else if (color.linearGradient) {
2494
+ gradName = 'linearGradient';
2491
2495
  }
2492
2496
 
2493
2497
  if (gradName) {
@@ -2508,9 +2512,14 @@
2508
2512
  }
2509
2513
 
2510
2514
  // Correct the radial gradient for the radial reference system
2511
- if (gradName === 'radialGradient' && radialReference && !defined(gradAttr.gradientUnits)) {
2515
+ if (
2516
+ gradName === 'radialGradient' &&
2517
+ radialReference &&
2518
+ !defined(gradAttr.gradientUnits)
2519
+ ) {
2512
2520
  radAttr = gradAttr; // Save the radial attributes for updating
2513
- gradAttr = merge(gradAttr,
2521
+ gradAttr = merge(
2522
+ gradAttr,
2514
2523
  renderer.getRadialAttr(radialReference, radAttr), {
2515
2524
  gradientUnits: 'userSpaceOnUse'
2516
2525
  }
@@ -2599,11 +2608,13 @@
2599
2608
  applyTextOutline: function(textOutline) {
2600
2609
  var elem = this.element,
2601
2610
  tspans,
2611
+ tspan,
2602
2612
  hasContrast = textOutline.indexOf('contrast') !== -1,
2603
2613
  styles = {},
2604
2614
  color,
2605
2615
  strokeWidth,
2606
- firstRealChild;
2616
+ firstRealChild,
2617
+ i;
2607
2618
 
2608
2619
  // When the text shadow is set to contrast, use dark stroke for light
2609
2620
  // text and vice versa.
@@ -2614,20 +2625,20 @@
2614
2625
  );
2615
2626
  }
2616
2627
 
2617
- this.fakeTS = true; // Fake text shadow
2618
-
2619
- // In order to get the right y position of the clone,
2620
- // copy over the y setter
2621
- this.ySetter = this.xSetter;
2622
-
2623
- tspans = [].slice.call(elem.getElementsByTagName('tspan'));
2624
-
2625
2628
  // Extract the stroke width and color
2626
2629
  textOutline = textOutline.split(' ');
2627
2630
  color = textOutline[textOutline.length - 1];
2628
2631
  strokeWidth = textOutline[0];
2629
2632
 
2630
- if (strokeWidth && strokeWidth !== 'none') {
2633
+ if (strokeWidth && strokeWidth !== 'none' && H.svg) {
2634
+
2635
+ this.fakeTS = true; // Fake text shadow
2636
+
2637
+ tspans = [].slice.call(elem.getElementsByTagName('tspan'));
2638
+
2639
+ // In order to get the right y position of the clone,
2640
+ // copy over the y setter
2641
+ this.ySetter = this.xSetter;
2631
2642
 
2632
2643
  // Since the stroke is applied on center of the actual outline, we
2633
2644
  // need to double it to get the correct stroke-width outside the
@@ -2639,13 +2650,16 @@
2639
2650
  }
2640
2651
  );
2641
2652
 
2642
- // Remove shadows from previous runs
2643
- each(tspans, function(tspan) {
2653
+ // Remove shadows from previous runs. Iterate from the end to
2654
+ // support removing items inside the cycle (#6472).
2655
+ i = tspans.length;
2656
+ while (i--) {
2657
+ tspan = tspans[i];
2644
2658
  if (tspan.getAttribute('class') === 'highcharts-text-outline') {
2645
2659
  // Remove then erase
2646
2660
  erase(tspans, elem.removeChild(tspan));
2647
2661
  }
2648
- });
2662
+ }
2649
2663
 
2650
2664
  // For each of the tspans, create a stroked copy behind it.
2651
2665
  firstRealChild = elem.firstChild;
@@ -2769,7 +2783,12 @@
2769
2783
  stop(this, key);
2770
2784
  }
2771
2785
 
2772
- if (this.symbolName && /^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(key)) {
2786
+ // Special handling of symbol attributes
2787
+ if (
2788
+ this.symbolName &&
2789
+ /^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)$/
2790
+ .test(key)
2791
+ ) {
2773
2792
  if (!hasSetSymbolSize) {
2774
2793
  this.symbolAttr(hash);
2775
2794
  hasSetSymbolSize = true;
@@ -2986,8 +3005,8 @@
2986
3005
  // These CSS properties are interpreted internally by the SVG
2987
3006
  // renderer, but are not supported by SVG and should not be added to
2988
3007
  // the DOM. In styled mode, no CSS should find its way to the DOM
2989
- // whatsoever (#6173).
2990
- svgPseudoProps = ['textOverflow', 'width'];
3008
+ // whatsoever (#6173, #6474).
3009
+ svgPseudoProps = ['textOutline', 'textOverflow', 'width'];
2991
3010
 
2992
3011
  // convert legacy
2993
3012
  if (styles && styles.color) {
@@ -3619,6 +3638,17 @@
3619
3638
  stop(wrapper); // stop running animations
3620
3639
 
3621
3640
  if (wrapper.clipPath) {
3641
+ // Look for existing references to this clipPath and remove them
3642
+ // before destroying the element (#6196).
3643
+ each(
3644
+ wrapper.element.ownerSVGElement.querySelectorAll('[clip-path]'),
3645
+ function(el) {
3646
+ if (el.getAttribute('clip-path')
3647
+ .indexOf(wrapper.clipPath.element.id) > -1) {
3648
+ el.removeAttribute('clip-path');
3649
+ }
3650
+ }
3651
+ );
3622
3652
  wrapper.clipPath = wrapper.clipPath.destroy();
3623
3653
  }
3624
3654
 
@@ -4061,7 +4091,7 @@
4061
4091
 
4062
4092
  // Add description
4063
4093
  desc = this.createElement('desc').add();
4064
- desc.element.appendChild(doc.createTextNode('Created with Highcharts 5.0.9'));
4094
+ desc.element.appendChild(doc.createTextNode('Created with Highcharts 5.0.10'));
4065
4095
 
4066
4096
 
4067
4097
  renderer.defs = this.createElement('defs').add();
@@ -4208,6 +4238,58 @@
4208
4238
  };
4209
4239
  },
4210
4240
 
4241
+ getSpanWidth: function(wrapper, tspan) {
4242
+ var renderer = this,
4243
+ bBox = wrapper.getBBox(true),
4244
+ actualWidth = bBox.width;
4245
+
4246
+ // Old IE cannot measure the actualWidth for SVG elements (#2314)
4247
+ if (!svg && renderer.forExport) {
4248
+ actualWidth = renderer.measureSpanWidth(tspan.firstChild.data, wrapper.styles);
4249
+ }
4250
+ return actualWidth;
4251
+ },
4252
+
4253
+ applyEllipsis: function(wrapper, tspan, text, width) {
4254
+ var renderer = this,
4255
+ actualWidth = renderer.getSpanWidth(wrapper, tspan),
4256
+ wasTooLong = actualWidth > width,
4257
+ str = text,
4258
+ currentIndex,
4259
+ minIndex = 0,
4260
+ maxIndex = text.length,
4261
+ updateTSpan = function(s) {
4262
+ tspan.removeChild(tspan.firstChild);
4263
+ if (s) {
4264
+ tspan.appendChild(doc.createTextNode(s));
4265
+ }
4266
+ };
4267
+ if (wasTooLong) {
4268
+ while (minIndex <= maxIndex) {
4269
+ currentIndex = Math.ceil((minIndex + maxIndex) / 2);
4270
+ str = text.substring(0, currentIndex) + '\u2026';
4271
+ updateTSpan(str);
4272
+ actualWidth = renderer.getSpanWidth(wrapper, tspan);
4273
+ if (minIndex === maxIndex) {
4274
+ // Complete
4275
+ minIndex = maxIndex + 1;
4276
+ } else if (actualWidth > width) {
4277
+ // Too large. Set max index to current.
4278
+ maxIndex = currentIndex - 1;
4279
+ } else {
4280
+ // Within width. Set min index to current.
4281
+ minIndex = currentIndex;
4282
+ }
4283
+ }
4284
+ // If max index was 0 it means just ellipsis was also to large.
4285
+ if (maxIndex === 0) {
4286
+ // Remove ellipses.
4287
+ updateTSpan('');
4288
+ }
4289
+ }
4290
+ return wasTooLong;
4291
+ },
4292
+
4211
4293
  /**
4212
4294
  * Parse a simple HTML string into SVG tspans. Called internally when text
4213
4295
  * is set on an SVGElement. The function supports a subset of HTML tags,
@@ -4237,6 +4319,7 @@
4237
4319
  noWrap = textStyles && textStyles.whiteSpace === 'nowrap',
4238
4320
  fontSize = textStyles && textStyles.fontSize,
4239
4321
  textCache,
4322
+ isSubsequentLine,
4240
4323
  i = childNodes.length,
4241
4324
  tempParent = width && !wrapper.added && this.box,
4242
4325
  getLineHeight = function(tspan) {
@@ -4371,7 +4454,7 @@
4371
4454
  textNode.appendChild(tspan);
4372
4455
 
4373
4456
  // first span on subsequent line, add the line height
4374
- if (!spanNo && lineNo) {
4457
+ if (!spanNo && isSubsequentLine) {
4375
4458
 
4376
4459
  // allow getting the right offset height in exporting in IE
4377
4460
  if (!svg && forExport) {
@@ -4398,44 +4481,28 @@
4398
4481
  var words = span.replace(/([^\^])-/g, '$1- ').split(' '), // #1273
4399
4482
  hasWhiteSpace = spans.length > 1 || lineNo || (words.length > 1 && !noWrap),
4400
4483
  tooLong,
4401
- actualWidth,
4402
4484
  rest = [],
4485
+ actualWidth,
4403
4486
  dy = getLineHeight(tspan),
4404
- rotation = wrapper.rotation,
4405
- wordStr = span, // for ellipsis
4406
- cursor = wordStr.length, // binary search cursor
4407
- bBox;
4487
+ rotation = wrapper.rotation;
4408
4488
 
4409
- while ((hasWhiteSpace || ellipsis) && (words.length || rest.length)) {
4410
- wrapper.rotation = 0; // discard rotation when computing box
4411
- bBox = wrapper.getBBox(true);
4412
- actualWidth = bBox.width;
4413
-
4414
- // Old IE cannot measure the actualWidth for SVG elements (#2314)
4415
- if (!svg && renderer.forExport) {
4416
- actualWidth = renderer.measureSpanWidth(tspan.firstChild.data, wrapper.styles);
4417
- }
4489
+ if (ellipsis) {
4490
+ wasTooLong = renderer.applyEllipsis(wrapper, tspan, span, width);
4491
+ }
4418
4492
 
4493
+ while (!ellipsis && hasWhiteSpace && (words.length || rest.length)) {
4494
+ wrapper.rotation = 0; // discard rotation when computing box
4495
+ actualWidth = renderer.getSpanWidth(wrapper, tspan);
4419
4496
  tooLong = actualWidth > width;
4420
4497
 
4421
4498
  // For ellipsis, do a binary search for the correct string length
4422
4499
  if (wasTooLong === undefined) {
4423
4500
  wasTooLong = tooLong; // First time
4424
4501
  }
4425
- if (ellipsis && wasTooLong) {
4426
- cursor /= 2;
4427
-
4428
- if (wordStr === '' || (!tooLong && cursor < 0.5)) {
4429
- words = []; // All ok, break out
4430
- } else {
4431
- wordStr = span.substring(0, wordStr.length + (tooLong ? -1 : 1) * Math.ceil(cursor));
4432
- words = [wordStr + (width > 3 ? '\u2026' : '')];
4433
- tspan.removeChild(tspan.firstChild);
4434
- }
4435
4502
 
4436
- // Looping down, this is the first word sequence that is not too long,
4437
- // so we can move on to build the next line.
4438
- } else if (!tooLong || words.length === 1) {
4503
+ // Looping down, this is the first word sequence that is not too long,
4504
+ // so we can move on to build the next line.
4505
+ if (!tooLong || words.length === 1) {
4439
4506
  words = rest;
4440
4507
  rest = [];
4441
4508
 
@@ -4468,6 +4535,8 @@
4468
4535
  }
4469
4536
  }
4470
4537
  });
4538
+ // To avoid beginning lines that doesn't add to the textNode (#6144)
4539
+ isSubsequentLine = isSubsequentLine || textNode.childNodes.length;
4471
4540
  });
4472
4541
 
4473
4542
  if (wasTooLong) {
@@ -5807,7 +5876,7 @@
5807
5876
  }(Highcharts));
5808
5877
  (function(H) {
5809
5878
  /**
5810
- * (c) 2010-2016 Torstein Honsi
5879
+ * (c) 2010-2017 Torstein Honsi
5811
5880
  *
5812
5881
  * License: www.highcharts.com/license
5813
5882
  */
@@ -6169,7 +6238,7 @@
6169
6238
  }(Highcharts));
6170
6239
  (function(H) {
6171
6240
  /**
6172
- * (c) 2010-2016 Torstein Honsi
6241
+ * (c) 2010-2017 Torstein Honsi
6173
6242
  *
6174
6243
  * License: www.highcharts.com/license
6175
6244
  */
@@ -7320,7 +7389,7 @@
7320
7389
  }(Highcharts));
7321
7390
  (function(H) {
7322
7391
  /**
7323
- * (c) 2010-2016 Torstein Honsi
7392
+ * (c) 2010-2017 Torstein Honsi
7324
7393
  *
7325
7394
  * License: www.highcharts.com/license
7326
7395
  */
@@ -7366,7 +7435,7 @@
7366
7435
  useUTC: true,
7367
7436
  //timezoneOffset: 0,
7368
7437
 
7369
- VMLRadialGradientURL: 'http://code.highcharts.com/5.0.9/gfx/vml-radial-gradient.png'
7438
+ VMLRadialGradientURL: 'http://code.highcharts.com/5.0.10/gfx/vml-radial-gradient.png'
7370
7439
 
7371
7440
  },
7372
7441
  chart: {
@@ -7708,7 +7777,7 @@
7708
7777
  }(Highcharts));
7709
7778
  (function(H) {
7710
7779
  /**
7711
- * (c) 2010-2016 Torstein Honsi
7780
+ * (c) 2010-2017 Torstein Honsi
7712
7781
  *
7713
7782
  * License: www.highcharts.com/license
7714
7783
  */
@@ -7801,9 +7870,9 @@
7801
7870
  groupAttribs.zIndex = zIndex;
7802
7871
  groupName += '-' + zIndex;
7803
7872
 
7804
- group = axis[groupName];
7873
+ group = axis.plotLinesAndBandsGroups[groupName];
7805
7874
  if (!group) {
7806
- axis[groupName] = group = renderer.g('plot-' + groupName)
7875
+ axis.plotLinesAndBandsGroups[groupName] = group = renderer.g('plot-' + groupName)
7807
7876
  .attr(groupAttribs).add();
7808
7877
  }
7809
7878
 
@@ -7956,19 +8025,26 @@
7956
8025
  */
7957
8026
  getPlotBandPath: function(from, to) {
7958
8027
  var toPath = this.getPlotLinePath(to, null, null, true),
7959
- path = this.getPlotLinePath(from, null, null, true);
8028
+ path = this.getPlotLinePath(from, null, null, true),
8029
+ // #4964 check if chart is inverted or plotband is on yAxis
8030
+ horiz = this.horiz,
8031
+ plus = 1,
8032
+ outside =
8033
+ (from < this.min && to < this.min) ||
8034
+ (from > this.max && to > this.max);
7960
8035
 
7961
8036
  if (path && toPath) {
7962
8037
 
7963
8038
  // Flat paths don't need labels (#3836)
7964
- path.flat = path.toString() === toPath.toString();
8039
+ if (outside) {
8040
+ path.flat = path.toString() === toPath.toString();
8041
+ plus = 0;
8042
+ }
7965
8043
 
8044
+ // Add 1 pixel, when coordinates are the same
7966
8045
  path.push(
7967
- toPath[4],
7968
- toPath[5],
7969
- toPath[1],
7970
- toPath[2],
7971
- 'z' // #5909
8046
+ horiz && toPath[4] === path[4] ? toPath[4] + plus : toPath[4], !horiz && toPath[5] === path[5] ? toPath[5] + plus : toPath[5],
8047
+ horiz && toPath[1] === path[1] ? toPath[1] + plus : toPath[1], !horiz && toPath[2] === path[2] ? toPath[2] + plus : toPath[2]
7972
8048
  );
7973
8049
  } else { // outside the axis area
7974
8050
  path = null;
@@ -8034,7 +8110,7 @@
8034
8110
  }(Highcharts));
8035
8111
  (function(H) {
8036
8112
  /**
8037
- * (c) 2010-2016 Torstein Honsi
8113
+ * (c) 2010-2017 Torstein Honsi
8038
8114
  *
8039
8115
  * License: www.highcharts.com/license
8040
8116
  */
@@ -8544,7 +8620,7 @@
8544
8620
  }(Highcharts));
8545
8621
  (function(H) {
8546
8622
  /**
8547
- * (c) 2010-2016 Torstein Honsi
8623
+ * (c) 2010-2017 Torstein Honsi
8548
8624
  *
8549
8625
  * License: www.highcharts.com/license
8550
8626
  */
@@ -8844,6 +8920,9 @@
8844
8920
  //axis.axisTitle = undefined;
8845
8921
  //axis.axisLine = undefined;
8846
8922
 
8923
+ // Placeholder for plotlines and plotbands groups
8924
+ axis.plotLinesAndBandsGroups = {};
8925
+
8847
8926
  // Shorthand types
8848
8927
  axis.isLog = type === 'logarithmic';
8849
8928
  axis.isDatetimeAxis = isDatetimeAxis;
@@ -9465,7 +9544,9 @@
9465
9544
  }
9466
9545
 
9467
9546
  // Write the last point's name to the names array
9468
- this.names[x] = point.name;
9547
+ if (x !== undefined) {
9548
+ this.names[x] = point.name;
9549
+ }
9469
9550
 
9470
9551
  return x;
9471
9552
  },
@@ -9494,7 +9575,7 @@
9494
9575
  var x;
9495
9576
  if (point.options) {
9496
9577
  x = axis.nameToX(point);
9497
- if (x !== point.x) {
9578
+ if (x !== undefined && x !== point.x) {
9498
9579
  point.x = x;
9499
9580
  series.xData[i] = x;
9500
9581
  }
@@ -9703,18 +9784,21 @@
9703
9784
  }
9704
9785
  }
9705
9786
 
9706
- // Handle options for floor, ceiling, softMin and softMax
9787
+ // Handle options for floor, ceiling, softMin and softMax (#6359)
9788
+ if (isNumber(options.softMin)) {
9789
+ axis.min = Math.min(axis.min, options.softMin);
9790
+ }
9791
+ if (isNumber(options.softMax)) {
9792
+ axis.max = Math.max(axis.max, options.softMax);
9793
+ }
9707
9794
  if (isNumber(options.floor)) {
9708
9795
  axis.min = Math.max(axis.min, options.floor);
9709
- } else if (isNumber(options.softMin)) {
9710
- axis.min = Math.min(axis.min, options.softMin);
9711
9796
  }
9712
9797
  if (isNumber(options.ceiling)) {
9713
9798
  axis.max = Math.min(axis.max, options.ceiling);
9714
- } else if (isNumber(options.softMax)) {
9715
- axis.max = Math.max(axis.max, options.softMax);
9716
9799
  }
9717
9800
 
9801
+
9718
9802
  // When the threshold is soft, adjust the extreme value only if
9719
9803
  // the data extreme and the padded extreme land on either side of the threshold. For example,
9720
9804
  // a series of [0, 1, 2, 3] would make the yAxis add a tick for -1 because of the
@@ -9889,7 +9973,7 @@
9889
9973
  minPointOffset = this.minPointOffset || 0;
9890
9974
 
9891
9975
  if (!this.isLinked) {
9892
- if (startOnTick) {
9976
+ if (startOnTick && roundedMin !== -Infinity) { // #6502
9893
9977
  this.min = roundedMin;
9894
9978
  } else {
9895
9979
  while (this.min - minPointOffset > tickPositions[0]) {
@@ -11053,6 +11137,7 @@
11053
11137
  stacks = axis.stacks,
11054
11138
  stackKey,
11055
11139
  plotLinesAndBands = axis.plotLinesAndBands,
11140
+ plotGroup,
11056
11141
  i,
11057
11142
  n;
11058
11143
 
@@ -11086,6 +11171,11 @@
11086
11171
  }
11087
11172
  });
11088
11173
 
11174
+ // Destroy each generated group for plotlines and plotbands
11175
+ for (plotGroup in axis.plotLinesAndBandsGroups) {
11176
+ axis.plotLinesAndBandsGroups[plotGroup] = axis.plotLinesAndBandsGroups[plotGroup].destroy();
11177
+ }
11178
+
11089
11179
  // Delete all properties and fall back to the prototype.
11090
11180
  for (n in axis) {
11091
11181
  if (axis.hasOwnProperty(n) && inArray(n, axis.keepProps) === -1) {
@@ -11203,7 +11293,7 @@
11203
11293
  }(Highcharts));
11204
11294
  (function(H) {
11205
11295
  /**
11206
- * (c) 2010-2016 Torstein Honsi
11296
+ * (c) 2010-2017 Torstein Honsi
11207
11297
  *
11208
11298
  * License: www.highcharts.com/license
11209
11299
  */
@@ -11463,7 +11553,7 @@
11463
11553
  }(Highcharts));
11464
11554
  (function(H) {
11465
11555
  /**
11466
- * (c) 2010-2016 Torstein Honsi
11556
+ * (c) 2010-2017 Torstein Honsi
11467
11557
  *
11468
11558
  * License: www.highcharts.com/license
11469
11559
  */
@@ -11586,7 +11676,7 @@
11586
11676
  }(Highcharts));
11587
11677
  (function(H) {
11588
11678
  /**
11589
- * (c) 2010-2016 Torstein Honsi
11679
+ * (c) 2010-2017 Torstein Honsi
11590
11680
  *
11591
11681
  * License: www.highcharts.com/license
11592
11682
  */
@@ -12338,7 +12428,7 @@
12338
12428
  }(Highcharts));
12339
12429
  (function(H) {
12340
12430
  /**
12341
- * (c) 2010-2016 Torstein Honsi
12431
+ * (c) 2010-2017 Torstein Honsi
12342
12432
  *
12343
12433
  * License: www.highcharts.com/license
12344
12434
  */
@@ -12497,8 +12587,11 @@
12497
12587
  // Skip hidden series
12498
12588
  noSharedTooltip = s.noSharedTooltip && shared;
12499
12589
  directTouch = !shared && s.directTouch;
12500
- if (s.visible && !noSharedTooltip && !directTouch && pick(s.options.enableMouseTracking, true)) { // #3821
12501
- kdpointT = s.searchPoint(e, !noSharedTooltip && s.kdDimensions === 1); // #3828
12590
+ if (s.visible && !directTouch && pick(s.options.enableMouseTracking, true)) { // #3821
12591
+ // #3828
12592
+ kdpointT = s.searchPoint(
12593
+ e, !noSharedTooltip && s.options.findNearestPointBy.indexOf('y') < 0
12594
+ );
12502
12595
  if (kdpointT && kdpointT.series) { // Point.series becomes null when reset and before redraw (#5197)
12503
12596
  kdpoints.push(kdpointT);
12504
12597
  }
@@ -12531,7 +12624,7 @@
12531
12624
  });
12532
12625
 
12533
12626
  // Remove points with different x-positions, required for shared tooltip and crosshairs (#4645):
12534
- if (shared) {
12627
+ if (shared && kdpoints[0] && !kdpoints[0].series.noSharedTooltip) {
12535
12628
  i = kdpoints.length;
12536
12629
  while (i--) {
12537
12630
  if (kdpoints[i].x !== kdpoints[0].x || kdpoints[i].series.noSharedTooltip) {
@@ -12553,9 +12646,9 @@
12553
12646
  },
12554
12647
 
12555
12648
  getHoverData: function(existingHoverPoint, existingHoverSeries, series, isDirectTouch, shared, e) {
12556
- var i,
12557
- hoverPoint = existingHoverPoint,
12649
+ var hoverPoint = existingHoverPoint,
12558
12650
  hoverSeries = existingHoverSeries,
12651
+ searchSeries,
12559
12652
  hoverPoints;
12560
12653
 
12561
12654
  // If it has a hoverPoint and that series requires direct touch (like columns, #3899), or we're on
@@ -12587,29 +12680,28 @@
12587
12680
  } else {
12588
12681
  hoverPoints = [hoverPoint];
12589
12682
  }
12590
- } else if (hoverSeries && !hoverSeries.options.stickyTracking) {
12591
- hoverPoints = this.getKDPoints([hoverSeries], shared, e);
12592
- hoverPoint = hoverPoints[0];
12593
- hoverSeries = hoverPoint && hoverPoint.series;
12594
- } else {
12683
+ // When the hovered series has stickyTracking false.
12684
+ } else if (hoverSeries && !hoverSeries.stickyTracking) {
12595
12685
  if (!shared) {
12596
- // For hovering over the empty parts of the plot area (hoverSeries is undefined).
12597
- // If there is one series with point tracking (combo chart), don't go to nearest neighbour.
12598
- if (!hoverSeries) {
12599
- for (i = 0; i < series.length; i++) {
12600
- if (series[i].directTouch || !series[i].options.stickyTracking) {
12601
- series = [];
12602
- }
12603
- }
12604
- // When we have non-shared tooltip and sticky tracking is disabled,
12605
- // search for the closest point only on hovered series: #5533, #5476
12606
- } else if (!hoverSeries.options.stickyTracking) {
12607
- series = [hoverSeries];
12608
- }
12686
+ series = [hoverSeries];
12609
12687
  }
12610
12688
  hoverPoints = this.getKDPoints(series, shared, e);
12689
+ hoverPoint = H.find(hoverPoints, function(p) {
12690
+ return p.series === hoverSeries;
12691
+ });
12692
+ // When the hoverSeries has stickyTracking or there is no series hovered.
12693
+ } else {
12694
+ // Avoid series with stickyTracking
12695
+ searchSeries = H.grep(series, function(s) {
12696
+ return s.stickyTracking;
12697
+ });
12698
+ hoverPoints = this.getKDPoints(searchSeries, shared, e);
12611
12699
  hoverPoint = hoverPoints[0];
12612
12700
  hoverSeries = hoverPoint && hoverPoint.series;
12701
+ // If
12702
+ if (shared) {
12703
+ hoverPoints = this.getKDPoints(series, shared, e);
12704
+ }
12613
12705
  }
12614
12706
  // Keep the order of series in tooltip
12615
12707
  // Must be done after assigning of hoverPoint
@@ -12636,7 +12728,7 @@
12636
12728
  hoverPoint = p || chart.hoverPoint,
12637
12729
  hoverSeries = hoverPoint && hoverPoint.series || chart.hoverSeries,
12638
12730
  // onMouseOver or already hovering a series with directTouch
12639
- isDirectTouch = !!p || (hoverSeries && hoverSeries.directTouch),
12731
+ isDirectTouch = !!p || (!shared && hoverSeries && hoverSeries.directTouch),
12640
12732
  hoverData = this.getHoverData(hoverPoint, hoverSeries, series, isDirectTouch, shared, e),
12641
12733
  useSharedTooltip,
12642
12734
  followPointer,
@@ -12648,7 +12740,10 @@
12648
12740
  hoverSeries = hoverData.hoverSeries;
12649
12741
  followPointer = hoverSeries && hoverSeries.tooltipOptions.followPointer;
12650
12742
  useSharedTooltip = shared && hoverPoint && !hoverPoint.series.noSharedTooltip;
12651
- points = useSharedTooltip ? hoverData.hoverPoints : [hoverPoint];
12743
+ points = (useSharedTooltip ?
12744
+ hoverData.hoverPoints :
12745
+ (hoverPoint ? [hoverPoint] : [])
12746
+ );
12652
12747
 
12653
12748
  // Refresh tooltip for kdpoint if new hover point or tooltip was hidden // #3926, #4200
12654
12749
  if (
@@ -12703,15 +12798,20 @@
12703
12798
  });
12704
12799
  }
12705
12800
 
12706
- // Crosshair. For each hover point, loop over axes and draw cross if that point
12707
- // belongs to the axis (#4927).
12708
- each(points, function drawPointCrosshair(point) { // #5269
12709
- each(chart.axes, function drawAxisCrosshair(axis) {
12710
- // In case of snap = false, point is undefined, and we draw the crosshair anyway (#5066)
12711
- if (!point || point.series && point.series[axis.coll] === axis) { // #5658
12712
- axis.drawCrosshair(e, point);
12713
- }
12714
- });
12801
+ // Draw crosshairs (#4927, #5269 #5066, #5658)
12802
+ each(chart.axes, function drawAxisCrosshair(axis) {
12803
+ // Snap is true. For each hover point, loop over the axes and draw a
12804
+ // crosshair if that point belongs to the axis.
12805
+ // @todo Consider only one crosshair per axis.
12806
+ if (pick(axis.crosshair.snap, true)) {
12807
+ each(points, function(p) {
12808
+ if (p.series[axis.coll] === axis) {
12809
+ axis.drawCrosshair(e, p);
12810
+ }
12811
+ });
12812
+ } else {
12813
+ axis.drawCrosshair(e);
12814
+ }
12715
12815
  });
12716
12816
  },
12717
12817
 
@@ -13091,7 +13191,7 @@
13091
13191
  var series = this.chart.hoverSeries,
13092
13192
  relatedTarget = e.relatedTarget || e.toElement;
13093
13193
 
13094
- if (series && relatedTarget && !series.options.stickyTracking &&
13194
+ if (series && relatedTarget && !series.stickyTracking &&
13095
13195
  !this.inClass(relatedTarget, 'highcharts-tooltip') &&
13096
13196
  (!this.inClass(relatedTarget, 'highcharts-series-' + series.index) || // #2499, #4465
13097
13197
  !this.inClass(relatedTarget, 'highcharts-tracker') // #5553
@@ -13181,7 +13281,15 @@
13181
13281
  destroy: function() {
13182
13282
  var prop;
13183
13283
 
13184
- removeEvent(this.chart.container, 'mouseleave', this.onContainerMouseLeave);
13284
+ if (this.unDocMouseMove) {
13285
+ this.unDocMouseMove();
13286
+ }
13287
+
13288
+ removeEvent(
13289
+ this.chart.container,
13290
+ 'mouseleave',
13291
+ this.onContainerMouseLeave
13292
+ );
13185
13293
  if (!H.chartCount) {
13186
13294
  removeEvent(doc, 'mouseup', this.onDocumentMouseUp);
13187
13295
  removeEvent(doc, 'touchend', this.onDocumentTouchEnd);
@@ -13199,7 +13307,7 @@
13199
13307
  }(Highcharts));
13200
13308
  (function(H) {
13201
13309
  /**
13202
- * (c) 2010-2016 Torstein Honsi
13310
+ * (c) 2010-2017 Torstein Honsi
13203
13311
  *
13204
13312
  * License: www.highcharts.com/license
13205
13313
  */
@@ -13476,7 +13584,7 @@
13476
13584
  }(Highcharts));
13477
13585
  (function(H) {
13478
13586
  /**
13479
- * (c) 2010-2016 Torstein Honsi
13587
+ * (c) 2010-2017 Torstein Honsi
13480
13588
  *
13481
13589
  * License: www.highcharts.com/license
13482
13590
  */
@@ -13595,7 +13703,7 @@
13595
13703
  }(Highcharts));
13596
13704
  (function(H) {
13597
13705
  /**
13598
- * (c) 2010-2016 Torstein Honsi
13706
+ * (c) 2010-2017 Torstein Honsi
13599
13707
  *
13600
13708
  * License: www.highcharts.com/license
13601
13709
  */
@@ -13657,8 +13765,7 @@
13657
13765
 
13658
13766
  this.itemMarginTop = options.itemMarginTop || 0;
13659
13767
  this.padding = padding;
13660
- this.initialItemX = padding;
13661
- this.initialItemY = padding - 5; // 5 is the number of pixels above the text
13768
+ this.initialItemY = padding - 5; // 5 is pixels above the text
13662
13769
  this.maxItemWidth = 0;
13663
13770
  this.itemHeight = 0;
13664
13771
  this.symbolWidth = pick(options.symbolWidth, 16);
@@ -13667,8 +13774,8 @@
13667
13774
  },
13668
13775
 
13669
13776
  /**
13670
- * Update the legend with new options. Equivalent to running chart.update with a legend
13671
- * configuration option.
13777
+ * Update the legend with new options. Equivalent to running chart.update
13778
+ * with a legend configuration option.
13672
13779
  * @param {Object} options Legend options
13673
13780
  * @param {Boolean} redraw Whether to redraw the chart, defaults to true.
13674
13781
  */
@@ -13689,7 +13796,9 @@
13689
13796
  * @param {Object} visible Dimmed or colored
13690
13797
  */
13691
13798
  colorizeItem: function(item, visible) {
13692
- item.legendGroup[visible ? 'removeClass' : 'addClass']('highcharts-legend-item-hidden');
13799
+ item.legendGroup[visible ? 'removeClass' : 'addClass'](
13800
+ 'highcharts-legend-item-hidden'
13801
+ );
13693
13802
 
13694
13803
 
13695
13804
  var legend = this,
@@ -13709,8 +13818,8 @@
13709
13818
  if (legendItem) {
13710
13819
  legendItem.css({
13711
13820
  fill: textColor,
13712
- color: textColor
13713
- }); // color for #1553, oldIE
13821
+ color: textColor // #1553, oldIE
13822
+ });
13714
13823
  }
13715
13824
  if (legendLine) {
13716
13825
  legendLine.attr({
@@ -13753,7 +13862,9 @@
13753
13862
 
13754
13863
  if (legendGroup && legendGroup.element) {
13755
13864
  legendGroup.translate(
13756
- ltr ? itemX : legend.legendWidth - itemX - 2 * symbolPadding - 4,
13865
+ ltr ?
13866
+ itemX :
13867
+ legend.legendWidth - itemX - 2 * symbolPadding - 4,
13757
13868
  itemY
13758
13869
  );
13759
13870
  }
@@ -13772,11 +13883,14 @@
13772
13883
  var checkbox = item.checkbox;
13773
13884
 
13774
13885
  // destroy SVG elements
13775
- each(['legendItem', 'legendLine', 'legendSymbol', 'legendGroup'], function(key) {
13776
- if (item[key]) {
13777
- item[key] = item[key].destroy();
13886
+ each(
13887
+ ['legendItem', 'legendLine', 'legendSymbol', 'legendGroup'],
13888
+ function(key) {
13889
+ if (item[key]) {
13890
+ item[key] = item[key].destroy();
13891
+ }
13778
13892
  }
13779
- });
13893
+ );
13780
13894
 
13781
13895
  if (checkbox) {
13782
13896
  discardElement(item.checkbox);
@@ -13828,11 +13942,14 @@
13828
13942
  top;
13829
13943
 
13830
13944
  if (checkbox) {
13831
- top = translateY + titleHeight + checkbox.y + (scrollOffset || 0) + 3;
13945
+ top = translateY + titleHeight + checkbox.y +
13946
+ (scrollOffset || 0) + 3;
13832
13947
  css(checkbox, {
13833
- left: (alignAttr.translateX + item.checkboxOffset + checkbox.x - 20) + 'px',
13948
+ left: (alignAttr.translateX + item.checkboxOffset +
13949
+ checkbox.x - 20) + 'px',
13834
13950
  top: top + 'px',
13835
- display: top > translateY - 6 && top < translateY + clipHeight - 6 ? '' : 'none'
13951
+ display: top > translateY - 6 && top < translateY +
13952
+ clipHeight - 6 ? '' : 'none'
13836
13953
  });
13837
13954
  }
13838
13955
  });
@@ -13851,7 +13968,17 @@
13851
13968
 
13852
13969
  if (titleOptions.text) {
13853
13970
  if (!this.title) {
13854
- this.title = this.chart.renderer.label(titleOptions.text, padding - 3, padding - 4, null, null, null, null, null, 'legend-title')
13971
+ this.title = this.chart.renderer.label(
13972
+ titleOptions.text,
13973
+ padding - 3,
13974
+ padding - 4,
13975
+ null,
13976
+ null,
13977
+ null,
13978
+ null,
13979
+ null,
13980
+ 'legend-title'
13981
+ )
13855
13982
  .attr({
13856
13983
  zIndex: 1
13857
13984
  })
@@ -13876,7 +14003,8 @@
13876
14003
  setText: function(item) {
13877
14004
  var options = this.options;
13878
14005
  item.legendItem.attr({
13879
- text: options.labelFormat ? H.format(options.labelFormat, item) : options.labelFormatter.call(item)
14006
+ text: options.labelFormat ?
14007
+ H.format(options.labelFormat, item) : options.labelFormatter.call(item)
13880
14008
  });
13881
14009
  },
13882
14010
 
@@ -13903,24 +14031,30 @@
13903
14031
  widthOption = options.width,
13904
14032
  itemMarginBottom = options.itemMarginBottom || 0,
13905
14033
  itemMarginTop = legend.itemMarginTop,
13906
- initialItemX = legend.initialItemX,
13907
14034
  bBox,
13908
14035
  itemWidth,
13909
14036
  li = item.legendItem,
13910
14037
  isSeries = !item.series,
13911
- series = !isSeries && item.series.drawLegendSymbol ? item.series : item,
14038
+ series = !isSeries && item.series.drawLegendSymbol ?
14039
+ item.series :
14040
+ item,
13912
14041
  seriesOptions = series.options,
13913
- showCheckbox = legend.createCheckboxForItem && seriesOptions && seriesOptions.showCheckbox,
14042
+ showCheckbox = legend.createCheckboxForItem &&
14043
+ seriesOptions &&
14044
+ seriesOptions.showCheckbox,
13914
14045
  useHTML = options.useHTML,
13915
- fontSize = 12;
14046
+ fontSize = 12,
14047
+ itemClassName = item.options.className;
13916
14048
 
13917
14049
  if (!li) { // generate it once, later move it
13918
14050
 
13919
- // Generate the group box
13920
- // A group to hold the symbol and text. Text is to be appended in Legend class.
14051
+ // Generate the group box, a group to hold the symbol and text. Text
14052
+ // is to be appended in Legend class.
13921
14053
  item.legendGroup = renderer.g('legend-item')
13922
- .addClass('highcharts-' + series.type + '-series highcharts-color-' + item.colorIndex +
13923
- (item.options.className ? ' ' + item.options.className : '') +
14054
+ .addClass(
14055
+ 'highcharts-' + series.type + '-series ' +
14056
+ 'highcharts-color-' + item.colorIndex +
14057
+ (itemClassName ? ' ' + itemClassName : '') +
13924
14058
  (isSeries ? ' highcharts-series-' + item.index : '')
13925
14059
  )
13926
14060
  .attr({
@@ -13936,7 +14070,8 @@
13936
14070
  useHTML
13937
14071
  )
13938
14072
 
13939
- .css(merge(item.visible ? itemStyle : itemHiddenStyle)) // merge to prevent modifying original (#1021)
14073
+ // merge to prevent modifying original (#1021)
14074
+ .css(merge(item.visible ? itemStyle : itemHiddenStyle))
13940
14075
 
13941
14076
  .attr({
13942
14077
  align: ltr ? 'left' : 'right',
@@ -13944,7 +14079,8 @@
13944
14079
  })
13945
14080
  .add(item.legendGroup);
13946
14081
 
13947
- // Get the baseline for the first item - the font size is equal for all
14082
+ // Get the baseline for the first item - the font size is equal for
14083
+ // all
13948
14084
  if (!legend.baseline) {
13949
14085
 
13950
14086
  fontSize = itemStyle.fontSize;
@@ -13983,19 +14119,30 @@
13983
14119
  itemWidth = item.checkboxOffset =
13984
14120
  options.itemWidth ||
13985
14121
  item.legendItemWidth ||
13986
- symbolWidth + symbolPadding + bBox.width + itemDistance + (showCheckbox ? 20 : 0);
13987
- legend.itemHeight = itemHeight = Math.round(item.legendItemHeight || bBox.height);
13988
-
13989
- // if the item exceeds the width, start a new line
13990
- if (horizontal && legend.itemX - initialItemX + itemWidth >
13991
- (widthOption || (chart.chartWidth - 2 * padding - initialItemX - options.x))) {
13992
- legend.itemX = initialItemX;
13993
- legend.itemY += itemMarginTop + legend.lastLineHeight + itemMarginBottom;
14122
+ symbolWidth + symbolPadding + bBox.width + itemDistance +
14123
+ (showCheckbox ? 20 : 0);
14124
+ legend.itemHeight = itemHeight = Math.round(
14125
+ item.legendItemHeight || bBox.height || legend.symbolHeight
14126
+ );
14127
+
14128
+ // If the item exceeds the width, start a new line
14129
+ if (
14130
+ horizontal &&
14131
+ legend.itemX - padding + itemWidth > (
14132
+ widthOption || (
14133
+ chart.spacingBox.width - 2 * padding - options.x
14134
+ )
14135
+ )
14136
+ ) {
14137
+ legend.itemX = padding;
14138
+ legend.itemY += itemMarginTop + legend.lastLineHeight +
14139
+ itemMarginBottom;
13994
14140
  legend.lastLineHeight = 0; // reset for next line (#915, #3976)
13995
14141
  }
13996
14142
 
13997
14143
  // If the item exceeds the height, start a new column
13998
- /*if (!horizontal && legend.itemY + options.y + itemHeight > chart.chartHeight - spacingTop - spacingBottom) {
14144
+ /*if (!horizontal && legend.itemY + options.y +
14145
+ itemHeight > chart.chartHeight - spacingTop - spacingBottom) {
13999
14146
  legend.itemY = legend.initialItemY;
14000
14147
  legend.itemX += legend.maxItemWidth;
14001
14148
  legend.maxItemWidth = 0;
@@ -14004,7 +14151,10 @@
14004
14151
  // Set the edge positions
14005
14152
  legend.maxItemWidth = Math.max(legend.maxItemWidth, itemWidth);
14006
14153
  legend.lastItemY = itemMarginTop + legend.itemY + itemMarginBottom;
14007
- legend.lastLineHeight = Math.max(itemHeight, legend.lastLineHeight); // #915
14154
+ legend.lastLineHeight = Math.max( // #915
14155
+ itemHeight,
14156
+ legend.lastLineHeight
14157
+ );
14008
14158
 
14009
14159
  // cache the position of the newly generated or reordered items
14010
14160
  item._legendItemPos = [legend.itemX, legend.itemY];
@@ -14020,29 +14170,36 @@
14020
14170
 
14021
14171
  // the width of the widest item
14022
14172
  legend.offsetWidth = widthOption || Math.max(
14023
- (horizontal ? legend.itemX - initialItemX - itemDistance : itemWidth) + padding,
14173
+ (horizontal ? legend.itemX - padding - itemDistance : itemWidth) +
14174
+ padding,
14024
14175
  legend.offsetWidth
14025
14176
  );
14026
14177
  },
14027
14178
 
14028
14179
  /**
14029
- * Get all items, which is one item per series for normal series and one item per point
14030
- * for pie series.
14180
+ * Get all items, which is one item per series for normal series and one
14181
+ * item per point for pie series.
14031
14182
  */
14032
14183
  getAllItems: function() {
14033
14184
  var allItems = [];
14034
14185
  each(this.chart.series, function(series) {
14035
14186
  var seriesOptions = series && series.options;
14036
14187
 
14037
- // Handle showInLegend. If the series is linked to another series, defaults to false.
14038
- if (series && pick(seriesOptions.showInLegend, !defined(seriesOptions.linkedTo) ? undefined : false, true)) {
14188
+ // Handle showInLegend. If the series is linked to another series,
14189
+ // defaults to false.
14190
+ if (series && pick(
14191
+ seriesOptions.showInLegend, !defined(seriesOptions.linkedTo) ? undefined : false, true
14192
+ )) {
14039
14193
 
14040
- // Use points or series for the legend item depending on legendType
14194
+ // Use points or series for the legend item depending on
14195
+ // legendType
14041
14196
  allItems = allItems.concat(
14042
14197
  series.legendItems ||
14043
- (seriesOptions.legendType === 'point' ?
14198
+ (
14199
+ seriesOptions.legendType === 'point' ?
14044
14200
  series.data :
14045
- series)
14201
+ series
14202
+ )
14046
14203
  );
14047
14204
  }
14048
14205
  });
@@ -14050,15 +14207,18 @@
14050
14207
  },
14051
14208
 
14052
14209
  /**
14053
- * Adjust the chart margins by reserving space for the legend on only one side
14054
- * of the chart. If the position is set to a corner, top or bottom is reserved
14055
- * for horizontal legends and left or right for vertical ones.
14210
+ * Adjust the chart margins by reserving space for the legend on only one
14211
+ * side of the chart. If the position is set to a corner, top or bottom is
14212
+ * reserved for horizontal legends and left or right for vertical ones.
14056
14213
  */
14057
14214
  adjustMargins: function(margin, spacing) {
14058
14215
  var chart = this.chart,
14059
14216
  options = this.options,
14060
- // Use the first letter of each alignment option in order to detect the side
14061
- alignment = options.align.charAt(0) + options.verticalAlign.charAt(0) + options.layout.charAt(0); // #4189 - use charAt(x) notation instead of [x] for IE7
14217
+ // Use the first letter of each alignment option in order to detect
14218
+ // the side. (#4189 - use charAt(x) notation instead of [x] for IE7)
14219
+ alignment = options.align.charAt(0) +
14220
+ options.verticalAlign.charAt(0) +
14221
+ options.layout.charAt(0);
14062
14222
 
14063
14223
  if (!options.floating) {
14064
14224
 
@@ -14069,12 +14229,19 @@
14069
14229
  /(lbv|lm|ltv)/
14070
14230
  ], function(alignments, side) {
14071
14231
  if (alignments.test(alignment) && !defined(margin[side])) {
14072
- // Now we have detected on which side of the chart we should reserve space for the legend
14232
+ // Now we have detected on which side of the chart we should
14233
+ // reserve space for the legend
14073
14234
  chart[marginNames[side]] = Math.max(
14074
14235
  chart[marginNames[side]],
14075
- chart.legend[(side + 1) % 2 ? 'legendHeight' : 'legendWidth'] + [1, -1, -1, 1][side] * options[(side % 2) ? 'x' : 'y'] +
14076
- pick(options.margin, 12) +
14077
- spacing[side]
14236
+ (
14237
+ chart.legend[
14238
+ (side + 1) % 2 ? 'legendHeight' : 'legendWidth'
14239
+ ] + [1, -1, -1, 1][side] * options[
14240
+ (side % 2) ? 'x' : 'y'
14241
+ ] +
14242
+ pick(options.margin, 12) +
14243
+ spacing[side]
14244
+ )
14078
14245
  );
14079
14246
  }
14080
14247
  });
@@ -14099,7 +14266,7 @@
14099
14266
  options = legend.options,
14100
14267
  padding = legend.padding;
14101
14268
 
14102
- legend.itemX = legend.initialItemX;
14269
+ legend.itemX = padding;
14103
14270
  legend.itemY = legend.initialItemY;
14104
14271
  legend.offsetWidth = 0;
14105
14272
  legend.lastItemY = 0;
@@ -14126,7 +14293,8 @@
14126
14293
 
14127
14294
  // sort by legendIndex
14128
14295
  stableSort(allItems, function(a, b) {
14129
- return ((a.options && a.options.legendIndex) || 0) - ((b.options && b.options.legendIndex) || 0);
14296
+ return ((a.options && a.options.legendIndex) || 0) -
14297
+ ((b.options && b.options.legendIndex) || 0);
14130
14298
  });
14131
14299
 
14132
14300
  // reversed legend
@@ -14145,7 +14313,8 @@
14145
14313
 
14146
14314
  // Get the box
14147
14315
  legendWidth = (options.width || legend.offsetWidth) + padding;
14148
- legendHeight = legend.lastItemY + legend.lastLineHeight + legend.titleHeight;
14316
+ legendHeight = legend.lastItemY + legend.lastLineHeight +
14317
+ legend.titleHeight;
14149
14318
  legendHeight = legend.handleOverflow(legendHeight);
14150
14319
  legendHeight += padding;
14151
14320
 
@@ -14191,8 +14360,8 @@
14191
14360
  legend.legendWidth = legendWidth;
14192
14361
  legend.legendHeight = legendHeight;
14193
14362
 
14194
- // Now that the legend width and height are established, put the items in the
14195
- // final position
14363
+ // Now that the legend width and height are established, put the items
14364
+ // in the final position
14196
14365
  each(allItems, function(item) {
14197
14366
  legend.positionItem(item);
14198
14367
  });
@@ -14205,7 +14374,8 @@
14205
14374
  prop = props[i];
14206
14375
  if (options.style[prop] && options.style[prop] !== 'auto') {
14207
14376
  options[i < 2 ? 'align' : 'verticalAlign'] = prop;
14208
- options[i < 2 ? 'x' : 'y'] = pInt(options.style[prop]) * (i % 2 ? -1 : 1);
14377
+ options[i < 2 ? 'x' : 'y'] =
14378
+ pInt(options.style[prop]) * (i % 2 ? -1 : 1);
14209
14379
  }
14210
14380
  }*/
14211
14381
 
@@ -14222,8 +14392,8 @@
14222
14392
  },
14223
14393
 
14224
14394
  /**
14225
- * Set up the overflow handling by adding navigation with up and down arrows below the
14226
- * legend.
14395
+ * Set up the overflow handling by adding navigation with up and down arrows
14396
+ * below the legend.
14227
14397
  */
14228
14398
  handleOverflow: function(legendHeight) {
14229
14399
  var legend = this,
@@ -14232,7 +14402,9 @@
14232
14402
  options = this.options,
14233
14403
  optionsY = options.y,
14234
14404
  alignTop = options.verticalAlign === 'top',
14235
- spaceHeight = chart.spacingBox.height + (alignTop ? -optionsY : optionsY) - this.padding,
14405
+ padding = this.padding,
14406
+ spaceHeight = chart.spacingBox.height +
14407
+ (alignTop ? -optionsY : optionsY) - padding,
14236
14408
  maxHeight = options.maxHeight,
14237
14409
  clipHeight,
14238
14410
  clipRect = this.clipRect,
@@ -14241,7 +14413,6 @@
14241
14413
  arrowSize = navOptions.arrowSize || 12,
14242
14414
  nav = this.nav,
14243
14415
  pages = this.pages,
14244
- padding = this.padding,
14245
14416
  lastY,
14246
14417
  allItems = this.allItems,
14247
14418
  clipToHeight = function(height) {
@@ -14265,7 +14436,11 @@
14265
14436
 
14266
14437
 
14267
14438
  // Adjust the height
14268
- if (options.layout === 'horizontal' && options.verticalAlign !== 'middle' && !options.floating) {
14439
+ if (
14440
+ options.layout === 'horizontal' &&
14441
+ options.verticalAlign !== 'middle' &&
14442
+ !options.floating
14443
+ ) {
14269
14444
  spaceHeight /= 2;
14270
14445
  }
14271
14446
  if (maxHeight) {
@@ -14276,23 +14451,26 @@
14276
14451
  pages.length = 0;
14277
14452
  if (legendHeight > spaceHeight && navOptions.enabled !== false) {
14278
14453
 
14279
- this.clipHeight = clipHeight = Math.max(spaceHeight - 20 - this.titleHeight - padding, 0);
14454
+ this.clipHeight = clipHeight =
14455
+ Math.max(spaceHeight - 20 - this.titleHeight - padding, 0);
14280
14456
  this.currentPage = pick(this.currentPage, 1);
14281
14457
  this.fullHeight = legendHeight;
14282
14458
 
14283
- // Fill pages with Y positions so that the top of each a legend item defines
14284
- // the scroll top for each page (#2098)
14459
+ // Fill pages with Y positions so that the top of each a legend item
14460
+ // defines the scroll top for each page (#2098)
14285
14461
  each(allItems, function(item, i) {
14286
14462
  var y = item._legendItemPos[1],
14287
14463
  h = Math.round(item.legendItem.getBBox().height),
14288
14464
  len = pages.length;
14289
14465
 
14290
- if (!len || (y - pages[len - 1] > clipHeight && (lastY || y) !== pages[len - 1])) {
14466
+ if (!len || (y - pages[len - 1] > clipHeight &&
14467
+ (lastY || y) !== pages[len - 1])) {
14291
14468
  pages.push(lastY || y);
14292
14469
  len++;
14293
14470
  }
14294
14471
 
14295
- if (i === allItems.length - 1 && y + h - pages[len - 1] > clipHeight) {
14472
+ if (i === allItems.length - 1 &&
14473
+ y + h - pages[len - 1] > clipHeight) {
14296
14474
  pages.push(y);
14297
14475
  }
14298
14476
  if (y !== lastY) {
@@ -14300,9 +14478,11 @@
14300
14478
  }
14301
14479
  });
14302
14480
 
14303
- // Only apply clipping if needed. Clipping causes blurred legend in PDF export (#1787)
14481
+ // Only apply clipping if needed. Clipping causes blurred legend in
14482
+ // PDF export (#1787)
14304
14483
  if (!clipRect) {
14305
- clipRect = legend.clipRect = renderer.clipRect(0, padding, 9999, 0);
14484
+ clipRect = legend.clipRect =
14485
+ renderer.clipRect(0, padding, 9999, 0);
14306
14486
  legend.contentGroup.clip(clipRect);
14307
14487
  }
14308
14488
 
@@ -14310,21 +14490,40 @@
14310
14490
 
14311
14491
  // Add navigation elements
14312
14492
  if (!nav) {
14313
- this.nav = nav = renderer.g().attr({
14314
- zIndex: 1
14315
- }).add(this.group);
14316
- this.up = renderer.symbol('triangle', 0, 0, arrowSize, arrowSize)
14493
+ this.nav = nav = renderer.g()
14494
+ .attr({
14495
+ zIndex: 1
14496
+ })
14497
+ .add(this.group);
14498
+
14499
+ this.up = renderer
14500
+ .symbol(
14501
+ 'triangle',
14502
+ 0,
14503
+ 0,
14504
+ arrowSize,
14505
+ arrowSize
14506
+ )
14317
14507
  .on('click', function() {
14318
14508
  legend.scroll(-1, animation);
14319
14509
  })
14320
14510
  .add(nav);
14511
+
14321
14512
  this.pager = renderer.text('', 15, 10)
14322
14513
  .addClass('highcharts-legend-navigation')
14323
14514
 
14324
14515
  .css(navOptions.style)
14325
14516
 
14326
14517
  .add(nav);
14327
- this.down = renderer.symbol('triangle-down', 0, 0, arrowSize, arrowSize)
14518
+
14519
+ this.down = renderer
14520
+ .symbol(
14521
+ 'triangle-down',
14522
+ 0,
14523
+ 0,
14524
+ arrowSize,
14525
+ arrowSize
14526
+ )
14328
14527
  .on('click', function() {
14329
14528
  legend.scroll(1, animation);
14330
14529
  })
@@ -14381,27 +14580,31 @@
14381
14580
  visibility: 'visible'
14382
14581
  });
14383
14582
  this.up.attr({
14384
- 'class': currentPage === 1 ? 'highcharts-legend-nav-inactive' : 'highcharts-legend-nav-active'
14583
+ 'class': currentPage === 1 ?
14584
+ 'highcharts-legend-nav-inactive' : 'highcharts-legend-nav-active'
14385
14585
  });
14386
14586
  pager.attr({
14387
14587
  text: currentPage + '/' + pageCount
14388
14588
  });
14389
14589
  this.down.attr({
14390
14590
  'x': 18 + this.pager.getBBox().width, // adjust to text width
14391
- 'class': currentPage === pageCount ? 'highcharts-legend-nav-inactive' : 'highcharts-legend-nav-active'
14591
+ 'class': currentPage === pageCount ?
14592
+ 'highcharts-legend-nav-inactive' : 'highcharts-legend-nav-active'
14392
14593
  });
14393
14594
 
14394
14595
 
14395
14596
  this.up
14396
14597
  .attr({
14397
- fill: currentPage === 1 ? navOptions.inactiveColor : navOptions.activeColor
14598
+ fill: currentPage === 1 ?
14599
+ navOptions.inactiveColor : navOptions.activeColor
14398
14600
  })
14399
14601
  .css({
14400
14602
  cursor: currentPage === 1 ? 'default' : 'pointer'
14401
14603
  });
14402
14604
  this.down
14403
14605
  .attr({
14404
- fill: currentPage === pageCount ? navOptions.inactiveColor : navOptions.activeColor
14606
+ fill: currentPage === pageCount ?
14607
+ navOptions.inactiveColor : navOptions.activeColor
14405
14608
  })
14406
14609
  .css({
14407
14610
  cursor: currentPage === pageCount ? 'default' : 'pointer'
@@ -14455,8 +14658,9 @@
14455
14658
  },
14456
14659
 
14457
14660
  /**
14458
- * Get the series' symbol in the legend. This method should be overridable to create custom
14459
- * symbols through Highcharts.seriesTypes[type].prototype.drawLegendSymbols.
14661
+ * Get the series' symbol in the legend. This method should be overridable
14662
+ * to create custom symbols through
14663
+ * Highcharts.seriesTypes[type].prototype.drawLegendSymbols.
14460
14664
  *
14461
14665
  * @param {Object} legend The legend object
14462
14666
  */
@@ -14471,7 +14675,8 @@
14471
14675
  generalRadius = symbolHeight / 2,
14472
14676
  renderer = this.chart.renderer,
14473
14677
  legendItemGroup = this.legendGroup,
14474
- verticalCenter = legend.baseline - Math.round(legend.fontMetrics.b * 0.3),
14678
+ verticalCenter = legend.baseline -
14679
+ Math.round(legend.fontMetrics.b * 0.3),
14475
14680
  attr = {};
14476
14681
 
14477
14682
  // Draw the line
@@ -14532,11 +14737,13 @@
14532
14737
  // Workaround for #2030, horizontal legend items not displaying in IE11 Preview,
14533
14738
  // and for #2580, a similar drawing flaw in Firefox 26.
14534
14739
  // Explore if there's a general cause for this. The problem may be related
14535
- // to nested group elements, as the legend item texts are within 4 group elements.
14740
+ // to nested group elements, as the legend item texts are within 4 group
14741
+ // elements.
14536
14742
  if (/Trident\/7\.0/.test(win.navigator.userAgent) || isFirefox) {
14537
14743
  wrap(Legend.prototype, 'positionItem', function(proceed, item) {
14538
14744
  var legend = this,
14539
- runPositionItem = function() { // If chart destroyed in sync, this is undefined (#2030)
14745
+ // If chart destroyed in sync, this is undefined (#2030)
14746
+ runPositionItem = function() {
14540
14747
  if (item._legendItemPos) {
14541
14748
  proceed.call(legend, item);
14542
14749
  }
@@ -14553,7 +14760,7 @@
14553
14760
  }(Highcharts));
14554
14761
  (function(H) {
14555
14762
  /**
14556
- * (c) 2010-2016 Torstein Honsi
14763
+ * (c) 2010-2017 Torstein Honsi
14557
14764
  *
14558
14765
  * License: www.highcharts.com/license
14559
14766
  */
@@ -15104,7 +15311,8 @@
15104
15311
  },
15105
15312
 
15106
15313
  /**
15107
- * Lay out the chart titles and cache the full offset height for use in getMargins
15314
+ * Lay out the chart titles and cache the full offset height for use
15315
+ * in getMargins
15108
15316
  */
15109
15317
  layOutTitles: function(redraw) {
15110
15318
  var titleOffset = 0,
@@ -15126,14 +15334,19 @@
15126
15334
 
15127
15335
  title
15128
15336
  .css({
15129
- width: (titleOptions.width || spacingBox.width + titleOptions.widthAdjust) + 'px'
15337
+ width: (titleOptions.width ||
15338
+ spacingBox.width + titleOptions.widthAdjust) + 'px'
15130
15339
  })
15131
15340
  .align(extend({
15132
15341
  y: titleOffset + titleSize + (key === 'title' ? -3 : 2)
15133
15342
  }, titleOptions), false, 'spacingBox');
15134
15343
 
15135
15344
  if (!titleOptions.floating && !titleOptions.verticalAlign) {
15136
- titleOffset = Math.ceil(titleOffset + title.getBBox().height);
15345
+ titleOffset = Math.ceil(
15346
+ titleOffset +
15347
+ // Skip the cache for HTML (#3481)
15348
+ title.getBBox(titleOptions.useHTML).height
15349
+ );
15137
15350
  }
15138
15351
  }
15139
15352
  }, this);
@@ -16156,7 +16369,7 @@
16156
16369
  }(Highcharts));
16157
16370
  (function(H) {
16158
16371
  /**
16159
- * (c) 2010-2016 Torstein Honsi
16372
+ * (c) 2010-2017 Torstein Honsi
16160
16373
  *
16161
16374
  * License: www.highcharts.com/license
16162
16375
  */
@@ -16506,7 +16719,7 @@
16506
16719
  }(Highcharts));
16507
16720
  (function(H) {
16508
16721
  /**
16509
- * (c) 2010-2016 Torstein Honsi
16722
+ * (c) 2010-2017 Torstein Honsi
16510
16723
  *
16511
16724
  * License: www.highcharts.com/license
16512
16725
  */
@@ -16669,9 +16882,9 @@
16669
16882
  //valuePrefix: '',
16670
16883
  //ySuffix: ''
16671
16884
  //}
16672
- turboThreshold: 1000
16885
+ turboThreshold: 1000,
16673
16886
  // zIndex: null
16674
-
16887
+ findNearestPointBy: 'x'
16675
16888
 
16676
16889
  }, /** @lends Series.prototype */ {
16677
16890
  isCartesian: true,
@@ -16915,6 +17128,19 @@
16915
17128
  itemOptions.tooltip
16916
17129
  );
16917
17130
 
17131
+ // When shared tooltip, stickyTracking is true by default,
17132
+ // unless user says otherwise.
17133
+ this.stickyTracking = pick(
17134
+ itemOptions.stickyTracking,
17135
+ userPlotOptions[this.type] && userPlotOptions[this.type].stickyTracking,
17136
+ userPlotOptions.series && userPlotOptions.series.stickyTracking,
17137
+ (
17138
+ this.tooltipOptions.shared && !this.noSharedTooltip ?
17139
+ true :
17140
+ options.stickyTracking
17141
+ )
17142
+ );
17143
+
16918
17144
  // Delete marker object if not allowed (#1125)
16919
17145
  if (typeOptions.marker === null) {
16920
17146
  delete options.marker;
@@ -17300,8 +17526,10 @@
17300
17526
  point = (new PointClass()).init(series, [processedXData[i]].concat(splat(processedYData[i])));
17301
17527
  point.dataGroup = series.groupMap[i];
17302
17528
  }
17303
- point.index = cursor; // For faster access in Point.update
17304
- points[i] = point;
17529
+ if (point) { // #6279
17530
+ point.index = cursor; // For faster access in Point.update
17531
+ points[i] = point;
17532
+ }
17305
17533
  }
17306
17534
 
17307
17535
  // Hide cropped-away points - this only runs when the number of points is above cropThreshold, or when
@@ -17354,7 +17582,7 @@
17354
17582
  // visible range, consider y extremes
17355
17583
  validValue = (isNumber(y, true) || isArray(y)) && (!yAxis.positiveValuesOnly || (y.length || y > 0));
17356
17584
  withinRange = this.getExtremesFromAll || this.options.getExtremesFromAll || this.cropped ||
17357
- ((xData[i + 1] || x) >= xMin && (xData[i - 1] || x) <= xMax);
17585
+ ((xData[i] || x) >= xMin && (xData[i] || x) <= xMax);
17358
17586
 
17359
17587
  if (validValue && withinRange) {
17360
17588
 
@@ -17370,6 +17598,7 @@
17370
17598
  }
17371
17599
  }
17372
17600
  }
17601
+
17373
17602
  this.dataMin = arrayMin(activeYData);
17374
17603
  this.dataMax = arrayMax(activeYData);
17375
17604
  },
@@ -17582,7 +17811,6 @@
17582
17811
  chart[sharedClipKey] = chart[sharedClipKey].destroy();
17583
17812
  }
17584
17813
  if (chart[sharedClipKey + 'm']) {
17585
- this.markerGroup.clip();
17586
17814
  chart[sharedClipKey + 'm'] = chart[sharedClipKey + 'm'].destroy();
17587
17815
  }
17588
17816
  }
@@ -18426,7 +18654,6 @@
18426
18654
  * KD Tree && PointSearching Implementation
18427
18655
  */
18428
18656
 
18429
- kdDimensions: 1,
18430
18657
  kdAxisArray: ['clientX', 'plotY'],
18431
18658
 
18432
18659
  searchPoint: function(e, compareX) {
@@ -18453,7 +18680,8 @@
18453
18680
  this.buildingKdTree = true;
18454
18681
 
18455
18682
  var series = this,
18456
- dimensions = series.kdDimensions;
18683
+ dimensions = series.options.findNearestPointBy.indexOf('y') > -1 ?
18684
+ 2 : 1;
18457
18685
 
18458
18686
  // Internal function
18459
18687
  function _kdtree(points, depth, dimensions) {
@@ -18504,7 +18732,9 @@
18504
18732
  var series = this,
18505
18733
  kdX = this.kdAxisArray[0],
18506
18734
  kdY = this.kdAxisArray[1],
18507
- kdComparer = compareX ? 'distX' : 'dist';
18735
+ kdComparer = compareX ? 'distX' : 'dist',
18736
+ kdDimensions = series.options.findNearestPointBy.indexOf('y') > -1 ?
18737
+ 2 : 1;
18508
18738
 
18509
18739
  // Set the one and two dimensional distance on the point object
18510
18740
  function setDistance(p1, p2) {
@@ -18555,8 +18785,7 @@
18555
18785
  }
18556
18786
 
18557
18787
  if (this.kdTree) {
18558
- return _search(point,
18559
- this.kdTree, this.kdDimensions, this.kdDimensions);
18788
+ return _search(point, this.kdTree, kdDimensions, kdDimensions);
18560
18789
  }
18561
18790
  }
18562
18791
 
@@ -18565,7 +18794,7 @@
18565
18794
  }(Highcharts));
18566
18795
  (function(H) {
18567
18796
  /**
18568
- * (c) 2010-2016 Torstein Honsi
18797
+ * (c) 2010-2017 Torstein Honsi
18569
18798
  *
18570
18799
  * License: www.highcharts.com/license
18571
18800
  */
@@ -19050,7 +19279,7 @@
19050
19279
  }(Highcharts));
19051
19280
  (function(H) {
19052
19281
  /**
19053
- * (c) 2010-2016 Torstein Honsi
19282
+ * (c) 2010-2017 Torstein Honsi
19054
19283
  *
19055
19284
  * License: www.highcharts.com/license
19056
19285
  */
@@ -19270,7 +19499,13 @@
19270
19499
  }
19271
19500
 
19272
19501
  if ('inverted' in optionsChart || 'polar' in optionsChart) {
19273
- this.propFromSeries(); // Parses options.chart.inverted and options.chart.polar together with the available series
19502
+ // Parse options.chart.inverted and options.chart.polar together
19503
+ // with the available series.
19504
+ this.propFromSeries();
19505
+ updateAllAxes = true;
19506
+ }
19507
+
19508
+ if ('alignTicks' in optionsChart) { // #6452
19274
19509
  updateAllAxes = true;
19275
19510
  }
19276
19511
 
@@ -19334,7 +19569,7 @@
19334
19569
  // update the first series in the chart. Setting two series without
19335
19570
  // an id will update the first and the second respectively (#6019)
19336
19571
  // chart.update and responsive.
19337
- each(['xAxis', 'yAxis', 'series'], function(coll) {
19572
+ each(['xAxis', 'yAxis', 'series', 'colorAxis', 'pane'], function(coll) {
19338
19573
  if (options[coll]) {
19339
19574
  each(splat(options[coll]), function(newOptions, i) {
19340
19575
  var item = (
@@ -19774,7 +20009,7 @@
19774
20009
  }(Highcharts));
19775
20010
  (function(H) {
19776
20011
  /**
19777
- * (c) 2010-2016 Torstein Honsi
20012
+ * (c) 2010-2017 Torstein Honsi
19778
20013
  *
19779
20014
  * License: www.highcharts.com/license
19780
20015
  */
@@ -20105,7 +20340,7 @@
20105
20340
  }(Highcharts));
20106
20341
  (function(H) {
20107
20342
  /**
20108
- * (c) 2010-2016 Torstein Honsi
20343
+ * (c) 2010-2017 Torstein Honsi
20109
20344
  *
20110
20345
  * License: www.highcharts.com/license
20111
20346
  */
@@ -20243,7 +20478,7 @@
20243
20478
  }(Highcharts));
20244
20479
  (function(H) {
20245
20480
  /**
20246
- * (c) 2010-2016 Torstein Honsi
20481
+ * (c) 2010-2017 Torstein Honsi
20247
20482
  *
20248
20483
  * License: www.highcharts.com/license
20249
20484
  */
@@ -20265,7 +20500,7 @@
20265
20500
  }(Highcharts));
20266
20501
  (function(H) {
20267
20502
  /**
20268
- * (c) 2010-2016 Torstein Honsi
20503
+ * (c) 2010-2017 Torstein Honsi
20269
20504
  *
20270
20505
  * License: www.highcharts.com/license
20271
20506
  */
@@ -20290,6 +20525,7 @@
20290
20525
  seriesType('column', 'line', {
20291
20526
  borderRadius: 0,
20292
20527
  //colorByPoint: undefined,
20528
+ crisp: true,
20293
20529
  groupPadding: 0.2,
20294
20530
  //grouping: true,
20295
20531
  marker: null, // point options are specified in the base options
@@ -20448,9 +20684,11 @@
20448
20684
 
20449
20685
  // Horizontal. We need to first compute the exact right edge, then round it
20450
20686
  // and compute the width from there.
20451
- right = Math.round(x + w) + xCrisp;
20452
- x = Math.round(x) + xCrisp;
20453
- w = right - x;
20687
+ if (this.options.crisp) {
20688
+ right = Math.round(x + w) + xCrisp;
20689
+ x = Math.round(x) + xCrisp;
20690
+ w = right - x;
20691
+ }
20454
20692
 
20455
20693
  // Vertical
20456
20694
  bottom = Math.round(y + h) + yCrisp;
@@ -20731,7 +20969,7 @@
20731
20969
  }(Highcharts));
20732
20970
  (function(H) {
20733
20971
  /**
20734
- * (c) 2010-2016 Torstein Honsi
20972
+ * (c) 2010-2017 Torstein Honsi
20735
20973
  *
20736
20974
  * License: www.highcharts.com/license
20737
20975
  */
@@ -20748,7 +20986,7 @@
20748
20986
  }(Highcharts));
20749
20987
  (function(H) {
20750
20988
  /**
20751
- * (c) 2010-2016 Torstein Honsi
20989
+ * (c) 2010-2017 Torstein Honsi
20752
20990
  *
20753
20991
  * License: www.highcharts.com/license
20754
20992
  */
@@ -20759,6 +20997,7 @@
20759
20997
  */
20760
20998
  seriesType('scatter', 'line', {
20761
20999
  lineWidth: 0,
21000
+ findNearestPointBy: 'xy',
20762
21001
  marker: {
20763
21002
  enabled: true // Overrides auto-enabling in line series (#3647)
20764
21003
  },
@@ -20777,7 +21016,6 @@
20777
21016
  noSharedTooltip: true,
20778
21017
  trackerGroups: ['group', 'markerGroup', 'dataLabelsGroup'],
20779
21018
  takeOrdinalPosition: false, // #2342
20780
- kdDimensions: 2,
20781
21019
  drawGraph: function() {
20782
21020
  if (this.options.lineWidth) {
20783
21021
  Series.prototype.drawGraph.call(this);
@@ -20788,7 +21026,7 @@
20788
21026
  }(Highcharts));
20789
21027
  (function(H) {
20790
21028
  /**
20791
- * (c) 2010-2016 Torstein Honsi
21029
+ * (c) 2010-2017 Torstein Honsi
20792
21030
  *
20793
21031
  * License: www.highcharts.com/license
20794
21032
  */
@@ -20837,7 +21075,7 @@
20837
21075
  }(Highcharts));
20838
21076
  (function(H) {
20839
21077
  /**
20840
- * (c) 2010-2016 Torstein Honsi
21078
+ * (c) 2010-2017 Torstein Honsi
20841
21079
  *
20842
21080
  * License: www.highcharts.com/license
20843
21081
  */
@@ -21338,7 +21576,7 @@
21338
21576
  }(Highcharts));
21339
21577
  (function(H) {
21340
21578
  /**
21341
- * (c) 2010-2016 Torstein Honsi
21579
+ * (c) 2010-2017 Torstein Honsi
21342
21580
  *
21343
21581
  * License: www.highcharts.com/license
21344
21582
  */
@@ -21537,9 +21775,9 @@
21537
21775
  style.color = pick(options.color, style.color, series.color, '#000000');
21538
21776
  // Get automated contrast color
21539
21777
  if (style.color === 'contrast') {
21778
+ point.contrastColor = renderer.getContrast(point.color || series.color);
21540
21779
  style.color = options.inside || options.distance < 0 || !!seriesOptions.stacking ?
21541
- renderer.getContrast(point.color || series.color) :
21542
- '#000000';
21780
+ point.contrastColor : '#000000';
21543
21781
  }
21544
21782
  if (seriesOptions.cursor) {
21545
21783
  style.cursor = seriesOptions.cursor;
@@ -21705,7 +21943,14 @@
21705
21943
 
21706
21944
  // Handle justify or crop
21707
21945
  if (justify) {
21708
- this.justifyDataLabel(dataLabel, options, alignAttr, bBox, alignTo, isNew);
21946
+ point.isLabelJustified = this.justifyDataLabel(
21947
+ dataLabel,
21948
+ options,
21949
+ alignAttr,
21950
+ bBox,
21951
+ alignTo,
21952
+ isNew
21953
+ );
21709
21954
 
21710
21955
  // Now check that the data label is within the plot area
21711
21956
  } else if (pick(options.crop, true)) {
@@ -21791,6 +22036,8 @@
21791
22036
  dataLabel.placed = !isNew;
21792
22037
  dataLabel.align(options, null, alignTo);
21793
22038
  }
22039
+
22040
+ return justified;
21794
22041
  };
21795
22042
 
21796
22043
  /**
@@ -22211,38 +22458,56 @@
22211
22458
 
22212
22459
  // Call the parent method
22213
22460
  Series.prototype.alignDataLabel.call(this, point, dataLabel, options, alignTo, isNew);
22461
+
22462
+ // If label was justified and we have contrast, set it:
22463
+ if (point.isLabelJustified && point.contrastColor) {
22464
+ point.dataLabel.css({
22465
+ color: point.contrastColor
22466
+ });
22467
+ }
22214
22468
  };
22215
22469
  }
22216
22470
 
22217
22471
  }(Highcharts));
22218
22472
  (function(H) {
22219
22473
  /**
22220
- * (c) 2009-2016 Torstein Honsi
22474
+ * (c) 2009-2017 Torstein Honsi
22221
22475
  *
22222
22476
  * License: www.highcharts.com/license
22223
22477
  */
22224
22478
  /**
22225
- * Highcharts module to hide overlapping data labels. This module is included in Highcharts.
22479
+ * Highcharts module to hide overlapping data labels. This module is included in
22480
+ * Highcharts.
22226
22481
  */
22227
22482
  var Chart = H.Chart,
22228
22483
  each = H.each,
22229
22484
  pick = H.pick,
22230
22485
  addEvent = H.addEvent;
22231
22486
 
22232
- // Collect potensial overlapping data labels. Stack labels probably don't need to be
22233
- // considered because they are usually accompanied by data labels that lie inside the columns.
22487
+ // Collect potensial overlapping data labels. Stack labels probably don't need
22488
+ // to be considered because they are usually accompanied by data labels that lie
22489
+ // inside the columns.
22234
22490
  Chart.prototype.callbacks.push(function(chart) {
22235
22491
  function collectAndHide() {
22236
22492
  var labels = [];
22237
22493
 
22238
22494
  each(chart.series || [], function(series) {
22239
22495
  var dlOptions = series.options.dataLabels,
22240
- collections = series.dataLabelCollections || ['dataLabel']; // Range series have two collections
22241
- if ((dlOptions.enabled || series._hasPointLabels) && !dlOptions.allowOverlap && series.visible) { // #3866
22496
+ // Range series have two collections
22497
+ collections = series.dataLabelCollections || ['dataLabel'];
22498
+
22499
+ if (
22500
+ (dlOptions.enabled || series._hasPointLabels) &&
22501
+ !dlOptions.allowOverlap &&
22502
+ series.visible
22503
+ ) { // #3866
22242
22504
  each(collections, function(coll) {
22243
22505
  each(series.points, function(point) {
22244
22506
  if (point[coll]) {
22245
- point[coll].labelrank = pick(point.labelrank, point.shapeArgs && point.shapeArgs.height); // #4118
22507
+ point[coll].labelrank = pick(
22508
+ point.labelrank,
22509
+ point.shapeArgs && point.shapeArgs.height
22510
+ ); // #4118
22246
22511
  labels.push(point[coll]);
22247
22512
  }
22248
22513
  });
@@ -22261,8 +22526,8 @@
22261
22526
  });
22262
22527
 
22263
22528
  /**
22264
- * Hide overlapping labels. Labels are moved and faded in and out on zoom to provide a smooth
22265
- * visual imression.
22529
+ * Hide overlapping labels. Labels are moved and faded in and out on zoom to
22530
+ * provide a smooth visual imression.
22266
22531
  */
22267
22532
  Chart.prototype.hideOverlappingLabels = function(labels) {
22268
22533
 
@@ -22296,9 +22561,8 @@
22296
22561
  }
22297
22562
  }
22298
22563
 
22299
- // Prevent a situation in a gradually rising slope, that each label
22300
- // will hide the previous one because the previous one always has
22301
- // lower rank.
22564
+ // Prevent a situation in a gradually rising slope, that each label will
22565
+ // hide the previous one because the previous one always has lower rank.
22302
22566
  labels.sort(function(a, b) {
22303
22567
  return (b.labelrank || 0) - (a.labelrank || 0);
22304
22568
  });
@@ -22309,12 +22573,19 @@
22309
22573
 
22310
22574
  for (j = i + 1; j < len; ++j) {
22311
22575
  label2 = labels[j];
22312
- if (label1 && label2 && label1.placed && label2.placed && label1.newOpacity !== 0 && label2.newOpacity !== 0) {
22576
+ if (
22577
+ label1 && label2 &&
22578
+ label1 !== label2 && // #6465, polar chart with connectEnds
22579
+ label1.placed && label2.placed &&
22580
+ label1.newOpacity !== 0 && label2.newOpacity !== 0
22581
+ ) {
22313
22582
  pos1 = label1.alignAttr;
22314
22583
  pos2 = label2.alignAttr;
22315
- parent1 = label1.parentGroup; // Different panes have different positions
22584
+ // Different panes have different positions
22585
+ parent1 = label1.parentGroup;
22316
22586
  parent2 = label2.parentGroup;
22317
- padding = 2 * (label1.box ? 0 : label1.padding); // Substract the padding if no background or border (#4333)
22587
+ // Substract the padding if no background or border (#4333)
22588
+ padding = 2 * (label1.box ? 0 : label1.padding);
22318
22589
  isIntersecting = intersectRect(
22319
22590
  pos1.x + parent1.translateX,
22320
22591
  pos1.y + parent1.translateY,
@@ -22327,7 +22598,8 @@
22327
22598
  );
22328
22599
 
22329
22600
  if (isIntersecting) {
22330
- (label1.labelrank < label2.labelrank ? label1 : label2).newOpacity = 0;
22601
+ (label1.labelrank < label2.labelrank ? label1 : label2)
22602
+ .newOpacity = 0;
22331
22603
  }
22332
22604
  }
22333
22605
  }
@@ -22343,7 +22615,8 @@
22343
22615
 
22344
22616
  if (label.oldOpacity !== newOpacity && label.placed) {
22345
22617
 
22346
- // Make sure the label is completely hidden to avoid catching clicks (#4362)
22618
+ // Make sure the label is completely hidden to avoid catching
22619
+ // clicks (#4362)
22347
22620
  if (newOpacity) {
22348
22621
  label.show(true);
22349
22622
  } else {
@@ -22354,7 +22627,11 @@
22354
22627
 
22355
22628
  // Animate or set the opacity
22356
22629
  label.alignAttr.opacity = newOpacity;
22357
- label[label.isOld ? 'animate' : 'attr'](label.alignAttr, null, complete);
22630
+ label[label.isOld ? 'animate' : 'attr'](
22631
+ label.alignAttr,
22632
+ null,
22633
+ complete
22634
+ );
22358
22635
 
22359
22636
  }
22360
22637
  label.isOld = true;
@@ -22365,7 +22642,7 @@
22365
22642
  }(Highcharts));
22366
22643
  (function(H) {
22367
22644
  /**
22368
- * (c) 2010-2016 Torstein Honsi
22645
+ * (c) 2010-2017 Torstein Honsi
22369
22646
  *
22370
22647
  * License: www.highcharts.com/license
22371
22648
  */
@@ -23145,7 +23422,7 @@
23145
23422
 
23146
23423
 
23147
23424
  // hide the tooltip
23148
- if (tooltip && !options.stickyTracking && (!tooltip.shared || series.noSharedTooltip)) {
23425
+ if (tooltip && !series.stickyTracking && (!tooltip.shared || series.noSharedTooltip)) {
23149
23426
  tooltip.hide();
23150
23427
  }
23151
23428
 
@@ -23324,7 +23601,7 @@
23324
23601
  }(Highcharts));
23325
23602
  (function(H) {
23326
23603
  /**
23327
- * (c) 2010-2016 Torstein Honsi
23604
+ * (c) 2010-2017 Torstein Honsi
23328
23605
  *
23329
23606
  * License: www.highcharts.com/license
23330
23607
  */