highcharts-rails 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.asc CHANGED
@@ -2,17 +2,17 @@
2
2
  Version: GnuPG/MacGPG2 v2.0.19 (Darwin)
3
3
  Comment: GPGTools - http://gpgtools.org
4
4
 
5
- iQIcBAABAgAGBQJRUZ5vAAoJEH1ncb0Txu7XOP8QAJqYLrvRoCF+ZJpIMLtTMYmR
6
- yO3rokbmTfBJsLO5q74P6PfZHme5t5iGOQSGcyHlubxBF0nt2HlxlxM9WRoFvILT
7
- fpbq08qtqwxn9BIduNgHnO8AL85Dh262rrIcwzy9W/Zorh59LjZZBUyfHa1Tq8JI
8
- fQtgacXkKmKipf6PkxzzlHeYNAz+ILJ4e8jQC079k686XytjYjqKyehP2Ol23lof
9
- KxG0ZP6x5Nhfzdy/IahAdLynr8OVL5UD9MQp0e1zX0o2Bs7rfDO4HyawDk+bY0ye
10
- Ogw8Y+QbAzvIAzKbePBp15COy7+SAhJdrh/oNcOU2yXKB1Hm9TBcdt680DGbJyQX
11
- KOCyMrlLs4oroMYxSsb5wtEaOxpNPfRPqhx8YkAk6TJifPbuRMnVmQbDbvfAeP9X
12
- Dt19j5vH8Kf3b9VMbvBZ01/9l1uO8caY4PEZOuJZ2PH94theHcBghhafjVkiYxXi
13
- 0j/AGyLDc0tSAYiRfCBQKjR97sxTn2j6WaOg03xTxqd2Iw1yGeXnsf/7nikcQjS6
14
- ifjeOOwbExcsRCm6O620BJ64W4AZu3m2nQUS0MSQ6CBmwHIo3UTi4uUt0o0J307C
15
- 7FUkhAatbmTcKVj/GO8ndn6bugvt7VT6j2aEiYzT5flRntUITw37Er7ULxxr1iQ3
16
- xT35BnLYojAVHhDxf3xF
17
- =rLxR
5
+ iQIcBAABAgAGBQJRZCX4AAoJEH1ncb0Txu7XWUgQAKSwMYAj6ECNovM5FQnW9Xrs
6
+ 84xcCzwhur/YD5/jOVxl85tTVmboBRdVPp53CmsuquGYUMRrrXRobt6C6/hMp4DP
7
+ imZ72AL1ZjYjFPCjHXuJzVXsiwGKLE7SdhGo01l3+69rhGwurpA3fZ9d1DaO+YZ6
8
+ BlwHypnXlQGOPapB7Eh2V/U5UbZi3V1kLTlUaJyUu914p99Jo6MutHobM7aShMOx
9
+ hdqn+ZqN0ha2ourKFk+wJKWTMKe4jvlp9SDrOLe9JY+AJ9zfCns+QFwFJQaC6+VE
10
+ DlxQVt33q2nl+W7DdQr23kBM9/Vr9tQzNPE4E17NvGGZBwTZGxPSwPVzoO1ajRVH
11
+ MwzbcKrqo1AkRDY5th1Hf2WAyruQ62DlbHF/5luJo1ezsuakus74/JWIo36BXKdp
12
+ R20yR4hnQflxGj9BwOUZ5oroG4+PvIBHEfy9no7R600u5Q/RzCj+C3MCekYTMyKV
13
+ KurzDyFfanNU1RNVkV2rJAAB2373cCZRiORqi7HNfdjkzzJiuFCTIWNkEo2eLPx4
14
+ KlCZL5czNj1fgiEZclMGqv7Le5RXR3SuQXzxTw/cpEbvy5Zwm1zUGWankUQb+TEg
15
+ 7hP/wQD5E8zJ/ZYbYjXCnS2K8e59+EOc5DcGpaPT9ELSmaCDlG3AvNnKuFS3g+nj
16
+ pm1NAKtYl8Y62Yf35hba
17
+ =qJvF
18
18
  -----END PGP SIGNATURE-----
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  sauce
6
+ tmp
@@ -1,3 +1,9 @@
1
+ # 3.0.1 / 2013-04-09
2
+
3
+ * Updated Highcharts to 3.0.1
4
+ * Moved assets from vendor/assets to app/assets, since the entire point of the
5
+ gem is to deliver those assets.
6
+
1
7
  # 3.0.0 / 2013-03-25
2
8
 
3
9
  * Updated Highcharts to 3.0.0
@@ -38,4 +44,4 @@
38
44
  # 2.2.1 / 2012-04-15
39
45
 
40
46
  * Updated Highcharts to 2.2.1
