highcharts-rails 4.1.4 → 4.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4a7d99b4cb1d1ab05f71178ae10706be52327a3b
4
- data.tar.gz: a7da74086801908f0f8bc9307b897d3785a72ef6
3
+ metadata.gz: 4cc9e5622951314ffef63262c82a65c0497f3fdb
4
+ data.tar.gz: 36185a5fe7cca92c015c733997b09003bb39f841
5
5
  SHA512:
6
- metadata.gz: 869e6f15881a96a6e4ea3702577060313f26390f05a6000824915dad2257e4750c3cfd580da5b241de82c097f565373e3b2a0c6c2f35c624ec48987b1a13529f
7
- data.tar.gz: 0a94857739a4ae98560cded6a9475ef03e53e3ecaacacd3be7cc368d6e33968fa7ece801cbf03585ad8e1920dc34df467a0139ca7bba486a00de38d7154fa904
6
+ metadata.gz: 8a739bc1dde01881470be2af26db1d39a1f8392c18bbe6855c8b4517819dcd013e29b6de70ce704328cc74a63787cd9f6322851fdae08af65a33a464b5dae520
7
+ data.tar.gz: 2cd5ffd46e58ea78a37cbb27c5a94d1fe92193fcd99bf3357e8eec612a9f68b18002087a3792f5f97d30c4095e9dc6e04271563a5a98a64e439a54f930969cfd
@@ -1,3 +1,49 @@
1
+ # 4.1.5 / 2015-04-13
2
+
3
+ * Updated Highcharts to 4.1.5
4
+ * Added new option, series.keys.
5
+ * Added now option, autoRotationLimit, as an upper limit for when to apply auto rotation. Closes #3941.
6
+ * Added options to solidgauge, radius and innerRadius on individual points.
7
+ * Changed tooltip behaviour in line charts and derivatives. This made swithching between series easier when the other series was covered by the tooltip.
8
+ * Fixed #2922, redundant drilldown event on clicking data label.
9
+ * Fixed #3355, causing misaligned bars around the threshold value.
10
+ * Fixed #3758, setData on heatmap caused X axis to lose point range.
11
+ * Fixed #3839, axis labels not using available space after resize.
12
+ * Fixed #3867, errors on drill up on multi-series multi-level chart.
13
+ * Fixed #3912, shared tooltips not working well with pointPlacement.
14
+ * Fixed #3935, time axes got wrong extremes in rare cases.
15
+ * Fixed #3951, drilldown activeLabelStyle was lost after setting extremes.
16
+ * Fixed #3962, tooltip covered stacked columns near edges of the chart.
17
+ * Fixed #3967, shared tooltip not working with two datetime axes.
18
+ * Fixed #3969, legend indicator not displayed on colorAxis for 0 values.
19
+ * Fixed #3976, one legend item's height influenced all subsequent boxes.
20
+ * Fixed #3985, clicks registering incorrectly on column charts.
21
+ * Fixed #3988, column legend markers were not aligned to baseline.
22
+ * Fixed #3990, drilldown failed after destroying and re-initialising chart.
23
+ * Fixed #3995, all points were black after drilling in treemap with a coloraxis.
24
+ * Fixed #3996, font-style not taking effect with useHTML.
25
+ * Fixed #4001, errors thrown on area with a single point and zones.
26
+ * Fixed #4003, text replacement in export replaced content in label.
27
+ * Fixed #4006, wrong rendering of zones with values less then the minimum.
28
+ * Fixed #4014, touch scrolling not working on charts since the default followTouchMove changed.
29
+ * Fixed #4015, solid gauge color not updating in IE8.
30
+ * Fixed #4035, lineWidthPlus adding to states.hover.lineWidth.
31
+ * Fixed #4046, treemap issue with drillToNode and redraw of the chart.
32
+ * Fixed #4051, minPointLength gave wrong position on reversed Y axis.
33
+ * Fixed #4055, unable to set borderWidth to 0 for 3d columns.
34
+ * Fixed #4056, stack labels on reversed axis not vertically aligned correctly.
35
+ * Fixed #4062, 3d zIndex incorrect on chart resize.
36
+ * Fixed #4067, 3d columns datalabels not aligned.
37
+ * Fixed #4068, null colors rendered as black in columns and white in pies.
38
+ * Fixed #4069, setVisible was very slow on pies with many legend items.
39
+ * Fixed #4070, label ellipsis lost on vertical axis after redraw.
40
+ * Fixed #4075, zone elements were not destroyed on series update.
41
+ * Fixed #4079, bullets in tooltips had wrong encoding in IE8 on non-UTC pages.
42
+ * Fixed #4082, series with zones didn't apply hover line width.
43
+ * Fixed #4083, series with zones animated wrong on addPoint.
44
+ * Fixed #4085, wrong usage of momentjs in demo.
45
+ * Fixed #3832, bundled PhantomJS scripts not copied to filesystem on Windows.
46
+
1
47
  # 4.1.4 / 2015-03-10
2
48
 
3
49
  * Updated Highcharts to 4.1.4
@@ -2,7 +2,7 @@
2
2
  // @compilation_level SIMPLE_OPTIMIZATIONS
3
3
 
