highcharts-rails 3.0.0 → 3.0.1

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.
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(