highcharts-rails 4.2.4 → 4.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 97714de447dedd03f4f7d06964a96824433b7915
4
- data.tar.gz: e14b8a7a89bf5de5a48bb2c2118036292fc4e96d
3
+ metadata.gz: 2939d4feed91c6aa1664e68c33af311c52c7bccc
4
+ data.tar.gz: cee7f47daf110070a74c538933732d46f056e8ad
5
5
  SHA512:
6
- metadata.gz: 38bb75286a35565c01ae20b6785d962a7ba5f4b9d2792807d490a89950838b2f1db2c1ba67bc3f3b9f3beeadaeea32cc0ddcbe1d4341ac6e674ce8c3b20cbe40
7
- data.tar.gz: 8d4f48c2627791d0ca196f4084adea4c9ab94306d7efa1373996e113c62ea76b36946121755b08c0beb4d4669008d4ad425a02016f7e388efa0ccf187b435f15
6
+ metadata.gz: df01b55b3c3e82c15e846e5f7f35fd0cfad67cbdbc67570ae7ebd737ff58d2c4cd19829ce599a08fb142ba771337f914b9079b688eef55dc8ae8e1079675fb1e
7
+ data.tar.gz: 54e18726fabf8b724ce627bd2538d4a8c6948d0da8fac305405e32eec19bd32229461455a11cb11a3895c21d1aab8d1602f58199775e45c7ef33cdbc92f45258
@@ -1,6 +1,33 @@
1
+ # 4.2.5 / 2016-05-06
2
+
3
+ * Updated Highcharts to 4.2.5 (2016-05-06)
4
+ * Added new option, exporting.printMaxWidth, to prevent printed charts cut off on the right side. Closes #2088.
5
+ * Added new option, title.widthAdjust and subtitle.widthAdjust, to prevent titles from flowing over elements.
6
+ * Added support for JPEG in offline download module, ref #5157
7
+ * Fixed #3070, verticalAlign didn't work with rotated data labels on column series.
8
+ * Fixed #4087, error 11 was not described on the website.
9
+ * Fixed #4670, zones colors were not applied for markers on hover.
10
+ * Fixed #5211, titleSetter in combination with buildText added duplicate content to the title.
11
+ * Fixed #5220, a regression causing JS error when resizing polar charts.
12
+ * Fixed #5221, support for minPointLength in xrange study.
13
+ * Fixed #5226, polar chart with no data failed with error.
14
+ * Fixed #5228, scroller.getUnionExtremes did not consider navigation axis min and max.
15
+ * Fixed #5230, a horizontal and opposite axis used to have wrong alignment for its title.
16
+ * Fixed #5234, x value of null cancelled rendering of all points.
17
+ * Fixed #5236, last point was not always visible due to rounding errors.
18
+ * Fixed #5237, inverted should not have an effect on polar charts.
19
+ * Fixed #5250, columns were not visible in IE10.
20
+ * Fixed #5254, data labels were not aligned to the point box in heatmaps.
21
+ * Fixed #5259, crosshair prevented point hover when drawn above points.
22
+ * Fixed #5261, break at the end of a label caused wrong bounding box.
23
+ * Fixed #5266, pinchDown was sometimes empty on Android.
24
+ * Fixed #5269, crosshairs on wrong point with multiple series and non-shared tooltip.
25
+ * Fixed #5274, dataLabels.overflow not always respected on heatmaps.
26
+ * Fixed issue in the xrange study with axis extremes when there were other, more extended series in the same chart.
27
+
1
28
  # 4.2.4 / 2016-05-06
2
29
 
3
- * Updated Highcharts to 4.2.4
30
+ * Updated Highcharts to 4.2.4 (2016-04-14)
4
31
  * Added support for polar columnrange series.
5
32
  * Added e.originalEvent to drilldown event in order to catch modifier keys and other properties. Closes #5113.
6
33
  * Added new drilldown event, chart.events.drillupall, that is triggered after multiple single drillup events. Closes #5158. Closes #5159.
@@ -2,7 +2,7 @@
2
2
  // @compilation_level SIMPLE_OPTIMIZATIONS
3
3
 
4
4
  /**
5
- * @license Highcharts JS v4.2.4 (2016-04-14)
5
+ * @license Highcharts JS v4.2.5 (2016-05-06)
6
6
  *
7
7
  * (c) 2009-2016 Torstein Honsi
8
8
  *
@@ -59,7 +59,7 @@
59
59
  charts = [],
60
60
  chartCount = 0,
61
61
  PRODUCT = 'Highcharts',
62
- VERSION = '4.2.4',
62
+ VERSION = '4.2.5',
63
63
 
64
64
  // some constants for frequently used strings
65
65
  DIV = 'div',
@@ -482,9 +482,9 @@
482
482
  * Check for number
483
483
  * @param {Object} n
484
484
  */
485
- function isNumber(n) {
486
- return typeof n === 'number';
487
- }
485
+ var isNumber = Highcharts.isNumber = function isNumber(n) {
486
+ return typeof n === 'number' && !isNaN(n);
487
+ };
488
488
 
489
489
  /**
490
490
  * Remove last occurence of an item from an array
@@ -676,7 +676,7 @@
676
676
  * @param {Boolean} capitalize
677
677
  */