4
4
  /**
5
- * @license Highcharts JS v4.1.4 (2015-03-10)
5
+ * @license Highcharts JS v4.1.5 (2015-04-13)
6
6
  *
7
7
  * (c) 2009-2014 Torstein Honsi
8
8
  *
@@ -56,7 +56,7 @@ var UNDEFINED,
56
56
  charts = [],
57
57
  chartCount = 0,
58
58
  PRODUCT = 'Highcharts',
59
- VERSION = '4.1.4',
59
+ VERSION = '4.1.5',
60
60
 
61
61
  // some constants for frequently used strings
62
62
  DIV = 'div',
@@ -92,6 +92,8 @@ var UNDEFINED,
92
92
  getDate,
93
93
  getMonth,
94
94
  getFullYear,
95
+ setMilliseconds,
96
+ setSeconds,
95
97
  setMinutes,
96
98
  setHours,
97
99
  setDate,
@@ -1259,8 +1261,8 @@ defaultOptions = {
1259
1261
  global: {
1260
1262
  useUTC: true,
1261
1263
  //timezoneOffset: 0,
1262
- canvasToolsURL: 'http://code.highcharts.com/4.1.4/modules/canvas-tools.js',
1263
- VMLRadialGradientURL: 'http://code.highcharts.com/4.1.4/gfx/vml-radial-gradient.png'
1264
+ canvasToolsURL: 'http://code.highcharts.com/4.1.5/modules/canvas-tools.js',
1265
+ VMLRadialGradientURL: 'http://code.highcharts.com/4.1.5/gfx/vml-radial-gradient.png'
1264
1266
  },
1265
1267
  chart: {
1266
1268
  //animation: true,
@@ -1613,17 +1615,19 @@ function setTimeMethods() {
1613
1615
  }
1614
1616
  return d;
1615
1617
  };
1616
- getMinutes = GET + 'Minutes';
1617
- getHours = GET + 'Hours';
1618
- getDay = GET + 'Day';
1619
- getDate = GET + 'Date';
1620
- getMonth = GET + 'Month';
1621
- getFullYear = GET + 'FullYear';
1622
- setMinutes = SET + 'Minutes';
1623
- setHours = SET + 'Hours';
1624
- setDate = SET + 'Date';
1625
- setMonth = SET + 'Month';
1626
- setFullYear = SET + 'FullYear';
1618
+ getMinutes = GET + 'Minutes';
1619
+ getHours = GET + 'Hours';
1620
+ getDay = GET + 'Day';
1621
+ getDate = GET + 'Date';
1622
+ getMonth = GET + 'Month';
1623
+ getFullYear = GET + 'FullYear';
1624
+ setMilliseconds = SET + 'Milliseconds';
1625
+ setSeconds = SET + 'Seconds';
1626
+ setMinutes = SET + 'Minutes';
1627
+ setHours = SET + 'Hours';
1628
+ setDate = SET + 'Date';
1629
+ setMonth = SET + 'Month';
1630
+ setFullYear = SET + 'FullYear';
1627
1631
 
1628
1632
  }
1629
1633
 
@@ -1784,7 +1788,7 @@ SVGElement.prototype = {
1784
1788
  // Default base for animation
1785
1789
  opacity: 1,
1786
1790
  // For labels, these CSS properties are applied to the <text> node directly
1787
- textProps: ['fontSize', 'fontWeight', 'fontFamily', 'color',
1791
+ textProps: ['fontSize', 'fontWeight', 'fontFamily', 'fontStyle', 'color',
1788
1792
  'lineHeight', 'width', 'textDecoration', 'textShadow'],
1789
1793
 
1790
1794
  /**
@@ -5912,7 +5916,10 @@ Tick.prototype = {
5912
5916
  label.attr({ align: 'right' });
5913
5917
  }
5914
5918
 
5915
- if (labelWidth > slotWidth) {
5919
+ // If the label width exceeds the available space, set a text width to be
5920
+ // picked up below. Also, if a width has been set before, we need to set a new
5921
+ // one because the reported labelWidth will be limited by the box (#3938).
5922
+ if (labelWidth > slotWidth || (axis.autoRotation && label.styles.width)) {
5916
5923
  textWidth = slotWidth;
5917
5924
  }
5918
5925
 
@@ -7890,7 +7897,7 @@ Axis.prototype = {
7890
7897
  if (horiz) {
7891
7898
  autoRotation = defined(rotationOption) ?
7892
7899
  [rotationOption] :
7893
- slotSize < 80 && !labelOptions.staggerLines && !labelOptions.step && labelOptions.autoRotation;
7900
+ slotSize < pick(labelOptions.autoRotationLimit, 80) && !labelOptions.staggerLines && !labelOptions.step && labelOptions.autoRotation;
7894
7901
 
7895
7902
  if (autoRotation) {
7896
7903
 
@@ -7979,7 +7986,11 @@ Axis.prototype = {
7979
7986
  pos = tickPositions[i];
7980
7987
  label = ticks[pos].label;
7981
7988
  if (label) {
7982
- if (this.len / tickPositions.length - 4 < label.getBBox().height) {
7989
+ // Reset ellipsis in order to get the correct bounding box (#4070)
7990
+ if (label.styles.textOverflow === 'ellipsis') {
7991
+ label.css({ textOverflow: 'clip' });
7992
+ }
7993
+ if (label.getBBox().height > this.len / tickPositions.length - (labelMetrics.h - labelMetrics.f)) {
7983
7994
  label.specCss = { textOverflow: 'ellipsis' };
7984
7995
  }
7985
7996
  }
@@ -8581,11 +8592,11 @@ Axis.prototype.getTimeTicks = function (normalizedInterval, min, max, startOfWee
8581
8592
  count = normalizedInterval.count;
8582
8593
 
8583
8594
  if (defined(min)) { // #1300
8584
- minDate.setMilliseconds(interval >= timeUnits.second ? 0 :
8595
+ minDate[setMilliseconds](interval >= timeUnits.second ? 0 : // #3935
8585
8596
  count * mathFloor(minDate.getMilliseconds() / count)); // #3652, #3654
8586
8597
 
8587
8598
  if (interval >= timeUnits.second) { // second
8588
- minDate.setSeconds(interval >= timeUnits.minute ? 0 :
8599
+ minDate[setSeconds](interval >= timeUnits.minute ? 0 : // #3935
8589
8600
  count * mathFloor(minDate.getSeconds() / count));
8590
8601
  }
8591
8602
 
@@ -9065,6 +9076,7 @@ Tooltip.prototype = {
9065
9076
  var chart = this.chart,
9066
9077
  distance = this.distance,
9067
9078
  ret = {},
9079
+ h = point.h,
9068
9080
  swapped,
9069
9081
  first = ['y', chart.chartHeight, boxHeight, point.plotY + chart.plotTop],
9070
9082
  second = ['x', chart.chartWidth, boxWidth, point.plotX + chart.plotLeft],
@@ -9085,9 +9097,9 @@ Tooltip.prototype = {
9085
9097
  } else if (!preferFarSide && roomLeft) {
9086
9098
  ret[dim] = alignedLeft;
9087
9099
  } else if (roomLeft) {
9088
- ret[dim] = alignedLeft;
9100
+ ret[dim] = alignedLeft - h < 0 ? alignedLeft : alignedLeft - h;
9089
9101
  } else if (roomRight) {
9090
- ret[dim] = alignedRight;
9102
+ ret[dim] = alignedRight + h + innerSize > outerSize ? alignedRight : alignedRight + h;
9091
9103
  } else {
9092
9104
  return false;
9093
9105
  }
@@ -9253,8 +9265,13 @@ Tooltip.prototype = {
9253
9265
  label.attr({
9254
9266
  stroke: borderColor
9255
9267
  });
9256
-
9257
- tooltip.updatePosition({ plotX: x, plotY: y, negative: point.negative, ttBelow: point.ttBelow });
9268
+ tooltip.updatePosition({
9269
+ plotX: x,
9270
+ plotY: y,
9271
+ negative: point.negative,
9272
+ ttBelow: point.ttBelow,
9273
+ h: (point.shapeArgs && point.shapeArgs.height) || 0
9274
+ });
9258
9275
 
9259
9276
  this.isHidden = false;
9260
9277
  }
@@ -9520,8 +9537,6 @@ Pointer.prototype = {
9520
9537
  hoverPoint = chart.hoverPoint,
9521
9538
  hoverSeries = chart.hoverSeries,
9522
9539
  i,
9523
- trueXkd,
9524
- trueX,
9525
9540
  //j,
9526
9541
  distance = chart.chartWidth,
9527
9542
  rdistance = chart.chartWidth,
@@ -9541,8 +9556,13 @@ Pointer.prototype = {
9541
9556
  }
9542
9557
  }
9543
9558
 
9559
+ // If it has a hoverPoint and that series requires direct touch (like columns),
9560
+ // use the hoverPoint (#3899). Otherwise, search the k-d tree.
9561
+ if (!shared && hoverSeries && hoverSeries.directTouch && hoverPoint) {
9562
+ kdpoint = hoverPoint;
9563
+
9544
9564
  // Handle shared tooltip or cases where a series is not yet hovered
9545
- if (!(hoverSeries && hoverSeries.noSharedTooltip) && (shared || !hoverSeries)) { // #3821
9565
+ } else {
9546
9566
  // Find nearest points on all series
9547
9567
  each(series, function (s) {
9548
9568
  // Skip hidden series
@@ -9557,19 +9577,14 @@ Pointer.prototype = {
9557
9577
  // Find absolute nearest point
9558
9578
  each(kdpoints, function (p) {
9559
9579
  if (p && defined(p.plotX) && defined(p.plotY)) {
9560
- if ((p.dist.distX < distance) || ((p.dist.distX === distance || p.series.kdDimensions > 1) && p.dist.distR < rdistance)) {
9580
+ if ((p.dist.distX < distance) || ((p.dist.distX === distance || p.series.kdDimensions > 1) &&
9581
+ p.dist.distR < rdistance)) {
9561
9582
  distance = p.dist.distX;
9562
9583
  rdistance = p.dist.distR;
9563
9584
  kdpoint = p;
9564
9585
  }
9565
9586
  }
9566
- });
9567
-
9568
- // Handle non-shared tooltips
9569
- } else {
9570
- // If it has a hoverPoint and that series requires direct touch (like columns), use the hoverPoint (#3899).
9571
- // Otherwise, search the k-d tree (like scatter).
9572
- kdpoint = (hoverSeries.directTouch && hoverPoint) || (hoverSeries && hoverSeries.searchPoint(e));
9587
+ });
9573
9588
  }
9574
9589
 
9575
9590
  // Refresh tooltip for kdpoint if new hover point or tooltip was hidden // #3926
@@ -9577,10 +9592,8 @@ Pointer.prototype = {
9577
9592
  // Draw tooltip if necessary
9578
9593
  if (shared && !kdpoint.series.noSharedTooltip) {
9579
9594
  i = kdpoints.length;
9580
- trueXkd = kdpoint.clientX;
9581
9595
  while (i--) {
9582
- trueX = kdpoints[i].clientX;
9583
- if (kdpoints[i].x !== kdpoint.x || trueX !== trueXkd || (kdpoints[i].series.noSharedTooltip || false)) {
9596
+ if (kdpoints[i].clientX !== kdpoint.clientX || kdpoints[i].series.noSharedTooltip) {
9584
9597
  kdpoints.splice(i, 1);
9585
9598
  }
9586
9599
  }
@@ -9593,8 +9606,9 @@ Pointer.prototype = {
9593
9606
  if (point !== kdpoint) {
9594
9607
  point.onMouseOver(e);
9595
9608
  }
9596
- });
9597
- kdpoint.onMouseOver(e); // #3919 do mouseover on the closest point last to ensure it is the hoverpoint
9609
+ });
9610
+ // #3919, #3985 do mouseover on the closest point last to ensure it is the hoverpoint
9611
+ ((hoverSeries && hoverSeries.directTouch && hoverPoint) || kdpoint).onMouseOver(e);
9598
9612
  } else {
9599
9613
  if (tooltip) {
9600
9614
  tooltip.refresh(kdpoint, e);
@@ -10348,7 +10362,7 @@ if (win.PointerEvent || win.MSPointerEvent) {
10348
10362
  });
10349
10363
  },
10350
10364
  onDocumentPointerUp: function (e) {
10351
- translateMSPointer(e, 'onContainerTouchEnd', 'touchend', function (e) {
10365
+ translateMSPointer(e, 'onDocumentTouchEnd', 'touchend', function (e) {
10352
10366
  delete touches[e.pointerId];
10353
10367
  });
10354
10368
  },
@@ -10366,7 +10380,7 @@ if (win.PointerEvent || win.MSPointerEvent) {
10366
10380
  // Disable default IE actions for pinch and such on chart element
10367
10381
  wrap(Pointer.prototype, 'init', function (proceed, chart, options) {
10368
10382
  proceed.call(this, chart, options);
10369
- if (this.hasZoom || this.followTouchMove) {
10383
+ if (this.hasZoom) { // #4014
10370
10384
  css(chart.container, {
10371
10385
  '-ms-touch-action': NONE,
10372
10386
  'touch-action': NONE
@@ -10657,7 +10671,8 @@ Legend.prototype = {
10657
10671
 
10658
10672
  // Get the baseline for the first item - the font size is equal for all
10659
10673
  if (!legend.baseline) {
10660
- legend.baseline = renderer.fontMetrics(itemStyle.fontSize, li).f + 3 + itemMarginTop;
10674
+ legend.fontMetrics = renderer.fontMetrics(itemStyle.fontSize, li);
10675
+ legend.baseline = legend.fontMetrics.f + 3 + itemMarginTop;
10661
10676
  li.attr('y', legend.baseline);
10662
10677
  }
10663
10678
 
@@ -10691,6 +10706,7 @@ Legend.prototype = {
10691
10706
  (widthOption || (chart.chartWidth - 2 * padding - initialItemX - options.x))) {
10692
10707
  legend.itemX = initialItemX;
10693
10708
  legend.itemY += itemMarginTop + legend.lastLineHeight + itemMarginBottom;
10709
+ legend.lastLineHeight = 0; // reset for next line (#915, #3976)
10694
10710
  }
10695
10711
 
10696
10712
  // If the item exceeds the height, start a new column
@@ -11094,11 +11110,11 @@ var LegendSymbolMixin = Highcharts.LegendSymbolMixin = {
11094
11110
  * @param {Object} item The series (this) or point
11095
11111
  */
