highcharts-rails 4.2.6 → 4.2.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f77a535a0b707c51c4f72e52ddf05fe4e3b911c3
4
- data.tar.gz: 6c75ffb6a157954665f1abd492d403529a3b557e
3
+ metadata.gz: 6c8a7e896fdcd7def1e83f3bcb1feb6872433807
4
+ data.tar.gz: b537b34e4eb511cc9990cf2849b906b5728ba8d1
5
5
  SHA512:
6
- metadata.gz: af2b1ec95756ae60312e86e5b7bbbfd3af55d35e9df0b0a910bfd7e8499d4304e859c7da71f8d2fe2ad7b951c3b28405cb5a31bed565485578050f7294d4dabb
7
- data.tar.gz: 76c61a2be05c827cf727b7ad23c99672f75d267646c977fc8f441365c6b6489d46d261001424be87d44e7a3e38155c1c7597bf466eff706b925a384bba00ae9b
6
+ metadata.gz: 42aed7fd6c6bd1bb90b4978307e5c2c025f4ede7fd283b09c12caf5313ec2d3741a8cd219c2541a5c38d91f9a3c43a4c23c9fa92b54a73c1ee86e4b14dd81bdc
7
+ data.tar.gz: 3642d9b1dc37b3f36a99972683ec45315091a1cc13db9487efdd435b0cfb25a02f9200142e14160b4564a6d14b9620e93a5856a3542a7698c3d43be9722b3b26
@@ -1,3 +1,49 @@
1
+ # 4.2.7 / 2017-01-25
2
+
3
+ * Updated Highcharts to 4.2.7 (2016-09-21)
4
+ * Added new feature, yAxis.angle, allowing positioning the axis line and labels in polar chart Y axes. This makes it practical to use multiple axes in polar charts.
5
+ * Added option, xAxis.nameToX, allowing points to have the same name but different axis positions on an axis of type category.
6
+ * Bug fixes
7
+ * Fixed #1011, ignoreHiddenSeries with ordinal axis caused artefacts on a chart.
8
+ * Fixed #1041, gaps in the area fill of stacked areasplines.
9
+ * Fixed #3169, error on drilldown from a null point.
10
+ * Fixed #3341, exceeded stack size on mutually linked series.
11
+ * Fixed #3571, NaN in the beginning of data broke series.
12
+ * Fixed #4778, wrong rendering waterfall series, when yAxis.max was set.
13
+ * Fixed #5186, gaps in the fill of areasplinerange.
14
+ * Fixed #5383, mouse position detection with pointPlacement.
15
+ * Fixed #5528, a regression causing polar arearanges to fail.
16
+ * Fixed #5533, stickyTracking when set to false caused highlighting wrong point.
17
+ * Fixed #5552, linejoins in boost module lines.
18
+ * Fixed #5556, JS error on polygon with empty data.
19
+ * Fixed #5563, JS error in treemap with zero values.
20
+ * Fixed #5568, pointIntervalUnit broke when using more data points than turboThreshold.
21
+ * Fixed #5569, generic options set on the yAxis affected the colorAxis.
22
+ * Fixed #5570 and #5590, regression causing blank export on Batik based export servers.
23
+ * Fixed #5572, pie slices were not hidden in 3D pie charts on legend click.
24
+ * Fixed #5595, HTML tooltip did not hide on point mouse out via the tooltip.
25
+ * Fixed #5605, error on async onload of destroyed chart.
26
+ * Fixed #5618, updating master series caused wrong visibility on linked series.
27
+ * Fixed #5619, the Series remove event was fired when updating a series.
28
+ * Fixed #5620, text was mispositioned when loading a chart in a hidden iframe in certain browsers.
29
+ * Fixed #5622, click event for line series point was not called when column was rendered below.
30
+ * Fixed #5631, zeroes in logarithmic chart made the whole graph crash.
31
+ * Fixed #5632, gaps were broken in arearange and areasplinerange.
32
+ * Fixed #5646, waterfall did not work correctly with logarithmic axis.
33
+ * Fixed #5647, xrange points disappeared if x was outside plot but x2 inside.
34
+ * Fixed #5647, xrange points disappeared when x was outside visible range.
35
+ * Fixed #5655, animation: true on a series config caused animation to jump from the middle.
36
+ * Fixed #5658, error on updating series from its own mouseOver event.
37
+ * Fixed #5662, setExtremes on polar chart caused padded max value.
38
+ * Fixed #5665, addPoint animation parameter was not used.
39
+ * Fixed #5679, handle isArray for ES6 iterator.
40
+ * Fixed #5681, JS error on adding custom group to points.
41
+ * Fixed #5689, text had soft line wraps when white-space: nowrap was used in combination with text-overflow: ellipsis.
42
+ * Fixed issue #4133, error bar data labels positions failing on redraw.
43
+ * Fixed issue #5205, color axis changed colors when legend was disabled.
44
+ * Fixed issue #5567, wrong clipping of offline exported SVG in IE11/Edge.
45
+ * Fixed wrong handling of minRange on logarithmic axis, related to #1227.
46
+
1
47
  # 4.2.6 / 2017-01-25
2
48
 
3
49
  * Updated Highcharts to 4.2.6 (2016-08-02)
data/Rakefile CHANGED
@@ -26,6 +26,7 @@ task :update, :version do |t, args|
26
26
  "broken-axis.src.js" => "highcharts/modules/broken-axis.js",
27
27
  "boost.src.js" => "highcharts/modules/boost.js",
28
28
  "offline-exporting.src.js" => "highcharts/modules/offline-exporting.js",
29
+ "series-label.src.js" => "highcharts/modules/series-label.js",
29
30
  }
30
31
  dest = "app/assets/javascripts/"
31
32
  Dir.glob("tmp/#{version}/js/**/*.src.js").each do |file|
@@ -2,7 +2,7 @@
2
2
  // @compilation_level SIMPLE_OPTIMIZATIONS
3
3
 
