highcharts-rails 4.1.1 → 4.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3b89f58bbf9482337db0d6631dafb3a0911f8f45
4
- data.tar.gz: 8240049f958306eb2a9347b663ea7741bbd4f6a8
3
+ metadata.gz: 920a1266c132250a90e02fbef2fb3ef6ec93b538
4
+ data.tar.gz: 6645f9f784882d6f340e8668a0f65d2dfb4d4406
5
5
  SHA512:
6
- metadata.gz: a9d52b81b531629a2ac87907ec296ed7a8ad208a0f622fbf007ef86f07177b9301fc5b1207ea6a57e160b330c470ce355902eab058c30c558192cc79efeb1a7d
7
- data.tar.gz: b39ea967f4042ca012d05e536bb9c27b4a068fc7d6d7af2336cd72c9bdf993d9200d0c7050ce9e62d3f13ac1329767bc3e8682a566fb5f4a98aab638f19d8022
6
+ metadata.gz: 349761d2a987b1243889b7c08796f380a4eda03871190399eb7f37d07726847f938c25aa26a232f5bbd50a115d73cc5c214e729c94dceffc2b07241bd9467255
7
+ data.tar.gz: d68832a6a9dcd46a7f1336edd861884bf99d59ae1e5995db37bbad2181171787fe2f3040019f64f0c79cf47e3f1415f3aeeeae51f47a6643facbcab37f5e9fe6
data/CHANGELOG.markdown CHANGED
@@ -1,3 +1,39 @@
1
+ # 4.1.2 / 2015-02-27
2
+
3
+ * Updated Highcharts to 4.1.2
4
+ * Added new option to tree maps: interactByLeaf
5
+ * Added new dataLabel option, shape, in order to allow callouts and connectors on data labels.
6
+ * Fixed #3567, Safari failed at exporting charts with images.
7
+ * Fixed #3898, zones incorrectly applied if outside axis range.
8
+ * Fixed #3895, JS error when setting element title to a non-string value.
9
+ * Fixed #3886, wrong rendering of waterfall with a non-zero Y axis minimum.
10
+ * Fixed #3873, series.points array order was modified when building the k-d tree.
11
+ * Fixed #3866, data labels not re-appearing in remaining series after hiding another series.
12
+ * Fixed #3875, eternal loop and crash in Chrome when using minorTickInterval on an axis with very close data points.
13
+ * Fixed #3842 and #3872, data labels with text shadow are mispositioned in Firefox and modern IE.
14
+ * Fixed #3849, duplicated text on data labels in export. Closes #3864.
15
+ * Fixed #3868, setData broke tooltip.
16
+ * Fixed issue with tooltip not hiding after hiding a series from a floating legend.
17
+ * Hide tooltip on mouse leaving the plot area, also when a hoverSeries is not defined.
18
+ * Fixed #3860, a regression causing onMouseOver event not to work on line series.
19
+ * Fixed #3856, shared tooltip in polar charts.
20
+ * Fixed #3863, pointer with data grouping and addSeries.
21
+ * Fixed #3844, colorByPoint not working on tree maps.
22
+ * Fixed #2202, chartOptions.xAxis options not added in export.
23
+ * Fixed #3852, a regression causing logarithmic axis on gauges to fail.
24
+ * Fixed #3845, problems with addPoint on 3D pies.
25
+ * Fixed #3841, 3d column layering issue.
26
+ * Fixed #3793, charts with huge numbers fail at Number.toFixed.
27
+ * Fixed #3841, issue with multiple columns in 3d.
28
+ * Fixed #3830, point names in category axis were lost after Axis.update.
29
+ * Fixed #3836, a regression causing plot band labels to always be visible.
30
+ * Fixed #3840, isIntermediateSum miscalculation.
31
+ * Fixed drilldown issue with labels having both drilldown and static points.
32
+ * Fixed #3839, a regression causing columns not to be clipped while animating in.
33
+ * Fixed #3837, too aggressive data label collision detection in heat maps.
34
+ * Fixed #3834, crosshair drawn incorrectly on dynamically added yAxes.
35
+ * Fixed #3806, JS errors on clicking on non-drillable axis label after drilldown.
36
+
1
37
  # 4.1.1 / 2015-02-17
2
38
 
3
39
  * Updated Highcharts to 4.1.1
@@ -2,7 +2,7 @@
2
2
  // @compilation_level SIMPLE_OPTIMIZATIONS
3
3
 
