highcharts-rails 4.1.1 → 4.1.2

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: 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