4
4
  /**
5
- * @license Highcharts JS v4.2.6 (2016-08-02)
5
+ * @license Highcharts JS v4.2.7 (2016-09-21)
6
6
  *
7
7
  * (c) 2009-2016 Torstein Honsi
8
8
  *
@@ -59,7 +59,7 @@
59
59
  charts = [],
60
60
  chartCount = 0,
61
61
  PRODUCT = 'Highcharts',
62
- VERSION = '4.2.6',
62
+ VERSION = '4.2.7',
63
63
 
64
64
  // some constants for frequently used strings
65
65
  DIV = 'div',
@@ -72,7 +72,7 @@
72
72
  NONE = 'none',
73
73
  M = 'M',
74
74
  L = 'L',
75
- numRegex = /^[0-9]+$/,
75
+ numRegex = /[0-9]/g,
76
76
  NORMAL_STATE = '',
77
77
  HOVER_STATE = 'hover',
78
78
  SELECT_STATE = 'select',
@@ -481,7 +481,7 @@
481
481
  value = original[key];
482
482
 
483
483
  // Copy the contents of objects, but not arrays or DOM nodes
484
- if (value && typeof value === 'object' && Object.prototype.toString.call(value) !== '[object Array]' &&
484
+ if (Highcharts.isObject(value, true) &&
485
485
  key !== 'renderTo' && typeof value.nodeType !== 'number') {
486
486
  copy[key] = doCopy(copy[key] || {}, value);
487
487
 
@@ -531,7 +531,8 @@
531
531
  * @param {Object} obj
532
532
  */
533
533
  function isArray(obj) {
534
- return Object.prototype.toString.call(obj) === '[object Array]';
534
+ var str = Object.prototype.toString.call(obj);
535
+ return str === '[object Array]' || str === '[object Array Iterator]';
535
536
  }
536
537
 