4
4
  /**
5
- * @license Highcharts JS v4.1.1 (2015-02-17)
5
+ * @license Highcharts JS v4.1.2 (2015-02-27)
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.1',
59
+ VERSION = '4.1.2',
60
60
 
61
61
  // some constants for frequently used strings
62
62
  DIV = 'div',
@@ -744,7 +744,7 @@ Highcharts.numberFormat = function (number, decimals, decPoint, thousandsSep) {
744
744
  // http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_number_format/
745
745
  n = +number || 0,
746
746
  c = decimals === -1 ?
747
- (n.toString().split('.')[1] || '').length : // preserve decimals
747
+ mathMin((n.toString().split('.')[1] || '').length, 20) : // Preserve decimals. Not huge numbers (#3793).
748
748
  (isNaN(decimals = mathAbs(decimals)) ? 2 : decimals),
749
749
  d = decPoint === undefined ? lang.decimalPoint : decPoint,
750
750
  t = thousandsSep === undefined ? lang.thousandsSep : thousandsSep,
@@ -1259,8 +1259,8 @@ defaultOptions = {
1259
1259
  global: {
1260
1260
  useUTC: true,
1261
1261
  //timezoneOffset: 0,
1262
- canvasToolsURL: 'http://code.highcharts.com/4.1.1/modules/canvas-tools.js',
1263
- VMLRadialGradientURL: 'http://code.highcharts.com/4.1.1/gfx/vml-radial-gradient.png'
1262
+ canvasToolsURL: 'http://code.highcharts.com/4.1.2/modules/canvas-tools.js',
1263
+ VMLRadialGradientURL: 'http://code.highcharts.com/4.1.2/gfx/vml-radial-gradient.png'
1264
1264
  },
1265
1265
  chart: {
1266
1266
  //animation: true,
@@ -1939,11 +1939,9 @@ SVGElement.prototype = {
1939
1939
  var elem = this.element,
1940
1940
  tspans,
1941
1941
  hasContrast = textShadow.indexOf('contrast') !== -1,
1942
- // Safari suffers from the double display bug (#3649)
1943
- isSafari = userAgent.indexOf('Safari') > 0 && userAgent.indexOf('Chrome') === -1,
1944
1942
  // IE10 and IE11 report textShadow in elem.style even though it doesn't work. Check
1945
- // this again with new IE release.
1946
- supports = elem.style.textShadow !== UNDEFINED && !isIE && !isSafari;
1943
+ // this again with new IE release. In exports, the rendering is passed to PhantomJS.
1944
+ supports = this.renderer.forExport || (elem.style.textShadow !== UNDEFINED && !isIE);
1947
1945
 
1948
1946
  // When the text shadow is set to contrast, use dark stroke for light text and vice versa
1949
1947
  if (hasContrast) {
@@ -1966,6 +1964,8 @@ SVGElement.prototype = {
1966
1964
  }
1967
1965
  } else {
1968
1966
 
1967
+ this.fakeTS = true; // Fake text shadow
1968
+
1969
1969
  // In order to get the right y position of the clones,
1970
1970
  // copy over the y setter
1971
1971
  this.ySetter = this.xSetter;
@@ -1999,6 +1999,8 @@ SVGElement.prototype = {
1999
1999
  // Create the clone and apply shadow properties
2000
2000
  clone = tspan.cloneNode(1);
2001
2001
  attr(clone, {
2002
+ 'class': PREFIX + 'text-shadow',
2003
+ 'fill': color,
2002
2004
  'stroke': color,
2003
2005
  'stroke-opacity': 1 / mathMax(pInt(strokeWidth), 3),
2004
2006
  'stroke-width': strokeWidth,
@@ -2452,6 +2454,9 @@ SVGElement.prototype = {
2452
2454
  styles = wrapper.styles,
2453
2455
  rad = rotation * deg2rad,
2454
2456
  textStr = wrapper.textStr,
2457
+ textShadow,
2458
+ elemStyle = element.style,
2459
+ toggleTextShadowShim,
2455
2460
  cacheKey;
2456
2461
 
2457
2462
  if (textStr !== UNDEFINED) {
@@ -2482,6 +2487,22 @@ SVGElement.prototype = {
2482
2487
  if (element.namespaceURI === SVG_NS || renderer.forExport) {
2483
2488
  try { // Fails in Firefox if the container has display: none.
2484
2489
 
2490
+ // When the text shadow shim is used, we need to hide the fake shadows
2491
+ // to get the correct bounding box (#3872)
2492
+ toggleTextShadowShim = this.fakeTS && function (display) {
2493
+ each(element.querySelectorAll('.' + PREFIX + 'text-shadow'), function (tspan) {
2494
+ tspan.style.display = display;
2495
+ });
2496
+ };
2497
+
2498
+ // Workaround for #3842, Firefox reporting wrong bounding box for shadows
2499
+ if (isFirefox && elemStyle.textShadow) {
2500
+ textShadow = elemStyle.textShadow;
2501
+ elemStyle.textShadow = '';
2502
+ } else if (toggleTextShadowShim) {
2503
+ toggleTextShadowShim(NONE);
2504
+ }
2505
+
2485
2506
  bBox = element.getBBox ?
2486
2507
  // SVG: use extend because IE9 is not allowed to change width and height in case
2487
2508
  // of rotation (below)
@@ -2491,6 +2512,13 @@ SVGElement.prototype = {
2491
2512
  width: element.offsetWidth,
2492
2513
  height: element.offsetHeight
2493
2514
  };
2515
+
2516
+ // #3842
2517
+ if (textShadow) {
2518
+ elemStyle.textShadow = textShadow;
2519
+ } else if (toggleTextShadowShim) {
2520
+ toggleTextShadowShim('');
2521
+ }
2494
2522
  } catch (e) {}
2495
2523
 
2496
2524
  // If the bBox is not set, the try-catch block above failed. The other condition
@@ -6294,7 +6322,7 @@ AxisPlotLineOrBandExtension = {
6294
6322
  var toPath = this.getPlotLinePath(to, null, null, true),
6295
6323
  path = this.getPlotLinePath(from, null, null, true);
6296
6324
 
6297
- if (path && toPath) {
6325
+ if (path && toPath && path.toString() !== toPath.toString()) { // #3836
6298
6326
  path.push(
6299
6327
  toPath[4],
6300
6328
  toPath[5],
@@ -6500,7 +6528,7 @@ Axis.prototype = {
6500
6528
  formatter: function () {
6501
6529
  return Highcharts.numberFormat(this.total, -1);
6502
6530
  },
6503
- style: defaultPlotOptions.line.dataLabels.style
6531
+ style: merge(defaultPlotOptions.line.dataLabels.style, { color: '#000000' })
6504
6532
  }
6505
6533
  },
6506
6534
 
@@ -6606,7 +6634,7 @@ Axis.prototype = {
6606
6634
 
6607
6635
  // Initial categories
6608
6636
  axis.categories = options.categories || type === 'category';
6609
- axis.names = [];
6637
+ axis.names = axis.names || []; // Preserve on update (#3830)
6610
6638
 
6611
6639
  // Elements
6612
6640
  //axis.axisGroup = UNDEFINED;
@@ -6871,7 +6899,7 @@ Axis.prototype = {
6871
6899
  localMin = old ? axis.oldMin : axis.min,
6872
6900
  returnValue,
6873
6901
  minPixelPadding = axis.minPixelPadding,
6874
- postTranslate = (axis.postTranslate || (axis.isLog && handleLog)) && axis.lin2val;
6902
+ doPostTranslate = (axis.doPostTranslate || (axis.isLog && handleLog)) && axis.lin2val;
6875
6903
 
6876
6904
  if (!localA) {
6877
6905
  localA = axis.transA;
@@ -6896,13 +6924,13 @@ Axis.prototype = {
6896
6924
  val = val * sign + cvsOffset;
6897
6925
  val -= minPixelPadding;
6898
6926
  returnValue = val / localA + localMin; // from chart pixel to value
6899
- if (postTranslate) { // log and ordinal axes
6927
+ if (doPostTranslate) { // log and ordinal axes
6900
6928
  returnValue = axis.lin2val(returnValue);
6901
6929
  }
6902
6930
 
6903
6931
  // From value to pixels
6904
6932
  } else {
6905
- if (postTranslate) { // log and ordinal axes
6933
+ if (doPostTranslate) { // log and ordinal axes
6906
6934
  val = axis.val2lin(val);
6907
6935
  }
6908
6936
  if (pointPlacement === 'between') {
@@ -7042,10 +7070,11 @@ Axis.prototype = {
7042
7070
  i,
7043
7071
  min = axis.min,
7044
7072
  max = axis.max,
7073
+ range = max - min,
7045
7074
  len;
7046
7075
 
7047
7076
  // If minor ticks get too dense, they are hard to read, and may cause long running script. So we don't draw them.
7048
- if ((max - min) / minorTickInterval < axis.len / 3) {
7077
+ if (range && range / minorTickInterval < axis.len / 3) { // #3875
7049
7078
 
7050
7079
  if (axis.isLog) {
7051
7080
  len = tickPositions.length;
@@ -7063,18 +7092,8 @@ Axis.prototype = {
7063
7092
  options.startOfWeek
7064
7093
  )
7065
7094
  );
7066
-
7067
- } else if (axis.isDatetimeAxis && options.minorTickInterval === 'auto') { // #1314
7068
- minorTickPositions = minorTickPositions.concat(
7069
- axis.getTimeTicks(
7070
- axis.normalizeTimeTickInterval(minorTickInterval),
7071
- axis.min,
7072
- axis.max,
7073
- options.startOfWeek
7074
- )
7075
- );
7076
7095
  } else {
7077
- for (pos = axis.min + (tickPositions[0] - axis.min) % minorTickInterval; pos <= axis.max; pos += minorTickInterval) {
7096
+ for (pos = min + (tickPositions[0] - min) % minorTickInterval; pos <= max; pos += minorTickInterval) {
7078
7097
  minorTickPositions.push(pos);
7079
7098
  }
7080
7099
  }
@@ -8467,10 +8486,8 @@ Axis.prototype = {
8467
8486
  if (
8468
8487
  // Disabled in options
8469
8488
  !this.crosshair ||
8470
- // snap
8471
- ((defined(point) || !pick(this.crosshair.snap, true)) === false) ||
8472
- // Do not draw the crosshair if this axis is not part of the point
8473
- (defined(point) && pick(this.crosshair.snap, true) && (!point.series || point.series[this.isXAxis ? 'xAxis' : 'yAxis'] !== this))
8489
+ // Snap
8490
+ ((defined(point) || !pick(this.crosshair.snap, true)) === false)
8474
8491
  ) {
8475
8492
  this.hideCrosshair();
8476
8493
 
@@ -8481,7 +8498,7 @@ Axis.prototype = {
8481
8498
  pos = (this.horiz ? e.chartX - this.pos : this.len - e.chartY + this.pos);
8482
8499
  } else if (defined(point)) {
8483
8500
  /*jslint eqeq: true*/