678
678
  dateFormat = function (format, timestamp, capitalize) {
679
- if (!defined(timestamp) || isNaN(timestamp)) {
679
+ if (!isNumber(timestamp)) {
680
680
  return defaultOptions.lang.invalidDate || '';
681
681
  }
682
682
  format = pick(format, '%Y-%m-%d %H:%M:%S');
@@ -1019,6 +1019,7 @@
1019
1019
  Highcharts.numberFormat = function (number, decimals, decimalPoint, thousandsSep) {
1020
1020
 
1021
1021
  number = +number || 0;
1022
+ decimals = +decimals;
1022
1023
 
1023
1024
  var lang = defaultOptions.lang,
1024
1025
  origDec = (number.toString().split('.')[1] || '').length,
@@ -1030,7 +1031,7 @@
1030
1031
 
1031
1032
  if (decimals === -1) {
1032
1033
  decimals = Math.min(origDec, 20); // Preserve decimals. Not huge numbers (#3793).
1033
- } else if (isNaN(decimals)) {
1034
+ } else if (!isNumber(decimals)) {
1034
1035
  decimals = 2;
1035
1036
  }
1036
1037
 
@@ -1055,7 +1056,7 @@
1055
1056
  ret += strinteger.substr(thousands).replace(/(\d{3})(?=\d)/g, '$1' + thousandsSep);
1056
1057
 
1057
1058
  // Add the decimal point and the decimal component
1058
- if (+decimals) {
1059
+ if (decimals) {
1059
1060
  // Get the decimal component, and add power to avoid rounding errors with float numbers (#4573)
1060
1061
  decimalComponent = Math.abs(absNumber - strinteger + Math.pow(10, -Math.max(decimals, origDec) - 1));
1061
1062
  ret += decimalPoint + decimalComponent.toFixed(decimals).slice(2);
@@ -1534,7 +1535,7 @@
1534
1535
  useUTC: true,
1535
1536
  //timezoneOffset: 0,
1536
1537
  canvasToolsURL: 'http://code.highcharts.com/modules/canvas-tools.js',
1537
- VMLRadialGradientURL: 'http://code.highcharts.com/4.2.4/gfx/vml-radial-gradient.png'
1538
+ VMLRadialGradientURL: 'http://code.highcharts.com/4.2.5/gfx/vml-radial-gradient.png'
1538
1539
  },
1539
1540
  chart: {
1540
1541
  //animation: true,
@@ -1593,7 +1594,8 @@
1593
1594
  style: {
1594
1595
  color: '#333333',
1595
1596
  fontSize: '18px'
1596
- }
1597
+ },
1598
+ widthAdjust: -44
1597
1599
 
1598
1600
  },
1599
1601
  subtitle: {
@@ -1605,7 +1607,8 @@
1605
1607
  // y: null,
1606
1608
  style: {
1607
1609
  color: '#555555'
1608
- }
1610
+ },
1611
+ widthAdjust: -44
1609
1612
  },
1610
1613
 
1611
1614
  plotOptions: {
@@ -2016,7 +2019,7 @@
2016
2019
  });
2017
2020
 
2018
2021
  // it's NaN if gradient colors on a column chart
2019
- } else if (rgba && !isNaN(rgba[0])) {
2022
+ } else if (rgba && isNumber(rgba[0])) {
2020
2023
  if (format === 'rgb' || (!format && rgba[3] === 1)) {
2021
2024
  ret = 'rgb(' + rgba[0] + ',' + rgba[1] + ',' + rgba[2] + ')';
2022
2025
  } else if (format === 'a') {
@@ -3179,6 +3182,12 @@
3179
3182
  titleNode = doc.createElementNS(SVG_NS, 'title');
3180
3183
  this.element.appendChild(titleNode);
3181
3184
  }
3185
+
3186
+ // Remove text content if it exists
3187
+ if (titleNode.firstChild) {
3188
+ titleNode.removeChild(titleNode.firstChild);
3189
+ }
3190
+
3182
3191
  titleNode.appendChild(
3183
3192
  doc.createTextNode(
3184
3193
  (String(pick(value), '')).replace(/<[^>]*>/g, '') // #3276, #3895
@@ -3474,6 +3483,7 @@
3474
3483
  childNodes = textNode.childNodes,
3475
3484
  styleRegex,
3476
3485
  hrefRegex,
3486
+ wasTooLong,
3477
3487
  parentX = attr(textNode, 'x'),
3478
3488
  textStyles = wrapper.styles,
3479
3489
  width = wrapper.textWidth,
@@ -3529,18 +3539,20 @@
3529
3539
  }
3530
3540
 
3531
3541
 
3532
- // remove empty line at end
3533
- if (lines[lines.length - 1] === '') {
3534
- lines.pop();
3535
- }
3542
+ // Trim empty lines (#5261)
3543
+ lines = grep(lines, function (line) {
3544
+ return line !== '';
3545
+ });
3536
3546
 
3537
3547
 
3538
3548
  // build the lines
3539
3549
  each(lines, function buildTextLines(line, lineNo) {
3540
3550
  var spans,
3541
3551
  spanNo = 0;
3542
-
3543
- line = line.replace(/<span/g, '|||<span').replace(/<\/span>/g, '</span>|||');
3552
+ line = line
3553
+ .replace(/^\s+|\s+$/g, '') // Trim to prevent useless/costly process on the spaces (#5258)
3554
+ .replace(/<span/g, '|||<span')
3555
+ .replace(/<\/span>/g, '</span>|||');
3544
3556
  spans = line.split('|||');
3545
3557
 
3546
3558
  each(spans, function buildTextSpans(span) {
@@ -3605,7 +3617,6 @@
3605
3617
  var words = span.replace(/([^\^])-/g, '$1- ').split(' '), // #1273
3606
3618
  hasWhiteSpace = spans.length > 1 || lineNo || (words.length > 1 && textStyles.whiteSpace !== 'nowrap'),
3607
3619
  tooLong,
3608
- wasTooLong,
3609
3620
  actualWidth,
3610
3621
  rest = [],
3611
3622
  dy = getLineHeight(tspan),
@@ -3637,9 +3648,6 @@
3637
3648
  if (wordStr === '' || (!tooLong && cursor < 0.5)) {
3638
3649
  words = []; // All ok, break out
3639
3650
  } else {
3640
- if (tooLong) {
3641
- wasTooLong = true;
3642
- }
3643
3651
  wordStr = span.substring(0, wordStr.length + (tooLong ? -1 : 1) * mathCeil(cursor));
3644
3652
  words = [wordStr + (width > 3 ? '\u2026' : '')];
3645
3653
  tspan.removeChild(tspan.firstChild);
@@ -3675,9 +3683,6 @@
3675
3683
  tspan.appendChild(doc.createTextNode(words.join(' ').replace(/- /g, '-')));
3676
3684
  }
3677
3685
  }
3678
- if (wasTooLong) {
3679
- wrapper.attr('title', wrapper.textStr);
3680
- }
3681
3686
  wrapper.rotation = rotation;
3682
3687
  }
3683
3688
 
@@ -3686,6 +3691,10 @@
3686
3691
  }
3687
3692
  });
3688
3693
  });
3694
+
3695
+ if (wasTooLong) {
3696
+ wrapper.attr('title', wrapper.textStr);
3697
+ }
3689
3698
  if (tempParent) {
3690
3699
  tempParent.removeChild(textNode); // attach it to the DOM to read offset width
3691
3700
  }
@@ -6576,7 +6585,7 @@
6576
6585
  }
6577
6586
 
6578
6587
  // the label is created on init - now move it into place