537
538
  /**
@@ -1601,7 +1602,7 @@
1601
1602
  useUTC: true,
1602
1603
  //timezoneOffset: 0,
1603
1604
  canvasToolsURL: 'http://code.highcharts.com/modules/canvas-tools.js',
1604
- VMLRadialGradientURL: 'http://code.highcharts.com/4.2.6/gfx/vml-radial-gradient.png'
1605
+ VMLRadialGradientURL: 'http://code.highcharts.com/4.2.7/gfx/vml-radial-gradient.png'
1605
1606
  },
1606
1607
  chart: {
1607
1608
  //animation: true,
@@ -2871,19 +2872,16 @@
2871
2872
 
2872
2873
  if (textStr !== UNDEFINED) {
2873
2874
 
2874
- // Properties that affect bounding box
2875
- cacheKey = ['', rotation || 0, styles && styles.fontSize, element.style.width].join(',');
2875
+ cacheKey =
2876
2876
 
2877
- // Since numbers are monospaced, and numerical labels appear a lot in a chart,
2878
- // we assume that a label of n characters has the same bounding box as others
2879
- // of the same length.
2880
- if (textStr === '' || numRegex.test(textStr)) {
2881
- cacheKey = 'num:' + textStr.toString().length + cacheKey;
2877
+ // Since numbers are monospaced, and numerical labels appear a lot in a chart,
2878
+ // we assume that a label of n characters has the same bounding box as others
2879
+ // of the same length.
2880
+ textStr.toString().replace(numRegex, '0') +
2881
+
2882
+ // Properties that affect bounding box
2883
+ ['', rotation || 0, styles && styles.fontSize, element.style.width].join(',');
2882
2884
 
2883
- // Caching all strings reduces rendering time by 4-5%.
2884
- } else {
2885
- cacheKey = textStr + cacheKey;
2886
- }
2887
2885
  }
2888
2886
 
2889
2887
  if (cacheKey && !reload) {
@@ -2963,8 +2961,9 @@
2963
2961
  }
2964
2962
  }
2965
2963
 
2966
- // Cache it
2967
- if (cacheKey) {
2964
+ // Cache it. When loading a chart in a hidden iframe in Firefox and IE/Edge, the
2965
+ // bounding box height is 0, so don't cache it (#5620).
2966
+ if (cacheKey && bBox.height > 0) {
2968
2967
 
2969
2968
  // Rotate (#4681)
2970
2969
  while (cacheKeys.length > 250) {
@@ -3240,10 +3239,6 @@
3240
3239
  alignSetter: function (value) {
3241
3240
  this.element.setAttribute('text-anchor', { left: 'start', center: 'middle', right: 'end' }[value]);
3242
3241
  },
3243
- opacitySetter: function (value, key, element) {
3244
- this[key] = value;
3245
- element.setAttribute(key, value);
3246
- },
3247
3242
  titleSetter: function (value) {
3248
3243
  var titleNode = this.element.getElementsByTagName('title')[0];
3249
3244
  if (!titleNode) {
@@ -3355,6 +3350,13 @@
3355
3350
  this.doTransform = true;
3356
3351
  };
3357
3352
 
3353
+ // These setters both set the key on the instance itself plus as an attribute
3354
+ SVGElement.prototype.opacitySetter = SVGElement.prototype.displaySetter = function (value, key, element) {
3355
+ this[key] = value;
3356
+ element.setAttribute(key, value);
3357
+ };
3358
+
3359
+
3358
3360
  // WebKit and Batik have problems with a stroke-width of zero, so in this case we remove the
3359
3361
  // stroke attribute altogether. #1270, #1369, #3065, #3072.
3360
3362
  SVGElement.prototype['stroke-widthSetter'] = SVGElement.prototype.strokeSetter = function (value, key, element) {
@@ -3380,7 +3382,6 @@
3380
3382
  };
3381
3383
  SVGRenderer.prototype = {
3382
3384
  Element: SVGElement,
3383
-
3384
3385
  /**
3385
3386
  * Initialize the SVGRenderer
3386
3387
  * @param {Object} container
@@ -3683,7 +3684,8 @@
3683
3684
  // Check width and apply soft breaks or ellipsis
3684
3685
  if (width) {
3685
3686
  var words = span.replace(/([^\^])-/g, '$1- ').split(' '), // #1273
3686
- hasWhiteSpace = spans.length > 1 || lineNo || (words.length > 1 && textStyles.whiteSpace !== 'nowrap'),
3687
+ noWrap = textStyles.whiteSpace === 'nowrap',
3688
+ hasWhiteSpace = spans.length > 1 || lineNo || (words.length > 1 && !noWrap),
3687
3689
  tooLong,
3688
3690
  actualWidth,
3689
3691
  rest = [],
@@ -3727,7 +3729,7 @@
3727
3729
  words = rest;
3728
3730
  rest = [];
3729
3731
 
3730
- if (words.length) {
3732
+ if (words.length && !noWrap) {
3731
3733
  softLineNo++;
3732
3734
 
3733
3735
  tspan = doc.createElementNS(SVG_NS, 'tspan');
@@ -4158,7 +4160,6 @@
4158
4160
  height,
4159
4161
  options
4160
4162
  ),
4161
-
4162
4163
  imageRegex = /^url\((.*?)\)$/,
4163
4164
  imageSrc,
4164
4165
  imageSize,
@@ -4222,6 +4223,8 @@
4222
4223
  createElement('img', {
4223
4224
  onload: function () {
4224
4225
 
4226
+ var chart = charts[ren.chartIndex];
4227
+
4225
4228
  // Special case for SVGs on IE11, the width is not accessible until the image is
4226
4229
  // part of the DOM (#2854).
4227
4230
  if (this.width === 0) {
@@ -4242,8 +4245,8 @@
4242
4245
 
4243
4246
  // Fire the load event when all external images are loaded
4244
4247
  ren.imgCount--;
4245
- if (!ren.imgCount && charts[ren.chartIndex].onload) {
4246
- charts[ren.chartIndex].onload();
4248
+ if (!ren.imgCount && chart && chart.onload) {
4249
+ chart.onload();
4247
4250
  }
4248
4251
  },
4249
4252
  src: imageSrc
@@ -4564,7 +4567,8 @@
4564
4567
  crispAdjust = 0,
4565
4568
  deferredAttr = {},
4566
4569
  baselineOffset,
4567
- needsBox,
4570
+ hasBGImage = /^url\((.*?)\)$/.test(shape),
4571
+ needsBox = hasBGImage,
4568
4572
  updateBoxSize,
4569
4573
  updateTextPadding,
4570
4574
  boxAttr;
@@ -4594,7 +4598,7 @@
4594
4598
  // create the border box if it is not already present
4595
4599
  boxX = crispAdjust;
4596
4600
  boxY = (baseline ? -baselineOffset : 0) + crispAdjust;
4597
- wrapper.box = box = renderer.symbols[shape] ? // Symbol definition exists (#5324)
4601
+ wrapper.box = box = renderer.symbols[shape] || hasBGImage ? // Symbol definition exists (#5324)
4598
4602
  renderer.symbol(shape, boxX, boxY, wrapper.width, wrapper.height, deferredAttr) :
4599
4603
  renderer.rect(boxX, boxY, wrapper.width, wrapper.height, 0, deferredAttr[STROKE_WIDTH]);
4600
4604
 
@@ -5016,7 +5020,7 @@
5016
5020
  addSetters = function (element, style) {
5017
5021
  // These properties are set as attributes on the SVG group, and as
5018
5022
  // identical CSS properties on the div. (#3542)
5019
- each(['opacity', 'visibility'], function (prop) {
5023
+ each(['display', 'opacity', 'visibility'], function (prop) {
5020
5024
  wrap(element, prop + 'Setter', function (proceed, value, key, elem) {
5021
5025
  proceed.call(this, value, key, elem);
5022
5026
  style[key] = value;
@@ -5107,7 +5111,9 @@
5107
5111
  position: ABSOLUTE,
5108
5112
  left: (parentGroup.translateX || 0) + PX,
5109
5113
  top: (parentGroup.translateY || 0) + PX,
5110
- opacity: parentGroup.opacity // #5075
5114
+ display: parentGroup.display,
5115
+ opacity: parentGroup.opacity, // #5075
5116
+ pointerEvents: parentGroup.styles && parentGroup.styles.pointerEvents // #5595
5111
5117
  }, htmlGroup || container); // the top group is appended to container
5112
5118
 
5113
5119
  // Shortcut
@@ -5619,6 +5625,9 @@
5619
5625
  }
5620
5626
  element.style[key] = value;
5621
5627
  },
5628
+ displaySetter: function (value, key, element) {
5629
+ element.style[key] = value;
5630
+ },
5622
5631
  xSetter: function (value, key, element) {
5623
5632
  this[key] = value; // used in getter
5624
5633
 
@@ -7174,7 +7183,7 @@
7174
7183
 
7175
7184
  // Flag, isXAxis
7176
7185
  axis.isXAxis = isXAxis;
7177
- axis.coll = isXAxis ? 'xAxis' : 'yAxis';
7186
+ axis.coll = axis.coll || (isXAxis ? 'xAxis' : 'yAxis');
7178
7187
 
7179
7188
  axis.opposite = userOptions.opposite; // needed in setOptions
7180
7189
  axis.side = userOptions.side || (axis.horiz ?
@@ -7202,7 +7211,8 @@
7202
7211
  axis.zoomEnabled = options.zoomEnabled !== false;
7203
7212
 
7204
7213
  // Initial categories
7205
- axis.categories = options.categories || type === 'category';
7214
+ axis.hasNames = type === 'category' || options.categories === true;
7215
+ axis.categories = options.categories || axis.hasNames;
7206
7216
  axis.names = axis.names || []; // Preserve on update (#3830)
7207
7217
 
7208
7218
  // Elements
@@ -7286,7 +7296,7 @@
7286
7296
 
7287
7297
  // Register
7288
7298
  if (inArray(axis, chart.axes) === -1) { // don't add it again on Axis.update()
7289
- if (isXAxis && !this.isColorAxis) { // #2713
7299
+ if (isXAxis) { // #2713
7290
7300
  chart.axes.splice(chart.xAxis.length, 0, axis);
7291
7301
  } else {
7292
7302
  chart.axes.push(axis);
@@ -7324,7 +7334,7 @@
7324
7334
  setOptions: function (userOptions) {
7325
7335
  this.options = merge(
7326
7336
  this.defaultOptions,
7327
- this.isXAxis ? {} : this.defaultYAxisOptions,
7337
+ this.coll === 'yAxis' && this.defaultYAxisOptions,
7328
7338
  [this.defaultTopAxisOptions, this.defaultRightAxisOptions,
7329
7339
  this.defaultBottomAxisOptions, this.defaultLeftAxisOptions][this.side],
7330
7340
  merge(
@@ -7740,13 +7750,13 @@
7740
7750
  // if min and max options have been set, don't go beyond it
7741
7751
  minArgs = [min - zoomOffset, pick(options.min, min - zoomOffset)];
7742
7752
  if (spaceAvailable) { // if space is available, stay within the data range
7743
- minArgs[2] = axis.dataMin;
7753
+ minArgs[2] = axis.isLog ? axis.log2lin(axis.dataMin) : axis.dataMin;
7744
7754
  }
7745
7755
  min = arrayMax(minArgs);
7746
7756
 
7747
7757
  maxArgs = [min + minRange, pick(options.max, min + minRange)];
7748
7758
  if (spaceAvailable) { // if space is availabe, stay within the data range
7749
- maxArgs[2] = axis.dataMax;
7759
+ maxArgs[2] = axis.isLog ? axis.log2lin(axis.dataMax) : axis.dataMax;
7750
7760
  }
7751
7761
 
7752
7762
  max = arrayMin(maxArgs);
@@ -7785,6 +7795,68 @@
7785
7795
  return ret;
7786
7796
  },
7787
7797
 
7798
+ /**
7799
+ * When a point name is given and no x, search for the name in the existing categories,
7800
+ * or if categories aren't provided, search names or create a new category (#2522).
7801
+ */
7802
+ nameToX: function (point) {
7803
+ var explicitCategories = isArray(this.categories),
7804
+ names = explicitCategories ? this.categories : this.names,
7805
+ nameX = point.options.x,
7806
+ x;
7807
+
7808
+ point.series.requireSorting = false;
7809
+
7810
+ if (!defined(nameX)) {
7811
+ nameX = this.options.nameToX === false ?
7812
+ point.series.autoIncrement() :
7813
+ inArray(point.name, names);
7814
+ }
7815
+ if (nameX === -1) { // The name is not found in currenct categories
7816
+ if (!explicitCategories) {
7817
+ x = names.length;
7818
+ }
7819
+ } else {
7820
+ x = nameX;
7821
+ }
7822
+
7823
+ // Write the last point's name to the names array
7824
+ this.names[x] = point.name;
7825
+
7826
+ return x;
7827
+ },
7828
+
7829
+ /**
7830
+ * When changes have been done to series data, update the axis.names.
7831
+ */
7832
+ updateNames: function () {
7833
+ var axis = this;
7834
+
7835
+ if (this.names.length > 0) {
7836
+ this.names.length = 0;
7837
+ this.minRange = undefined;
7838
+ each(this.series || [], function (series) {
7839
+
7840
+ // When adding a series, points are not yet generated
7841
+ if (!series.processedXData) {
7842
+ series.processData();
7843
+ series.generatePoints();
7844
+ }
7845
+
7846
+ each(series.points, function (point, i) {
7847
+ var x;
7848
+ if (point.options && point.options.x === undefined) {
7849
+ x = axis.nameToX(point);
7850
+ if (x !== point.x) {
7851
+ point.x = x;
7852
+ series.xData[i] = x;
7853
+ }
7854
+ }
7855
+ });
7856
+ });
7857
+ }
7858
+ },
7859
+
7788
7860
  /**
7789
7861
  * Update translation information
7790
7862
  */