8484
- pos = (this.chart.inverted != this.horiz) ? point.plotX : this.len - point.plotY;
8501
+ pos = this.isXAxis ? point.plotX : this.len - point.plotY; // #3834
8485
8502
  /*jslint eqeq: false*/
8486
8503
  }
8487
8504
 
@@ -9498,7 +9515,8 @@ Pointer.prototype = {
9498
9515
  anchor,
9499
9516
  noSharedTooltip,
9500
9517
  kdpoints = [],
9501
- kdpoint;
9518
+ kdpoint,
9519
+ kdpointT;
9502
9520
 
9503
9521
  // For hovering over the empty parts of the plot area (hoverSeries is undefined).
9504
9522
  // If there is one series with point tracking (combo chart), don't go to nearest neighbour.
@@ -9516,7 +9534,10 @@ Pointer.prototype = {
9516
9534
  // Skip hidden series
9517
9535
  noSharedTooltip = s.noSharedTooltip && shared;
9518
9536
  if (s.visible && !noSharedTooltip && pick(s.options.enableMouseTracking, true)) { // #3821
9519
- kdpoints.push(s.searchPoint(e));
9537
+ kdpointT = s.searchPoint(e); // #3828
9538
+ if (kdpointT) {
9539
+ kdpoints.push(kdpointT);
9540
+ }
9520
9541
  }
9521
9542
  });
9522
9543
  // Find absolute nearest point
@@ -9535,23 +9556,27 @@ Pointer.prototype = {
9535
9556
  }
9536
9557
 
9537
9558
  // Refresh tooltip for kdpoint