11096
11112
  drawRectangle: function (legend, item) {
11097
- var symbolHeight = legend.options.symbolHeight || 12;
11098
-
11113
+ var symbolHeight = legend.options.symbolHeight || legend.fontMetrics.f;
11114
+
11099
11115
  item.legendSymbol = this.chart.renderer.rect(
11100
11116
  0,
11101
- legend.baseline - 5 - (symbolHeight / 2),
11117
+ legend.baseline - symbolHeight + 1, // #3988
11102
11118
  legend.symbolWidth,
11103
11119
  symbolHeight,
11104
11120
  legend.options.symbolRadius || 0
@@ -11119,12 +11135,11 @@ var LegendSymbolMixin = Highcharts.LegendSymbolMixin = {
11119
11135
  var options = this.options,
11120
11136
  markerOptions = options.marker,
11121
11137
  radius,
11122
- legendOptions = legend.options,
11123
11138
  legendSymbol,
11124
11139
  symbolWidth = legend.symbolWidth,
11125
11140
  renderer = this.chart.renderer,
11126
11141
  legendItemGroup = this.legendGroup,
11127
- verticalCenter = legend.baseline - mathRound(renderer.fontMetrics(legendOptions.itemStyle.fontSize, this.legendItem).b * 0.3),
11142
+ verticalCenter = legend.baseline - mathRound(legend.fontMetrics.b * 0.3),
11128
11143
  attr;
11129
11144
 
11130
11145
  // Draw the line
@@ -12365,7 +12380,7 @@ Chart.prototype = {
12365
12380
  chart.getAxisMargins();
12366
12381
 
12367
12382
  // If the plot area size has changed significantly, calculate tick positions again
12368
- redoHorizontal = tempWidth / chart.plotWidth > 1.2;
12383
+ redoHorizontal = tempWidth / chart.plotWidth > 1.1;
12369
12384
  redoVertical = tempHeight / chart.plotHeight > 1.1;
12370
12385
 
12371
12386
  if (redoHorizontal || redoVertical) {
@@ -12713,7 +12728,8 @@ Point.prototype = {
12713
12728
  optionsToObject: function (options) {
12714
12729
  var ret = {},
12715
12730
  series = this.series,
12716
- pointArrayMap = series.pointArrayMap || ['y'],
12731
+ keys = series.options.keys, // docs: http://jsfiddle.net/ch4v7n8v/1
12732
+ pointArrayMap = keys || series.pointArrayMap || ['y'],
12717
12733
  valueCount = pointArrayMap.length,
12718
12734
  firstItemType,
12719
12735
  i = 0,
@@ -12724,7 +12740,7 @@ Point.prototype = {
12724
12740
 
12725
12741
  } else if (isArray(options)) {
12726
12742
  // with leading x value
12727
- if (options.length > valueCount) {
12743
+ if (!keys && options.length > valueCount) {
12728
12744
  firstItemType = typeof options[0];
12729
12745
  if (firstItemType === 'string') {
12730
12746
  ret.name = options[0];
@@ -13559,8 +13575,6 @@ Series.prototype = {
13559
13575
  xMax = xExtremes.max,
13560
13576
  validValue,
13561
13577
  withinRange,
13562
- dataMin,
13563
- dataMax,
13564
13578
  x,
13565
13579
  y,
13566
13580
  i,
@@ -13594,8 +13608,8 @@ Series.prototype = {
13594
13608
  }
13595
13609
  }
13596
13610
  }
13597
- this.dataMin = pick(dataMin, arrayMin(activeYData));
13598
- this.dataMax = pick(dataMax, arrayMax(activeYData));
13611
+ this.dataMin = arrayMin(activeYData);
13612
+ this.dataMax = arrayMax(activeYData);
13599
13613
  },
13600
13614
 
13601
13615
  /**
@@ -13751,7 +13765,7 @@ Series.prototype = {
13751
13765
  this.sharedClipKey = sharedClipKey;
13752
13766
  }
13753
13767
 
13754
- // Remove the shared clipping rectancgle when all series are shown
13768
+ // Remove the shared clipping rectangle when all series are shown
13755
13769
  if (!animation) {
13756
13770
  clipRect.count -= 1;
13757
13771
  if (clipRect.count <= 0 && sharedClipKey && chart[sharedClipKey]) {
@@ -14048,6 +14062,10 @@ Series.prototype = {
14048
14062
  if (!defaultLineColor) {
14049
14063
  attr.lineColor = point.color; // Bubbles take point color, line markers use white
14050
14064
  }
14065
+ // Color is explicitly set to null or undefined (#1288, #4068)
14066
+ if (normalOptions.hasOwnProperty('color') && !normalOptions.color) {
14067
+ delete normalOptions.color;
14068
+ }
14051
14069
  pointAttr[NORMAL_STATE] = series.convertAttribs(extend(attr, normalOptions), seriesPointAttr[NORMAL_STATE]);
14052
14070
 
14053
14071
  // inherit from point normal and series hover
@@ -14123,10 +14141,9 @@ Series.prototype = {
14123
14141
  // Clear the animation timeout if we are destroying the series during initial animation
14124
14142
  clearTimeout(series.animationTimeout);
14125
14143
 
14126
- // destroy all SVGElements associated to the series
14127
- each(['area', 'graph', 'dataLabelsGroup', 'group', 'markerGroup', 'tracker',
14128
- 'graphNeg', 'areaNeg', 'posClip', 'negClip'], function (prop) {
14129
- if (series[prop]) {
14144
+ // Destroy all SVGElements associated to the series
14145
+ for (prop in series) {
14146
+ if (series[prop] instanceof SVGElement && !series[prop].survive) { // Survive provides a hook for not destroying
14130
14147
 
14131
14148
  // issue 134 workaround
14132
14149
  destroy = issue134 && prop === 'group' ?
@@ -14135,7 +14152,7 @@ Series.prototype = {
14135
14152
 
14136
14153
  series[prop][destroy]();
14137
14154
  }
14138
- });
14155
+ }
14139
14156
 
14140
14157
  // remove from hoverSeries
14141
14158
  if (chart.hoverSeries === series) {
@@ -14252,7 +14269,7 @@ Series.prototype = {
14252
14269
  zones = this.zones;
14253
14270
 
14254
14271
  each(zones, function (threshold, i) {
14255
- props.push(['colorGraph' + i, threshold.color || series.color, threshold.dashStyle || options.dashStyle]);
14272
+ props.push(['zoneGraph' + i, threshold.color || series.color, threshold.dashStyle || options.dashStyle]);
14256
14273
  });
14257
14274
 
14258
14275
  // Draw the graph
@@ -14310,14 +14327,24 @@ Series.prototype = {
14310
14327
  if (zones.length && (graph || area)) {
14311
14328
  // The use of the Color Threshold assumes there are no gaps
14312
14329
  // so it is safe to hide the original graph and area
14313
- graph.hide();
14314
- if (area) { area.hide(); }
14330
+ if (graph) {
14331
+ graph.hide();
14332
+ }
14333
+ if (area) {
14334
+ area.hide();
14335
+ }
14315
14336
 
14316
14337
  // Create the clips
14317
14338
  each(zones, function (threshold, i) {
14318
14339
  translatedFrom = pick(translatedTo, (reversed ? (horiz ? chart.plotWidth : 0) : (horiz ? 0 : axis.toPixels(axis.min))));
14319
14340
  translatedTo = mathRound(axis.toPixels(pick(threshold.value, axis.max), true));
14320
14341
 
14342
+ if (axis.isXAxis) {
14343
+ translatedFrom = translatedFrom > translatedTo ? translatedTo : translatedFrom; //#4006 from should be less or equal then to
14344
+ } else {
14345
+ translatedFrom = translatedFrom < translatedTo ? translatedTo : translatedFrom; //#4006 from should be less or equal then to
14346
+ }
14347
+
14321
14348
  if (ignoreZones) {
14322
14349
  translatedFrom = translatedTo = axis.toPixels(axis.max);
14323
14350
  }
@@ -14369,10 +14396,12 @@ Series.prototype = {
14369
14396
  } else {
14370
14397
  clips[i] = renderer.clipRect(clipAttr);
14371
14398
 
14372
- series['colorGraph' + i].clip(clips[i]);
14399
+ if (graph) {
14400
+ series['zoneGraph' + i].clip(clips[i]);
14401
+ }
14373
14402
 
14374
14403
  if (area) {
14375
- series['colorArea' + i].clip(clips[i]);
14404
+ series['zoneArea' + i].clip(clips[i]);
14376
14405
  }
14377
14406
  }
14378
14407
  // if this zone extends out of the axis, ignore the others
@@ -14611,7 +14640,7 @@ Series.prototype = {
14611
14640
 
14612
14641
  kdDimensions: 1,
14613
14642
  kdTree: null,
14614
- kdAxisArray: ['plotX', 'plotY'],
14643
+ kdAxisArray: ['clientX', 'plotY'],
14615
14644
  kdComparer: 'distX',
14616
14645
 
14617
14646
  searchPoint: function (e) {
@@ -14620,10 +14649,10 @@ Series.prototype = {
14620
14649
  yAxis = series.yAxis,
14621
14650
  inverted = series.chart.inverted;
14622
14651
 
14623
- e.plotX = inverted ? xAxis.len - e.chartY + xAxis.pos : e.chartX - xAxis.pos;
14624
- e.plotY = inverted ? yAxis.len - e.chartX + yAxis.pos : e.chartY - yAxis.pos;
14625
-
14626
- return this.searchKDTree(e);
14652
+ return this.searchKDTree({
14653
+ clientX: inverted ? xAxis.len - e.chartY + xAxis.pos : e.chartX - xAxis.pos,
14654
+ plotY: inverted ? yAxis.len - e.chartX + yAxis.pos : e.chartY - yAxis.pos
14655
+ });
14627
14656
  },
14628
14657
 
14629
14658
  buildKDTree: function () {
@@ -14816,7 +14845,8 @@ StackItem.prototype = {
14816
14845
  axis = stackItem.axis,
14817
14846
  chart = axis.chart,
14818
14847
  inverted = chart.inverted,
14819
- neg = this.isNegative, // special treatment is needed for negative stacks
14848
+ reversed = axis.reversed,
14849
+ neg = (this.isNegative && !reversed) || (!this.isNegative && reversed), // #4056
14820
14850
  y = axis.translate(axis.usePercentage ? 100 : this.total, 0, 0, 0, 1), // stack value translated mapped to chart coordinates
14821
14851
  yZero = axis.translate(0), // stack origin
14822
14852
  h = mathAbs(y - yZero), // stack height
@@ -15273,20 +15303,25 @@ extend(Series.prototype, {
15273
15303
  chart = series.chart,
15274
15304
  names = series.xAxis && series.xAxis.names,
15275
15305
  currentShift = (graph && graph.shift) || 0,
15306
+ shiftShapes = ['graph', 'area'],
15276
15307
  dataOptions = seriesOptions.data,
15277
15308
  point,
15278
15309
  isInTheMiddle,
15279
15310
  xData = series.xData,
15280
- x,
15281
- i;
15311
+ i,
15312
+ x;
15282
15313
 
15283
15314
  setAnimation(animation, chart);
15284
15315
 
15285
15316
  // Make graph animate sideways
15286
15317
  if (shift) {
15287
- each([graph, area, series.graphNeg, series.areaNeg], function (shape) {
15288
- if (shape) {
15289
- shape.shift = currentShift + 1;
15318
+ i = series.zones.length;
15319
+ while (i--) {
15320
+ shiftShapes.push('zoneGraph' + i, 'zoneArea' + i);
15321
+ }
15322
+ each(shiftShapes, function (shape) {
15323
+ if (series[shape]) {
15324
+ series[shape].shift = currentShift + 1;
15290
15325
  }
15291
15326
  });
15292
15327
  }
@@ -15744,7 +15779,7 @@ var AreaSeries = extendClass(Series, {
15744
15779
  props = [['area', this.color, options.fillColor]]; // area name, main color, fill color
15745
15780
 
15746
15781
  each(zones, function (threshold, i) {
15747
- props.push(['colorArea' + i, threshold.color || series.color, threshold.fillColor || options.fillColor]);
15782
+ props.push(['zoneArea' + i, threshold.color || series.color, threshold.fillColor || options.fillColor]);
15748
15783
  });
15749
15784
  each(props, function (prop) {
15750
15785
  var areaKey = prop[0],
@@ -16083,8 +16118,11 @@ var ColumnSeries = extendClass(Series, {
16083
16118
  xCrisp = -(borderWidth % 2 ? 0.5 : 0),
16084
16119
  yCrisp = borderWidth % 2 ? 0.5 : 1;
16085
16120
 
16086
- if (chart.renderer.isVML && chart.inverted) {
16087
- yCrisp += 1;
16121
+ if (chart.inverted) {
16122
+ translatedThreshold -= 0.5; // #3355
16123
+ if (chart.renderer.isVML) {
16124
+ yCrisp += 1;
16125
+ }
16088
16126
  }
16089
16127
 
16090
16128
  // When the pointPadding is 0, we want the columns to be packed tightly, so we allow individual
@@ -16106,16 +16144,18 @@ var ColumnSeries = extendClass(Series, {
16106
16144
  right,
16107
16145
  bottom,
16108
16146
  fromTop,
16147
+ up,
16109
16148
  barH = mathMax(plotY, yBottom) - barY;
16110
16149
 
16111
16150
  // Handle options.minPointLength
16112
16151
  if (mathAbs(barH) < minPointLength) {
16113
16152
  if (minPointLength) {
16114
16153
  barH = minPointLength;
16154
+ up = (!yAxis.reversed && !point.negative) || (yAxis.reversed && point.negative);
16115
16155
  barY =
16116
16156
  mathRound(mathAbs(barY - translatedThreshold) > minPointLength ? // stacked
16117
16157
  yBottom - minPointLength : // keep position
16118
- translatedThreshold - (yAxis.translate(point.y, 0, 1, 0, 1) <= translatedThreshold ? minPointLength : 0)); // use exact yAxis.translation (#1485)
16158
+ translatedThreshold - (up ? minPointLength : 0)); // #1485, #4051
16119
16159
  }
16120
16160
  }
16121
16161
 
@@ -16397,38 +16437,42 @@ var PiePoint = extendClass(Point, {
16397
16437
  * @param {Boolean} vis Whether to show the slice or not. If undefined, the
16398
16438
  * visibility is toggled
16399
16439
  */
16400
- setVisible: function (vis) {
16440
+ setVisible: function (vis, force) {
16401
16441
  var point = this,
16402
16442
  series = point.series,
16403
16443
  chart = series.chart,
16404
16444
  doRedraw = !series.isDirty && series.options.ignoreHiddenPoint;
16405
16445
 
16406
- // if called without an argument, toggle visibility
16407
- point.visible = point.options.visible = vis = vis === UNDEFINED ? !point.visible : vis;
16408
- series.options.data[inArray(point, series.data)] = point.options; // update userOptions.data
16409
-
16410
- // Show and hide associated elements
16411
- each(['graphic', 'dataLabel', 'connector', 'shadowGroup'], function (key) {
16412
- if (point[key]) {
16413
- point[key][vis ? 'show' : 'hide'](true);
16414
- }
16415
- });
16446
+ // Only if the value has changed
16447
+ if (vis !== point.visible || force) {
16448
+
16449
+ // If called without an argument, toggle visibility
16450
+ point.visible = point.options.visible = vis = vis === UNDEFINED ? !point.visible : vis;
16451
+ series.options.data[inArray(point, series.data)] = point.options; // update userOptions.data
16452
+
16453
+ // Show and hide associated elements
16454
+ each(['graphic', 'dataLabel', 'connector', 'shadowGroup'], function (key) {
16455
+ if (point[key]) {
16456
+ point[key][vis ? 'show' : 'hide'](true);
16457
+ }
16458
+ });
16416
16459
 
16417
- if (point.legendItem) {
16418
- if (chart.hasRendered) {
16419
- series.updateTotals();
16420
- chart.legend.clearItems();
16421
- if (!doRedraw) {
16422
- chart.legend.render();
16460
+ if (point.legendItem) {
16461
+ if (chart.hasRendered) {
16462
+ series.updateTotals();
16463
+ chart.legend.clearItems();
16464
+ if (!doRedraw) {
16465
+ chart.legend.render();
16466
+ }
16423
16467
  }
16468
+ chart.legend.colorizeItem(point, vis);
16424
16469
  }
16425
- chart.legend.colorizeItem(point, vis);
16426
- }
16427
16470
 
16428
- // Handle ignore hidden slices
16429
- if (doRedraw) {
16430
- series.isDirty = true;
16431
- chart.redraw();
16471
+ // Handle ignore hidden slices
16472
+ if (doRedraw) {
16473
+ series.isDirty = true;
16474
+ chart.redraw();
16475
+ }
16432
16476
  }
16433
16477
  },
16434
16478
 
@@ -16515,7 +16559,7 @@ var PieSeries = {
16515
16559
  if (graphic) {
16516
16560
  // start values
16517
16561
  graphic.attr({
16518
- r: series.center[3] / 2, // animate from inner radius (#779)
16562
+ r: point.startR || (series.center[3] / 2), // animate from inner radius (#779)
16519
16563
  start: startAngleRad,
16520
16564
  end: startAngleRad
16521
16565
  });
@@ -16727,6 +16771,9 @@ var PieSeries = {
16727
16771
 
16728
16772
  // draw the slices
16729
16773
  each(series.points, function (point) {
16774
+
16775
+ var visible = point.options.visible;
16776
+
16730
16777
  graphic = point.graphic;
16731
16778
  shapeArgs = point.shapeArgs;
16732
16779
  shadowGroup = point.shadowGroup;
@@ -16766,9 +16813,9 @@ var PieSeries = {
16766
16813
  .shadow(shadow, shadowGroup);
16767
16814
  }
16768
16815
 
16769
- // detect point specific visibility (#2430)
16770
- if (point.visible !== undefined) {
16771
- point.setVisible(point.visible);
16816
+ // Detect point specific visibility (#2430)
16817
+ if (visible !== undefined) {
16818
+ point.setVisible(visible, true);
16772
16819
  }
16773
16820
 
16774
16821
  });
@@ -17302,7 +17349,7 @@ if (seriesTypes.pie) {
17302
17349
  point = points[j];
17303
17350
  labelPos = point.labelPos;
17304
17351
  dataLabel = point.dataLabel;
17305
- visibility = point.visible === false ? HIDDEN : VISIBLE;
17352
+ visibility = point.visible === false ? HIDDEN : 'inherit';
17306
17353
  naturalY = labelPos[1];
17307
17354
 
17308
17355
  if (distanceOption > 0) {
@@ -17323,6 +17370,7 @@ if (seriesTypes.pie) {
17323
17370
 
17324
17371
  // get the x - use the natural x position for first and last slot, to prevent the top
17325
17372
  // and botton slice connectors from touching each other on either side
17373
+ // Problem: Should check that it makes sense - http://jsfiddle.net/highcharts/n1y6ngxz/
17326
17374
  x = options.justify ?
17327
17375
  seriesCenter[0] + (i ? -1 : 1) * (radius + distanceOption) :
17328
17376
  series.getX(y === centerY - radius - distanceOption || y === centerY + radius + distanceOption ? naturalY : y, i);
@@ -17565,7 +17613,7 @@ if (seriesTypes.column) {
17565
17613
 
17566
17614
 
17567
17615
  /**
17568
- * Highcharts JS v4.1.4 (2015-03-10)
17616
+ * Highcharts JS v4.1.5 (2015-04-13)
17569
17617
  * Highcharts module to hide overlapping data labels. This module is included by default in Highmaps.
17570
17618
  *
17571
17619
  * (c) 2010-2014 Torstein Honsi
@@ -18333,10 +18381,10 @@ extend(Series.prototype, {
18333
18381
  var series = this,
18334
18382
  options = series.options,
18335
18383
  graph = series.graph,
18336
- graphNeg = series.graphNeg,
18337
18384
  stateOptions = options.states,
18338
18385
  lineWidth = options.lineWidth,
18339
- attribs;
18386
+ attribs,
18387
+ i = 0;
18340
18388
 
18341
18389
  state = state || NORMAL_STATE;
18342
18390
 
@@ -18348,7 +18396,7 @@ extend(Series.prototype, {
18348
18396
  }
18349
18397
 
18350
18398
  if (state) {
18351
- lineWidth = (stateOptions[state].lineWidth || lineWidth) + (stateOptions[state].lineWidthPlus || 0);
18399
+ lineWidth = stateOptions[state].lineWidth || lineWidth + (stateOptions[state].lineWidthPlus || 0); // #4035
18352
18400
  }
18353
18401
 
18354
18402
  if (graph && !graph.dashstyle) { // hover is turned off for dashed lines in VML
@@ -18357,8 +18405,9 @@ extend(Series.prototype, {
18357
18405
  };
18358
18406
  // use attr because animate will cause any other animation on the graph to stop
18359
18407
  graph.attr(attribs);
18360
- if (graphNeg) {
18361
- graphNeg.attr(attribs);
18408
+ while (series['zoneGraph' + i]) {
18409
+ series['zoneGraph' + i].attr(attribs);
18410
+ i = i + 1;
18362
18411
  }
18363
18412
  }
18364
18413
  }