@@ -8065,7 +8137,7 @@
8065
8137
  }
8066
8138
 
8067
8139
  // Prevent ticks from getting so close that we can't draw the labels
8068
- if (!this.tickAmount && this.len) { // Color axis with disabled legend has no length
8140
+ if (!this.tickAmount) {
8069
8141
  axis.tickInterval = axis.unsquish();
8070
8142
  }
8071
8143
 
@@ -8637,7 +8709,7 @@
8637
8709
  labelMetrics = this.labelMetrics(),
8638
8710
  textOverflowOption = labelOptions.style.textOverflow,
8639
8711
  css,
8640
- labelLength = 0,
8712
+ maxLabelLength = 0,
8641
8713
  label,
8642
8714
  i,
8643
8715
  pos;
@@ -8647,20 +8719,22 @@
8647
8719
  attr.rotation = labelOptions.rotation || 0; // #4443
8648
8720
  }
8649
8721
 
8722
+ // Get the longest label length
8723
+ each(tickPositions, function (tick) {
8724
+ tick = ticks[tick];
8725
+ if (tick && tick.labelLength > maxLabelLength) {
8726
+ maxLabelLength = tick.labelLength;
8727
+ }
8728
+ });
8729
+ this.maxLabelLength = maxLabelLength;
8730
+
8731
+
8650
8732
  // Handle auto rotation on horizontal axis