9538
- if (kdpoint && tooltip && kdpoint !== hoverPoint) {
9559
+ if (kdpoint && kdpoint !== hoverPoint) {
9539
9560
  // Draw tooltip if necessary
9540
9561
  if (shared && !kdpoint.series.noSharedTooltip) {
9541
9562
  i = kdpoints.length;
9542
- trueXkd = kdpoint.plotX + kdpoint.series.xAxis.left;
9563
+ trueXkd = kdpoint.clientX;
9543
9564
  while (i--) {
9544
- trueX = kdpoints[i].plotX + kdpoints[i].series.xAxis.left;
9565
+ trueX = kdpoints[i].clientX;
9545
9566
  if (kdpoints[i].x !== kdpoint.x || trueX !== trueXkd || !defined(kdpoints[i].y) || (kdpoints[i].series.noSharedTooltip || false)) {
9546
9567
  kdpoints.splice(i, 1);
9547
9568
  }
9548
9569
  }
9549
- tooltip.refresh(kdpoints, e);
9570
+ if (tooltip) {
9571
+ tooltip.refresh(kdpoints, e);
9572
+ }
9550
9573
  each(kdpoints, function (point) {
9551
9574
  point.onMouseOver(e);
9552
9575
  });
9553
9576
  } else {
9554
- tooltip.refresh(kdpoint, e);
9577
+ if (tooltip) {
9578
+ tooltip.refresh(kdpoint, e);
9579
+ }
9555
9580
  kdpoint.onMouseOver(e);
9556
9581
  }
9557
9582
 
@@ -9563,6 +9588,14 @@ Pointer.prototype = {
9563
9588
  tooltip.updatePosition({ plotX: anchor[0], plotY: anchor[1] });
9564
9589
  }
9565
9590
  }
9591
+
9592
+ // Start the event listener to pick up the tooltip
9593
+ if (tooltip && !pointer._onDocumentMouseMove) {
9594
+ pointer._onDocumentMouseMove = function (e) {
9595
+ pointer.onDocumentMouseMove(e);
9596
+ };
9597
+ addEvent(doc, 'mousemove', pointer._onDocumentMouseMove);
9598
+ }
9566
9599
 
9567
9600
  // Crosshair
9568
9601
  each(chart.axes, function (axis) {
@@ -9854,13 +9887,12 @@ Pointer.prototype = {
9854
9887
  */
9855
9888
  onDocumentMouseMove: function (e) {
9856
9889
  var chart = this.chart,
9857
- chartPosition = this.chartPosition,
9858
- hoverSeries = chart.hoverSeries;
9890
+ chartPosition = this.chartPosition;
9859
9891
 
9860
9892
  e = this.normalize(e, chartPosition);
9861
9893
 
9862
9894
  // If we're outside, hide the tooltip
9863
- if (chartPosition && hoverSeries && !this.inClass(e.target, 'highcharts-tracker') &&
9895
+ if (chartPosition && !this.inClass(e.target, 'highcharts-tracker') &&
9864
9896
  !chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) {
9865
9897
  this.reset();
9866
9898
  }
@@ -10468,6 +10500,16 @@ Legend.prototype = {
10468
10500
  }
10469
10501
  },
10470
10502
 
10503
+ /**
10504
+ * Destroy all items.
10505
+ */
10506
+ clearItems: function () {
10507
+ var legend = this;
10508
+ each(legend.getAllItems(), function (item) {
10509
+ legend.destroyItem(item);
10510
+ });
10511
+ },
10512
+
10471
10513
  /**
10472
10514
  * Destroys the legend.
10473
10515
  */
@@ -12556,20 +12598,24 @@ var CenteredSeriesMixin = Highcharts.CenteredSeriesMixin = {
12556
12598
  centerOption = options.center,
12557
12599
  positions = [pick(centerOption[0], '50%'), pick(centerOption[1], '50%'), options.size || '100%', options.innerSize || 0],
12558
12600
  smallestSize = mathMin(plotWidth, plotHeight),
12559
- isPercent;
12560
-
12561
- return map(positions, function (length, i) {
12562
- isPercent = /%$/.test(length);
12601
+ isPercent,
12602
+ i,
12603
+ value;
12604
+
12605
+ for (i = 0; i < 4; ++i) {
12606
+ value = positions[i];
12607
+ isPercent = /%$/.test(value);
12563
12608
  handleSlicingRoom = i < 2 || (i === 2 && isPercent);
12564
- return (isPercent ?
12609
+ positions[i] = (isPercent ?
12565
12610
  // i == 0: centerX, relative to width
12566
12611
  // i == 1: centerY, relative to height
12567
12612
  // i == 2: size, relative to smallestSize
12568
- // i == 4: innerSize, relative to smallestSize
12569
- [plotWidth, plotHeight, smallestSize, smallestSize][i] *
12570
- pInt(length) / 100 :
12571
- length) + (handleSlicingRoom ? slicingRoom : 0);
12572
- });
12613
+ // i == 3: innerSize, relative to size
12614
+ [plotWidth, plotHeight, smallestSize, positions[2]][i] *
12615
+ pInt(value) / 100 :
12616
+ pInt(value)) + (handleSlicingRoom ? slicingRoom : 0);
12617
+ }
12618
+ return positions;
12573
12619
  }
12574
12620
  };
12575
12621
 
@@ -13074,6 +13120,10 @@ Series.prototype = {
13074
13120
 
13075
13121
  this.userOptions = itemOptions;
13076
13122
 
13123
+ // General series options take precedence over type options because otherwise, default
13124
+ // type options like column.animation would be overwritten by the general option.
13125
+ // But issues have been raised here (#3881), and the solution may be to distinguish
13126
+ // between default option and userOptions like in the tooltip below.
13077
13127
  options = merge(
13078
13128
  typeOptions,
13079
13129
  plotOptions.series,
@@ -14459,6 +14509,11 @@ Series.prototype = {
14459
14509
  series.invertGroups();
14460
14510
  }
14461
14511
 
14512
+ // Initial clipping, must be defined after inverting groups for VML. Applies to columns etc. (#3839).
14513
+ if (options.clip !== false && !series.sharedClipKey && !hasRendered) {
14514
+ group.clip(chart.clipRect);
14515
+ }
14516
+
14462
14517
  // Run the animation
14463
14518
  if (animDuration) {
14464
14519
  series.animate();
@@ -14511,6 +14566,7 @@ Series.prototype = {
14511
14566
  series.render();
14512
14567
 
14513
14568
  if (wasDirtyData) {
14569
+ delete this.kdTree; // #3868 recalculate the kdtree with dirty data
14514
14570
  fireEvent(series, 'updatedData');
14515
14571
  }
14516
14572
  },
@@ -14566,8 +14622,9 @@ Series.prototype = {
14566
14622
  }
14567
14623
  }
14568
14624
 
14625
+ // Start the recursive build process with a clone of the points array (#3873)
14569
14626
  function startRecursive() {
14570
- series.kdTree = _kdtree(series.points, dimensions, dimensions);
14627
+ series.kdTree = _kdtree(series.points.slice(), dimensions, dimensions);
14571
14628
  }
14572
14629
 
14573
14630
  delete series.kdTree;
@@ -14637,8 +14694,6 @@ Series.prototype = {
14637
14694
  if (this.kdTree) {
14638
14695
  return _search(point,
14639
14696
  this.kdTree, this.kdDimensions, this.kdDimensions);
14640
- } else {
14641
- return UNDEFINED;
14642
14697
  }
14643
14698
  }
14644
14699
 
@@ -15134,7 +15189,8 @@ extend(Point.prototype, {
15134
15189
  }
15135
15190
 
15136
15191
  if (seriesOptions.legendType === 'point') { // #1831, #1885
15137
- chart.legend.destroyItem(point);
15192
+ series.updateTotals();
15193
+ chart.legend.clearItems();
15138
15194
  }
15139
15195
  if (redraw) {
15140
15196
  chart.redraw(animation);
@@ -15251,7 +15307,6 @@ extend(Series.prototype, {
15251
15307
  }
15252
15308
 
15253
15309
  // redraw
15254
- delete series.kdTree; // #3816 kdTree has to be rebuild.
15255
15310
  series.isDirty = true;
15256
15311
  series.isDirtyData = true;
15257
15312
  if (redraw) {
@@ -15284,7 +15339,6 @@ extend(Series.prototype, {
15284
15339
  }
15285
15340
 
15286
15341
  // redraw
15287
- delete series.kdTree; // #3816 kdTree has to be rebuild.
15288
15342
  series.isDirty = true;
15289
15343
  series.isDirtyData = true;
15290
15344
  if (redraw) {
@@ -16309,7 +16363,8 @@ var PiePoint = extendClass(Point, {
16309
16363
  setVisible: function (vis) {
16310
16364
  var point = this,
16311
16365
  series = point.series,
16312
- chart = series.chart;
16366
+ chart = series.chart,
16367
+ doRedraw = !series.isDirty && series.options.ignoreHiddenPoint;
16313
16368
 
16314
16369
  // if called without an argument, toggle visibility
16315
16370
  point.visible = point.options.visible = vis = vis === UNDEFINED ? !point.visible : vis;
@@ -16323,11 +16378,18 @@ var PiePoint = extendClass(Point, {
16323
16378
  });
16324
16379
 
16325
16380
  if (point.legendItem) {
16381
+ if (chart.hasRendered) {
16382
+ series.updateTotals();
16383
+ chart.legend.clearItems();
16384
+ if (!doRedraw) {
16385
+ chart.legend.render();
16386
+ }
16387
+ }
16326
16388
  chart.legend.colorizeItem(point, vis);
16327
16389
  }
16328
-
16390
+
16329
16391
  // Handle ignore hidden slices
16330
- if (!series.isDirty && series.options.ignoreHiddenPoint) {
16392
+ if (doRedraw) {
16331
16393
  series.isDirty = true;
16332
16394
  chart.redraw();
16333
16395
  }
@@ -16449,9 +16511,9 @@ var PieSeries = {
16449
16511
  },
16450
16512
 
16451
16513
  /**
16452
- * Extend the generatePoints method by adding total and percentage properties to each point
16514
+ * Recompute total chart sum and update percentages of points.
16453
16515
  */
16454
- generatePoints: function () {
16516
+ updateTotals: function () {
16455
16517
  var i,
16456
16518
  total = 0,
16457
16519
  points,
@@ -16459,8 +16521,6 @@ var PieSeries = {
16459
16521
  point,
16460
16522
  ignoreHiddenPoint = this.options.ignoreHiddenPoint;
16461
16523
 
16462
- Series.prototype.generatePoints.call(this);
16463
-
16464
16524
  // Populate local vars
16465
16525
  points = this.points;
16466
16526
  len = points.length;
@@ -16481,10 +16541,18 @@ var PieSeries = {
16481
16541
  // Set each point's properties
16482
16542
  for (i = 0; i < len; i++) {
16483
16543
  point = points[i];
16484
- point.percentage = total > 0 ? (point.y / total) * 100 : 0;
16544
+ //point.percentage = (total <= 0 || ignoreHiddenPoint && !point.visible) ? 0 : point.y / total * 100;
16545
+ point.percentage = (total > 0 && (point.visible || !ignoreHiddenPoint)) ? point.y / total * 100 : 0;
16485
16546
  point.total = total;
16486
16547
  }
16487
-
16548
+ },
16549
+
16550
+ /**
16551
+ * Extend the generatePoints method by adding total and percentage properties to each point
16552
+ */
16553
+ generatePoints: function () {
16554
+ Series.prototype.generatePoints.call(this);
16555
+ this.updateTotals();
16488
16556
  },
16489
16557
 
16490
16558
  /**
@@ -16842,7 +16910,7 @@ Series.prototype.drawDataLabels = function () {
16842
16910
  str,
16843
16911
  0,
16844
16912
  -999,
16845
- null,
16913
+ options.shape,
16846
16914
  null,
16847
16915
  null,
16848
16916
  options.useHTML
@@ -16918,6 +16986,15 @@ Series.prototype.alignDataLabel = function (point, dataLabel, options, alignTo,
16918
16986
  visible = chart.isInsidePlot(alignAttr.x, alignAttr.y) && chart.isInsidePlot(alignAttr.x + bBox.width, alignAttr.y + bBox.height);
16919
16987
 
16920
16988
  }
16989
+
16990
+ // When we're using a shape, make it possible with a connector or an arrow pointing to thie point
16991
+ if (options.shape) {
16992
+ dataLabel.attr({
16993
+ anchorX: point.plotX,
16994
+ anchorY: point.plotY
16995
+ });
16996
+ }
16997
+
16921
16998
  }
16922
16999
  }
16923
17000
 
@@ -17451,7 +17528,7 @@ if (seriesTypes.column) {
17451
17528
 
17452
17529
 
17453
17530
  /**
17454
- * Highcharts JS v4.1.1 (2015-02-17)
17531
+ * Highcharts JS v4.1.2 (2015-02-27)
17455
17532
  * Highcharts module to hide overlapping data labels. This module is included by default in Highmaps.
17456
17533
  *
17457
17534
  * (c) 2010-2014 Torstein Honsi
@@ -17473,7 +17550,7 @@ if (seriesTypes.column) {
17473
17550
 
17474
17551
  each(chart.series, function (series) {
17475
17552
  var dlOptions = series.options.dataLabels;
17476
- if ((dlOptions.enabled || series._hasPointLabels) && !dlOptions.allowOverlap) {
17553
+ if ((dlOptions.enabled || series._hasPointLabels) && !dlOptions.allowOverlap && series.visible) { // #3866
17477
17554
  each(series.points, function (point) {
17478
17555
  if (point.dataLabel) {
17479
17556
  point.dataLabel.labelrank = point.labelrank;
@@ -18277,7 +18354,7 @@ extend(Series.prototype, {
18277
18354
 
18278
18355
 
18279
18356
  // hide tooltip (#1361)
18280
- if (chart.hoverSeries === series) {
18357
+ if (chart.hoverSeries === series || (chart.hoverPoint && chart.hoverPoint.series) === series) {
18281
18358
  series.onMouseOut();
18282
18359
  }
18283
18360
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.1 (2015-02-17)
2
+ * @license Highcharts JS v4.1.2 (2015-02-27)
3
3
  *
4
4
  * Standalone Highcharts Framework
5
5
  *
@@ -2,7 +2,7 @@
2
2
  // @compilation_level SIMPLE_OPTIMIZATIONS
3
3
 
4
4
  /**
5
- * @license Highcharts JS v4.1.1 (2015-02-17)
5
+ * @license Highcharts JS v4.1.2 (2015-02-27)
6
6
  *
7
7
  * (c) 2009-2013 Torstein Hønsi
8
8
  *
@@ -590,21 +590,22 @@ Highcharts.Chart.prototype.renderSeries = function () {
590
590
  }
591
591
  };
592
592
 
593
- Highcharts.Chart.prototype.retrieveStacks = function (grouping, stacking) {
594
-
595
- var stacks = {},
593
+ Highcharts.Chart.prototype.retrieveStacks = function (stacking) {
594
+ var series = this.series,
595
+ stacks = {},
596
+ stackNumber,
596
597
  i = 1;
597
598
 
598
- if (grouping || !stacking) { return this.series; }
599
-
600
599
  Highcharts.each(this.series, function (S) {
601
- if (!stacks[S.options.stack || 0]) {
602
- stacks[S.options.stack || 0] = { series: [S], position: i};
600
+ stackNumber = stacking ? (S.options.stack || 0) : series.length - 1 - S.index; // #3841
601
+ if (!stacks[stackNumber]) {
602
+ stacks[stackNumber] = { series: [S], position: i};
603
603
  i++;
604
604
  } else {
605
- stacks[S.options.stack || 0].series.push(S);
605
+ stacks[stackNumber].series.push(S);
606
606
  }
607
607
  });
608
+
608
609
  stacks.totalStacks = i + 1;
609
610
  return stacks;
610
611
  };
@@ -904,8 +905,8 @@ Highcharts.wrap(Highcharts.seriesTypes.column.prototype, 'init', function (proce
904
905
  stacking = seriesOptions.stacking,
905
906
  z = 0;
906
907
 
907
- if (!(grouping !== undefined && !grouping) && stacking) {
908
- var stacks = this.chart.retrieveStacks(grouping, stacking),
908
+ if (!(grouping !== undefined && !grouping)) {
909
+ var stacks = this.chart.retrieveStacks(stacking),
909
910
  stack = seriesOptions.stack || 0,
910
911
  i; // position within the stack
911
912
  for (i = 0; i < stacks[stack].series.length; i++) {
@@ -1150,7 +1151,7 @@ Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'addPoint', function (proc
1150
1151
  proceed.apply(this, [].slice.call(arguments, 1));
1151
1152
  if (this.chart.is3d()) {
1152
1153
  // destroy (and rebuild) everything!!!
1153
- this.update();
1154
+ this.update(this.userOptions, true); // #3845 pass the old options
1154
1155
  }
1155
1156
  });
1156
1157
 
@@ -2,7 +2,7 @@
2
2
  // @compilation_level SIMPLE_OPTIMIZATIONS
3
3
 
4
4
  /**
5
- * @license Highcharts JS v4.1.1 (2015-02-17)
5
+ * @license Highcharts JS v4.1.2 (2015-02-27)
6
6
  *
7
7
  * (c) 2009-2014 Torstein Honsi
8
8
  *
@@ -1606,10 +1606,12 @@ seriesTypes.waterfall = extendClass(seriesTypes.column, {
1606
1606
  [0, yValue];
1607
1607
 
1608
1608
  // override point value for sums
1609
- if (point.isSum || point.isIntermediateSum) { // #3710 Update point does not propagate to sum
1609
+ // #3710 Update point does not propagate to sum
1610
+ if (point.isSum) {
1610
1611
  point.y = yValue;
1612
+ } else if (point.isIntermediateSum) {
1613
+ point.y = yValue - previousIntermediate; // #3840
1611
1614
  }
1612
-
1613
1615
  // up points
1614
1616
  y = mathMax(previousY, previousY + point.y) + range[0];
1615
1617
  shapeArgs.y = yAxis.translate(y, 0, 1);
@@ -1625,17 +1627,17 @@ seriesTypes.waterfall = extendClass(seriesTypes.column, {
1625
1627
  shapeArgs.height = yAxis.translate(previousIntermediate, 0, 1) - shapeArgs.y;
1626
1628
  previousIntermediate = range[1];
1627
1629
 
1628
- // if it's not the sum point, update previous stack end position
1630
+ // If it's not the sum point, update previous stack end position and get
1631
+ // shape height (#3886)
1629
1632
  } else {
1633
+ if (previousY !== 0) { // Not the first point
1634
+ shapeArgs.height = yValue > 0 ?
1635
+ yAxis.translate(previousY, 0, 1) - shapeArgs.y :
1636
+ yAxis.translate(previousY, 0, 1) - yAxis.translate(previousY - yValue, 0, 1);
1637
+ }
1630
1638
  previousY += yValue;
1631
1639
  }
1632
1640
 
1633
- // negative points
1634
- if (shapeArgs.height < 0) {
1635
- shapeArgs.y += shapeArgs.height;
1636
- shapeArgs.height *= -1;
1637
- }
1638
-
1639
1641
  point.plotY = shapeArgs.y = mathRound(shapeArgs.y) - (series.borderWidth % 2) / 2;
1640
1642
  shapeArgs.height = mathMax(mathRound(shapeArgs.height), 0.001); // #3151
1641
1643
  point.yBottom = shapeArgs.y + shapeArgs.height;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Highcharts JS v4.1.1 (2015-02-17)
2
+ * Highcharts JS v4.1.2 (2015-02-27)
3
3
  * Highcharts Broken Axis module
4
4
  *
5
5
  * Author: Stephane Vanraes, Torstein Honsi
@@ -101,7 +101,7 @@
101
101
 
102
102
  var axis = this;
103
103
 
104
- axis.postTranslate = true;
104
+ axis.doPostTranslate = true;
105
105
 
106
106
  this.val2lin = function (val) {
107
107
  var nval = val,
@@ -255,6 +255,7 @@
255
255
 
256
256
  if (xAxis.isInAnyBreak(point.x, true) || yAxis.isInAnyBreak(point.y, true)) {
257
257
  points.splice(i, 1);
258
+ this.data[i].destroyElements(); // removes the graphics for this point if they exist
258
259
  }
259
260
  }
260
261
  }
@@ -2908,7 +2908,7 @@ if (CanvasRenderingContext2D) {
2908
2908
  });
2909
2909
  }
2910
2910
  }/**
2911
- * @license Highcharts JS v4.1.1 (2015-02-17)
2911
+ * @license Highcharts JS v4.1.2 (2015-02-27)
2912
2912
  * CanVGRenderer Extension module
2913
2913
  *
2914
2914
  * (c) 2011-2012 Torstein Honsi, Erik Olsson
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.1 (2015-02-17)
2
+ * @license Highcharts JS v4.1.2 (2015-02-27)
3
3
  * Data module
4
4
  *
5
5
  * (c) 2012-2014 Torstein Honsi
@@ -518,7 +518,8 @@
518
518
  fireEvent(chart, 'drilldown', {
519
519
  point: this,
520
520
  seriesOptions: seriesOptions,
521
- category: category
521
+ category: category,
522
+ points: category !== undefined && this.series.xAxis.ticks[category].label.ddPoints.slice(0)
522
523
  });
523
524
 
524
525
  if (seriesOptions) {
@@ -542,11 +543,26 @@
542
543
  this.chart.applyDrilldown();
543
544
  };
544
545
 
546
+
547
+ /**
548
+ * On initialization of each point, identify its label and make it clickable. Also, provide a
549
+ * list of points associated to that label.
550
+ */
545
551
  wrap(H.Point.prototype, 'init', function (proceed, series, options, x) {
546
552
  var point = proceed.call(this, series, options, x),
547
553
  chart = series.chart,
548
554
  tick = series.xAxis && series.xAxis.ticks[x],
549
555
  tickLabel = tick && tick.label;
556
+
557
+ // Create a collection of points associated with the label. Reset it for each level.
558
+ if (tickLabel) {
559
+ if (!tickLabel.ddPoints) {
560
+ tickLabel.ddPoints = [];
561
+ }
562
+ if (tickLabel.levelNumber !== series.options._levelNumber) {
563
+ tickLabel.ddPoints.length = 0; // reset
564
+ }
565
+ }
550
566
 
551
567
  if (point.drilldown) {
552
568
 
@@ -574,17 +590,17 @@
574
590
  .on('click', function () {
575
591
  series.xAxis.drilldownCategory(x);
576
592
  });
577
- if (!tickLabel.ddPoints) {
578
- tickLabel.ddPoints = [];
579
- }
593
+
580
594
  tickLabel.ddPoints.push(point);
595
+ tickLabel.levelNumber = series.options._levelNumber;
581
596
 
582
597
  }
583
- } else if (tickLabel && tickLabel.basicStyles) {
598
+ } else if (tickLabel && tickLabel.basicStyles && tickLabel.levelNumber !== series.options._levelNumber) {
584
599
  tickLabel.styles = {}; // reset for full overwrite of styles
585
600
  tickLabel.css(tickLabel.basicStyles);
601
+ tickLabel.on('click', null); // #3806
586
602
  }
587
-
603
+
588
604
  return point;
589
605
  });
590
606
 
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.1 (2015-02-17)
2
+ * @license Highcharts JS v4.1.2 (2015-02-27)
3
3
  * Exporting module
4
4
  *
5
5
  * (c) 2010-2014 Torstein Honsi
@@ -23,6 +23,7 @@ var Chart = Highcharts.Chart,
23
23
  merge = Highcharts.merge,
24
24
  each = Highcharts.each,
25
25
  extend = Highcharts.extend,
26
+ splat = Highcharts.splat,
26
27
  math = Math,
27
28
  mathMax = math.max,
28
29
  doc = document,
@@ -190,6 +191,63 @@ Highcharts.post = function (url, data, formAttributes) {
190
191
 
191
192
  extend(Chart.prototype, {
192
193
 
194
+ /**
195
+ * A collection of regex fixes on the produces SVG to account for expando properties,
196
+ * browser bugs, VML problems and other. Returns a cleaned SVG.
197
+ */
198
+ sanitizeSVG: function (svg) {
199
+ return svg
200
+ .replace(/zIndex="[^"]+"/g, '')
201
+ .replace(/isShadow="[^"]+"/g, '')
202
+ .replace(/symbolName="[^"]+"/g, '')
203
+ .replace(/jQuery[0-9]+="[^"]+"/g, '')
204
+ .replace(/url\([^#]+#/g, 'url(#')
205
+ .replace(/<svg /, '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ')
206
+ .replace(/ (NS[0-9]+\:)?href=/g, ' xlink:href=') // #3567
207
+ .replace(/\n/, ' ')
208
+ // Any HTML added to the container after the SVG (#894)
209
+ .replace(/<\/svg>.*?$/, '</svg>')
210
+ // Batik doesn't support rgba fills and strokes (#3095)
211
+ .replace(/(fill|stroke)="rgba\(([ 0-9]+,[ 0-9]+,[ 0-9]+),([ 0-9\.]+)\)"/g, '$1="rgb($2)" $1-opacity="$3"')
212
+
213
+ // An issue with PhantomJS as of 2015-01-11. Revisit with newer versions. (#3649)
214
+ .replace(/(text-shadow:)([^;"]+)([;"])/g, function (s, $1, $2, $3) {
215
+ // Escape commas within rgb and rgba definitions
216
+ $2 = $2.replace(/\([^\)]+\)/g, function (s) {
217
+ return s.replace(/,/g, '|');
218
+ });
219
+ // Keep the first definition
220
+ $2 = $2.split(',')[0];
221
+ // Re-inert commas
222
+ $2 = $2.replace(/\([^\)]+\)/g, function (s) {
223
+ return s.replace(/\|/g, ',');
224
+ });
225
+ s = $1 + $2 + $3;
226
+ return s;
227
+ })
228
+ /* This fails in IE < 8
229
+ .replace(/([0-9]+)\.([0-9]+)/g, function(s1, s2, s3) { // round off to save weight
230
+ return s2 +'.'+ s3[0];
231
+ })*/
232
+
233
+ // Replace HTML entities, issue #347
234
+ .replace(/&nbsp;/g, '\u00A0') // no-break space
235
+ .replace(/&shy;/g, '\u00AD') // soft hyphen
236
+
237
+ // IE specific
238
+ .replace(/<IMG /g, '<image ')
239
+ .replace(/height=([^" ]+)/g, 'height="$1"')
240
+ .replace(/width=([^" ]+)/g, 'width="$1"')
241
+ .replace(/hc-svg-href="([^"]+)">/g, 'xlink:href="$1"/>')
242
+ .replace(/id=([^" >]+)/g, 'id="$1"')
243
+ .replace(/class=([^" >]+)/g, 'class="$1"')
244
+ .replace(/ transform /g, ' ')
245
+ .replace(/:(path|rect)/g, '$1')
246
+ .replace(/style="([^"]+)"/g, function (s) {
247
+ return s.toLowerCase();
248
+ });
249
+ },
250
+
193
251
  /**
194
252
  * Return an SVG representation of the chart
195
253
  *
@@ -262,6 +320,15 @@ extend(Chart.prototype, {
262
320
  }
263
321
  });
264
322
 
323
+ // Axis options must be merged in one by one, since it may be an array or an object (#2022)
324
+ if (additionalOptions) {
325
+ each(['xAxis', 'yAxis'], function (axisType, i) {
326
+ each(splat(additionalOptions[axisType]), function (axisOptions) {
327
+ options[axisType][i] = merge(options[axisType][i], axisOptions);
328
+ });
329
+ });
330
+ }
331
+
265
332
  // generate the chart copy
266
333
  chartCopy = new Highcharts.Chart(options, chart.callback);
267
334
 
@@ -288,42 +355,7 @@ extend(Chart.prototype, {
288
355
  discardElement(sandbox);
289
356
 
290
357
  // sanitize
291
- svg = svg
292
- .replace(/zIndex="[^"]+"/g, '')
293
- .replace(/isShadow="[^"]+"/g, '')
294
- .replace(/symbolName="[^"]+"/g, '')
295
- .replace(/jQuery[0-9]+="[^"]+"/g, '')
296
- .replace(/url\([^#]+#/g, 'url(#')
297
- .replace(/<svg /, '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ')
298
- .replace(/ href=/g, ' xlink:href=')
299
- .replace(/\n/, ' ')
300
- // Any HTML added to the container after the SVG (#894)
301
- .replace(/<\/svg>.*?$/, '</svg>')
302
- // Batik doesn't support rgba fills and strokes (#3095)
303
- .replace(/(fill|stroke)="rgba\(([ 0-9]+,[ 0-9]+,[ 0-9]+),([ 0-9\.]+)\)"/g, '$1="rgb($2)" $1-opacity="$3"')
304
- // An issue with PhantomJS as of 2015-01-11. Revisit with newer versions. (#3649)
305
- .replace(/(text-shadow:[ 0-9a-z]+),[^"]+([;"])/g, '$1$2')
306
- /* This fails in IE < 8
307
- .replace(/([0-9]+)\.([0-9]+)/g, function(s1, s2, s3) { // round off to save weight
308
- return s2 +'.'+ s3[0];
309
- })*/
310
-
311
- // Replace HTML entities, issue #347
312
- .replace(/&nbsp;/g, '\u00A0') // no-break space
313
- .replace(/&shy;/g, '\u00AD') // soft hyphen
314
-
315
- // IE specific
316
- .replace(/<IMG /g, '<image ')
317
- .replace(/height=([^" ]+)/g, 'height="$1"')
318
- .replace(/width=([^" ]+)/g, 'width="$1"')
319
- .replace(/hc-svg-href="([^"]+)">/g, 'xlink:href="$1"/>')
320
- .replace(/id=([^" >]+)/g, 'id="$1"')
321
- .replace(/class=([^" >]+)/g, 'class="$1"')
322
- .replace(/ transform /g, ' ')
323
- .replace(/:(path|rect)/g, '$1')
324
- .replace(/style="([^"]+)"/g, function (s) {
325
- return s.toLowerCase();
326
- });
358
+ svg = this.sanitizeSVG(svg);
327
359
 
328
360
  // IE9 beta bugs with innerHTML. Test again with final IE9.
329
361
  svg = svg.replace(/(url\(#highcharts-[0-9]+)&quot;/g, '$1')
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.1 (2015-02-17)
2
+ * @license Highcharts JS v4.1.2 (2015-02-27)
3
3
  *
4
4
  * (c) 2011-2014 Torstein Honsi
5
5
  *
@@ -336,8 +336,7 @@ extend(ColorAxis.prototype, {
336
336
  }
337
337
  },
338
338
  drawCrosshair: function (e, point) {
339
- var newCross = !this.cross,
340
- plotX = point && point.plotX,
339
+ var plotX = point && point.plotX,
341
340
  plotY = point && point.plotY,
342
341
  crossPos,
343
342
  axisPos = this.pos,
@@ -357,7 +356,7 @@ extend(ColorAxis.prototype, {
357
356
  point.plotX = plotX;
358
357
  point.plotY = plotY;
359
358
 
360
- if (!newCross && this.cross) {
359
+ if (this.cross) {
361
360
  this.cross
362
361
  .attr({
363
362
  fill: this.crosshair.color
@@ -556,7 +555,8 @@ defaultOptions.plotOptions.heatmap = merge(defaultOptions.plotOptions.scatter, {
556
555
  inside: true,
557
556
  verticalAlign: 'middle',
558
557
  crop: false,
559
- overflow: false
558
+ overflow: false,
559
+ padding: 0 // #3837
560
560
  },
561
561
  marker: null,
562
562
  tooltip: {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.1 (2015-02-17)
2
+ * @license Highcharts JS v4.1.2 (2015-02-27)
3
3
  * Plugin for displaying a message when there is no data visible in chart.
4
4
  *
5
5
  * (c) 2010-2014 Highsoft AS
@@ -13,7 +13,8 @@
13
13
  var seriesTypes = H.seriesTypes,
14
14
  chartPrototype = H.Chart.prototype,
15
15
  defaultOptions = H.getOptions(),
16
- extend = H.extend;
16
+ extend = H.extend,
17
+ each = H.each;
17
18
 
18
19
  // Add language option
19
20
  extend(defaultOptions.lang, {
@@ -44,17 +45,11 @@
44
45
  return !!this.points.length; /* != 0 */
45
46
  }
46
47
 
47
- if (seriesTypes.pie) {
48
- seriesTypes.pie.prototype.hasData = hasDataPie;
49
- }
50
-
51
- if (seriesTypes.gauge) {
52
- seriesTypes.gauge.prototype.hasData = hasDataPie;
53
- }
54
-
55
- if (seriesTypes.waterfall) {
56
- seriesTypes.waterfall.prototype.hasData = hasDataPie;
57
- }
48
+ each(['pie', 'gauge', 'waterfall', 'bubble'], function (type) {
49
+ if (seriesTypes[type]) {
50
+ seriesTypes[type].prototype.hasData = hasDataPie;
51
+ }
52
+ });
58
53
 
59
54
  H.Series.prototype.hasData = function () {
60
55
  return this.visible && this.dataMax !== undefined && this.dataMin !== undefined; // #3703
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.1 (2015-02-17)
2
+ * @license Highcharts JS v4.1.2 (2015-02-27)
3
3
  * Solid angular gauge module
4
4
  *
5
5
  * (c) 2010-2014 Torstein Honsi
@@ -172,7 +172,9 @@
172
172
  center = yAxis.center,
173
173
  options = series.options,
174
174
  radius = series.radius = (pInt(pick(options.radius, 100)) * center[2]) / 200,
175
- renderer = series.chart.renderer;
175
+ renderer = series.chart.renderer,
176
+ overshoot = options.overshoot,
177
+ overshootVal = overshoot && typeof overshoot === 'number' ? overshoot / 180 * Math.PI : 0;
176
178
 
177
179
  H.each(series.points, function (point) {
178
180
  var graphic = point.graphic,
@@ -191,6 +193,9 @@
191
193
  point.color = toColor;
192
194
  }
193
195
 
196
+ // Handle overshoot and clipping to axis max/min
197
+ rotation = Math.max(yAxis.startAngleRad - overshootVal, Math.min(yAxis.endAngleRad + overshootVal, rotation));
198
+
194
199
  // Handle the wrap option
195
200
  if (options.wrap === false) {
196
201
  rotation = Math.max(yAxis.startAngleRad, Math.min(yAxis.endAngleRad, rotation));
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.1.1 (2015-02-17)
2
+ * @license Highcharts JS v4.1.2 (2015-02-27)
3
3
  *
4
4
  * (c) 2014 Highsoft AS
5
5
  * Authors: Jon Arild Nygard / Oystein Moseng
@@ -557,7 +557,7 @@
557
557
  // If a colorAxis is defined
558
558
  if (this.colorAxis) {
559
559
  this.translateColors();
560
- } else {
560
+ } else if (!this.options.colorByPoint) {
561
561
  this.setColorRecursive(this.tree, undefined);
562
562
  }
563
563
  },
@@ -638,13 +638,13 @@
638
638
  hover.fill = Color(attr.fill).brighten(seriesOptions.states.hover.brightness).get();
639
639
  // If not a leaf, then remove fill
640
640
  if (!point.isLeaf) {
641
- if (seriesOptions.allowDrillToNode) {
641
+ if (pick(seriesOptions.interactByLeaf, !seriesOptions.allowDrillToNode)) {
642
+ attr.fill = 'none';
643
+ delete hover.fill;
644
+ } else {
642
645
  // TODO: let users set the opacity
643
646
  attr.fill = Color(attr.fill).setOpacity(0.15).get();
644
647
  hover.fill = Color(hover.fill).setOpacity(0.75).get();
645
- } else {
646
- attr.fill = 'none';
647
- delete hover.fill;
648
648
  }
649
649
  }
650
650
  if (point.node.level <= series.nodeMap[series.rootNode].level) {
@@ -669,40 +669,81 @@
669
669
 
670
670
  // Set click events on points
671
671
  if (seriesOptions.allowDrillToNode) {
672
- series.drillCloser();
672
+ series.drillTo();
673
673
  }
674
674
  },
675
675
  /**
676
676
  * Add drilling on the suitable points
677
- * TODO: review and better naming
678
677
  */
679
- drillCloser: function () {
678
+ drillTo: function () {
680
679
  var series = this,
681
- points = series.points,
682
- nodeParent;
680
+ points = series.points;
683
681
  each(points, function (point) {
684
- var nodeParentName;
682
+ var drillId,
683
+ drillName;
685
684
  if (point.node.isVisible) {
686
685
  H.removeEvent(point, 'click');
687
686
  if (point.graphic) {
688
687
  point.graphic.css({ cursor: 'default' });
689
688
  }
690
- if ((point.node.level - series.nodeMap[series.rootNode].level) === 1 && !point.isLeaf) {
691
- nodeParent = series.nodeMap[series.nodeMap[point.id].parent];
692
- nodeParentName = nodeParent.name || nodeParent.id;
689
+
690
+ // Get the drill to id
691
+ if (series.options.interactByLeaf) {
692
+ drillId = series.drillToByLeaf(point);
693
+ } else {
694
+ drillId = series.drillToByGroup(point);
695
+ }
696
+
697
+ // If a drill id is returned, add click event and cursor.
698
+ if (drillId) {
699
+ drillName = series.nodeMap[series.rootNode].name || series.rootNode;
693
700
  if (point.graphic) {
694
701
  point.graphic.css({ cursor: 'pointer' });
695
702
  }
696
703
  H.addEvent(point, 'click', function () {
697
- // Remove hover
698
- point.setState('');
699
- series.drillToNode(point.id);
700
- series.showDrillUpButton(nodeParentName);
704
+ point.setState(''); // Remove hover
705
+ series.drillToNode(drillId);
706
+ series.showDrillUpButton(drillName);
701
707
  });
702
708
  }
703
709
  }
704
710
  });
705
711
  },
712
+ /**
713
+ * Finds the drill id for a parent node.
714
+ * Returns false if point should not have a click event
715
+ * @param {Object} point
716
+ * @return {string || boolean} Drill to id or false when point should not have a click event
717
+ */
718
+ drillToByGroup: function (point) {
719
+ var series = this,
720
+ drillId = false;
721
+ if ((point.node.level - series.nodeMap[series.rootNode].level) === 1 && !point.isLeaf) {
722
+ drillId = point.id;
723
+ }
724
+ return drillId;
725
+ },
726
+ /**
727
+ * Finds the drill id for a leaf node.
728
+ * Returns false if point should not have a click event
729
+ * @param {Object} point
730
+ * @return {string || boolean} Drill to id or false when point should not have a click event
731
+ */
732
+ drillToByLeaf: function (point) {
733
+ var series = this,
734
+ drillId = false,
735
+ nodeParent;
736
+ if ((point.node.parent !== series.rootNode) && (point.isLeaf)) {
737
+ nodeParent = point.node;
738
+ while (!drillId) {
739
+ nodeParent = series.nodeMap[nodeParent.parent];
740
+ if (nodeParent.parent === series.rootNode) {
741
+ drillId = nodeParent.id;
742
+ }
743
+ }
744
+ }
745
+ return drillId;
746
+ },
706
747
  drillUp: function () {
707
748
  var drillPoint = null,
708
749
  node,
@@ -1,3 +1,3 @@
1
1
  module Highcharts
2
- VERSION = "4.1.1"
2
+ VERSION = "4.1.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: highcharts-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.1
4
+ version: 4.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Per Christian B. Viken