41
- * Added the skies theme (graphic hardcoded to `/assets/highcharts/skies.jpg`)
47
+ * Added the skies theme (graphic hardcoded to `/assets/highcharts/skies.jpg`)
@@ -49,4 +49,14 @@ Other than that, refer to the [Highcharts documentation](http://highcharts.com/d
49
49
 
50
50
  Highcharts, which makes up the majority of this gem, has [its own, separate licensing](http://highcharts.com/license).
51
51
 
52
- The gem itself is released under the MIT license
52
+ The gem itself is released under the MIT license
53
+
54
+ ## Signing
55
+
56
+ Release tags and all released gems (from 3.0.0 onwards) is signed using [rubygems-openpgp](https://www.rubygems-openpgp-ca.org/) using [my personal key](https://eastblue.org/blag/contact/), and the fingerprint is also included below.
57
+
58
+ pub 4096R/CCFBB9EF 2013-02-01 [expires: 2017-02-01]
59
+ Key fingerprint = 6077 34FC 32B6 6041 BF06 43F2 205D 9784 CCFB B9EF
60
+ uid Per Christian Bechström Viken <perchr@northblue.org>
61
+ uid [jpeg image of size 6240]
62
+ sub 4096R/13C6EED7 2013-02-01 [expires: 2017-02-01]
@@ -2,7 +2,7 @@
2
2
  // @compilation_level SIMPLE_OPTIMIZATIONS
3
3
 
4
4
  /**
5
- * @license Highcharts JS v3.0.0 (2013-03-22)
5
+ * @license Highcharts JS v3.0.1 (2013-04-09)
6
6
  *
7
7
  * (c) 2009-2013 Torstein Hønsi
8
8
  *
@@ -55,7 +55,7 @@ var UNDEFINED,
55
55
  noop = function () {},
56
56
  charts = [],
57
57
  PRODUCT = 'Highcharts',
58
- VERSION = '3.0.0',
58
+ VERSION = '3.0.1',
59
59
 
60
60
  // some constants for frequently used strings
61
61
  DIV = 'div',
@@ -377,18 +377,6 @@ function extendClass(parent, members) {
377
377
  return object;
378
378
  }
379
379
 
380
- /**
381
- * How many decimals are there in a number
382
- */
383
- function getDecimals(number) {
384
-
385
- number = (number || 0).toString();
386
-
387
- return number.indexOf('.') > -1 ?
388
- number.split('.')[1].length :
389
- 0;
390
- }
391
-
392
380
  /**
393
381
  * Format a number and return a string based on input settings
394
382
  * @param {Number} number The input number to format
@@ -401,7 +389,7 @@ function numberFormat(number, decimals, decPoint, thousandsSep) {
401
389
  // http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_number_format/
402
390
  n = number,
403
391
  c = decimals === -1 ?
404
- getDecimals(number) :
392
+ ((n || 0).toString().split('.')[1] || '').length : // preserve decimals
405
393
  (isNaN(decimals = mathAbs(decimals)) ? 2 : decimals),
406
394
  d = decPoint === undefined ? lang.decimalPoint : decPoint,
407
395
  t = thousandsSep === undefined ? lang.thousandsSep : thousandsSep,
@@ -464,7 +452,6 @@ dateFormat = function (format, timestamp, capitalize) {
464
452
  langWeekdays = lang.weekdays,
465
453
 
466
454
  // List all format keys. Custom formats can be added from the outside.
467
- // See http://jsfiddle.net/highcharts/7PB5N/ // docs
468
455
  replacements = extend({
469
456
 
470
457
  // Day
@@ -519,7 +506,7 @@ function formatSingle(format, val) {
519
506
 
520
507
  if (floatRegex.test(format)) { // float
521
508
  decimals = format.match(decRegex);
522
- decimals = decimals ? decimals[1] : 6;
509
+ decimals = decimals ? decimals[1] : -1;
523
510
  val = numberFormat(
524
511
  val,
525
512
  decimals,
@@ -795,12 +782,14 @@ function getTimeTicks(normalizedInterval, min, max, startOfWeek) {
795
782
 
796
783
  // else, the interval is fixed and we use simple addition
797
784
  } else {
798
- time += interval * count;
799
785
 
800
786
  // mark new days if the time is dividable by day
801
787
  if (interval <= timeUnits[HOUR] && time % timeUnits[DAY] === timezoneOffset) {
802
788
  higherRanks[time] = DAY;
803
789
  }
790
+
791
+ time += interval * count;
792
+
804
793
  }
805
794
 
806
795
  i++;
@@ -1206,7 +1195,7 @@ pathAnim = {
1206
1195
  };
1207
1196
 
1208
1197
  /**
1209
- * Register Highcharts as a plugin in the respective framework // docs
1198
+ * Register Highcharts as a plugin in the respective framework
1210
1199
  */
1211
1200
  $.fn.highcharts = function () {
1212
1201
  var constr = 'Chart', // default constructor
@@ -1312,7 +1301,7 @@ pathAnim = {
1312
1301
  // workaround for jQuery issue with unbinding custom events:
1313
1302
  // http://forum.jQuery.com/topic/javascript-error-when-unbinding-a-custom-event-using-jQuery-1-4-2
1314
1303
  var func = doc.removeEventListener ? 'removeEventListener' : 'detachEvent';
1315
- if (doc[func] && !el[func]) {
1304
+ if (doc[func] && el && !el[func]) {
1316
1305
  el[func] = function () {};
1317
1306
  }
1318
1307
 
@@ -1482,7 +1471,7 @@ defaultLabelOptions = {
1482
1471
 
1483
1472
  defaultOptions = {
1484
1473
  colors: ['#2f7ed8', '#0d233a', '#8bbc21', '#910000', '#1aadce', '#492970',
1485
- '#f28f43', '#77a1e5', '#c42525', '#a6c96a'], // docs
1474
+ '#f28f43', '#77a1e5', '#c42525', '#a6c96a'],
1486
1475
  symbols: ['circle', 'diamond', 'square', 'triangle', 'triangle-down'],
1487
1476
  lang: {
1488
1477
  loading: 'Loading...',
@@ -1498,8 +1487,8 @@ defaultOptions = {
1498
1487
  },
1499
1488
  global: {
1500
1489
  useUTC: true,
1501
- canvasToolsURL: 'http://code.highcharts.com/3.0.0/modules/canvas-tools.js',
1502
- VMLRadialGradientURL: 'http://code.highcharts.com/3.0.0/gfx/vml-radial-gradient.png'
1490
+ canvasToolsURL: 'http://code.highcharts.com/3.0.1/modules/canvas-tools.js',
1491
+ VMLRadialGradientURL: 'http://code.highcharts.com/3.0.1/gfx/vml-radial-gradient.png'
1503
1492
  },
1504
1493
  chart: {
1505
1494
  //animation: true,
@@ -1587,7 +1576,7 @@ defaultOptions = {
1587
1576
  events: {},
1588
1577
  //legendIndex: 0,
1589
1578
  lineWidth: 2,
1590
- //shadow: false, // docs
1579
+ //shadow: false,
1591
1580
  // stacking: null,
1592
1581
  marker: {
1593
1582
  enabled: true,
@@ -1676,7 +1665,7 @@ defaultOptions = {
1676
1665
  borderRadius: 5,
1677
1666
  navigation: {
1678
1667
  // animation: true,
1679
- activeColor: '#274b6d', // docs
1668
+ activeColor: '#274b6d',
1680
1669
  // arrowSize: 12
1681
1670
  inactiveColor: '#CCC'
1682
1671
  // style: {} // text styles
@@ -1690,7 +1679,7 @@ defaultOptions = {
1690
1679
  },*/
1691
1680
  itemStyle: {
1692
1681
  cursor: 'pointer',
1693
- color: '#274b6d', // docs
1682
+ color: '#274b6d',
1694
1683
  fontSize: '12px'
1695
1684
  },
1696
1685
  itemHoverStyle: {
@@ -1712,7 +1701,7 @@ defaultOptions = {
1712
1701
  // width: undefined,
1713
1702
  x: 0,
1714
1703
  y: 0,
1715
- title: { // docs
1704
+ title: {
1716
1705
  //text: null,
1717
1706
  style: {
1718
1707
  fontWeight: 'bold'
@@ -1738,11 +1727,11 @@ defaultOptions = {
1738
1727
 
1739
1728
  tooltip: {
1740
1729
  enabled: true,
1741
- animation: hasSVG, // docs
1730
+ animation: hasSVG,
1742
1731
  //crosshairs: null,
1743
1732
  backgroundColor: 'rgba(255, 255, 255, .85)',
1744
- borderWidth: 1, // docs
1745
- borderRadius: 3, // docs
1733
+ borderWidth: 1,
1734
+ borderRadius: 3,
1746
1735
  dateTimeLabelFormats: {
1747
1736
  millisecond: '%A, %b %e, %H:%M:%S.%L',
1748
1737
  second: '%A, %b %e, %H:%M:%S',
@@ -1763,7 +1752,7 @@ defaultOptions = {
1763
1752
  color: '#333333',
1764
1753
  cursor: 'default',
1765
1754
  fontSize: '12px',
1766
- padding: '8px', // docs
1755
+ padding: '8px',
1767
1756
  whiteSpace: 'nowrap'
1768
1757
  }
1769
1758
  //xDateFormat: '%A, %b %e, %Y',
@@ -2827,8 +2816,8 @@ SVGElement.prototype = {
2827
2816
  width = bBox.width;
2828
2817
  height = bBox.height;
2829
2818
 
2830
- // Workaround for wrong bounding box in IE9 and IE10 (#1101, #1505)
2831
- if (isIE && styles && styles.fontSize === '11px' && height.toPrecision(3) === 22.7) {
2819
+ // Workaround for wrong bounding box in IE9 and IE10 (#1101, #1505, #1669)
2820
+ if (isIE && styles && styles.fontSize === '11px' && height.toPrecision(3) === '22.7') {
2832
2821
  bBox.height = height = 14;
2833
2822
  }
2834
2823
 
@@ -3693,6 +3682,7 @@ SVGRenderer.prototype = {
3693
3682
  x: x,
3694
3683
  y: y
3695
3684
  });
3685
+ obj.isImg = true;
3696
3686
 
3697
3687
  if (imageSize) {
3698
3688
  centerImage(obj, imageSize);
@@ -4216,10 +4206,12 @@ SVGRenderer.prototype = {
4216
4206
  }
4217
4207
 
4218
4208
  // apply the box attributes
4219
- box.attr(merge({
4220
- width: wrapper.width,
4221
- height: wrapper.height
4222
- }, deferredAttr));
4209
+ if (!box.isImg) { // #1630
4210
+ box.attr(merge({
4211
+ width: wrapper.width,
4212
+ height: wrapper.height
4213
+ }, deferredAttr));
4214
+ }
4223
4215
  deferredAttr = null;
4224
4216
  }
4225
4217
  }
@@ -4608,7 +4600,8 @@ Highcharts.VMLElement = VMLElement = {
4608
4600
 
4609
4601
  // convert paths
4610
4602
  i = value.length;
4611
- var convertedPath = [];
4603
+ var convertedPath = [],
4604
+ clockwise;
4612
4605
  while (i--) {
4613
4606
 
4614
4607
  // Multiply by 10 to allow subpixel precision.
@@ -4624,13 +4617,14 @@ Highcharts.VMLElement = VMLElement = {
4624
4617
  // When the start X and end X coordinates of an arc are too close,
4625
4618
  // they are rounded to the same value above. In this case, substract 1 from the end X
4626
4619
  // position. #760, #1371.
4627
- if (value[i] === 'wa' || value[i] === 'at') {
4620
+ if (value.isArc && (value[i] === 'wa' || value[i] === 'at')) {
4621
+ clockwise = value[i] === 'wa' ? 1 : -1; // #1642
4628
4622
  if (convertedPath[i + 5] === convertedPath[i + 7]) {
4629
- convertedPath[i + 7] -= 1;
4623
+ convertedPath[i + 7] -= clockwise;
4630
4624
  }
4631
4625
  // Start and end Y (#1410)
4632
4626
  if (convertedPath[i + 6] === convertedPath[i + 8]) {
4633
- convertedPath[i + 8] -= 1;
4627
+ convertedPath[i + 8] -= clockwise;
4634
4628
  }
4635
4629
  }
4636
4630
  }
@@ -4668,7 +4662,7 @@ Highcharts.VMLElement = VMLElement = {
4668
4662
  // outside the viewport. So the visibility is actually opposite of
4669
4663
  // the expected value. This applies to the tooltip only.
4670
4664
  if (!docMode8) {
4671
- elemStyle[key] = value ? HIDDEN : VISIBLE;
4665
+ elemStyle[key] = value ? VISIBLE : HIDDEN;
4672
4666
  }
4673
4667
  key = 'top';
4674
4668
  }
@@ -5451,6 +5445,7 @@ var VMLRendererExtension = { // inherit SVGRenderer
5451
5445
  'e' // close
5452
5446
  );
5453
5447
 
5448
+ ret.isArc = true;
5454
5449
  return ret;
5455
5450
 
5456
5451
  },
@@ -5658,7 +5653,7 @@ Tick.prototype = {
5658
5653
  !labelOptions.step && !labelOptions.staggerLines &&
5659
5654
  !labelOptions.rotation &&
5660
5655
  chart.plotWidth / tickPositions.length) ||
5661
- (!horiz && chart.plotWidth / 2),
5656
+ (!horiz && (chart.optionsMarginLeft || chart.plotWidth / 2)), // #1580
5662
5657
  isFirst = pos === tickPositions[0],
5663
5658
  isLast = pos === tickPositions[tickPositions.length - 1],
5664
5659
  css,
@@ -6257,7 +6252,7 @@ StackItem.prototype = {
6257
6252
  // Create new label
6258
6253
  } else {
6259
6254
  this.label =
6260
- this.axis.chart.renderer.text(str, 0, 0, options.useHTML) // dummy positions, actual position updated with setOffset method in columnseries // docs: useHTML for stackLabels
6255
+ this.axis.chart.renderer.text(str, 0, 0, options.useHTML) // dummy positions, actual position updated with setOffset method in columnseries
6261
6256
  .css(options.style) // apply style
6262
6257
  .attr({
6263
6258
  align: this.textAlign, // fix the text-anchor
@@ -6724,7 +6719,7 @@ Axis.prototype = {
6724
6719
  i = numericSymbols && numericSymbols.length,
6725
6720
  multi,
6726
6721
  ret,
6727
- formatOption = axis.options.labels.format, // docs
6722
+ formatOption = axis.options.labels.format,
6728
6723
 
6729
6724
  // make sure the same symbol is added for all labels on a linear axis
6730
6725
  numericSymbolDetector = axis.isLog ? value : axis.tickInterval;
@@ -6895,7 +6890,7 @@ Axis.prototype = {
6895
6890
  }
6896
6891
 
6897
6892
  // Handle non null values
6898
- if (y !== null && y !== UNDEFINED && (!axis.isLog || y > 0)) {
6893
+ if (y !== null && y !== UNDEFINED && (!axis.isLog || (y.length || y > 0))) {
6899
6894
 
6900
6895
  // general hook, used for Highstock compare values feature
6901
6896
  if (hasModifyValue) {
@@ -7017,7 +7012,7 @@ Axis.prototype = {
7017
7012
  * @param {Boolean} paneCoordinates Whether to return the pixel coordinate relative to the chart
7018
7013
  * or just the axis/pane itself.
7019
7014
  */
7020
- toPixels: function (value, paneCoordinates) { // docs
7015
+ toPixels: function (value, paneCoordinates) {
7021
7016
  return this.translate(value, false, !this.horiz, null, true) + (paneCoordinates ? 0 : this.pos);
7022
7017
  },
7023
7018
 
@@ -7027,7 +7022,7 @@ Axis.prototype = {
7027
7022
  * @param {Boolean} paneCoordiantes Whether the input pixel is relative to the chart or just the
7028
7023
  * axis/pane itself.
7029
7024
  */
7030
- toValue: function (pixel, paneCoordinates) { // docs
7025
+ toValue: function (pixel, paneCoordinates) {
7031
7026
  return this.translate(pixel - (paneCoordinates ? 0 : this.pos), true, !this.horiz, null, true);
7032
7027
  },
7033
7028
 
@@ -7178,7 +7173,7 @@ Axis.prototype = {
7178
7173
  for (j = 0; j < len && !break2; j++) {
7179
7174
  pos = log2lin(lin2log(i) * intermediate[j]);
7180
7175
 
7181
- if (pos > min && lastPos <= max) {
7176
+ if (pos > min && (!minor || lastPos <= max)) { // #1670
7182
7177
  positions.push(lastPos);
7183
7178
  }
7184
7179
 
@@ -7359,6 +7354,7 @@ Axis.prototype = {
7359
7354
  minPointOffset = 0,
7360
7355
  pointRangePadding = 0,
7361
7356
  linkedParent = axis.linkedParent,
7357
+ ordinalCorrection,
7362
7358
  transA = axis.transA;
7363
7359
 
7364
7360
  // adjust translation for padding
@@ -7403,8 +7399,9 @@ Axis.prototype = {
7403
7399
  }
7404
7400
 
7405
7401
  // Record minPointOffset and pointRangePadding
7406
- axis.minPointOffset = minPointOffset;
7407
- axis.pointRangePadding = pointRangePadding;
7402
+ ordinalCorrection = axis.ordinalSlope ? axis.ordinalSlope / closestPointRange : 1; // #988
7403
+ axis.minPointOffset = minPointOffset = minPointOffset * ordinalCorrection;
7404
+ axis.pointRangePadding = pointRangePadding = pointRangePadding * ordinalCorrection;
7408
7405
 
7409
7406
  // pointRange means the width reserved for each point, like in a column chart
7410
7407
  axis.pointRange = mathMin(pointRange, range);
@@ -7769,11 +7766,13 @@ Axis.prototype = {
7769
7766
  zoom: function (newMin, newMax) {
7770
7767
 
7771
7768
  // Prevent pinch zooming out of range
7772
- if (newMin <= this.dataMin) {
7773
- newMin = UNDEFINED;
7774
- }
7775
- if (newMax >= this.dataMax) {
7776
- newMax = UNDEFINED;
7769
+ if (!this.allowZoomOutside) {
7770
+ if (newMin <= this.dataMin) {
7771
+ newMin = UNDEFINED;
7772
+ }
7773
+ if (newMax >= this.dataMax) {
7774
+ newMax = UNDEFINED;
7775
+ }
7777
7776
  }
7778
7777
 
7779
7778
  // In full view, displaying the reset zoom button is not required
@@ -8108,17 +8107,17 @@ Axis.prototype = {
8108
8107
  from,
8109
8108
  to;
8110
8109
 
8110
+ // Mark all elements inActive before we go over and mark the active ones
8111
+ each([ticks, minorTicks, alternateBands], function (coll) {
8112
+ var pos;
8113
+ for (pos in coll) {
8114
+ coll[pos].isActive = false;
8115
+ }
8116
+ });
8117
+
8111
8118
  // If the series has data draw the ticks. Else only the line and title
8112
8119
  if (hasData || isLinked) {
8113
8120
 
8114
- // Mark all elements inActive before we go over and mark the active ones
8115
- each([ticks, minorTicks, alternateBands], function (coll) {
8116
- var pos;
8117
- for (pos in coll) {
8118
- coll[pos].isActive = false;
8119
- }
8120
- });
8121
-
8122
8121
  // minor ticks
8123
8122
  if (axis.minorTickInterval && !axis.categories) {
8124
8123
  each(axis.getMinorTickPositions(), function (pos) {
@@ -8519,7 +8518,7 @@ Tooltip.prototype = {
8519
8518
  this.hideTimer = setTimeout(function () {
8520
8519
  tooltip.label.fadeOut();
8521
8520
  tooltip.isHidden = true;
8522
- }, pick(this.options.hideDelay, 500)); // docs
8521
+ }, pick(this.options.hideDelay, 500));
8523
8522
 
8524
8523
  // hide previous hoverPoints and set new
8525
8524
  if (hoverPoints) {
@@ -8773,14 +8772,19 @@ Tooltip.prototype = {
8773
8772
  var path,
8774
8773
  i = crosshairsOptions.length,
8775
8774
  attribs,
8776
- axis;
8775
+ axis,
8776
+ val;
8777
8777
 
8778
8778
  while (i--) {
8779
8779
  axis = point.series[i ? 'yAxis' : 'xAxis'];
8780
8780
  if (crosshairsOptions[i] && axis) {
8781
+ val = i ? pick(point.stackY, point.y) : point.x; // #814
8782
+ if (axis.isLog) { // #1671
8783
+ val = log2lin(val);
8784
+ }
8781
8785
 
8782
8786
  path = axis.getPlotLinePath(
8783
- i ? pick(point.stackY, point.y) : point.x, // #814
8787
+ val,
8784
8788
  1
8785
8789
  );
8786
8790
 
@@ -9175,21 +9179,24 @@ Pointer.prototype = {
9175
9179
  var self = this,
9176
9180
  chart = self.chart,
9177
9181
  pinchDown = self.pinchDown,
9182
+ followTouchMove = chart.tooltip.options.followTouchMove,
9178
9183
  touches = e.touches,
9184
+ touchesLength = touches.length,
9179
9185
  lastValidTouch = self.lastValidTouch,
9180
9186
  zoomHor = self.zoomHor || self.pinchHor,
9181
9187
  zoomVert = self.zoomVert || self.pinchVert,
9188
+ hasZoom = zoomHor || zoomVert,
9182
9189
  selectionMarker = self.selectionMarker,
9183
9190
  transform = {},
9184
9191
  clip = {};
9185
9192
 
9186
9193
  // On touch devices, only proceed to trigger click if a handler is defined
9187
- if (e.type === 'touchstart') {
9194
+ if (e.type === 'touchstart' && followTouchMove) {
9188
9195
  if (self.inClass(e.target, PREFIX + 'tracker')) {
9189
- if (!chart.runTrackerClick) {
9196
+ if (!chart.runTrackerClick || touchesLength > 1) {
9190
9197
  e.preventDefault();
9191
9198
  }
9192
- } else if (!chart.runChartClick) {
9199
+ } else if (!chart.runChartClick || touchesLength > 1) {
9193
9200
  e.preventDefault();
9194
9201
  }
9195
9202
  }
@@ -9243,12 +9250,15 @@ Pointer.prototype = {
9243
9250
  self.pinchTranslateDirection(false, pinchDown, touches, transform, selectionMarker, clip, lastValidTouch);
9244
9251
  }
9245
9252
 
9246
- self.hasPinched = zoomHor || zoomVert;
9253
+ self.hasPinched = hasZoom;
9247
9254
 
9248
9255
  // Scale and translate the groups to provide visual feedback during pinching
9249
9256
  self.scaleGroups(transform, clip);
9250
9257
 
9251
-
9258
+ // Optionally move the tooltip on touchmove
9259
+ if (!hasZoom && followTouchMove && touchesLength === 1) {
9260
+ this.runPointActions(self.normalize(e));
9261
+ }
9252
9262
  }
9253
9263
  },
9254
9264
 
@@ -9409,7 +9419,7 @@ Pointer.prototype = {
9409
9419
 
9410
9420
  // Reset all
9411
9421
  if (chart) { // it may be destroyed on mouse up - #877
9412
- css(chart.container, { cursor: 'auto' });
9422
+ css(chart.container, { cursor: chart._cursor });
9413
9423
  chart.cancelClick = this.hasDragged; // #370
9414
9424
  chart.mouseIsDown = this.hasDragged = this.hasPinched = false;
9415
9425
  this.pinchDown = [];
@@ -9910,7 +9920,7 @@ Legend.prototype = {
9910
9920
 
9911
9921
  // Generate the list item text and add it to the group
9912
9922
  item.legendItem = li = renderer.text(
9913
- options.labelFormat ? format(options.labelFormat, item) : options.labelFormatter.call(item), // docs,
9923
+ options.labelFormat ? format(options.labelFormat, item) : options.labelFormatter.call(item),
9914
9924
  ltr ? symbolWidth + symbolPadding : -symbolPadding,
9915
9925
  legend.baseline,
9916
9926
  useHTML
@@ -10199,7 +10209,7 @@ Legend.prototype = {
10199
10209
  }
10200
10210
 
10201
10211
  // Reset the legend height and adjust the clipping rectangle
10202
- if (legendHeight > spaceHeight && !options.useHTML) { // docs - disable navigation when useHTML
10212
+ if (legendHeight > spaceHeight && !options.useHTML) {
10203
10213
 
10204
10214
  this.clipHeight = clipHeight = spaceHeight - 20 - this.titleHeight;
10205
10215
  this.pageCount = pageCount = mathCeil(legendHeight / clipHeight);
@@ -10478,7 +10488,7 @@ Chart.prototype = {
10478
10488
  * @param {Object} options The axis option
10479
10489
  * @param {Boolean} isX Whether it is an X axis or a value axis
10480
10490
  */
10481
- addAxis: function (options, isX, redraw, animation) { // docs
10491
+ addAxis: function (options, isX, redraw, animation) {
10482
10492
  var key = isX ? 'xAxis' : 'yAxis',
10483
10493
  chartOptions = this.options,
10484
10494
  axis;
@@ -10678,10 +10688,6 @@ Chart.prototype = {
10678
10688
  chart.loadingDiv = loadingDiv = createElement(DIV, {
10679
10689
  className: PREFIX + 'loading'
10680
10690
  }, extend(loadingOptions.style, {
10681
- left: chart.plotLeft + PX,
10682
- top: chart.plotTop + PX,
10683
- width: chart.plotWidth + PX,
10684
- height: chart.plotHeight + PX,
10685
10691
  zIndex: 10,
10686
10692
  display: NONE
10687
10693
  }), chart.container);
@@ -10700,7 +10706,14 @@ Chart.prototype = {
10700
10706
 
10701
10707
  // show it
10702
10708
  if (!chart.loadingShown) {
10703
- css(loadingDiv, { opacity: 0, display: '' });
10709
+ css(loadingDiv, {
10710
+ opacity: 0,
10711
+ display: '',
10712
+ left: chart.plotLeft + PX,
10713
+ top: chart.plotTop + PX,
10714
+ width: chart.plotWidth + PX,
10715
+ height: chart.plotHeight + PX
10716
+ });
10704
10717
  animate(loadingDiv, {
10705
10718
  opacity: loadingOptions.style.opacity
10706
10719
  }, {
@@ -10807,7 +10820,7 @@ Chart.prototype = {
10807
10820
  getSelectedPoints: function () {
10808
10821
  var points = [];
10809
10822
  each(this.series, function (serie) {
10810
- points = points.concat(grep(serie.points, function (point) {
10823
+ points = points.concat(grep(serie.points || [], function (point) {
10811
10824
  return point.selected;
10812
10825
  }));
10813
10826
  });
@@ -11104,6 +11117,9 @@ Chart.prototype = {
11104
11117
  chart.renderToClone || renderTo
11105
11118
  );
11106
11119
 
11120
+ // cache the cursor (#1650)
11121
+ chart._cursor = container.style.cursor;
11122
+
11107
11123
  chart.renderer =
11108
11124
  optionsChart.forExport ? // force SVG, used for SVG export
11109
11125
  new SVGRenderer(container, chartWidth, chartHeight, true) :
@@ -11852,7 +11868,7 @@ Point.prototype = {
11852
11868
  point.pointAttr = {};
11853
11869
 
11854
11870
  if (series.options.colorByPoint) {
11855
- colors = series.options.colors || series.chart.options.colors; // docs: series.options.colors when colorByPoint is true
11871
+ colors = series.options.colors || series.chart.options.colors;
11856
11872
  point.color = point.color || colors[series.colorCounter++];
11857
11873
  // loop back to zero
11858
11874
  if (series.colorCounter === colors.length) {
@@ -12101,7 +12117,7 @@ Point.prototype = {
12101
12117
  // Insert options for valueDecimals, valuePrefix, and valueSuffix
12102
12118
  var series = this.series,
12103
12119
  seriesTooltipOptions = series.tooltipOptions,
12104
- valueDecimals = seriesTooltipOptions.valueDecimals,
12120
+ valueDecimals = pick(seriesTooltipOptions.valueDecimals, ''),
12105
12121
  valuePrefix = seriesTooltipOptions.valuePrefix || '',
12106
12122
  valueSuffix = seriesTooltipOptions.valueSuffix || '';
12107
12123
 
@@ -12111,9 +12127,7 @@ Point.prototype = {
12111
12127
  if (valuePrefix || valueSuffix) {
12112
12128
  pointFormat = pointFormat.replace(key + '}', valuePrefix + key + '}' + valueSuffix);
12113
12129
  }
12114
- if (isNumber(valueDecimals)) {
12115
- pointFormat = pointFormat.replace(key + '}', key + ':,.' + valueDecimals + 'f}');
12116
- }
12130
+ pointFormat = pointFormat.replace(key + '}', key + ':,.' + valueDecimals + 'f}');
12117
12131
  });
12118
12132
 
12119
12133
  return format(pointFormat, {
@@ -12452,7 +12466,7 @@ Series.prototype = {
12452
12466
  });
12453
12467
 
12454
12468
  // Linked series
12455
- linkedTo = options.linkedTo; // docs: ':previous' or Series.id - set up demo with linked temperature range and mean temperature
12469
+ linkedTo = options.linkedTo;
12456
12470
  series.linkedSeries = [];
12457
12471
  if (isString(linkedTo)) {
12458
12472
  if (linkedTo === ':previous') {
@@ -12488,7 +12502,7 @@ Series.prototype = {
12488
12502
  // apply if the series xAxis or yAxis option mathches the number of the
12489
12503
  // axis, or if undefined, use the first axis
12490
12504
  if ((seriesOptions[AXIS] === axisOptions.index) ||
12491
- (seriesOptions[AXIS] !== UNDEFINED && seriesOptions[AXIS] === axisOptions.id) || // docs: series.xAxis and series.yAxis can point to axis.id
12505
+ (seriesOptions[AXIS] !== UNDEFINED && seriesOptions[AXIS] === axisOptions.id) ||
12492
12506
  (seriesOptions[AXIS] === UNDEFINED && axisOptions.index === 0)) {
12493
12507
 
12494
12508
  // register this series in the axis.series lookup
@@ -13602,7 +13616,7 @@ Series.prototype = {
13602
13616
  normalOptions.radius = 0;
13603
13617
  }
13604
13618
 
13605
- if (point.negative) {
13619
+ if (point.negative && negativeColor) {
13606
13620
  point.color = point.fillColor = negativeColor;
13607
13621
  }
13608
13622
 
@@ -13673,7 +13687,7 @@ Series.prototype = {
13673
13687
 
13674
13688
  },
13675
13689
  /**
13676
- * Update the series with a new set of options // docs (demo: members/series-update)
13690
+ * Update the series with a new set of options
13677
13691
  */
13678
13692
  update: function (newOptions, redraw) {
13679
13693
  var chart = this.chart,
@@ -13836,7 +13850,7 @@ Series.prototype = {
13836
13850
 
13837
13851
  // Get the string
13838
13852
  labelConfig = point.getLabelConfig();
13839
- str = options.format ? // docs
13853
+ str = options.format ?
13840
13854
  format(options.format, labelConfig) :
13841
13855
  options.formatter.call(labelConfig, options);
13842
13856
 
@@ -14216,7 +14230,9 @@ Series.prototype = {
14216
14230
  // Place it on first and subsequent (redraw) calls
14217
14231
  group[isNew ? 'attr' : 'animate']({
14218
14232
  translateX: xAxis ? xAxis.left : chart.plotLeft,
14219
- translateY: yAxis ? yAxis.top : chart.plotTop
14233
+ translateY: yAxis ? yAxis.top : chart.plotTop,
14234
+ scaleX: 1, // #1623
14235
+ scaleY: 1
14220
14236
  });
14221
14237
 
14222
14238
  return group;
@@ -14234,7 +14250,7 @@ Series.prototype = {
14234
14250
  animation = options.animation,
14235
14251
  doAnimation = animation && !!series.animate &&
14236
14252
  chart.renderer.isSVG, // this animation doesn't work in IE8 quirks when the group div is hidden,
14237
- // and looks bad in other oldIE // docs
14253
+ // and looks bad in other oldIE
14238
14254
  visibility = series.visible ? VISIBLE : HIDDEN,
14239
14255
  zIndex = options.zIndex,
14240
14256
  hasRendered = series.hasRendered,
@@ -14590,7 +14606,11 @@ var AreaSeries = extendClass(Series, {
14590
14606
  */
14591
14607
  getSegments: function () {
14592
14608
  var segments = [],
14593
- stack = this.yAxis.stacks[this.stackKey],
14609
+ segment = [],
14610
+ keys = [],
14611
+ xAxis = this.xAxis,
14612
+ yAxis = this.yAxis,
14613
+ stack = yAxis.stacks[this.stackKey],
14594
14614
  pointMap = {},
14595
14615
  plotX,
14596
14616
  plotY,
@@ -14604,19 +14624,26 @@ var AreaSeries = extendClass(Series, {
14604
14624
  pointMap[points[i].x] = points[i];
14605
14625
  }
14606
14626
 
14627
+ // Sort the keys (#1651)
14607
14628
  for (x in stack) {
14629
+ keys.push(+x);
14630
+ }
14631
+ keys.sort(function (a, b) {
14632
+ return a - b;
14633
+ });
14608
14634
 
14635
+ each(keys, function (x) {
14609
14636
  // The point exists, push it to the segment
14610
14637
  if (pointMap[x]) {
14611
- segments.push(pointMap[x]);
14638
+ segment.push(pointMap[x]);
14612
14639
 
14613
14640
  // There is no point for this X value in this series, so we
14614
14641
  // insert a dummy point in order for the areas to be drawn
14615
14642
  // correctly.
14616
14643
  } else {
14617
- plotX = this.xAxis.translate(x);
14618
- plotY = this.yAxis.toPixels(stack[x].cum, true);
14619
- segments.push({
14644
+ plotX = xAxis.translate(x);
14645
+ plotY = yAxis.toPixels(stack[x].cum, true);
14646
+ segment.push({
14620
14647
  y: null,
14621
14648
  plotX: plotX,
14622
14649
  clientX: plotX,
@@ -14625,8 +14652,11 @@ var AreaSeries = extendClass(Series, {
14625
14652
  onMouseOver: noop
14626
14653
  });
14627
14654
  }
14655
+ });
14656
+
14657
+ if (segment.length) {
14658
+ segments.push(segment);
14628
14659
  }
14629
- segments = [segments];
14630
14660
 
14631
14661
  } else {
14632
14662
  Series.prototype.getSegments.call(this);
@@ -15212,7 +15242,7 @@ var ColumnSeries = extendClass(Series, {
15212
15242
  inverted = chart.inverted,
15213
15243
  dlBox = point.dlBox || point.shapeArgs, // data label box for alignment
15214
15244
  below = point.below || (point.plotY > pick(this.translatedThreshold, chart.plotSizeY)),
15215
- inside = pick(options.inside, !!this.options.stacking); // draw it inside the box? // docs: inside
15245
+ inside = pick(options.inside, !!this.options.stacking); // draw it inside the box?
15216
15246
 
15217
15247
  // Align to the column itself, or the top of it
15218
15248
  if (dlBox) { // Area range uses this method but not alignTo
@@ -15266,7 +15296,7 @@ var ColumnSeries = extendClass(Series, {
15266
15296
  attr = {},
15267
15297
  translatedThreshold;
15268
15298
 
15269
- if (hasSVG) { // VML is too slow anyway // docs
15299
+ if (hasSVG) { // VML is too slow anyway
15270
15300
  if (init) {
15271
15301
  attr.scaleY = 0.001;
15272
15302
  translatedThreshold = mathMin(yAxis.pos + yAxis.len, mathMax(yAxis.pos, yAxis.toPixels(options.threshold)));
@@ -15331,9 +15361,9 @@ defaultPlotOptions.scatter = merge(defaultSeriesOptions, {
15331
15361
  tooltip: {
15332
15362
  headerFormat: '<span style="font-size: 10px; color:{series.color}">{series.name}</span><br/>',
15333
15363
  pointFormat: 'x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>',
15334
- followPointer: true // docs
15364
+ followPointer: true
15335
15365
  },
15336
- stickyTracking: false // docs: new default
15366
+ stickyTracking: false
15337
15367
  });
15338
15368
 
15339
15369
  /**
@@ -15358,7 +15388,8 @@ seriesTypes.scatter = ScatterSeries;
15358
15388
  defaultPlotOptions.pie = merge(defaultSeriesOptions, {
15359
15389
  borderColor: '#FFFFFF',
15360
15390
  borderWidth: 1,
15361
- center: [null, null],//['50%', '50%'], // docs: new default
15391
+ center: [null, null],
15392
+ clip: false,
15362
15393
  colorByPoint: true, // always true for pies
15363
15394
  dataLabels: {
15364
15395
  // align: null,
@@ -15373,11 +15404,11 @@ defaultPlotOptions.pie = merge(defaultSeriesOptions, {
15373
15404
  // softConnector: true,
15374
15405
  //y: 0
15375
15406
  },
15376
- ignoreHiddenPoint: true, // docs: new default
15407
+ ignoreHiddenPoint: true,
15377
15408
  //innerSize: 0,
15378
15409
  legendType: 'point',
15379
15410
  marker: null, // point options are specified in the base options
15380
- size: null,//'75%', // docs: new default
15411
+ size: null,
15381
15412
  showInLegend: false,
15382
15413
  slicedOffset: 10,
15383
15414
  states: {
@@ -15386,9 +15417,9 @@ defaultPlotOptions.pie = merge(defaultSeriesOptions, {
15386
15417
  shadow: false
15387
15418
  }
15388
15419
  },
15389
- stickyTracking: false, // docs
15420
+ stickyTracking: false,
15390
15421
  tooltip: {
15391
- followPointer: true // docs
15422
+ followPointer: true
15392
15423
  }
15393
15424
  });
15394
15425
 
@@ -15573,7 +15604,8 @@ var PieSeries = {
15573
15604
 
15574
15605
  var options = this.options,
15575
15606
  chart = this.chart,
15576
- slicingRoom = 2 * (options.dataLabels && options.dataLabels.enabled ? 0 : (options.slicedOffset || 0)),
15607
+ slicingRoom = 2 * (options.slicedOffset || 0),
15608
+ handleSlicingRoom,
15577
15609
  plotWidth = chart.plotWidth - 2 * slicingRoom,
15578
15610
  plotHeight = chart.plotHeight - 2 * slicingRoom,
15579
15611
  centerOption = options.center,
@@ -15583,6 +15615,7 @@ var PieSeries = {
15583
15615
 
15584
15616
  return map(positions, function (length, i) {
15585
15617
  isPercent = /%$/.test(length);
15618
+ handleSlicingRoom = i < 2 || (i === 2 && isPercent);
15586
15619
  return (isPercent ?
15587
15620
  // i == 0: centerX, relative to width
15588
15621
  // i == 1: centerY, relative to height
@@ -15590,7 +15623,7 @@ var PieSeries = {
15590
15623
  // i == 4: innerSize, relative to smallestSize
15591
15624
  [plotWidth, plotHeight, smallestSize, smallestSize][i] *
15592
15625
  pInt(length) / 100 :
15593
- length) + (i < 3 ? slicingRoom : 0);
15626
+ length) + (handleSlicingRoom ? slicingRoom : 0);
15594
15627
  });
15595
15628
  },
15596
15629
 
@@ -15691,6 +15724,7 @@ var PieSeries = {
15691
15724
  point.angle = angle;
15692
15725
 
15693
15726
  // set the anchor point for data labels
15727
+ connectorOffset = mathMin(connectorOffset, labelDistance / 2); // #1678
15694
15728
  point.labelPos = [
15695
15729
  positions[0] + radiusX + mathCos(angle) * labelDistance, // first break of connector
15696
15730
  positions[1] + radiusY + mathSin(angle) * labelDistance, // a/a
@@ -16099,7 +16133,7 @@ var PieSeries = {
16099
16133
 
16100
16134
  // Handle horizontal size and center
16101
16135
  if (centerOption[0] !== null) { // Fixed center
16102
- newSize = mathMax(center[2] - mathMax(overflow[1], overflow[3]), minSize); // docs: minSize
16136
+ newSize = mathMax(center[2] - mathMax(overflow[1], overflow[3]), minSize);
16103
16137
 
16104
16138
  } else { // Auto center
16105
16139
  newSize = mathMax(
@@ -16111,7 +16145,7 @@ var PieSeries = {
16111
16145
 
16112
16146
  // Handle vertical size and center
16113
16147
  if (centerOption[1] !== null) { // Fixed center
16114
- newSize = mathMax(mathMin(newSize, center[2] - mathMax(overflow[0], overflow[2])), minSize); // docs: minSize
16148
+ newSize = mathMax(mathMin(newSize, center[2] - mathMax(overflow[0], overflow[2])), minSize);
16115
16149
 
16116
16150
  } else { // Auto center
16117
16151
  newSize = mathMax(