8651
8733
  if (this.autoRotation) {
8652
8734
 
8653
- // Get the longest label length
8654
- each(tickPositions, function (tick) {
8655
- tick = ticks[tick];
8656
- if (tick && tick.labelLength > labelLength) {
8657
- labelLength = tick.labelLength;
8658
- }
8659
- });
8660
-
8661
8735
  // Apply rotation only if the label is too wide for the slot, and
8662
8736
  // the label is wider than its height.
8663
- if (labelLength > innerWidth && labelLength > labelMetrics.h) {
8737
+ if (maxLabelLength > innerWidth && maxLabelLength > labelMetrics.h) {
8664
8738
  attr.rotation = this.labelRotation;
8665
8739
  } else {
8666
8740
  this.labelRotation = 0;
@@ -8701,7 +8775,7 @@
8701
8775
  // Add ellipsis if the label length is significantly longer than ideal
8702
8776
  if (attr.rotation) {
8703
8777
  css = {
8704
- width: (labelLength > chart.chartHeight * 0.5 ? chart.chartHeight * 0.33 : chart.chartHeight) + PX
8778
+ width: (maxLabelLength > chart.chartHeight * 0.5 ? chart.chartHeight * 0.33 : chart.chartHeight) + PX
8705
8779
  };
8706
8780
  if (!textOverflowOption) {
8707
8781
  css.textOverflow = 'ellipsis';
@@ -9684,12 +9758,12 @@
9684
9758
  fill: options.backgroundColor,
9685
9759
  'stroke-width': borderWidth,
9686
9760
  r: options.borderRadius,
9687
- zIndex: 8
9761
+ zIndex: 8,
9762
+ display: 'none' // #2301, #2657, #3532, #5570
9688
9763
  })
9689
9764
  .css(style)
9690
9765
  .css({ padding: 0 }) // Remove it from VML, the padding is applied as an attribute instead (#1117)
9691
- .add()
9692
- .attr({ y: -9e9 }); // #2301, #2657, #3532
9766
+ .add();
9693
9767
 
9694
9768
  // When using canVG the shadow shows up as a gray circle
9695
9769
  // even if the tooltip is hidden.
@@ -10013,7 +10087,10 @@
10013
10087
  // show it
10014
10088
  if (tooltip.isHidden) {
10015
10089
  stop(label);
10016
- label.attr('opacity', 1).show();
10090
+ label.attr({
10091
+ opacity: 1,
10092
+ display: 'block'
10093
+ }).show();
10017
10094
  }
10018
10095
 
10019
10096
  // update text
@@ -10290,16 +10367,15 @@
10290
10367
  tooltip = chart.tooltip,
10291
10368
  shared = tooltip ? tooltip.shared : false,
10292
10369
  followPointer,
10370
+ updatePosition = true,
10293
10371
  hoverPoint = chart.hoverPoint,
10294
10372
  hoverSeries = chart.hoverSeries,
10295
10373
  i,
10296
- distance = [Number.MAX_VALUE, Number.MAX_VALUE], // #4511
10297
10374
  anchor,
10298
10375
  noSharedTooltip,
10299
10376
  stickToHoverSeries,
10300
10377
  directTouch,
10301
10378
  kdpoints = [],
10302
- kdpoint = [],
10303
10379
  kdpointT;
10304
10380
 
10305
10381
  // For hovering over the empty parts of the plot area (hoverSeries is undefined).
@@ -10317,10 +10393,15 @@
10317
10393
  // search the k-d tree.
10318
10394
  stickToHoverSeries = hoverSeries && (shared ? hoverSeries.noSharedTooltip : hoverSeries.directTouch);
10319
10395
  if (stickToHoverSeries && hoverPoint) {
10320
- kdpoint = [hoverPoint];
10396
+ kdpoints = [hoverPoint];
10321
10397
 
10322
10398
  // Handle shared tooltip or cases where a series is not yet hovered
10323
10399
  } else {
10400
+ // When we have non-shared tooltip and sticky tracking is disabled,
10401
+ // search for the closest point only on hovered series: #5533, #5476
10402
+ if (!shared && hoverSeries && !hoverSeries.options.stickyTracking) {
10403
+ series = [hoverSeries];
10404
+ }
10324
10405
  // Find nearest points on all series
10325
10406
  each(series, function (s) {
10326
10407
  // Skip hidden series
@@ -10333,25 +10414,22 @@
10333
10414
  }
10334
10415
  }
10335
10416
  });
10336
- // Find absolute nearest point
10337
- each(kdpoints, function (p) {
10338
- if (p) {
10339
- // Store both closest points, using point.dist and point.distX comparisons (#4645):
10340
- each(['dist', 'distX'], function (dist, k) {
10341
- if (isNumber(p[dist])) {
10342
- var
10343
- // It is closer than the reference point
10344
- isCloser = p[dist] < distance[k],
10345
- // It is equally close, but above the reference point (#4679)
10346
- isAbove = p[dist] === distance[k] && p.series.group.zIndex >= kdpoint[k].series.group.zIndex;
10347
-
10348
- if (isCloser || isAbove) {
10349
- distance[k] = p[dist];
10350
- kdpoint[k] = p;
10351
- }
10352
- }
10353
- });
10417
+
10418
+ // Sort kdpoints by distance to mouse pointer
10419
+ kdpoints.sort(function (p1, p2) {
10420
+ var isCloserX = p1.distX - p2.distX,
10421
+ isCloser = p1.dist - p2.dist,
10422
+ isAbove = p1.series.group.zIndex > p2.series.group.zIndex ? -1 : 1;
10423
+ // We have two points which are not in the same place on xAxis and shared tooltip:
10424
+ if (isCloserX !== 0) {
10425
+ return isCloserX;
10426
+ }
10427
+ // Points are not exactly in the same place on x/yAxis:
10428
+ if (isCloser !== 0) {
10429
+ return isCloser;
10354
10430
  }
10431
+ // The same xAxis and yAxis position, sort by z-index:
10432
+ return isAbove;
10355
10433
  });
10356
10434
  }
10357
10435
 
@@ -10359,37 +10437,43 @@
10359
10437
  if (shared) {
10360
10438
  i = kdpoints.length;
10361
10439
  while (i--) {
10362
- if (kdpoints[i].clientX !== kdpoint[1].clientX || kdpoints[i].series.noSharedTooltip) {
10440
+ if (kdpoints[i].clientX !== kdpoints[0].clientX || kdpoints[i].series.noSharedTooltip) {
10363
10441
  kdpoints.splice(i, 1);
10364
10442
  }
10365
10443
  }
10366
10444
  }
10367
10445
 
10368
10446
  // Refresh tooltip for kdpoint if new hover point or tooltip was hidden // #3926, #4200
10369
- if (kdpoint[0] && (kdpoint[0] !== this.prevKDPoint || (tooltip && tooltip.isHidden))) {
10447
+ if (kdpoints[0] && (kdpoints[0] !== pointer.hoverPoint || (tooltip && tooltip.isHidden))) {
10370
10448
  // Draw tooltip if necessary
10371
- if (shared && !kdpoint[0].series.noSharedTooltip) {
10449
+ if (shared && !kdpoints[0].series.noSharedTooltip) {
10450
+ // Do mouseover on all points (#3919, #3985, #4410)
10451
+ for (i = 0; i >= 0; i--) {
10452
+ kdpoints[i].onMouseOver(e, kdpoints[i] !== ((hoverSeries && hoverSeries.directTouch && hoverPoint) || kdpoints[0]));
10453
+ }
10454
+ // Make sure that the hoverPoint and hoverSeries are stored for events (e.g. click), #5622
10455
+ if (hoverSeries && hoverSeries.directTouch && hoverPoint && hoverPoint !== kdpoints[0]) {
10456
+ hoverPoint.onMouseOver(e, false);
10457
+ }
10372
10458
  if (kdpoints.length && tooltip) {
10373
- tooltip.refresh(kdpoints, e);
10459
+ // Keep the order of series in tooltip:
10460
+ tooltip.refresh(kdpoints.sort(function (p1, p2) {
10461
+ return p1.series.index - p2.series.index;
10462
+ }), e);
10374
10463
  }
10375
-
10376
- // Do mouseover on all points (#3919, #3985, #4410)
10377
- each(kdpoints, function (point) {
10378
- point.onMouseOver(e, point !== ((hoverSeries && hoverSeries.directTouch && hoverPoint) || kdpoint[0]));
10379
- });
10380
- this.prevKDPoint = kdpoint[1];
10381
10464
  } else {
10382
10465
  if (tooltip) {
10383
- tooltip.refresh(kdpoint[0], e);
10466
+ tooltip.refresh(kdpoints[0], e);
10384
10467
  }
10385
10468
  if (!hoverSeries || !hoverSeries.directTouch) { // #4448
10386
- kdpoint[0].onMouseOver(e);
10469
+ kdpoints[0].onMouseOver(e);
10387
10470
  }
10388
- this.prevKDPoint = kdpoint[0];
10389
10471
  }
10390
-
10472
+ pointer.prevKDPoint = kdpoints[0];
10473
+ updatePosition = false;
10474
+ }
10391
10475
  // Update positions (regardless of kdpoint or hoverPoint)
10392
- } else {
10476
+ if (updatePosition) {
10393
10477
  followPointer = hoverSeries && hoverSeries.tooltipOptions.followPointer;
10394
10478
  if (tooltip && followPointer && !tooltip.isHidden) {
10395
10479
  anchor = tooltip.getAnchor([{}], e);
@@ -10409,10 +10493,10 @@
10409
10493
 
10410
10494
  // Crosshair. For each hover point, loop over axes and draw cross if that point
10411
10495
  // belongs to the axis (#4927).
10412
- each(shared ? kdpoints : [pick(hoverPoint, kdpoint[1])], function (point) { // #5269
10413
- each(chart.axes, function (axis) {
10496
+ each(shared ? kdpoints : [pick(hoverPoint, kdpoints[0])], function drawPointCrosshair(point) { // #5269
10497
+ each(chart.axes, function drawAxisCrosshair(axis) {
10414
10498
  // In case of snap = false, point is undefined, and we draw the crosshair anyway (#5066)
10415
- if (!point || point.series[axis.coll] === axis) {
10499
+ if (!point || point.series && point.series[axis.coll] === axis) { // #5658
10416
10500
  axis.drawCrosshair(e, point);
10417
10501
  }
10418
10502
  });
@@ -12297,6 +12381,7 @@
12297
12381
 
12298
12382
  // set axes scales
12299
12383
  each(axes, function (axis) {
12384
+ axis.updateNames();
12300
12385
  axis.setScale();
12301
12386
  });
12302
12387
  }
@@ -12589,7 +12674,9 @@
12589
12674
  // Destroy the clone and bring the container back to the real renderTo div
12590
12675
  if (revert) {
12591
12676
  if (clone) {
12592
- this.renderTo.appendChild(container);
12677
+ while (clone.childNodes.length) { // #5231
12678
+ this.renderTo.appendChild(clone.firstChild);
12679
+ }
12593
12680
  discardElement(clone);
12594
12681
  delete this.renderToClone;
12595
12682
  }
@@ -13143,7 +13230,7 @@
13143
13230
  } else {
13144
13231
  linkedTo = chart.get(linkedTo);
13145
13232
  }
13146
- if (linkedTo) {
13233
+ if (linkedTo && linkedTo.linkedParent !== series) { // #3341 avoid mutual linking
13147
13234
  linkedTo.linkedSeries.push(series);
13148
13235
  series.linkedParent = linkedTo;
13149
13236
  series.visible = pick(series.options.visible, linkedTo.options.visible, series.visible); // #3879
@@ -13574,14 +13661,25 @@
13574
13661
  extend(point, options);
13575
13662
  point.options = point.options ? extend(point.options, options) : options;
13576
13663
 
13664
+ // Since options are copied into the Point instance, some accidental options must be shielded (#5681)
13665
+ if (options.group) {
13666
+ delete point.group;
13667
+ }
13668
+
13577
13669
  // For higher dimension series types. For instance, for ranges, point.y is mapped to point.low.
13578
13670
  if (pointValKey) {
13579
13671
  point.y = point[pointValKey];
13580
13672
  }
13581
- point.isNull = point.x === null || !isNumber(point.y, true); // #3571, check for NaN
13673
+ point.isNull = pick(
13674
+ point.isValid && !point.isValid(),
13675
+ point.x === null || !isNumber(point.y, true)
13676
+ ); // #3571, check for NaN
13582
13677
 
13583
13678
  // If no x is set by now, get auto incremented value. All points must have an
13584
13679
  // x value, however the y value can be null to create a gap in the series
13680
+ if ('name' in point && x === undefined && series.xAxis && series.xAxis.hasNames) {
13681
+ point.x = series.xAxis.nameToX(point);
13682
+ }
13585
13683
  if (point.x === undefined && series) {
13586
13684
  if (x === undefined) {
13587
13685
  point.x = series.autoIncrement(point);
@@ -13589,12 +13687,7 @@
13589
13687
  point.x = x;
13590
13688
  }
13591
13689
  }
13592
-
13593
- // Write the last point's name to the names array
13594
- if (series.xAxis && series.xAxis.names) {
13595
- series.xAxis.names[point.x] = point.name;
13596
- }
13597
-
13690
+
13598
13691
  return point;
13599
13692
  },
13600
13693
 
@@ -13780,7 +13873,8 @@
13780
13873
  fireEvent(this, eventType, eventArgs, defaultFunction);
13781
13874
  },
13782
13875
  visible: true
13783
- };/**
13876
+ };
13877
+ /**
13784
13878
  * @classDescription The base function which all other series types inherit from. The data in the series is stored
13785
13879
  * in various arrays.
13786
13880
  *
@@ -13959,38 +14053,18 @@
13959
14053
  * Return an auto incremented x value based on the pointStart and pointInterval options.
13960
14054
  * This is only used if an x value is not given for the point that calls autoIncrement.
13961
14055
  */
13962
- autoIncrement: function (point) {
14056
+ autoIncrement: function () {
13963
14057
 
13964
14058
  var options = this.options,
13965
14059
  xIncrement = this.xIncrement,
13966
14060
  date,
13967
14061
  pointInterval,
13968
- pointIntervalUnit = options.pointIntervalUnit,
13969
- xAxis = this.xAxis,
13970
- explicitCategories,
13971
- names,
13972
- nameX;
14062
+ pointIntervalUnit = options.pointIntervalUnit;
13973
14063
 
13974
14064
  xIncrement = pick(xIncrement, options.pointStart, 0);
13975
14065
 
13976
14066
  this.pointInterval = pointInterval = pick(this.pointInterval, options.pointInterval, 1);
13977
14067
 
13978
- // When a point name is given and no x, search for the name in the existing categories,
13979
- // or if categories aren't provided, search names or create a new category (#2522).
13980
- if (xAxis && xAxis.categories && point.name) {
13981
- this.requireSorting = false;
13982
- explicitCategories = isArray(xAxis.categories);
13983
- names = explicitCategories ? xAxis.categories : xAxis.names;
13984
- nameX = inArray(point.name, names); // #2522
13985
- if (nameX === -1) { // The name is not found in currenct categories
13986
- if (!explicitCategories) {
13987
- xIncrement = names.length;
13988
- }
13989
- } else {
13990
- xIncrement = nameX;
13991
- }
13992
- }
13993
-
13994
14068
  // Added code for pointInterval strings
13995
14069
  if (pointIntervalUnit) {
13996
14070
  date = new Date(xIncrement);
@@ -14178,15 +14252,10 @@
14178
14252
 
14179
14253
 
14180
14254
  if (isNumber(firstPoint)) { // assume all points are numbers
14181
- var x = pick(options.pointStart, 0),
14182
- pointInterval = pick(options.pointInterval, 1);
14183
-
14184
14255
  for (i = 0; i < dataLength; i++) {
14185
- xData[i] = x;
14256
+ xData[i] = this.autoIncrement();
14186
14257
  yData[i] = data[i];
14187
- x += pointInterval;
14188
14258
  }
14189
- series.xIncrement = x;
14190
14259
  } else if (isArray(firstPoint)) { // assume all points are arrays
14191
14260
  if (valueCount) { // [x, low, high] or [x, o, h, l, c]
14192
14261
  for (i = 0; i < dataLength; i++) {
@@ -14465,7 +14534,7 @@
14465
14534
 
14466
14535
  // For points within the visible range, including the first point outside the
14467
14536
  // visible range, consider y extremes
14468
- validValue = y !== null && y !== UNDEFINED && (!yAxis.isLog || (y.length || y > 0));
14537
+ validValue = (isNumber(y, true) || isArray(y)) && (!yAxis.isLog || (y.length || y > 0));
14469
14538
  withinRange = this.getExtremesFromAll || this.options.getExtremesFromAll || this.cropped ||
14470
14539
  ((xData[i + 1] || x) >= xMin && (xData[i - 1] || x) <= xMax);
14471
14540
 
@@ -14528,8 +14597,7 @@
14528
14597
 
14529
14598
  // Discard disallowed y values for log axes (#3434)
14530
14599
  if (yAxis.isLog && yValue !== null && yValue <= 0) {
14531
- point.y = yValue = null;
14532
- error(10);
14600
+ point.isNull = true;
14533
14601
  }
14534
14602
 
14535
14603
  // Get the plotX translation
@@ -14580,7 +14648,7 @@
14580
14648
 
14581
14649
 
14582
14650
  // Set client related positions for mouse tracking
14583
- point.clientX = dynamicallyPlaced ? correctFloat(xAxis.translate(xValue, 0, 0, 0, 1)) : plotX; // #1514
14651
+ point.clientX = dynamicallyPlaced ? correctFloat(xAxis.translate(xValue, 0, 0, 0, 1, pointPlacement)) : plotX; // #1514, #5383, #5518
14584
14652
 
14585
14653
  point.negative = point.y < (threshold || 0);
14586
14654
 
@@ -14685,14 +14753,9 @@
14685
14753
  var series = this,
14686
14754
  chart = series.chart,
14687
14755
  clipRect,
14688
- animation = series.options.animation,
14756
+ animation = animObject(series.options.animation),
14689
14757
  sharedClipKey;
14690
14758
 
14691
- // Animation option is set to true
14692
- if (animation && !isObject(animation)) {
14693
- animation = defaultPlotOptions[series.type].animation;
14694
- }
14695
-
14696
14759
  // Initialize the animation. Set up the clipping rectangle.
14697
14760
  if (init) {
14698
14761
 
@@ -15262,15 +15325,17 @@
15262
15325
  chartSizeMax = mathMax(chart.chartWidth, chart.chartHeight),
15263
15326
  axis = this[(this.zoneAxis || 'y') + 'Axis'],
15264
15327
  extremes,
15265
- reversed = axis.reversed,
15328
+ reversed,
15266
15329
  inverted = chart.inverted,
15267
- horiz = axis.horiz,
15330
+ horiz,
15268
15331
  pxRange,
15269
15332
  pxPosMin,
15270
15333
  pxPosMax,
15271
15334
  ignoreZones = false;
15272
15335
 
15273
- if (zones.length && (graph || area) && axis.min !== UNDEFINED) {
15336
+ if (zones.length && (graph || area) && axis && axis.min !== UNDEFINED) {
15337
+ reversed = axis.reversed;
15338
+ horiz = axis.horiz;
15274
15339
  // The use of the Color Threshold assumes there are no gaps
15275
15340
  // so it is safe to hide the original graph and area
15276
15341
  if (graph) {
@@ -15320,7 +15385,7 @@
15320
15385
  }
15321
15386
 
15322
15387
  /// VML SUPPPORT
15323
- if (chart.inverted && renderer.isVML) {
15388
+ if (inverted && renderer.isVML) {
15324
15389
  if (axis.isXAxis) {
15325
15390
  clipAttr = {
15326
15391
  x: 0,
@@ -16268,8 +16333,7 @@
16268
16333
  graphic = point.graphic,
16269
16334
  i,
16270
16335
  chart = series.chart,
16271
- seriesOptions = series.options,
16272
- names = series.xAxis && series.xAxis.names;
16336
+ seriesOptions = series.options;
16273
16337
 
16274
16338
  redraw = pick(redraw, true);
16275
16339
 
@@ -16299,10 +16363,7 @@
16299
16363
  // record changes in the parallel arrays
16300
16364
  i = point.index;
16301
16365
  series.updateParallelArrays(point, i);
16302
- if (names && point.name) {
16303
- names[point.x] = point.name;
16304
- }
16305
-
16366
+
16306
16367
  // Record the options to options.data. If there is an object from before,
16307
16368
  // use point options, otherwise use raw options. (#4701)
16308
16369
  seriesOptions.data[i] = isObject(seriesOptions.data[i], true) ? point.options : options;
@@ -16364,8 +16425,6 @@
16364
16425
  i,
16365
16426
  x;
16366
16427
 
16367
- setAnimation(animation, chart);
16368
-
16369
16428
  // Optional redraw, defaults to true
16370
16429
  redraw = pick(redraw, true);
16371
16430
 
@@ -16417,9 +16476,10 @@
16417
16476
  // redraw
16418
16477
  series.isDirty = true;
16419
16478
  series.isDirtyData = true;
16479
+
16420
16480
  if (redraw) {
16421
16481
  series.getAttribs(); // #1937
16422
- chart.redraw();
16482
+ chart.redraw(animation); // Animation is set anyway on redraw, #5665
16423
16483
  }
16424
16484
  },
16425
16485
 
@@ -16472,12 +16532,11 @@
16472
16532
  * @param {Boolean|Object} animation Whether to apply animation, and optionally animation
16473
16533
  * configuration
16474
16534
  */
16475
- remove: function (redraw, animation) {
16535
+ remove: function (redraw, animation, withEvent) {
16476
16536
  var series = this,
16477
16537
  chart = series.chart;
16478
16538
 
16479
- // Fire the event with a default handler of removing the point
16480
- fireEvent(series, 'remove', null, function () {
16539
+ function remove() {
16481
16540
 
16482
16541
  // Destroy elements
16483
16542
  series.destroy();
@@ -16489,7 +16548,14 @@
16489
16548
  if (pick(redraw, true)) {
16490
16549
  chart.redraw(animation);
16491
16550
  }
16492
- });
16551
+ }
16552
+
16553
+ // Fire the event with a default handler of removing the point
16554
+ if (withEvent !== false) {
16555
+ fireEvent(series, 'remove', null, remove);
16556
+ } else {
16557
+ remove();
16558
+ }
16493
16559
  },
16494
16560
 
16495
16561
  /**
@@ -16526,7 +16592,7 @@
16526
16592
 
16527
16593
  // Destroy the series and delete all properties. Reinsert all methods
16528
16594
  // and properties from the new type prototype (#2270, #3719)
16529
- this.remove(false);
16595
+ this.remove(false, null, false);
16530
16596
  for (n in proto) {
16531
16597
  this[n] = UNDEFINED;
16532
16598
  }
@@ -16811,14 +16877,14 @@
16811
16877
  });
16812
16878
  bottomPoints.push({
16813
16879
  plotX: plotX,
16814
- plotY: bottom === null ? translatedThreshold : yAxis.getThreshold(bottom)
16880
+ plotY: bottom === null ? translatedThreshold : yAxis.getThreshold(bottom),
16881
+ doCurve: false // #1041, gaps in areaspline areas
16815
16882
  });
16816
16883
  }
16817
16884
  };
16818
16885
 
16819
16886
  // Find what points to use
16820
16887
  points = points || this.points;
16821
-
16822
16888
 
16823
16889
  // Fill in missing points
16824
16890
  if (stacking) {
@@ -16949,8 +17015,12 @@
16949
17015
  rightContY,
16950
17016
  ret;
16951
17017
 
17018
+ function doCurve(otherPoint) {
17019
+ return otherPoint && !otherPoint.isNull && otherPoint.doCurve !== false;
17020
+ }
17021
+
16952
17022
  // Find control points
16953
- if (lastPoint && !lastPoint.isNull && nextPoint && !nextPoint.isNull) {
17023
+ if (doCurve(lastPoint) && doCurve(nextPoint)) {
16954
17024
  var lastX = lastPoint.plotX,
16955
17025
  lastY = lastPoint.plotY,
16956
17026
  nextX = nextPoint.plotX,
@@ -17001,29 +17071,35 @@
17001
17071
  this.chart.renderer.circle(leftContX + this.chart.plotLeft, leftContY + this.chart.plotTop, 2)
17002
17072
  .attr({
17003
17073
  stroke: 'red',
17004
- 'stroke-width': 1,
17005
- fill: 'none'
17074
+ 'stroke-width': 2,
17075
+ fill: 'none',
17076
+ zIndex: 9
17006
17077
  })
17007
17078
  .add();
17008
17079
  this.chart.renderer.path(['M', leftContX + this.chart.plotLeft, leftContY + this.chart.plotTop,
17009
17080
  'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop])
17010
17081
  .attr({
17011
17082
  stroke: 'red',
17012
- 'stroke-width': 1
17083
+ 'stroke-width': 2,
17084
+ zIndex: 9
17013
17085
  })
17014
17086
  .add();
17087
+ }
17088
+ if (rightContX) {
17015
17089
  this.chart.renderer.circle(rightContX + this.chart.plotLeft, rightContY + this.chart.plotTop, 2)
17016
17090
  .attr({
17017
17091
  stroke: 'green',
17018
- 'stroke-width': 1,
17019
- fill: 'none'
17092
+ 'stroke-width': 2,
17093
+ fill: 'none',
17094
+ zIndex: 9
17020
17095
  })
17021
17096
  .add();
17022
17097
  this.chart.renderer.path(['M', rightContX + this.chart.plotLeft, rightContY + this.chart.plotTop,
17023
17098
  'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop])
17024
17099
  .attr({
17025
17100
  stroke: 'green',
17026
- 'stroke-width': 1
17101
+ 'stroke-width': 2,
17102
+ zIndex: 9
17027
17103
  })
17028
17104
  .add();
17029
17105
  }
@@ -17316,7 +17392,12 @@
17316
17392
 
17317
17393
  // Register shape type and arguments to be used in drawPoints
17318
17394
  point.shapeType = 'rect';
17319
- point.shapeArgs = series.crispCol(barX, barY, barW, barH);
17395
+ point.shapeArgs = series.crispCol.apply(
17396
+ series,
17397
+ point.isNull ?
17398
+ [point.plotX, yAxis.len / 2, 0, 0] : // #3169, drilldown from null must have a position to work from
17399
+ [barX, barY, barW, barH]
17400
+ );
17320
17401
  });
17321
17402
 
17322
17403
  },
@@ -19643,7 +19724,7 @@
19643
19724
  oldVisibility = series.visible;
19644
19725
 
19645
19726
  // if called without an argument, toggle visibility
19646
- series.visible = vis = series.userOptions.visible = vis === UNDEFINED ? !oldVisibility : vis;
19727
+ series.visible = vis = series.options.visible = series.userOptions.visible = vis === undefined ? !oldVisibility : vis; // #5618
19647
19728
  showOrHide = vis ? 'show' : 'hide';
19648
19729
 
19649
19730
  // show or hide elements