6579
- if (label && !isNaN(x)) {
6588
+ if (label && isNumber(x)) {
6580
6589
  label.xy = xy = tick.getLabelPosition(x, y, label, horiz, labelOptions, tickmarkOffset, index, step);
6581
6590
 
6582
6591
  // Apply show first and show last. If the tick is both first and last, it is
@@ -6597,7 +6606,7 @@
6597
6606
  }
6598
6607
 
6599
6608
  // Set the new position, and show or hide
6600
- if (show && !isNaN(xy.y)) {
6609
+ if (show && isNumber(xy.y)) {
6601
6610
  xy.opacity = opacity;
6602
6611
  label[tick.isNew ? 'attr' : 'animate'](xy);
6603
6612
  tick.isNew = false;
@@ -7347,8 +7356,20 @@
7347
7356
  if (axis.isXAxis) {
7348
7357
  xData = series.xData;
7349
7358
  if (xData.length) {
7350
- axis.dataMin = mathMin(pick(axis.dataMin, xData[0]), arrayMin(xData));
7359
+ // If xData contains values which is not numbers, then filter them out.
7360
+ // To prevent performance hit, we only do this after we have already
7361
+ // found seriesDataMin because in most cases all data is valid. #5234.
7362
+ seriesDataMin = arrayMin(xData);
7363
+ if (!isNumber(seriesDataMin) && !(seriesDataMin instanceof Date)) { // Date for #5010
7364
+ xData = grep(xData, function (x) {
7365
+ return isNumber(x);
7366
+ });
7367
+ seriesDataMin = arrayMin(xData); // Do it again with valid data
7368
+ }
7369
+
7370
+ axis.dataMin = mathMin(pick(axis.dataMin, xData[0]), seriesDataMin);
7351
7371
  axis.dataMax = mathMax(pick(axis.dataMax, xData[0]), arrayMax(xData));
7372
+
7352
7373
  }
7353
7374
 
7354
7375
  // Get dataMin and dataMax for Y axes, as well as handle stacking and processed data
@@ -7494,8 +7515,7 @@
7494
7515
  translatedValue = pick(translatedValue, axis.translate(value, null, null, old));
7495
7516
  x1 = x2 = mathRound(translatedValue + transB);
7496
7517
  y1 = y2 = mathRound(cHeight - translatedValue - transB);
7497
-
7498
- if (isNaN(translatedValue)) { // no min or max
7518
+ if (!isNumber(translatedValue)) { // no min or max
7499
7519
  skip = true;
7500
7520
 
7501
7521
  } else if (axis.horiz) {
@@ -7862,6 +7882,9 @@
7862
7882
  axis.range = null; // don't use it when running setExtremes
7863
7883
  }
7864
7884
 
7885
+ // Hook for Highstock Scroller. Consider combining with beforePadding.
7886
+ fireEvent(axis, 'foundExtremes');
7887
+
7865
7888
  // Hook for adjusting this.min and this.max. Used by bubble series.
7866
7889
  if (axis.beforePadding) {
7867
7890
  axis.beforePadding();
@@ -8674,6 +8697,7 @@
8674
8697
  clip,
8675
8698
  directionFactor = [-1, 1, 1, -1][side],
8676
8699
  n,
8700
+ textAlign,
8677
8701
  axisParent = axis.axisParent, // Used in color axis
8678
8702
  lineHeightCorrection,
8679
8703
  tickSize = this.tickSize('tick');
@@ -8741,6 +8765,18 @@
8741
8765
 
8742
8766
  if (axisTitleOptions && axisTitleOptions.text && axisTitleOptions.enabled !== false) {
8743
8767
  if (!axis.axisTitle) {
8768
+ textAlign = axisTitleOptions.textAlign;
8769
+ if (!textAlign) {
8770
+ textAlign = (horiz ? {
8771
+ low: 'left',
8772
+ middle: 'center',
8773
+ high: 'right'
8774
+ } : {
8775
+ low: opposite ? 'right' : 'left',
8776
+ middle: 'center',
8777
+ high: opposite ? 'left' : 'right'
8778
+ })[axisTitleOptions.align];
8779
+ }
8744
8780
  axis.axisTitle = renderer.text(
8745
8781
  axisTitleOptions.text,
8746
8782
  0,
@@ -8750,12 +8786,7 @@
8750
8786
  .attr({
8751
8787
  zIndex: 7,
8752
8788
  rotation: axisTitleOptions.rotation || 0,
8753
- align:
8754
- axisTitleOptions.textAlign || {
8755
- low: opposite ? 'right' : 'left',
8756
- middle: 'center',
8757
- high: opposite ? 'left' : 'right'
8758
- }[axisTitleOptions.align]
8789
+ align: textAlign
8759
8790
  })
8760
8791
  .addClass(PREFIX + this.coll.toLowerCase() + '-title')
8761
8792
  .css(axisTitleOptions.style)
@@ -8902,7 +8933,7 @@
8902
8933
  lineWidth = options.lineWidth,
8903
8934
  linePath,
8904
8935
  hasRendered = chart.hasRendered,
8905
- slideInTicks = hasRendered && defined(axis.oldMin) && !isNaN(axis.oldMin),
8936
+ slideInTicks = hasRendered && isNumber(axis.oldMin),
8906
8937
  showAxis = axis.showAxis,
8907
8938
  animation = animObject(renderer.globalAnimation),
8908
8939
  from,
@@ -9198,6 +9229,7 @@
9198
9229
  });
9199
9230
  } else {
9200
9231
  attribs = {
9232
+ 'pointer-events': 'none', // #5259
9201
9233
  'stroke-width': strokeWidth,
9202
9234
  stroke: options.color || (categorized ? 'rgba(155,200,255,0.2)' : '#C0C0C0'),
9203
9235
  zIndex: pick(options.zIndex, 2)
@@ -10233,7 +10265,7 @@
10233
10265
  if (p) {
10234
10266
  // Store both closest points, using point.dist and point.distX comparisons (#4645):
10235
10267
  each(['dist', 'distX'], function (dist, k) {
10236
- if (typeof p[dist] === 'number') {
10268
+ if (isNumber(p[dist])) {
10237
10269
  var
10238
10270
  // It is closer than the reference point
10239
10271
  isCloser = p[dist] < distance[k],
@@ -10304,7 +10336,7 @@
10304
10336
 
10305
10337
  // Crosshair. For each hover point, loop over axes and draw cross if that point
10306
10338
  // belongs to the axis (#4927).
10307
- each(shared ? kdpoints : [pick(kdpoint[1], hoverPoint)], function (point) {
10339
+ each(shared ? kdpoints : [pick(hoverPoint, kdpoint[1])], function (point) { // #5269
10308
10340
  each(chart.axes, function (axis) {
10309
10341
  // In case of snap = false, point is undefined, and we draw the crosshair anyway (#5066)
10310
10342
  if (!point || point.series[axis.coll] === axis) {
@@ -10995,10 +11027,10 @@
10995
11027
  // moved, and cancelling on small distances. #3450.
10996
11028
  if (e.type === 'touchmove') {
10997
11029
  pinchDown = this.pinchDown;
10998
- hasMoved = Math.sqrt(
11030
+ hasMoved = pinchDown[0] ? Math.sqrt( // #5266
10999
11031
  Math.pow(pinchDown[0].chartX - e.chartX, 2) +
11000
11032
  Math.pow(pinchDown[0].chartY - e.chartY, 2)
11001
- ) >= 4;
11033
+ ) >= 4 : false;
11002
11034
  }
11003
11035
 
11004
11036
  if (pick(hasMoved, true)) {
@@ -12169,6 +12201,9 @@
12169
12201
  redrawLegend = true;
12170
12202
  }
12171
12203
  }
12204
+ if (serie.isDirtyData) {
12205
+ fireEvent(serie, 'updatedData');
12206
+ }
12172
12207
  });
12173
12208
 
12174
12209
  // handle added or removed series
@@ -12395,6 +12430,7 @@
12395
12430
  })
12396
12431
  .css(chartTitleOptions.style)
12397
12432
  .add();
12433
+
12398
12434
  }
12399
12435
  });
12400
12436
  chart.layOutTitles(redraw);
@@ -12412,14 +12448,14 @@
12412
12448
  subtitleOptions = options.subtitle,
12413
12449
  requiresDirtyBox,
12414
12450
  renderer = this.renderer,
12415
- autoWidth = this.spacingBox.width - 44; // 44 makes room for default context button
12451
+ spacingBox = this.spacingBox;
12416
12452
 
12417
12453
  if (title) {
12418
12454
  title
12419
- .css({ width: (titleOptions.width || autoWidth) + PX })
12455
+ .css({ width: (titleOptions.width || spacingBox.width + titleOptions.widthAdjust) + PX })
12420
12456
  .align(extend({
12421
12457
  y: renderer.fontMetrics(titleOptions.style.fontSize, title).b - 3
12422
- }, titleOptions), false, 'spacingBox');
12458
+ }, titleOptions), false, spacingBox);
12423
12459
 
12424
12460
  if (!titleOptions.floating && !titleOptions.verticalAlign) {
12425
12461
  titleOffset = title.getBBox().height;
@@ -12427,10 +12463,10 @@
12427
12463
  }
12428
12464
  if (subtitle) {
12429
12465
  subtitle
12430
- .css({ width: (subtitleOptions.width || autoWidth) + PX })
12466
+ .css({ width: (subtitleOptions.width || spacingBox.width + subtitleOptions.widthAdjust) + PX })
12431
12467
  .align(extend({
12432
12468
  y: titleOffset + (titleOptions.margin - 13) + renderer.fontMetrics(subtitleOptions.style.fontSize, title).b
12433
- }, subtitleOptions), false, 'spacingBox');
12469
+ }, subtitleOptions), false, spacingBox);
12434
12470
 
12435
12471
  if (!subtitleOptions.floating && !subtitleOptions.verticalAlign) {
12436
12472
  titleOffset = mathCeil(titleOffset + subtitle.getBBox().height);
@@ -12545,7 +12581,7 @@
12545
12581
  // attribute and the SVG contents, but not an interactive chart. So in this case,
12546
12582
  // charts[oldChartIndex] will point to the wrong chart if any (#2609).
12547
12583
  oldChartIndex = pInt(attr(renderTo, indexAttrName));
12548
- if (!isNaN(oldChartIndex) && charts[oldChartIndex] && charts[oldChartIndex].hasRendered) {
12584
+ if (isNumber(oldChartIndex) && charts[oldChartIndex] && charts[oldChartIndex].hasRendered) {
12549
12585
  charts[oldChartIndex].destroy();
12550
12586
  }
12551
12587
 
@@ -13473,7 +13509,7 @@
13473
13509
  if (pointValKey) {
13474
13510
  point.y = point[pointValKey];
13475
13511
  }
13476
- point.isNull = point.y === null;
13512
+ point.isNull = point.x === null || point.y === null;
13477
13513
 
13478
13514
  // If no x is set by now, get auto incremented value. All points must have an
13479
13515
  // x value, however the y value can be null to create a gap in the series
@@ -13497,7 +13533,7 @@
13497
13533
  i = 0,
13498
13534
  j = 0;
13499
13535
 
13500
- if (typeof options === 'number' || options === null) {
13536
+ if (isNumber(options) || options === null) {
13501
13537
  ret[pointArrayMap[0]] = options;
13502
13538
 
13503
13539
  } else if (isArray(options)) {
@@ -13827,7 +13863,7 @@
13827
13863
  updateParallelArrays: function (point, i) {
13828
13864
  var series = point.series,
13829
13865
  args = arguments,
13830
- fn = typeof i === 'number' ?
13866
+ fn = isNumber(i) ?
13831
13867
  // Insert the value in the given position
13832
13868
  function (key) {
13833
13869
  var val = key === 'y' && series.toYData ? series.toYData(point) : point[key];
@@ -14325,7 +14361,7 @@
14325
14361
  i,
14326
14362
  j;
14327
14363
 
14328
- yData = yData || this.stackedYData || this.processedYData;
14364
+ yData = yData || this.stackedYData || this.processedYData || [];
14329
14365
  yDataLength = yData.length;
14330
14366
 
14331
14367
  for (i = 0; i < yDataLength; i++) {
@@ -14403,8 +14439,9 @@
14403
14439
  }
14404
14440
 
14405
14441
  // Get the plotX translation
14406
- point.plotX = plotX = mathMin(mathMax(-1e5, xAxis.translate(xValue, 0, 0, 0, 1, pointPlacement, this.type === 'flags')), 1e5); // #3923
14407
-
14442
+ point.plotX = plotX = correctFloat( // #5236
14443
+ mathMin(mathMax(-1e5, xAxis.translate(xValue, 0, 0, 0, 1, pointPlacement, this.type === 'flags')), 1e5) // #3923
14444
+ );
14408
14445
 
14409
14446
  // Calculate the bottom y value for stacked series
14410
14447
  if (stacking && series.visible && !point.isNull && stack && stack[xValue]) {
@@ -14632,7 +14669,7 @@
14632
14669
  isInside = point.isInside;
14633
14670
 
14634
14671
  // only draw the point if y is defined
14635
- if (enabled && plotY !== UNDEFINED && !isNaN(plotY) && point.y !== null) {
14672
+ if (enabled && isNumber(plotY) && point.y !== null) {
14636
14673
 
14637
14674
  // shortcuts
14638
14675
  pointAttr = point.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE] || seriesPointAttr;
@@ -14730,6 +14767,7 @@
14730
14767
  turboThreshold = seriesOptions.turboThreshold,
14731
14768
  zones = series.zones,
14732
14769
  zoneAxis = series.zoneAxis || 'y',
14770
+ zoneColor,
14733
14771
  attr,
14734
14772
  key;
14735
14773
 
@@ -14778,6 +14816,7 @@
14778
14816
  normalOptions.radius = 0;
14779
14817
  }
14780
14818
 
14819
+ zoneColor = null;
14781
14820
  if (zones.length) {
14782
14821
  j = 0;
14783
14822
  threshold = zones[j];
@@ -14785,7 +14824,7 @@
14785
14824
  threshold = zones[++j];
14786
14825
  }
14787
14826
 
14788
- point.color = point.fillColor = pick(threshold.color, series.color); // #3636, #4267, #4430 - inherit color from series, when color is undefined
14827
+ point.color = point.fillColor = zoneColor = pick(threshold.color, series.color); // #3636, #4267, #4430 - inherit color from series, when color is undefined
14789
14828
 
14790
14829
  }
14791
14830
 
@@ -14829,6 +14868,12 @@
14829
14868
  if (normalOptions.hasOwnProperty('color') && !normalOptions.color) {
14830
14869
  delete normalOptions.color;
14831
14870
  }
14871
+
14872
+ // When zone is set, but series.states.hover.color is not set, apply zone color on hover, #4670:
14873
+ if (zoneColor && !stateOptionsHover.fillColor) {
14874
+ pointStateOptionsHover.fillColor = zoneColor;
14875
+ }
14876
+
14832
14877
  pointAttr[NORMAL_STATE] = series.convertAttribs(extend(attr, normalOptions), seriesPointAttr[NORMAL_STATE]);
14833
14878
 
14834
14879
  // inherit from point normal and series hover
@@ -15386,8 +15431,7 @@
15386
15431
  redraw: function () {
15387
15432
  var series = this,
15388
15433
  chart = series.chart,
15389
- wasDirtyData = series.isDirtyData, // cache it here as it is set to false in render, but used after
15390
- wasDirty = series.isDirty,
15434
+ wasDirty = series.isDirty || series.isDirtyData, // cache it here as it is set to false in render, but used after
15391
15435
  group = series.group,
15392
15436
  xAxis = series.xAxis,
15393
15437
  yAxis = series.yAxis;
@@ -15409,11 +15453,8 @@
15409
15453
 
15410
15454
  series.translate();
15411
15455
  series.render();
15412
- if (wasDirtyData) {
15413
- fireEvent(series, 'updatedData');
15414
- }
15415
- if (wasDirty || wasDirtyData) { // #3945 recalculate the kdtree when dirty
15416
- delete this.kdTree; // #3868 recalculate the kdtree with dirty data
15456
+ if (wasDirty) { // #3868, #3945
15457
+ delete this.kdTree;
15417
15458
  }
15418
15459
  },
15419
15460
 
@@ -17207,7 +17248,7 @@
17207
17248
  graphic = point.graphic,
17208
17249
  borderAttr;
17209
17250
 
17210
- if (plotY !== UNDEFINED && !isNaN(plotY) && point.y !== null) {
17251
+ if (isNumber(plotY) && point.y !== null) {
17211
17252
  shapeArgs = point.shapeArgs;
17212
17253
 
17213
17254
  borderAttr = defined(series.borderWidth) ? {
@@ -17264,7 +17305,7 @@
17264
17305
  // Do the scale synchronously to ensure smooth updating (#5030)
17265
17306
  step: function (val, fx) {
17266
17307
  series.group.attr({
17267
- scaleY: fx.pos
17308
+ scaleY: mathMax(0.001, fx.pos) // #5250
17268
17309
  });
17269
17310
  }
17270
17311
  }));
@@ -18015,11 +18056,11 @@
18015
18056
  rotCorr = chart.renderer.rotCorr(baseline, rotation); // #3723
18016
18057
  alignAttr = {
18017
18058
  x: alignTo.x + options.x + alignTo.width / 2 + rotCorr.x,
18018
- y: alignTo.y + options.y + alignTo.height / 2
18059
+ y: alignTo.y + options.y + { top: 0, middle: 0.5, bottom: 1 }[options.verticalAlign] * alignTo.height
18019
18060
  };
18020
18061
  dataLabel[isNew ? 'attr' : 'animate'](alignAttr)
18021
18062
  .attr({ // #3003
18022
- align: options.align
18063
+ align: align
18023
18064
  });
18024
18065
 
18025
18066
  // Compensate for the rotated label sticking out on the sides
@@ -18246,7 +18287,7 @@
18246
18287
  var slotX = series.getX(pos, i) + chart.plotLeft - (i ? 100 : 0),
18247
18288
  slotY = pos + chart.plotTop;
18248
18289
 
18249
- if (!isNaN(slotX)) {
18290
+ if (isNumber(slotX)) {
18250
18291
  series.slotElements.push(chart.renderer.rect(slotX, slotY - 7, 100, labelHeight, 1)
18251
18292
  .attr({
18252
18293
  'stroke-width': 1,
@@ -2,7 +2,7 @@
2
2
  // @compilation_level SIMPLE_OPTIMIZATIONS
3
3
 
4
4
  /**
5
- * @license Highcharts JS v4.2.4 (2016-04-14)
5
+ * @license Highcharts JS v4.2.5 (2016-05-06)
6
6
  *
7
7
  * 3D features for Highcharts JS
8
8
  *
@@ -2,7 +2,7 @@
2
2
  // @compilation_level SIMPLE_OPTIMIZATIONS
3
3
 
4
4
  /**
5
- * @license Highcharts JS v4.2.4 (2016-04-14)
5
+ * @license Highcharts JS v4.2.5 (2016-05-06)
6
6
  *
7
7
  * (c) 2009-2016 Torstein Honsi
8
8
  *
@@ -20,6 +20,7 @@ var arrayMin = Highcharts.arrayMin,
20
20
  arrayMax = Highcharts.arrayMax,
21
21
  each = Highcharts.each,
22
22
  extend = Highcharts.extend,
23
+ isNumber = Highcharts.isNumber,
23
24
  merge = Highcharts.merge,
24
25
  map = Highcharts.map,
25
26
  pick = Highcharts.pick,
@@ -525,6 +526,12 @@ var arrayMin = Highcharts.arrayMin,
525
526
 
526
527
  }
527
528
 
529
+ // Disable certain features on angular and polar axes
530
+ if (angular || polar) {
531
+ chart.inverted = false;
532
+ chartOptions.chart.zoomType = null;
533
+ }
534
+
528
535
  // Run prototype.init
529
536
  proceed.call(this, chart, userOptions);
530
537
 
@@ -542,11 +549,6 @@ var arrayMin = Highcharts.arrayMin,
542
549
  );
543
550
  paneOptions = pane.options;
544
551
 
545
-
546
- // Disable certain features on angular and polar axes
547
- chart.inverted = false;
548
- chartOptions.chart.zoomType = null;
549
-
550
552
  // Start and end angle options are
551
553
  // given in degrees relative to top, while internal computations are
552
554
  // in radians relative to right (like SVG).
@@ -1144,7 +1146,7 @@ var arrayMin = Highcharts.arrayMin,
1144
1146
  rotation = yAxis.startAngleRad + yAxis.translate(point.y, null, null, null, true);
1145
1147
 
1146
1148
  // Handle the wrap and overshoot options
1147
- if (overshoot && typeof overshoot === 'number') {
1149
+ if (isNumber(overshoot)) {
1148
1150
  overshoot = overshoot / 180 * Math.PI;
1149
1151
  rotation = Math.max(yAxis.startAngleRad - overshoot, Math.min(yAxis.endAngleRad + overshoot, rotation));
1150
1152
 
@@ -2085,7 +2087,7 @@ var arrayMin = Highcharts.arrayMin,
2085
2087
  point = data[i];
2086
2088
  radius = radii ? radii[i] : 0; // #1737
2087
2089
 
2088
- if (typeof radius === 'number' && radius >= this.minPxSize / 2) {
2090
+ if (isNumber(radius) && radius >= this.minPxSize / 2) {
2089
2091
  // Shape arguments
2090
2092
  point.shapeType = 'circle';
2091
2093
  point.shapeArgs = {
@@ -2213,7 +2215,7 @@ var arrayMin = Highcharts.arrayMin,
2213
2215
 
2214
2216
  if (range > 0) {
2215
2217
  while (i--) {
2216
- if (typeof data[i] === 'number' && axis.dataMin <= data[i] && data[i] <= axis.dataMax) {
2218
+ if (isNumber(data[i]) && axis.dataMin <= data[i] && data[i] <= axis.dataMax) {
2217
2219
  radius = series.radii[i];
2218
2220
  pxMin = Math.min(((data[i] - min) * transA) - radius, pxMin);
2219
2221
  pxMax = Math.max(((data[i] - min) * transA) + radius, pxMax);
@@ -2459,8 +2461,8 @@ var arrayMin = Highcharts.arrayMin,
2459
2461
  // Connect the path
2460
2462
  if (this.chart.polar) {
2461
2463
  points = points || this.points;
2462
-
2463
- if (this.options.connectEnds !== false && points[0].y !== null) {
2464
+
2465
+ if (this.options.connectEnds !== false && points[0] && points[0].y !== null) {
2464
2466
  this.connectEnds = true; // re-used in splines
2465
2467
  points.splice(points.length, 0, points[0]);
2466
2468
  }
@@ -2597,7 +2599,9 @@ var arrayMin = Highcharts.arrayMin,
2597
2599
  point = points[i];
2598
2600
  start = point.barX + startAngleRad;
2599
2601
  point.shapeType = 'path';
2600
- point.shapeArgs = this.polarArc(point.yBottom, point.plotY, start, start + point.pointWidth);
2602
+ point.shapeArgs = {
2603
+ d: this.polarArc(point.yBottom, point.plotY, start, start + point.pointWidth)
2604
+ };
2601
2605
  // Provide correct plotX, plotY for tooltip
2602
2606
  this.toXY(point);
2603
2607
  point.tooltipPos = [point.plotX, point.plotY];
@@ -67,6 +67,7 @@
67
67
  addEvent = H.addEvent,
68
68
  fireEvent = H.fireEvent,
69
69
  grep = H.grep,
70
+ isNumber = H.isNumber,
70
71
  merge = H.merge,
71
72
  pick = H.pick,
72
73
  wrap = H.wrap,
@@ -169,8 +170,8 @@
169
170
  data = options.data,
170
171
  xAxis = this.xAxis && this.xAxis.options,
171
172
  yAxis = this.yAxis && this.yAxis.options;
172
- return data.length > (options.boostThreshold || Number.MAX_VALUE) && typeof yAxis.min === 'number' && typeof yAxis.max === 'number' &&
173
- (!checkX || (typeof xAxis.min === 'number' && typeof xAxis.max === 'number'));
173
+ return data.length > (options.boostThreshold || Number.MAX_VALUE) && isNumber(yAxis.min) && isNumber(yAxis.max) &&
174
+ (!checkX || (isNumber(xAxis.min) && isNumber(xAxis.max)));
174
175
  },
175
176
 
176
177
  /**
@@ -275,7 +276,7 @@
275
276
  lastPoint,
276
277
  threshold = options.threshold,
277
278
  yBottom = yAxis.getThreshold(threshold),
278
- hasThreshold = typeof threshold === 'number',
279
+ hasThreshold = isNumber(threshold),
279
280
  translatedThreshold = yBottom,
280
281
  doFill = this.fill,
281
282
  isRange = series.pointArrayMap && series.pointArrayMap.join(',') === 'low,high',
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Highcharts JS v4.2.4 (2016-04-14)
2
+ * Highcharts JS v4.2.5 (2016-05-06)
3
3
  * Highcharts Broken Axis module
4
4
  *
5
5
  * License: www.highcharts.com/license
@@ -2908,7 +2908,7 @@ if (CanvasRenderingContext2D) {
2908
2908
  });
2909
2909
  }
2910
2910
  }/**
2911
- * @license Highcharts JS v4.2.4 (2016-04-14)
2911
+ * @license Highcharts JS v4.2.5 (2016-05-06)
2912
2912
  * CanVGRenderer Extension module
2913
2913
  *
2914
2914
  * (c) 2011-2016 Torstein Honsi, Erik Olsson
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.2.4 (2016-04-14)
2
+ * @license Highcharts JS v4.2.5 (2016-05-06)
3
3
  * Data module
4
4
  *
5
5
  * (c) 2012-2016 Torstein Honsi
@@ -22,6 +22,7 @@
22
22
  each = Highcharts.each,
23
23
  pick = Highcharts.pick,
24
24
  inArray = Highcharts.inArray,
25
+ isNumber = Highcharts.isNumber,
25
26
  splat = Highcharts.splat,
26
27
  SeriesBuilder;
27
28
 
@@ -424,7 +425,7 @@
424
425
  } else {
425
426
  dateVal = this.parseDate(val);
426
427
  // Only allow parsing of dates if this column is an x-column
427
- if (isXColumn && typeof dateVal === 'number' && !isNaN(dateVal) && columnType !== 'float') { // is date
428
+ if (isXColumn && isNumber(dateVal) && columnType !== 'float') { // is date
428
429
  backup[row] = val;
429
430
  column[row] = dateVal;
430
431
  column.isDatetime = true;
@@ -557,7 +558,7 @@
557
558
  ret = match.getTime() - match.getTimezoneOffset() * 60000;
558
559
 
559
560
  // Timestamp
560
- } else if (typeof match === 'number' && !isNaN(match)) {
561
+ } else if (isNumber(match)) {
561
562
  ret = match - (new Date(match)).getTimezoneOffset() * 60000;
562
563
  }
563
564
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.2.4 (2016-04-14)
2
+ * @license Highcharts JS v4.2.5 (2016-05-06)
3
3
  * Exporting module
4
4
  *
5
5
  * (c) 2010-2016 Torstein Honsi
@@ -104,6 +104,7 @@ defaultOptions.exporting = {
104
104
  type: 'image/png',
105
105
  url: 'http://export.highcharts.com/',
106
106
  //width: undefined,
107
+ printMaxWidth: 780,
107
108
  //scale: 2
108
109
  buttons: {
109
110
  contextButton: {
@@ -424,7 +425,11 @@ extend(Chart.prototype, {
424
425
  origDisplay = [],
425
426
  origParent = container.parentNode,
426
427
  body = doc.body,
427
- childNodes = body.childNodes;
428
+ childNodes = body.childNodes,
429
+ printMaxWidth = chart.options.exporting.printMaxWidth,
430
+ hasUserSize,
431
+ resetParams,
432
+ handleMaxWidth;
428
433
 
429
434
  if (chart.isPrinting) { // block the button while in printing mode
430
435
  return;
@@ -435,6 +440,14 @@ extend(Chart.prototype, {
435
440
 
436
441
  fireEvent(chart, 'beforePrint');
437
442
 
443
+ // Handle printMaxWidth
444
+ handleMaxWidth = printMaxWidth && chart.chartWidth > printMaxWidth;
445
+ if (handleMaxWidth) {
446
+ hasUserSize = chart.hasUserSize;
447
+ resetParams = [chart.chartWidth, chart.chartHeight, false];
448
+ chart.setSize(printMaxWidth, chart.chartHeight, false);
449
+ }
450
+
438
451
  // hide all body content
439
452
  each(childNodes, function (node, i) {
440
453
  if (node.nodeType === 1) {
@@ -465,6 +478,12 @@ extend(Chart.prototype, {
465
478
 
466
479
  chart.isPrinting = false;
467
480
 
481
+ // Reset printMaxWidth
482
+ if (handleMaxWidth) {
483
+ chart.setSize.apply(chart, resetParams);
484
+ chart.hasUserSize = hasUserSize;
485
+ }
486
+
468
487
  fireEvent(chart, 'afterPrint');
469
488
 
470
489
  }, 1000);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.2.4 (2016-04-14)
2
+ * @license Highcharts JS v4.2.5 (2016-05-06)
3
3
  *
4
4
  * (c) 2011-2016 Torstein Honsi
5
5
  *
@@ -28,6 +28,7 @@
28
28
  each = Highcharts.each,
29
29
  extend = Highcharts.extend,
30
30
  extendClass = Highcharts.extendClass,
31
+ isNumber = Highcharts.isNumber,
31
32
  merge = Highcharts.merge,
32
33
  pick = Highcharts.pick,
33
34
  seriesTypes = Highcharts.seriesTypes,
@@ -383,7 +384,7 @@
383
384
  }
384
385
  },
385
386
  getPlotLinePath: function (a, b, c, d, pos) {
386
- return typeof pos === 'number' ? // crosshairs only // #3969 pos can be 0 !!
387
+ return isNumber(pos) ? // crosshairs only // #3969 pos can be 0 !!
387
388
  (this.horiz ?
388
389
  ['M', pos - 4, this.top - 6, 'L', pos + 4, this.top - 6, pos, this.top, 'Z'] :
389
390
  ['M', this.left, pos, 'L', this.left - 6, pos + 6, this.left - 6, pos - 6, 'Z']
@@ -663,10 +664,10 @@
663
664
  each(series.points, function (point) {
664
665
  var xPad = (options.colsize || 1) / 2,
665
666
  yPad = (options.rowsize || 1) / 2,
666
- x1 = between(Math.round(xAxis.len - xAxis.translate(point.x - xPad, 0, 1, 0, 1)), 0, xAxis.len),
667
- x2 = between(Math.round(xAxis.len - xAxis.translate(point.x + xPad, 0, 1, 0, 1)), 0, xAxis.len),
668
- y1 = between(Math.round(yAxis.translate(point.y - yPad, 0, 1, 0, 1)), 0, yAxis.len),
669
- y2 = between(Math.round(yAxis.translate(point.y + yPad, 0, 1, 0, 1)), 0, yAxis.len);
667
+ x1 = between(Math.round(xAxis.len - xAxis.translate(point.x - xPad, 0, 1, 0, 1)), -xAxis.len, 2 * xAxis.len),
668
+ x2 = between(Math.round(xAxis.len - xAxis.translate(point.x + xPad, 0, 1, 0, 1)), -xAxis.len, 2 * xAxis.len),
669
+ y1 = between(Math.round(yAxis.translate(point.y - yPad, 0, 1, 0, 1)), -yAxis.len, 2 * yAxis.len),
670
+ y2 = between(Math.round(yAxis.translate(point.y + yPad, 0, 1, 0, 1)), -yAxis.len, 2 * yAxis.len);
670
671
 
671
672
  // Set plotX and plotY for use in K-D-Tree and more
672
673
  point.plotX = point.clientX = (x1 + x2) / 2;
@@ -694,7 +695,7 @@
694
695
  animate: noop,
695
696
  getBox: noop,
696
697
  drawLegendSymbol: LegendSymbolMixin.drawRectangle,
697
-
698
+ alignDataLabel: seriesTypes.column.prototype.alignDataLabel,
698
699
  getExtremes: function () {
699
700
  // Get the extremes from the value data
700
701
  Series.prototype.getExtremes.call(this, this.valueData);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.2.4 (2016-04-14)
2
+ * @license Highcharts JS v4.2.5 (2016-05-06)
3
3
  * Plugin for displaying a message when there is no data visible in chart.
4
4
  *
5
5
  * (c) 2010-2016 Highsoft AS
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.2.4 (2016-04-14)
2
+ * @license Highcharts JS v4.2.5 (2016-05-06)
3
3
  * Client side exporting module
4
4
  *
5
5
  * (c) 2015 Torstein Honsi / Oystein Moseng
@@ -68,8 +68,8 @@
68
68
  },
69
69
  // Get data:URL from image URL
70
70
  // Pass in callbacks to handle results. finallyCallback is always called at the end of the process. Supplying this callback is optional.
71
- // All callbacks receive two arguments: imageURL, and callbackArgs. callbackArgs is used only by callbacks and can contain whatever.
72
- imageToDataUrl = function (imageURL, callbackArgs, successCallback, taintedCallback, noCanvasSupportCallback, failedLoadCallback, finallyCallback) {
71
+ // All callbacks receive three arguments: imageURL, imageType, and callbackArgs. callbackArgs is used only by callbacks and can contain whatever.
72
+ imageToDataUrl = function (imageURL, imageType, callbackArgs, successCallback, taintedCallback, noCanvasSupportCallback, failedLoadCallback, finallyCallback) {
73
73
  var img = new win.Image(),
74
74
  taintedHandler,
75
75
  loadHandler = function () {
@@ -78,7 +78,7 @@
78
78
  dataURL;
79
79
  try {
80
80
  if (!ctx) {
81
- noCanvasSupportCallback(imageURL, callbackArgs);
81
+ noCanvasSupportCallback(imageURL, imageType, callbackArgs);
82
82
  } else {
83
83
  canvas.height = img.height * scale;
84
84
  canvas.width = img.width * scale;
@@ -86,12 +86,12 @@
86
86
 
87
87
  // Now we try to get the contents of the canvas.
88
88
  try {
89
- dataURL = canvas.toDataURL();
90
- successCallback(dataURL, callbackArgs);
89
+ dataURL = canvas.toDataURL(imageType);
90
+ successCallback(dataURL, imageType, callbackArgs);
91
91
  } catch (e) {
92
92
  // Failed - either tainted canvas or something else went horribly wrong
93
93
  if (e.name === 'SecurityError' || e.name === 'SECURITY_ERR' || e.message === 'SecurityError') {
94
- taintedHandler(imageURL, callbackArgs);
94
+ taintedHandler(imageURL, imageType, callbackArgs);
95
95
  } else {
96
96
  throw e;
97
97
  }
@@ -99,15 +99,15 @@
99
99
  }
100
100
  } finally {
101
101
  if (finallyCallback) {
102
- finallyCallback(imageURL, callbackArgs);
102
+ finallyCallback(imageURL, imageType, callbackArgs);
103
103
  }
104
104
  }
105
105
  },
106
106
  // Image load failed (e.g. invalid URL)
107
107
  errorHandler = function () {
108
- failedLoadCallback(imageURL, callbackArgs);
108
+ failedLoadCallback(imageURL, imageType, callbackArgs);
109
109
  if (finallyCallback) {
110
- finallyCallback(imageURL, callbackArgs);
110
+ finallyCallback(imageURL, imageType, callbackArgs);
111
111
  }
112
112
  };
113
113
 
@@ -176,10 +176,12 @@
176
176
  initiateDownload = function () {
177
177
  var svgurl,
178
178
  blob,
179
+ imageType = options && options.type || 'image/png',
180
+ imageExtension = imageType.split('/')[1],
179
181
  svg = chart.sanitizeSVG(chartCopyContainer.innerHTML); // SVG of chart copy
180
182
 
181
183
  // Initiate download depending on file type
182
- if (options && options.type === 'image/svg+xml') {
184
+ if (imageType === 'image/svg+xml') {
183
185
  // SVG download. In this case, we want to use Microsoft specific Blob if available
184
186
  try {
185
187
  if (nav.msSaveOrOpenBlob) {
@@ -194,14 +196,14 @@
194
196
  fallbackToExportServer();
195
197
  }
196
198
  } else {
197
- // PNG download - create bitmap from SVG
199
+ // PNG/JPEG download - create bitmap from SVG
198
200
 
199
201
  // First, try to get PNG by rendering on canvas
200
202
  svgurl = svgToDataUrl(svg);
201
- imageToDataUrl(svgurl, { /* args */ }, function (imageURL) {
203
+ imageToDataUrl(svgurl, imageType, { /* args */ }, function (imageURL) {
202
204
  // Success
203
205
  try {
204
- download(imageURL, 'png');
206
+ download(imageURL, imageExtension);
205
207
  } catch (e) {
206
208
  fallbackToExportServer();
207
209
  }
@@ -215,7 +217,7 @@
215
217
  downloadWithCanVG = function () {
216
218
  ctx.drawSvg(svg, 0, 0, imageWidth, imageHeight);
217
219
  try {
218
- download(nav.msSaveOrOpenBlob ? canvas.msToBlob() : canvas.toDataURL('image/png'), 'png');
220
+ download(nav.msSaveOrOpenBlob ? canvas.msToBlob() : canvas.toDataURL(imageType), imageExtension);
219
221
  } catch (e) {
220
222
  fallbackToExportServer();
221
223
  }
@@ -250,7 +252,7 @@
250
252
  }
251
253
  },
252
254
  // Success handler, we converted image to base64!
253
- embeddedSuccess = function (imageURL, callbackArgs) {
255
+ embeddedSuccess = function (imageURL, imageType, callbackArgs) {
254
256
  ++imagesEmbedded;
255
257
 
256
258
  // Change image href in chart copy
@@ -281,7 +283,7 @@
281
283
  // Go through the images we want to embed
282
284
  for (i = 0, l = images.length; i < l; ++i) {
283
285
  el = images[i];
284
- imageToDataUrl(el.getAttributeNS('http://www.w3.org/1999/xlink', 'href'), { imageElement: el },
286
+ imageToDataUrl(el.getAttributeNS('http://www.w3.org/1999/xlink', 'href'), 'image/png', { imageElement: el },
285
287
  embeddedSuccess,
286
288
  // Tainted canvas
287
289
  fallbackToExportServer,
@@ -309,6 +311,13 @@
309
311
  onclick: function () {
310
312
  this.exportChartLocal();
311
313
  }
314
+ }, {
315
+ textKey: 'downloadJPEG',
316
+ onclick: function () {
317
+ this.exportChartLocal({
318
+ type: 'image/jpeg'
319
+ });
320
+ }
312
321
  }, {
313
322
  textKey: 'downloadSVG',
314
323
  onclick: function () {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.2.4 (2016-04-14)
2
+ * @license Highcharts JS v4.2.5 (2016-05-06)
3
3
  * Solid angular gauge module
4
4
  *
5
5
  * (c) 2010-2016 Torstein Honsi
@@ -20,6 +20,7 @@
20
20
  pInt = H.pInt,
21
21
  pick = H.pick,
22
22
  each = H.each,
23
+ isNumber = H.isNumber,
23
24
  colorAxisMethods,
24
25
  UNDEFINED;
25
26
 
@@ -191,7 +192,7 @@
191
192
  options = series.options,
192
193
  renderer = series.chart.renderer,
193
194
  overshoot = options.overshoot,
194
- overshootVal = overshoot && typeof overshoot === 'number' ? overshoot / 180 * Math.PI : 0;
195
+ overshootVal = isNumber(overshoot) ? overshoot / 180 * Math.PI : 0;
195
196
 
196
197
  H.each(series.points, function (point) {
197
198
  var graphic = point.graphic,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Highcharts JS v4.2.4 (2016-04-14)
2
+ * @license Highcharts JS v4.2.5 (2016-05-06)
3
3
  *
4
4
  * (c) 2014 Highsoft AS
5
5
  * Authors: Jon Arild Nygard / Oystein Moseng
@@ -5,7 +5,7 @@
5
5
 
6
6
  // Load the fonts
7
7
  Highcharts.createElement('link', {
8
- href: '//fonts.googleapis.com/css?family=Unica+One',
8
+ href: 'https://fonts.googleapis.com/css?family=Unica+One',
9
9
  rel: 'stylesheet',
10
10
  type: 'text/css'
11
11
  }, null, document.getElementsByTagName('head')[0]);
@@ -5,7 +5,7 @@
5
5
 
6
6
  // Load the fonts
7
7
  Highcharts.createElement('link', {
8
- href: '//fonts.googleapis.com/css?family=Dosis:400,600',
8
+ href: 'https://fonts.googleapis.com/css?family=Dosis:400,600',
9
9
  rel: 'stylesheet',
10
10
  type: 'text/css'
11
11
  }, null, document.getElementsByTagName('head')[0]);
@@ -5,7 +5,7 @@
5
5
 
6
6
  // Load the fonts
7
7
  Highcharts.createElement('link', {
8
- href: '//fonts.googleapis.com/css?family=Signika:400,700',
8
+ href: 'https://fonts.googleapis.com/css?family=Signika:400,700',
9
9
  rel: 'stylesheet',
10
10
  type: 'text/css'
11
11
  }, null, document.getElementsByTagName('head')[0]);
@@ -1,3 +1,3 @@
1
1
  module Highcharts
2
- VERSION = "4.2.4"
2
+ VERSION = "4.2.5"
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.2.4
4
+ version: 4.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Per Christian B. Viken