highcharts-js-rails 0.1.5 → 0.1.6

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/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## v0.1.6 (2012-05-16) ##
2
+
3
+ * Update Highcharts to 2.2.3.
4
+
1
5
  ## v0.1.5 (2012-04-30) ##
2
6
 
3
7
  * Update Highcharts to 2.2.2.
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'highcharts-js-rails'
6
- s.version = '0.1.5'
6
+ s.version = '0.1.6'
7
7
  s.authors = ['Alex Robbin']
8
8
  s.email = ['agrobbin@gmail.com']
9
9
  s.homepage = 'https://github.com/agrobbin/highcharts-js-rails'
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license @product.name@ JS v@product.version@ (@product.date@)
2
+ * @license Highcharts JS v2.2.3 (2012-05-07)
3
3
  * MooTools adapter
4
4
  *
5
5
  * (c) 2010-2011 Torstein Hønsi
@@ -284,7 +284,7 @@ win.HighchartsAdapter = {
284
284
  defaultFunction(event);
285
285
  }
286
286
  },
287
-
287
+
288
288
  /**
289
289
  * Set back e.pageX and e.pageY that MooTools has abstracted away
290
290
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license @product.name@ JS v@product.version@ (@product.date@)
2
+ * @license Highcharts JS v2.2.3 (2012-05-07)
3
3
  * Prototype adapter
4
4
  *
5
5
  * @author Michael Nelson, Torstein Hønsi.
@@ -84,13 +84,13 @@ return {
84
84
 
85
85
  if (element.attr) { // SVGElement
86
86
  element.attr(this.options.attribute, position);
87
-
87
+
88
88
  } else { // HTML, #409
89
89
  obj = {};
90
90
  obj[this.options.attribute] = position;
91
91
  $(element).setStyle(obj);
92
92
  }
93
-
93
+
94
94
  },
95
95
  finish: function () {
96
96
  // Delete the property that holds this animation now that it is finished.
@@ -229,7 +229,7 @@ return {
229
229
  el._highcharts_stop_observing(event, handler);
230
230
  }
231
231
  },
232
-
232
+
233
233
  washMouseEvent: function (e) {
234
234
  return e;
235
235
  },
@@ -2,7 +2,7 @@
2
2
  // @compilation_level SIMPLE_OPTIMIZATIONS
3
3
 
4
4
  /**
5
- * @license Highcharts JS v2.2.2 (2012-04-26)
5
+ * @license Highcharts JS v2.2.3 (2012-05-07)
6
6
  *
7
7
  * (c) 2009-2011 Torstein Hønsi
8
8
  *
@@ -498,10 +498,10 @@ function normalizeTickInterval(interval, multiples, magnitude, options) {
498
498
 
499
499
  /**
500
500
  * Get a normalized tick interval for dates. Returns a configuration object with
501
- * unit range (interval), count and name. Used to prepare data for getTimeTicks.
501
+ * unit range (interval), count and name. Used to prepare data for getTimeTicks.
502
502
  * Previously this logic was part of getTimeTicks, but as getTimeTicks now runs
503
- * of segments in stock charts, the normalizing logic was extracted in order to
504
- * prevent it for running over again for each segment having the same interval.
503
+ * of segments in stock charts, the normalizing logic was extracted in order to
504
+ * prevent it for running over again for each segment having the same interval.
505
505
  * #662, #697.
506
506
  */
507
507
  function normalizeTimeTickInterval(tickInterval, unitsOption) {
@@ -535,7 +535,7 @@ function normalizeTimeTickInterval(tickInterval, unitsOption) {
535
535
  multiples = unit[1],
536
536
  count,
537
537
  i;
538
-
538
+
539
539
  // loop through the units to find the one that best fits the tickInterval
540
540
  for (i = 0; i < units.length; i++) {
541
541
  unit = units[i];
@@ -559,7 +559,7 @@ function normalizeTimeTickInterval(tickInterval, unitsOption) {
559
559
  if (interval === timeUnits[YEAR] && tickInterval < 5 * interval) {
560
560
  multiples = [1, 2, 5];
561
561
  }
562
-
562
+
563
563
  // prevent 2.5 years intervals, though 25, 250 etc. are allowed
564
564
  if (interval === timeUnits[YEAR] && tickInterval < 5 * interval) {
565
565
  multiples = [1, 2, 5];
@@ -567,7 +567,7 @@ function normalizeTimeTickInterval(tickInterval, unitsOption) {
567
567
 
568
568
  // get the count
569
569
  count = normalizeTickInterval(tickInterval / interval, multiples);
570
-
570
+
571
571
  return {
572
572
  unitRange: interval,
573
573
  count: count,
@@ -596,7 +596,7 @@ function getTimeTicks(normalizedInterval, min, max, startOfWeek) {
596
596
  interval = normalizedInterval.unitRange,
597
597
  count = normalizedInterval.count;
598
598
 
599
-
599
+
600
600
 
601
601
  if (interval >= timeUnits[SECOND]) { // second
602
602
  minDate.setMilliseconds(0);
@@ -666,7 +666,7 @@ function getTimeTicks(normalizedInterval, min, max, startOfWeek) {
666
666
  // else, the interval is fixed and we use simple addition
667
667
  } else {
668
668
  time += interval * count;
669
-
669
+
670
670
  // mark new days if the time is dividable by day
671
671
  if (interval <= timeUnits[HOUR] && time % timeUnits[DAY] === 0) {
672
672
  higherRanks[time] = DAY;
@@ -675,7 +675,7 @@ function getTimeTicks(normalizedInterval, min, max, startOfWeek) {
675
675
 
676
676
  i++;
677
677
  }
678
-
678
+
679
679
  // push the last time
680
680
  tickPositions.push(time);
681
681
 
@@ -721,7 +721,7 @@ ChartCounters.prototype = {
721
721
  * and not covering the point it self.
722
722
  */
723
723
  function placeBox(boxWidth, boxHeight, outerLeft, outerTop, outerWidth, outerHeight, point, distance, preferRight) {
724
-
724
+
725
725
  // keep the box within the chart area
726
726
  var pointX = point.x,
727
727
  pointY = point.y,
@@ -750,14 +750,14 @@ function placeBox(boxWidth, boxHeight, outerLeft, outerTop, outerWidth, outerHei
750
750
  if (alignedRight && pointY >= y && pointY <= (y + boxHeight)) {
751
751
  y = pointY + outerTop + distance; // below
752
752
  }
753
- }
753
+ }
754
754
 
755
755
  // Now if the tooltip is below the chart, move it up. It's better to cover the
756
756
  // point than to disappear outside the chart. #834.
757
757
  if (y + boxHeight > outerTop + outerHeight) {
758
758
  y = outerTop + outerHeight - boxHeight - distance; // below
759
759
  }
760
-
760
+
761
761
 
762
762
  return {x: x, y: y};
763
763
  }
@@ -859,7 +859,7 @@ function discardElement(element) {
859
859
  }
860
860
 
861
861
  /**
862
- * Provide error messages for debugging, with links to online explanation
862
+ * Provide error messages for debugging, with links to online explanation
863
863
  */
864
864
  function error(code, stop) {
865
865
  var msg = 'Highcharts error #' + code + ': www.highcharts.com/errors/' + code;
@@ -1151,7 +1151,7 @@ if (!globalAdapter && win.jQuery) {
1151
1151
  defaultFunction(event);
1152
1152
  }
1153
1153
  };
1154
-
1154
+
1155
1155
  /**
1156
1156
  * Extension method needed for MooTools
1157
1157
  */
@@ -1284,7 +1284,7 @@ defaultOptions = {
1284
1284
  },
1285
1285
  global: {
1286
1286
  useUTC: true,
1287
- canvasToolsURL: 'http://code.highcharts.com/2.2.2/modules/canvas-tools.js'
1287
+ canvasToolsURL: 'http://code.highcharts.com/2.2.3/modules/canvas-tools.js'
1288
1288
  },
1289
1289
  chart: {
1290
1290
  //animation: true,
@@ -1432,7 +1432,7 @@ defaultOptions = {
1432
1432
  //valueDecimals: null,
1433
1433
  //xDateFormat: '%A, %b %e, %Y',
1434
1434
  //valuePrefix: '',
1435
- //ySuffix: ''
1435
+ //ySuffix: ''
1436
1436
  //}
1437
1437
  // turboThreshold: 1000
1438
1438
  // zIndex: null
@@ -1845,15 +1845,15 @@ function setTimeMethods() {
1845
1845
  * @param {Object} options The new custom options
1846
1846
  */
1847
1847
  function setOptions(options) {
1848
-
1849
- // Pull out axis options and apply them to the respective default axis options
1848
+
1849
+ // Pull out axis options and apply them to the respective default axis options
1850
1850
  defaultXAxisOptions = merge(defaultXAxisOptions, options.xAxis);
1851
1851
  defaultYAxisOptions = merge(defaultYAxisOptions, options.yAxis);
1852
1852
  options.xAxis = options.yAxis = UNDEFINED;
1853
-
1853
+
1854
1854
  // Merge in the default options
1855
1855
  defaultOptions = merge(defaultOptions, options);
1856
-
1856
+
1857
1857
  // Apply UTC
1858
1858
  setTimeMethods();
1859
1859
 
@@ -2218,14 +2218,14 @@ SVGElement.prototype = {
2218
2218
  }
2219
2219
 
2220
2220
  }
2221
-
2221
+
2222
2222
  // Workaround for our #732, WebKit's issue https://bugs.webkit.org/show_bug.cgi?id=78385
2223
2223
  // TODO: If the WebKit team fix this bug before the final release of Chrome 18, remove the workaround.
2224
2224
  if (isWebKit && /Chrome\/(18|19)/.test(userAgent)) {
2225
2225
  if (nodeName === 'text' && (hash.x !== UNDEFINED || hash.y !== UNDEFINED)) {
2226
2226
  var parent = element.parentNode,
2227
2227
  next = element.nextSibling;
2228
-
2228
+
2229
2229
  if (parent) {
2230
2230
  parent.removeChild(element);
2231
2231
  if (next) {
@@ -2237,7 +2237,7 @@ SVGElement.prototype = {
2237
2237
  }
2238
2238
  }
2239
2239
  // End of workaround for #732
2240
-
2240
+
2241
2241
  return ret;
2242
2242
  },
2243
2243
 
@@ -2696,7 +2696,7 @@ SVGElement.prototype = {
2696
2696
  // SVG elements
2697
2697
  if (element.namespaceURI === SVG_NS) {
2698
2698
  try { // Fails in Firefox if the container has display: none.
2699
-
2699
+
2700
2700
  bBox = element.getBBox ?
2701
2701
  // SVG: use extend because IE9 is not allowed to change width and height in case
2702
2702
  // of rotation (below)
@@ -2707,13 +2707,13 @@ SVGElement.prototype = {
2707
2707
  height: element.offsetHeight
2708
2708
  };
2709
2709
  } catch (e) {}
2710
-
2710
+
2711
2711
  // If the bBox is not set, the try-catch block above failed. The other condition
2712
2712
  // is for Opera that returns a width of -Infinity on hidden elements.
2713
2713
  if (!bBox || bBox.width < 0) {
2714
2714
  bBox = { width: 0, height: 0 };
2715
2715
  }
2716
-
2716
+
2717
2717
  width = bBox.width;
2718
2718
  height = bBox.height;
2719
2719
 
@@ -2969,8 +2969,8 @@ SVGRenderer.prototype = {
2969
2969
  renderer.gradients = {}; // Object where gradient SvgElements are stored
2970
2970
 
2971
2971
  renderer.setSize(width, height, false);
2972
-
2973
-
2972
+
2973
+
2974
2974
 
2975
2975
  // Issue 110 workaround:
2976
2976
  // In Firefox, if a div is positioned by percentage, its pixel position may land
@@ -2988,7 +2988,7 @@ SVGRenderer.prototype = {
2988
2988
  top: (-(rect.top - pInt(rect.top))) + PX
2989
2989
  });
2990
2990
  };
2991
-
2991
+
2992
2992
  // run the fix now
2993
2993
  subPixelFix();
2994
2994
 
@@ -3015,7 +3015,7 @@ SVGRenderer.prototype = {
3015
3015
  if (rendererDefs) {
3016
3016
  renderer.defs = rendererDefs.destroy();
3017
3017
  }
3018
-
3018
+
3019
3019
  // Remove sub pixel fix handler
3020
3020
  removeEvent(win, 'resize', renderer.subPixelFix);
3021
3021
 
@@ -3063,13 +3063,13 @@ SVGRenderer.prototype = {
3063
3063
  GET_COMPUTED_STYLE = 'getComputedStyle',
3064
3064
  i = childNodes.length,
3065
3065
  linePositions = [];
3066
-
3066
+
3067
3067
  // Needed in IE9 because it doesn't report tspan's offsetHeight (#893)
3068
3068
  function getLineHeightByBBox(lineNo) {
3069
3069
  linePositions[lineNo] = textNode.getBBox().height;
3070
3070
  return mathRound(linePositions[lineNo] - (linePositions[lineNo - 1] || 0));
3071
3071
  }
3072
-
3072
+
3073
3073
  // remove old text
3074
3074
  while (i--) {
3075
3075
  textNode.removeChild(childNodes[i]);
@@ -3535,7 +3535,7 @@ SVGRenderer.prototype = {
3535
3535
  width: size[0],
3536
3536
  height: size[1]
3537
3537
  });
3538
-
3538
+
3539
3539
  if (!img.alignByTranslate) { // #185
3540
3540
  img.translate(
3541
3541
  -mathRound(size[0] / 2),
@@ -3925,14 +3925,14 @@ SVGRenderer.prototype = {
3925
3925
  */
3926
3926
  fontMetrics: function (fontSize) {
3927
3927
  fontSize = pInt(fontSize || 11);
3928
-
3928
+
3929
3929
  // Empirical values found by comparing font size and bounding box height.
3930
3930
  // Applies to the default font family. http://jsfiddle.net/highcharts/7xvn7/
3931
3931
  var lineHeight = fontSize < 24 ? fontSize + 4 : mathRound(fontSize * 1.2),
3932
3932
  baseline = mathRound(lineHeight * 0.8);
3933
-
3933
+
3934
3934
  return {
3935
- h: lineHeight,
3935
+ h: lineHeight,
3936
3936
  b: baseline
3937
3937
  };
3938
3938
  },
@@ -3948,8 +3948,8 @@ SVGRenderer.prototype = {
3948
3948
  * coordinates it should be pinned to
3949
3949
  * @param {Number} anchorY
3950
3950
  * @param {Boolean} baseline Whether to position the label relative to the text baseline,
3951
- * like renderer.text, or to the upper border of the rectangle.
3952
- * @param {String} className Class name for the group
3951
+ * like renderer.text, or to the upper border of the rectangle.
3952
+ * @param {String} className Class name for the group
3953
3953
  */
3954
3954
  label: function (str, x, y, shape, anchorX, anchorY, useHTML, baseline, className) {
3955
3955
 
@@ -3981,20 +3981,20 @@ SVGRenderer.prototype = {
3981
3981
  function updateBoxSize() {
3982
3982
  var boxY,
3983
3983
  style = text.element.style;
3984
-
3984
+
3985
3985
  bBox = (width === undefined || height === undefined || wrapper.styles.textAlign) &&
3986
3986
  text.getBBox(true);
3987
3987
  wrapper.width = (width || bBox.width || 0) + 2 * padding;
3988
3988
  wrapper.height = (height || bBox.height || 0) + 2 * padding;
3989
-
3989
+
3990
3990
  // update the label-scoped y offset
3991
3991
  baselineOffset = padding + renderer.fontMetrics(style && style.fontSize).b;
3992
-
3993
-
3992
+
3993
+
3994
3994
  // create the border box if it is not already present
3995
3995
  if (!box) {
3996
3996
  boxY = baseline ? -baselineOffset : 0;
3997
-
3997
+
3998
3998
  wrapper.box = box = shape ?
3999
3999
  renderer.symbol(shape, -alignFactor * padding, boxY, wrapper.width, wrapper.height) :
4000
4000
  renderer.rect(-alignFactor * padding, boxY, wrapper.width, wrapper.height, 0, deferredAttr[STROKE_WIDTH]);
@@ -4017,7 +4017,7 @@ SVGRenderer.prototype = {
4017
4017
  textAlign = styles && styles.textAlign,
4018
4018
  x = padding * (1 - alignFactor),
4019
4019
  y;
4020
-
4020
+
4021
4021
  // determin y based on the baseline
4022
4022
  y = baseline ? 0 : baselineOffset;
4023
4023
 
@@ -4095,7 +4095,7 @@ SVGRenderer.prototype = {
4095
4095
  alignFactor = { left: 0, center: 0.5, right: 1 }[value];
4096
4096
  return false; // prevent setting text-anchor on the group
4097
4097
  };
4098
-
4098
+
4099
4099
  // apply these to the box and the text alike
4100
4100
  attrSetters.text = function (value, key) {
4101
4101
  text.attr(key, value);
@@ -4124,13 +4124,13 @@ SVGRenderer.prototype = {
4124
4124
  boxAttr(key, value - wrapperY);
4125
4125
  return false;
4126
4126
  };
4127
-
4127
+
4128
4128
  // rename attributes
4129
4129
  attrSetters.x = function (value) {
4130
4130
  wrapper.x = value; // for animation getter
4131
4131
  value -= alignFactor * ((width || bBox.width) + padding);
4132
- wrapperX = mathRound(value);
4133
-
4132
+ wrapperX = mathRound(value);
4133
+
4134
4134
  wrapper.attr('translateX', wrapperX);
4135
4135
  return false;
4136
4136
  };
@@ -4301,12 +4301,12 @@ var VMLElement = {
4301
4301
  toggleChildren: function (element, visibility) {
4302
4302
  var childNodes = element.childNodes,
4303
4303
  i = childNodes.length;
4304
-
4304
+
4305
4305
  while (i--) {
4306
-
4306
+
4307
4307
  // apply the visibility
4308
4308
  css(childNodes[i], { visibility: visibility });
4309
-
4309
+
4310
4310
  // we have a nested group, apply it to its children again
4311
4311
  if (childNodes[i].nodeName === 'DIV') {
4312
4312
  this.toggleChildren(childNodes[i], visibility);
@@ -4439,9 +4439,9 @@ var VMLElement = {
4439
4439
 
4440
4440
  // width and height
4441
4441
  } else if (key === 'width' || key === 'height') {
4442
-
4442
+
4443
4443
  value = mathMax(0, value); // don't set width or height below zero (#311)
4444
-
4444
+
4445
4445
  this[key] = value; // used in getter
4446
4446
 
4447
4447
  // clipping rectangle special
@@ -4556,12 +4556,12 @@ var VMLElement = {
4556
4556
  wrapper.destroyClip = function () {
4557
4557
  erase(clipMembers, wrapper);
4558
4558
  };
4559
-
4559
+
4560
4560
  // Issue #863 workaround - related to #140, #61, #74
4561
4561
  if (element.parentNode.className === 'highcharts-tracker' && !docMode8) {
4562
4562
  css(element, { visibility: HIDDEN });
4563
4563
  }
4564
-
4564
+
4565
4565
  return wrapper.css(clipRect.getCSS(wrapper.inverted));
4566
4566
  },
4567
4567
 
@@ -4775,7 +4775,7 @@ var VMLRendererExtension = { // inherit SVGRenderer
4775
4775
  height: bottom + PX
4776
4776
  });
4777
4777
  }
4778
-
4778
+
4779
4779
  return ret;
4780
4780
  },
4781
4781
 
@@ -4842,15 +4842,15 @@ var VMLRendererExtension = { // inherit SVGRenderer
4842
4842
  (y2 - y1) / // y vector
4843
4843
  (x2 - x1) // x vector
4844
4844
  ) * 180 / mathPI;
4845
-
4846
-
4845
+
4846
+
4847
4847
  // when colors attribute is used, the meanings of opacity and o:opacity2
4848
4848
  // are reversed.
4849
4849
  markup = ['<fill colors="0% ', color1, ',100% ', color2, '" angle="', angle,
4850
4850
  '" opacity="', opacity2, '" o:opacity2="', opacity1,
4851
4851
  '" type="gradient" focus="100%" method="sigma" />'];
4852
4852
  createElement(this.prepVML(markup), null, null, elem);
4853
-
4853
+
4854
4854
  // Gradients are not supported for VML stroke, return the first color. #722.
4855
4855
  } else {
4856
4856
  return stopColor;
@@ -5245,7 +5245,7 @@ function Chart(userOptions, callback) {
5245
5245
  userOptions.series = null;
5246
5246
  options = merge(defaultOptions, userOptions); // do the merge
5247
5247
  options.series = userOptions.series = seriesOptions; // set back the series data
5248
-
5248
+
5249
5249
  var optionsChart = options.chart,
5250
5250
  optionsMargin = optionsChart.margin,
5251
5251
  margin = isObject(optionsMargin) ?
@@ -5524,7 +5524,7 @@ function Chart(userOptions, callback) {
5524
5524
  ((this.labelBBox = label.getBBox(true)))[horiz ? 'height' : 'width'] :
5525
5525
  0;
5526
5526
  },
5527
-
5527
+
5528
5528
  /**
5529
5529
  * Find how far the labels extend to the right and left of the tick's x position. Used for anti-collision
5530
5530
  * detection with overflow logic.
@@ -5534,10 +5534,10 @@ function Chart(userOptions, callback) {
5534
5534
  labelOptions = options.labels,
5535
5535
  width = bBox.width,
5536
5536
  leftSide = width * { left: 0, center: 0.5, right: 1 }[labelOptions.align] - labelOptions.x;
5537
-
5538
- return [-leftSide, width - leftSide];
5537
+
5538
+ return [-leftSide, width - leftSide];
5539
5539
  },
5540
-
5540
+
5541
5541
  /**
5542
5542
  * Handle the label overflow by adjusting the labels to the left and right edge, or
5543
5543
  * hide them if they collide into the neighbour label.
@@ -5548,9 +5548,9 @@ function Chart(userOptions, callback) {
5548
5548
  isLast = this.isLast,
5549
5549
  label = this.label,
5550
5550
  x = label.x;
5551
-
5551
+
5552
5552
  if (isFirst || isLast) {
5553
-
5553
+
5554
5554
  var sides = this.getLabelSides(),
5555
5555
  leftSide = sides[0],
5556
5556
  rightSide = sides[1],
@@ -5558,41 +5558,41 @@ function Chart(userOptions, callback) {
5558
5558
  plotRight = plotLeft + axis.len,
5559
5559
  neighbour = ticks[tickPositions[index + (isFirst ? 1 : -1)]],
5560
5560
  neighbourEdge = neighbour && neighbour.label.x + neighbour.getLabelSides()[isFirst ? 0 : 1];
5561
-
5561
+
5562
5562
  if ((isFirst && !reversed) || (isLast && reversed)) {
5563
5563
  // Is the label spilling out to the left of the plot area?
5564
5564
  if (x + leftSide < plotLeft) {
5565
-
5565
+
5566
5566
  // Align it to plot left
5567
5567
  x = plotLeft - leftSide;
5568
-
5568
+
5569
5569
  // Hide it if it now overlaps the neighbour label
5570
5570
  if (neighbour && x + rightSide > neighbourEdge) {
5571
5571
  show = false;
5572
5572
  }
5573
5573
  }
5574
-
5574
+
5575
5575
  } else {
5576
5576
  // Is the label spilling out to the right of the plot area?
5577
5577
  if (x + rightSide > plotRight) {
5578
-
5578
+
5579
5579
  // Align it to plot right
5580
5580
  x = plotRight - rightSide;
5581
-
5581
+
5582
5582
  // Hide it if it now overlaps the neighbour label
5583
5583
  if (neighbour && x + leftSide < neighbourEdge) {
5584
5584
  show = false;
5585
5585
  }
5586
-
5586
+
5587
5587
  }
5588
5588
  }
5589
-
5589
+
5590
5590
  // Set the modified x position of the label
5591
5591
  label.x = x;
5592
5592
  }
5593
5593
  return show;
5594
5594
  },
5595
-
5595
+
5596
5596
  /**
5597
5597
  * Put everything in place
5598
5598
  *
@@ -5716,7 +5716,7 @@ function Chart(userOptions, callback) {
5716
5716
  if (staggerLines) {
5717
5717
  y += (index / (step || 1) % staggerLines) * 16;
5718
5718
  }
5719
-
5719
+
5720
5720
  // Cache x and y to be able to read final position before animation
5721
5721
  label.x = x;
5722
5722
  label.y = y;
@@ -5725,9 +5725,9 @@ function Chart(userOptions, callback) {
5725
5725
  if ((tick.isFirst && !pick(options.showFirstLabel, 1)) ||
5726
5726
  (tick.isLast && !pick(options.showLastLabel, 1))) {
5727
5727
  show = false;
5728
-
5728
+
5729
5729
  // Handle label overflow and show or hide accordingly
5730
- } else if (!staggerLines && horiz && labelOptions.overflow === 'justify' && !tick.handleOverflow(index)) {
5730
+ } else if (!staggerLines && horiz && labelOptions.overflow === 'justify' && !tick.handleOverflow(index)) {
5731
5731
  show = false;
5732
5732
  }
5733
5733
 
@@ -5736,7 +5736,7 @@ function Chart(userOptions, callback) {
5736
5736
  // show those indices dividable by step
5737
5737
  show = false;
5738
5738
  }
5739
-
5739
+
5740
5740
  // Set the new position, and show or hide
5741
5741
  if (show) {
5742
5742
  label[tick.isNew ? 'attr' : 'animate']({
@@ -5750,9 +5750,9 @@ function Chart(userOptions, callback) {
5750
5750
  }
5751
5751
  }
5752
5752
 
5753
-
5753
+
5754
5754
  },
5755
-
5755
+
5756
5756
  /**
5757
5757
  * Destructor for the tick prototype
5758
5758
  */
@@ -6067,7 +6067,7 @@ function Chart(userOptions, callback) {
6067
6067
  yDataLength,
6068
6068
  activeYData = [],
6069
6069
  activeCounter = 0;
6070
-
6070
+
6071
6071
  // Validate threshold in logarithmic axes
6072
6072
  if (isLog && threshold <= 0) {
6073
6073
  threshold = seriesOptions.threshold = null;
@@ -6218,7 +6218,7 @@ function Chart(userOptions, callback) {
6218
6218
  *
6219
6219
  */
6220
6220
  translate = function (val, backwards, cvsCoord, old, handleLog) {
6221
-
6221
+
6222
6222
  var sign = 1,
6223
6223
  cvsOffset = 0,
6224
6224
  localA = old ? oldTransA : transA,
@@ -6333,28 +6333,28 @@ function Chart(userOptions, callback) {
6333
6333
  }
6334
6334
  return tickPositions;
6335
6335
  }
6336
-
6336
+
6337
6337
  /**
6338
6338
  * Set the tick positions of a logarithmic axis
6339
6339
  */
6340
6340
  function getLogTickPositions(interval, min, max, minor) {
6341
-
6341
+
6342
6342
  // Since we use this method for both major and minor ticks,
6343
6343
  // use a local variable and return the result
6344
- var positions = [];
6345
-
6344
+ var positions = [];
6345
+
6346
6346
  // Reset
6347
6347
  if (!minor) {
6348
6348
  axis._minorAutoInterval = null;
6349
6349
  }
6350
-
6350
+
6351
6351
  // First case: All ticks fall on whole logarithms: 1, 10, 100 etc.
6352
6352
  if (interval >= 0.5) {
6353
6353
  interval = mathRound(interval);
6354
6354
  positions = getLinearTickPositions(interval, min, max);
6355
-
6356
- // Second case: We need intermediary ticks. For example
6357
- // 1, 2, 4, 6, 8, 10, 20, 40 etc.
6355
+
6356
+ // Second case: We need intermediary ticks. For example
6357
+ // 1, 2, 4, 6, 8, 10, 20, 40 etc.
6358
6358
  } else if (interval >= 0.08) {
6359
6359
  var roundedMin = mathFloor(min),
6360
6360
  intermediate,
@@ -6364,7 +6364,7 @@ function Chart(userOptions, callback) {
6364
6364
  pos,
6365
6365
  lastPos,
6366
6366
  break2;
6367
-
6367
+
6368
6368
  if (interval > 0.3) {
6369
6369
  intermediate = [1, 2, 4];
6370
6370
  } else if (interval > 0.15) { // 0.2 equals five minor ticks per 1, 10, 100 etc
@@ -6372,23 +6372,23 @@ function Chart(userOptions, callback) {
6372
6372
  } else { // 0.1 equals ten minor ticks per 1, 10, 100 etc
6373
6373
  intermediate = [1, 2, 3, 4, 5, 6, 7, 8, 9];
6374
6374
  }
6375
-
6375
+
6376
6376
  for (i = roundedMin; i < max + 1 && !break2; i++) {
6377
6377
  len = intermediate.length;
6378
6378
  for (j = 0; j < len && !break2; j++) {
6379
6379
  pos = log2lin(lin2log(i) * intermediate[j]);
6380
-
6380
+
6381
6381
  if (pos > min) {
6382
6382
  positions.push(lastPos);
6383
6383
  }
6384
-
6384
+
6385
6385
  if (lastPos > max) {
6386
6386
  break2 = true;
6387
6387
  }
6388
6388
  lastPos = pos;
6389
6389
  }
6390
6390
  }
6391
-
6391
+
6392
6392
  // Third case: We are so deep in between whole logarithmic values that
6393
6393
  // we might as well handle the tick positions like a linear axis. For
6394
6394
  // example 1.01, 1.02, 1.03, 1.04.
@@ -6399,37 +6399,37 @@ function Chart(userOptions, callback) {
6399
6399
  filteredTickIntervalOption = tickIntervalOption === 'auto' ? null : tickIntervalOption,
6400
6400
  tickPixelIntervalOption = options.tickPixelInterval / (minor ? 5 : 1),
6401
6401
  totalPixelLength = minor ? axisLength / tickPositions.length : axisLength;
6402
-
6402
+
6403
6403
  interval = pick(
6404
6404
  filteredTickIntervalOption,
6405
6405
  axis._minorAutoInterval,
6406
6406
  (realMax - realMin) * tickPixelIntervalOption / (totalPixelLength || 1)
6407
6407
  );
6408
-
6408
+
6409
6409
  interval = normalizeTickInterval(
6410
- interval,
6411
- null,
6410
+ interval,
6411
+ null,
6412
6412
  math.pow(10, mathFloor(math.log(interval) / math.LN10))
6413
6413
  );
6414
-
6414
+
6415
6415
  positions = map(getLinearTickPositions(
6416
- interval,
6416
+ interval,
6417
6417
  realMin,
6418
- realMax
6418
+ realMax
6419
6419
  ), log2lin);
6420
-
6420
+
6421
6421
  if (!minor) {
6422
6422
  axis._minorAutoInterval = interval / 5;
6423
6423
  }
6424
6424
  }
6425
-
6426
- // Set the axis-level tickInterval variable
6425
+
6426
+ // Set the axis-level tickInterval variable
6427
6427
  if (!minor) {
6428
6428
  tickInterval = interval;
6429
6429
  }
6430
6430
  return positions;
6431
6431
  }
6432
-
6432
+
6433
6433
  /**
6434
6434
  * Return the minor tick positions. For logarithmic axes, reuse the same logic
6435
6435
  * as for major ticks.
@@ -6439,27 +6439,27 @@ function Chart(userOptions, callback) {
6439
6439
  pos,
6440
6440
  i,
6441
6441
  len;
6442
-
6442
+
6443
6443
  if (isLog) {
6444
6444
  len = tickPositions.length;
6445
6445
  for (i = 1; i < len; i++) {
6446
6446
  minorTickPositions = minorTickPositions.concat(
6447
6447
  getLogTickPositions(minorTickInterval, tickPositions[i - 1], tickPositions[i], true)
6448
- );
6448
+ );
6449
6449
  }
6450
-
6451
- } else {
6450
+
6451
+ } else {
6452
6452
  for (pos = min + (tickPositions[0] - min) % minorTickInterval; pos <= max; pos += minorTickInterval) {
6453
- minorTickPositions.push(pos);
6453
+ minorTickPositions.push(pos);
6454
6454
  }
6455
6455
  }
6456
-
6456
+
6457
6457
  return minorTickPositions;
6458
6458
  }
6459
6459
 
6460
6460
  /**
6461
- * Adjust the min and max for the minimum range. Keep in mind that the series data is
6462
- * not yet processed, so we don't have information on data cropping and grouping, or
6461
+ * Adjust the min and max for the minimum range. Keep in mind that the series data is
6462
+ * not yet processed, so we don't have information on data cropping and grouping, or
6463
6463
  * updated axis.pointRange or series.pointRange. The data can't be processed until
6464
6464
  * we have finally established min and max.
6465
6465
  */
@@ -6473,10 +6473,10 @@ function Chart(userOptions, callback) {
6473
6473
  loopLength,
6474
6474
  minArgs,
6475
6475
  maxArgs;
6476
-
6476
+
6477
6477
  // Set the automatic minimum range based on the closest point distance
6478
6478
  if (isXAxis && minRange === UNDEFINED && !isLog) {
6479
-
6479
+
6480
6480
  if (defined(options.min) || defined(options.max)) {
6481
6481
  minRange = null; // don't do this again
6482
6482
 
@@ -6496,14 +6496,14 @@ function Chart(userOptions, callback) {
6496
6496
  });
6497
6497
  minRange = mathMin(closestDataRange * 5, dataMax - dataMin);
6498
6498
  }
6499
-
6499
+
6500
6500
  // A hook for resetting the minRange in series.setData (#878)
6501
6501
  // TODO: remove this in protofy, where xAxis.minRange can be set directly
6502
6502
  axis.setMinRange = function (newMinRange) {
6503
6503
  minRange = newMinRange;
6504
6504
  };
6505
6505
  }
6506
-
6506
+
6507
6507
  // if minRange is exceeded, adjust
6508
6508
  if (max - min < minRange) {
6509
6509
 
@@ -6520,7 +6520,7 @@ function Chart(userOptions, callback) {
6520
6520
  if (spaceAvailable) { // if space is availabe, stay within the data range
6521
6521
  maxArgs[2] = dataMax;
6522
6522
  }
6523
-
6523
+
6524
6524
  max = arrayMin(maxArgs);
6525
6525
 
6526
6526
  // now if the max is adjusted, adjust the min back
@@ -6604,10 +6604,10 @@ function Chart(userOptions, callback) {
6604
6604
  }
6605
6605
 
6606
6606
  // Now we're finished detecting min and max, crop and group series data. This
6607
- // is in turn needed in order to find tick positions in ordinal axes.
6607
+ // is in turn needed in order to find tick positions in ordinal axes.
6608
6608
  if (isXAxis && !secondPass) {
6609
6609
  each(axis.series, function (series) {
6610
- series.processData(min !== oldMin || max !== oldMax);
6610
+ series.processData(min !== oldMin || max !== oldMax);
6611
6611
  });
6612
6612
  }
6613
6613
 
@@ -6618,10 +6618,10 @@ function Chart(userOptions, callback) {
6618
6618
  if (axis.beforeSetTickPositions) {
6619
6619
  axis.beforeSetTickPositions();
6620
6620
  }
6621
-
6621
+
6622
6622
  // hook for extensions, used in Highstock ordinal axes
6623
6623
  if (axis.postProcessTickInterval) {
6624
- tickInterval = axis.postProcessTickInterval(tickInterval);
6624
+ tickInterval = axis.postProcessTickInterval(tickInterval);
6625
6625
  }
6626
6626
 
6627
6627
  // for linear axes, get magnitude and normalize the interval
@@ -6676,20 +6676,26 @@ function Chart(userOptions, callback) {
6676
6676
  } else if (max < roundedMax) {
6677
6677
  tickPositions.pop();
6678
6678
  }
6679
+ }
6680
+ }
6681
+
6682
+ /**
6683
+ * Set the max ticks of either the x and y axis collection. #840.
6684
+ */
6685
+ axis.setMaxTicks = function () {
6679
6686
 
6680
- // record the greatest number of ticks for multi axis
6681
- if (!maxTicks) { // first call, or maxTicks have been reset after a zoom operation
6682
- maxTicks = {
6683
- x: 0,
6684
- y: 0
6685
- };
6686
- }
6687
+ // record the greatest number of ticks for multi axis
6688
+ if (!maxTicks) { // first call, or maxTicks have been reset after a zoom operation
6689
+ maxTicks = {
6690
+ x: 0,
6691
+ y: 0
6692
+ };
6693
+ }
6687
6694
 
6688
- if (!isDatetimeAxis && tickPositions.length > maxTicks[xOrY] && options.alignTicks !== false) {
6689
- maxTicks[xOrY] = tickPositions.length;
6690
- }
6695
+ if (!isLinked && !isDatetimeAxis && tickPositions.length > maxTicks[xOrY] && options.alignTicks !== false) {
6696
+ maxTicks[xOrY] = tickPositions.length;
6691
6697
  }
6692
- }
6698
+ };
6693
6699
 
6694
6700
  /**
6695
6701
  * When using multiple axes, adjust the number of ticks to match the highest
@@ -6730,7 +6736,7 @@ function Chart(userOptions, callback) {
6730
6736
  i,
6731
6737
  isDirtyData,
6732
6738
  isDirtyAxisLength;
6733
-
6739
+
6734
6740
  oldMin = min;
6735
6741
  oldMax = max;
6736
6742
  oldAxisLength = axisLength;
@@ -6757,7 +6763,7 @@ function Chart(userOptions, callback) {
6757
6763
 
6758
6764
  // get fixed positions based on tickInterval
6759
6765
  setTickPositions();
6760
-
6766
+
6761
6767
  // record old values to decide whether a rescale is necessary later on (#540)
6762
6768
  oldUserMin = userMin;
6763
6769
  oldUserMax = userMax;
@@ -6776,6 +6782,8 @@ function Chart(userOptions, callback) {
6776
6782
  axis.isDirty = isDirtyAxisLength || min !== oldMin || max !== oldMax;
6777
6783
  }
6778
6784
  }
6785
+
6786
+ axis.setMaxTicks();
6779
6787
  }
6780
6788
 
6781
6789
  /**
@@ -6785,13 +6793,13 @@ function Chart(userOptions, callback) {
6785
6793
  * @param {Boolean} redraw
6786
6794
  * @param {Boolean|Object} animation Whether to apply animation, and optionally animation
6787
6795
  * configuration
6788
- * @param {Object} eventArguments
6796
+ * @param {Object} eventArguments
6789
6797
  *
6790
6798
  */
6791
6799
  function setExtremes(newMin, newMax, redraw, animation, eventArguments) {
6792
6800
 
6793
6801
  redraw = pick(redraw, true); // defaults to true
6794
-
6802
+
6795
6803
  // Extend the arguments with min and max
6796
6804
  eventArguments = extend(eventArguments, {
6797
6805
  min: newMin,
@@ -6803,17 +6811,17 @@ function Chart(userOptions, callback) {
6803
6811
 
6804
6812
  userMin = newMin;
6805
6813
  userMax = newMax;
6806
-
6814
+
6807
6815
  // Mark for running afterSetExtremes
6808
6816
  axis.isDirtyExtremes = true;
6809
-
6817
+
6810
6818
  // redraw
6811
6819
  if (redraw) {
6812
6820
  chart.redraw(animation);
6813
6821
  }
6814
6822
  });
6815
6823
  }
6816
-
6824
+
6817
6825
  /**
6818
6826
  * Update translation information
6819
6827
  */
@@ -6822,7 +6830,7 @@ function Chart(userOptions, callback) {
6822
6830
  pointRange = 0,
6823
6831
  closestPointRange,
6824
6832
  seriesClosestPointRange;
6825
-
6833
+
6826
6834
  // adjust translation for padding
6827
6835
  if (isXAxis) {
6828
6836
  if (isLinked) {
@@ -6838,7 +6846,7 @@ function Chart(userOptions, callback) {
6838
6846
  }
6839
6847
  });
6840
6848
  }
6841
-
6849
+
6842
6850
  // pointRange means the width reserved for each point, like in a column chart
6843
6851
  axis.pointRange = pointRange;
6844
6852
 
@@ -6900,7 +6908,7 @@ function Chart(userOptions, callback) {
6900
6908
  function getThreshold(threshold) {
6901
6909
  var realMin = isLog ? lin2log(min) : min,
6902
6910
  realMax = isLog ? lin2log(max) : max;
6903
-
6911
+
6904
6912
  if (realMin > threshold || threshold === null) {
6905
6913
  threshold = realMin;
6906
6914
  } else if (realMax < threshold) {
@@ -7071,10 +7079,10 @@ function Chart(userOptions, callback) {
7071
7079
  // Major ticks. Pull out the first item and render it last so that
7072
7080
  // we can get the position of the neighbour label. #808.
7073
7081
  each(tickPositions.slice(1).concat([tickPositions[0]]), function (pos, i) {
7074
-
7082
+
7075
7083
  // Reorganize the indices
7076
7084
  i = (i === tickPositions.length - 1) ? 0 : i + 1;
7077
-
7085
+
7078
7086
  // linked axes need an extra check to find out if
7079
7087
  if (!isLinked || (pos >= min && pos <= max)) {
7080
7088
 
@@ -7257,16 +7265,16 @@ function Chart(userOptions, callback) {
7257
7265
  }
7258
7266
  }
7259
7267
  }
7260
-
7268
+
7261
7269
  /**
7262
7270
  * Update the axis title by options
7263
7271
  */
7264
7272
  function setTitle(newTitleOptions, redraw) {
7265
7273
  options.title = merge(options.title, newTitleOptions);
7266
-
7274
+
7267
7275
  axisTitle = axisTitle.destroy();
7268
7276
  axis.isDirty = true;
7269
-
7277
+
7270
7278
  if (pick(redraw, true)) {
7271
7279
  chart.redraw();
7272
7280
  }
@@ -7486,10 +7494,10 @@ function Chart(userOptions, callback) {
7486
7494
  s.push((series.tooltipFormatter && series.tooltipFormatter(item)) ||
7487
7495
  item.point.tooltipFormatter(series.tooltipOptions.pointFormat));
7488
7496
  });
7489
-
7497
+
7490
7498
  // footer
7491
7499
  s.push(options.footerFormat || '');
7492
-
7500
+
7493
7501
  return s.join('');
7494
7502
  }
7495
7503
 
@@ -7672,7 +7680,7 @@ function Chart(userOptions, callback) {
7672
7680
  axis = point.series[i ? 'yAxis' : 'xAxis'];
7673
7681
  if (crosshairsOptions[i] && axis) {
7674
7682
  path = axis.getPlotLinePath(
7675
- i ? pick(point.stackY, point.y) : point.x, // #814
7683
+ i ? pick(point.stackY, point.y) : point.x, // #814
7676
7684
  1
7677
7685
  );
7678
7686
  if (crosshairs[i]) {
@@ -7770,7 +7778,7 @@ function Chart(userOptions, callback) {
7770
7778
  chartX = ePos.pageX - chartPosition.left;
7771
7779
  chartY = ePos.pageY - chartPosition.top;
7772
7780
  }
7773
-
7781
+
7774
7782
  return extend(e, {
7775
7783
  chartX: mathRound(chartX),
7776
7784
  chartY: mathRound(chartY)
@@ -7816,7 +7824,7 @@ function Chart(userOptions, callback) {
7816
7824
  i,
7817
7825
  j,
7818
7826
  distance = chartWidth,
7819
- // the index in the tooltipPoints array, corresponding to pixel position in plot area
7827
+ // the index in the tooltipPoints array, corresponding to pixel position in plot area
7820
7828
  index = inverted ? plotHeight + plotTop - e.chartY : e.chartX - plotLeft;
7821
7829
 
7822
7830
  // shared tooltip
@@ -7874,29 +7882,29 @@ function Chart(userOptions, callback) {
7874
7882
  var hoverSeries = chart.hoverSeries,
7875
7883
  hoverPoint = chart.hoverPoint,
7876
7884
  tooltipPoints = chart.hoverPoints || hoverPoint;
7877
-
7885
+
7878
7886
  // Just move the tooltip, #349
7879
7887
  if (allowMove && tooltip && tooltipPoints) {
7880
7888
  tooltip.refresh(tooltipPoints);
7881
-
7889
+
7882
7890
  // Full reset
7883
7891
  } else {
7884
-
7892
+
7885
7893
  if (hoverPoint) {
7886
7894
  hoverPoint.onMouseOut();
7887
7895
  }
7888
-
7896
+
7889
7897
  if (hoverSeries) {
7890
7898
  hoverSeries.onMouseOut();
7891
7899
  }
7892
-
7900
+
7893
7901
  if (tooltip) {
7894
7902
  tooltip.hide();
7895
7903
  tooltip.hideCrosshairs();
7896
7904
  }
7897
-
7905
+
7898
7906
  hoverX = null;
7899
-
7907
+
7900
7908
  }
7901
7909
  }
7902
7910
 
@@ -7959,7 +7967,7 @@ function Chart(userOptions, callback) {
7959
7967
  }
7960
7968
  selectionMarker = selectionMarker.destroy();
7961
7969
  }
7962
-
7970
+
7963
7971
  if (chart) { // it may be destroyed on mouse up - #877
7964
7972
  css(container, { cursor: 'auto' });
7965
7973
  chart.cancelClick = hasDragged; // #370
@@ -7974,9 +7982,9 @@ function Chart(userOptions, callback) {
7974
7982
  * Special handler for mouse move that will hide the tooltip when the mouse leaves the plotarea.
7975
7983
  */
7976
7984
  function hideTooltipOnMouseMove(e) {
7977
-
7985
+
7978
7986
  // Get e.pageX and e.pageY back in MooTools
7979
- washMouseEvent(e);
7987
+ washMouseEvent(e);
7980
7988
 
7981
7989
  // If we're outside, hide the tooltip
7982
7990
  if (chartPosition &&
@@ -8185,8 +8193,8 @@ function Chart(userOptions, callback) {
8185
8193
 
8186
8194
 
8187
8195
  if (!chart.cancelClick) {
8188
-
8189
- // Detect clicks on trackers or tracker groups, #783
8196
+
8197
+ // Detect clicks on trackers or tracker groups, #783
8190
8198
  if (hoverPoint && (attr(e.target, 'isTracker') || attr(e.target.parentNode, 'isTracker'))) {
8191
8199
  var plotX = hoverPoint.plotX,
8192
8200
  plotY = hoverPoint.plotY;
@@ -8236,15 +8244,15 @@ function Chart(userOptions, callback) {
8236
8244
  container.onclick = container.onmousedown = container.onmousemove = container.ontouchstart = container.ontouchend = container.ontouchmove = null;
8237
8245
  }
8238
8246
 
8239
-
8247
+
8240
8248
  // Run MouseTracker
8241
-
8249
+
8242
8250
  if (!trackerGroup) {
8243
8251
  chart.trackerGroup = trackerGroup = renderer.g('tracker')
8244
8252
  .attr({ zIndex: 9 })
8245
8253
  .add();
8246
8254
  }
8247
-
8255
+
8248
8256
  if (options.enabled) {
8249
8257
  chart.tooltip = tooltip = Tooltip(options);
8250
8258
 
@@ -8353,7 +8361,7 @@ function Chart(userOptions, callback) {
8353
8361
  legendSymbol = item.legendSymbol,
8354
8362
  symbolX,
8355
8363
  checkbox = item.checkbox;
8356
-
8364
+
8357
8365
  if (legendItem) {
8358
8366
  legendItem.attr({
8359
8367
  x: ltr ? itemX : legendWidth - itemX,
@@ -8521,11 +8529,11 @@ function Chart(userOptions, callback) {
8521
8529
  //'stroke-width': 0,
8522
8530
  zIndex: 3
8523
8531
  }).add(legendGroup);
8524
-
8532
+
8525
8533
  if (!ltr) {
8526
8534
  symbolX += symbolWidth;
8527
8535
  }
8528
-
8536
+
8529
8537
  } else if (itemOptions && itemOptions.marker && itemOptions.marker.enabled) { // draw the marker
8530
8538
  radius = itemOptions.marker.radius;
8531
8539
  legendSymbol = renderer.symbol(
@@ -8538,14 +8546,14 @@ function Chart(userOptions, callback) {
8538
8546
  .attr(item.pointAttr[NORMAL_STATE])
8539
8547
  .attr({ zIndex: 3 })
8540
8548
  .add(legendGroup);
8541
-
8549
+
8542
8550
  if (!ltr) {
8543
8551
  symbolX += symbolWidth / 2;
8544
8552
  }
8545
8553
 
8546
8554
  }
8547
8555
  if (legendSymbol) {
8548
-
8556
+
8549
8557
  legendSymbol.xOff = symbolX + (strokeWidth % 2 / 2);
8550
8558
  legendSymbol.yOff = symbolY + (strokeWidth % 2 / 2);
8551
8559
  }
@@ -8591,7 +8599,7 @@ function Chart(userOptions, callback) {
8591
8599
  itemX = initialItemX;
8592
8600
  itemY += itemMarginTop + itemHeight + itemMarginBottom;
8593
8601
  }
8594
-
8602
+
8595
8603
  // If the item exceeds the height, start a new column
8596
8604
  if (!horizontal && itemY + options.y + itemHeight > chartHeight - spacingTop - spacingBottom) {
8597
8605
  itemY = initialItemY;
@@ -8602,7 +8610,7 @@ function Chart(userOptions, callback) {
8602
8610
  // Set the edge positions
8603
8611
  maxItemWidth = mathMax(maxItemWidth, itemWidth);
8604
8612
  lastItemY = mathMax(lastItemY, itemY + itemMarginBottom);
8605
-
8613
+
8606
8614
  // cache the position of the newly generated or reordered items
8607
8615
  item._legendItemPos = [itemX, itemY];
8608
8616
 
@@ -8634,10 +8642,10 @@ function Chart(userOptions, callback) {
8634
8642
 
8635
8643
  if (!legendGroup) {
8636
8644
  legendGroup = renderer.g('legend')
8637
- // #414, #759. Trackers will be drawn above the legend, but we have
8645
+ // #414, #759. Trackers will be drawn above the legend, but we have
8638
8646
  // to sacrifice that because tooltips need to be above the legend
8639
8647
  // and trackers above tooltips
8640
- .attr({ zIndex: 7 })
8648
+ .attr({ zIndex: 7 })
8641
8649
  .add();
8642
8650
  }
8643
8651
 
@@ -8710,8 +8718,8 @@ function Chart(userOptions, callback) {
8710
8718
  // hide the border if no items
8711
8719
  box[allItems.length ? 'show' : 'hide']();
8712
8720
  }
8713
-
8714
- // Now that the legend width and height are extablished, put the items in the
8721
+
8722
+ // Now that the legend width and height are extablished, put the items in the
8715
8723
  // final position
8716
8724
  each(allItems, positionItem);
8717
8725
 
@@ -8920,13 +8928,13 @@ function Chart(userOptions, callback) {
8920
8928
 
8921
8929
  // redraw axes
8922
8930
  each(axes, function (axis) {
8923
-
8931
+
8924
8932
  // Fire 'afterSetExtremes' only if extremes are set
8925
8933
  if (axis.isDirtyExtremes) { // #821
8926
8934
  axis.isDirtyExtremes = false;
8927
8935
  fireEvent(axis, 'afterSetExtremes', axis.getExtremes()); // #747, #751
8928
8936
  }
8929
-
8937
+
8930
8938
  if (axis.isDirty || isDirtyBox || hasStackedSeries) {
8931
8939
  axis.redraw();
8932
8940
  isDirtyBox = true; // #792
@@ -9193,7 +9201,7 @@ function Chart(userOptions, callback) {
9193
9201
 
9194
9202
  // Redraw
9195
9203
  if (hasZoomed) {
9196
- redraw(
9204
+ redraw(
9197
9205
  pick(optionsChart.animation, chart.pointCount < 100) // animation
9198
9206
  );
9199
9207
  }
@@ -9299,19 +9307,19 @@ function Chart(userOptions, callback) {
9299
9307
  if (isString(renderTo)) {
9300
9308
  renderTo = doc.getElementById(renderTo);
9301
9309
  }
9302
-
9310
+
9303
9311
  // Display an error if the renderTo is wrong
9304
9312
  if (!renderTo) {
9305
9313
  error(13, true);
9306
9314
  }
9307
9315
 
9308
9316
  // remove previous chart
9309
- renderTo.innerHTML = '';
9317
+ renderTo.innerHTML = '';
9310
9318
 
9311
9319
  // If the container doesn't have an offsetWidth, it ha s or is a child of a node
9312
9320
  // that has display:none. We need to temporarily move it out to a visible
9313
9321
  // state to determine the size, else the legend and tooltips won't render
9314
- // properly
9322
+ // properly
9315
9323
  if (!renderTo.offsetWidth) {
9316
9324
  renderToClone = renderTo.cloneNode(0);
9317
9325
  css(renderToClone, {
@@ -9457,11 +9465,11 @@ function Chart(userOptions, callback) {
9457
9465
  var width = optionsChart.width || renderTo.offsetWidth,
9458
9466
  height = optionsChart.height || renderTo.offsetHeight,
9459
9467
  target = e ? e.target : win; // #805 - MooTools doesn't supply e
9460
-
9468
+
9461
9469
  // Width and height checks for display:none. Target is doc in IE8 and Opera,
9462
9470
  // win in Firefox, Chrome and IE9.
9463
9471
  if (width && height && (target === win || target === doc)) {
9464
-
9472
+
9465
9473
  if (width !== containerWidth || height !== containerHeight) {
9466
9474
  clearTimeout(reflowTimeout);
9467
9475
  reflowTimeout = setTimeout(function () {
@@ -9729,10 +9737,11 @@ function Chart(userOptions, callback) {
9729
9737
  axis.setScale();
9730
9738
  });
9731
9739
  getMargins();
9732
-
9740
+
9733
9741
  maxTicks = null; // reset for second pass
9734
9742
  each(axes, function (axis) {
9735
9743
  axis.setTickPositions(true); // update to reflect the new margins
9744
+ axis.setMaxTicks();
9736
9745
  });
9737
9746
  adjustTickAmounts();
9738
9747
  getMargins(); // second pass to check for new labels
@@ -9961,8 +9970,8 @@ function Chart(userOptions, callback) {
9961
9970
  each(chart.callbacks, function (fn) {
9962
9971
  fn.apply(chart, [chart]);
9963
9972
  });
9964
-
9965
-
9973
+
9974
+
9966
9975
  // If the chart was rendered outside the top container, put it back in
9967
9976
  if (renderToClone) {
9968
9977
  renderTo.appendChild(container);
@@ -10118,8 +10127,8 @@ Point.prototype = {
10118
10127
  // copy options directly to point
10119
10128
  extend(point, options);
10120
10129
  point.options = options;
10121
-
10122
- // This is the fastest way to detect if there are individual point dataLabels that need
10130
+
10131
+ // This is the fastest way to detect if there are individual point dataLabels that need
10123
10132
  // to be considered in drawDataLabels. These can only occur in object configs.
10124
10133
  if (options.dataLabels) {
10125
10134
  series._hasPointLabels = true;
@@ -10128,7 +10137,7 @@ Point.prototype = {
10128
10137
  point.name = options[0];
10129
10138
  point.y = options[1];
10130
10139
  }
10131
-
10140
+
10132
10141
  /*
10133
10142
  * If no x is set by now, get auto incremented value. All points must have an
10134
10143
  * x value, however the y value can be null to create a gap in the series
@@ -10137,8 +10146,8 @@ Point.prototype = {
10137
10146
  if (point.x === UNDEFINED) {
10138
10147
  point.x = x === UNDEFINED ? series.autoIncrement() : x;
10139
10148
  }
10140
-
10141
-
10149
+
10150
+
10142
10151
 
10143
10152
  },
10144
10153
 
@@ -10165,7 +10174,7 @@ Point.prototype = {
10165
10174
  if (point === chart.hoverPoint) {
10166
10175
  point.onMouseOut();
10167
10176
  }
10168
-
10177
+
10169
10178
  // remove all events
10170
10179
  if (point.graphic || point.dataLabel) { // removeEvent and destroyElements are performance expensive
10171
10180
  removeEvent(point);
@@ -10303,28 +10312,28 @@ Point.prototype = {
10303
10312
  for (i in match) {
10304
10313
  key = match[i];
10305
10314
  if (isString(key) && key !== pointFormat) { // IE matches more than just the variables
10306
-
10315
+
10307
10316
  // Split it further into parts
10308
10317
  parts = (' ' + key).split(splitter); // add empty string because IE and the rest handles it differently
10309
10318
  obj = { 'point': point, 'series': series }[parts[1]];
10310
10319
  prop = parts[2];
10311
-
10320
+
10312
10321
  // Add some preformatting
10313
- if (obj === point && (prop === 'y' || prop === 'open' || prop === 'high' ||
10314
- prop === 'low' || prop === 'close')) {
10315
- replacement = (seriesTooltipOptions.valuePrefix || seriesTooltipOptions.yPrefix || '') +
10322
+ if (obj === point && (prop === 'y' || prop === 'open' || prop === 'high' ||
10323
+ prop === 'low' || prop === 'close')) {
10324
+ replacement = (seriesTooltipOptions.valuePrefix || seriesTooltipOptions.yPrefix || '') +
10316
10325
  numberFormat(point[prop], pick(seriesTooltipOptions.valueDecimals, seriesTooltipOptions.yDecimals, originalDecimals)) +
10317
10326
  (seriesTooltipOptions.valueSuffix || seriesTooltipOptions.ySuffix || '');
10318
-
10327
+
10319
10328
  // Automatic replacement
10320
10329
  } else {
10321
10330
  replacement = obj[prop];
10322
10331
  }
10323
-
10332
+
10324
10333
  pointFormat = pointFormat.replace(key, replacement);
10325
10334
  }
10326
10335
  }
10327
-
10336
+
10328
10337
  return pointFormat;
10329
10338
  },
10330
10339
 
@@ -10597,7 +10606,7 @@ Series.prototype = {
10597
10606
 
10598
10607
  series.chart = chart;
10599
10608
  series.options = options = series.setOptions(options); // merge with plotOptions
10600
-
10609
+
10601
10610
  // bind the axes
10602
10611
  series.bindAxes();
10603
10612
 
@@ -10610,7 +10619,7 @@ Series.prototype = {
10610
10619
  visible: options.visible !== false, // true by default
10611
10620
  selected: options.selected === true // false by default
10612
10621
  });
10613
-
10622
+
10614
10623
  // special
10615
10624
  if (useCanVG) {
10616
10625
  options.animation = false;
@@ -10636,9 +10645,9 @@ Series.prototype = {
10636
10645
  series.setData(options.data, false);
10637
10646
 
10638
10647
  },
10639
-
10640
-
10641
-
10648
+
10649
+
10650
+
10642
10651
  /**
10643
10652
  * Set the xAxis and yAxis properties of cartesian series, and register the series
10644
10653
  * in the axis.series array
@@ -10648,31 +10657,31 @@ Series.prototype = {
10648
10657
  seriesOptions = series.options,
10649
10658
  chart = series.chart,
10650
10659
  axisOptions;
10651
-
10660
+
10652
10661
  if (series.isCartesian) {
10653
-
10662
+
10654
10663
  each(['xAxis', 'yAxis'], function (AXIS) { // repeat for xAxis and yAxis
10655
-
10664
+
10656
10665
  each(chart[AXIS], function (axis) { // loop through the chart's axis objects
10657
-
10666
+
10658
10667
  axisOptions = axis.options;
10659
-
10660
- // apply if the series xAxis or yAxis option mathches the number of the
10668
+
10669
+ // apply if the series xAxis or yAxis option mathches the number of the
10661
10670
  // axis, or if undefined, use the first axis
10662
10671
  if ((seriesOptions[AXIS] === axisOptions.index) ||
10663
10672
  (seriesOptions[AXIS] === UNDEFINED && axisOptions.index === 0)) {
10664
-
10673
+
10665
10674
  // register this series in the axis.series lookup
10666
10675
  axis.series.push(series);
10667
-
10676
+
10668
10677
  // set this series.xAxis or series.yAxis reference
10669
10678
  series[AXIS] = axis;
10670
-
10679
+
10671
10680
  // mark dirty for redraw
10672
10681
  axis.isDirty = true;
10673
10682
  }
10674
10683
  });
10675
-
10684
+
10676
10685
  });
10677
10686
  }
10678
10687
  },
@@ -10707,7 +10716,7 @@ Series.prototype = {
10707
10716
  pointsLength = points.length;
10708
10717
 
10709
10718
  if (pointsLength) { // no action required for []
10710
-
10719
+
10711
10720
  // if connect nulls, just remove null points
10712
10721
  if (series.options.connectNulls) {
10713
10722
  i = pointsLength;
@@ -10719,7 +10728,7 @@ Series.prototype = {
10719
10728
  if (points.length) {
10720
10729
  segments = [points];
10721
10730
  }
10722
-
10731
+
10723
10732
  // else, split on null points
10724
10733
  } else {
10725
10734
  each(points, function (point, i) {
@@ -10734,7 +10743,7 @@ Series.prototype = {
10734
10743
  });
10735
10744
  }
10736
10745
  }
10737
-
10746
+
10738
10747
  // register it
10739
10748
  series.segments = segments;
10740
10749
  },
@@ -10757,13 +10766,13 @@ Series.prototype = {
10757
10766
  plotOptions.series,
10758
10767
  itemOptions
10759
10768
  );
10760
-
10769
+
10761
10770
  // Re-insert the data array to the options and the original config (#717)
10762
10771
  options.data = itemOptions.data = data;
10763
-
10772
+
10764
10773
  // the tooltip options are merged between global and series specific options
10765
10774
  series.tooltipOptions = merge(chartOptions.tooltip, options.tooltip);
10766
-
10775
+
10767
10776
  return options;
10768
10777
 
10769
10778
  },
@@ -10786,7 +10795,7 @@ Series.prototype = {
10786
10795
  defaultSymbols = chart.options.symbols,
10787
10796
  counters = chart.counters;
10788
10797
  series.symbol = seriesMarkerOption.symbol || defaultSymbols[counters.symbol++];
10789
-
10798
+
10790
10799
  // don't substract radius in image symbols (#604)
10791
10800
  if (/^url/.test(series.symbol)) {
10792
10801
  seriesMarkerOption.radius = 0;
@@ -10819,7 +10828,7 @@ Series.prototype = {
10819
10828
  setAnimation(animation, chart);
10820
10829
 
10821
10830
  // Make graph animate sideways
10822
- if (graph && shift) {
10831
+ if (graph && shift) {
10823
10832
  graph.shift = currentShift + 1;
10824
10833
  }
10825
10834
  if (area) {
@@ -10828,7 +10837,7 @@ Series.prototype = {
10828
10837
  }
10829
10838
  area.isArea = true; // needed in animation, both with and without shift
10830
10839
  }
10831
-
10840
+
10832
10841
  // Optional redraw, defaults to true
10833
10842
  redraw = pick(redraw, true);
10834
10843
 
@@ -10881,11 +10890,11 @@ Series.prototype = {
10881
10890
  // reset properties
10882
10891
  series.xIncrement = null;
10883
10892
  series.pointRange = (xAxis && xAxis.categories && 1) || options.pointRange;
10884
-
10893
+
10885
10894
  if (defined(initialColor)) { // reset colors for pie
10886
10895
  chart.counters.color = initialColor;
10887
10896
  }
10888
-
10897
+
10889
10898
  // parallel arrays
10890
10899
  var xData = [],
10891
10900
  yData = [],
@@ -10899,15 +10908,15 @@ Series.prototype = {
10899
10908
  // way. Although the 'for' loops are similar, they are repeated inside each
10900
10909
  // if-else conditional for max performance.
10901
10910
  if (dataLength > turboThreshold) {
10902
-
10911
+
10903
10912
  // find the first non-null point
10904
10913
  i = 0;
10905
10914
  while (firstPoint === null && i < dataLength) {
10906
10915
  firstPoint = data[i];
10907
10916
  i++;
10908
10917
  }
10909
-
10910
-
10918
+
10919
+
10911
10920
  if (isNumber(firstPoint)) { // assume all points are numbers
10912
10921
  var x = pick(options.pointStart, 0),
10913
10922
  pointInterval = pick(options.pointInterval, 1);
@@ -10956,7 +10965,7 @@ Series.prototype = {
10956
10965
  oldData[i].destroy();
10957
10966
  }
10958
10967
  }
10959
-
10968
+
10960
10969
  // reset minRange (#878)
10961
10970
  // TODO: In protofy, run this code instead:
10962
10971
  // if (xAxis) xAxis.minRange = UNDEFINED;
@@ -11028,7 +11037,7 @@ Series.prototype = {
11028
11037
  isCartesian = series.isCartesian;
11029
11038
 
11030
11039
  // If the series data or axes haven't changed, don't go through this. Return false to pass
11031
- // the message on to override methods like in data grouping.
11040
+ // the message on to override methods like in data grouping.
11032
11041
  if (isCartesian && !series.isDirty && !xAxis.isDirty && !series.yAxis.isDirty && !force) {
11033
11042
  return false;
11034
11043
  }
@@ -11043,7 +11052,7 @@ Series.prototype = {
11043
11052
  if (processedXData[dataLength - 1] < min || processedXData[0] > max) {
11044
11053
  processedXData = [];
11045
11054
  processedYData = [];
11046
-
11055
+
11047
11056
  // only crop if it's actually spilling out
11048
11057
  } else if (processedXData[0] < min || processedXData[dataLength - 1] > max) {
11049
11058
 
@@ -11060,15 +11069,15 @@ Series.prototype = {
11060
11069
  cropEnd = i + 1;
11061
11070
  break;
11062
11071
  }
11063
-
11072
+
11064
11073
  }
11065
11074
  processedXData = processedXData.slice(cropStart, cropEnd);
11066
11075
  processedYData = processedYData.slice(cropStart, cropEnd);
11067
11076
  cropped = true;
11068
11077
  }
11069
11078
  }
11070
-
11071
-
11079
+
11080
+
11072
11081
  // Find the closest distance between processed points
11073
11082
  for (i = processedXData.length - 1; i > 0; i--) {
11074
11083
  distance = processedXData[i] - processedXData[i - 1];
@@ -11076,18 +11085,18 @@ Series.prototype = {
11076
11085
  closestPointRange = distance;
11077
11086
  }
11078
11087
  }
11079
-
11088
+
11080
11089
  // Record the properties
11081
11090
  series.cropped = cropped; // undefined or true
11082
11091
  series.cropStart = cropStart;
11083
11092
  series.processedXData = processedXData;
11084
11093
  series.processedYData = processedYData;
11085
-
11094
+
11086
11095
  if (options.pointRange === null) { // null means auto, as for columns, candlesticks and OHLC
11087
11096
  series.pointRange = closestPointRange || 1;
11088
11097
  }
11089
11098
  series.closestPointRange = closestPointRange;
11090
-
11099
+
11091
11100
  },
11092
11101
 
11093
11102
  /**
@@ -11133,7 +11142,7 @@ Series.prototype = {
11133
11142
  }
11134
11143
 
11135
11144
  // Hide cropped-away points - this only runs when the number of points is above cropThreshold, or when
11136
- // swithching view from non-grouped data to grouped data (#637)
11145
+ // swithching view from non-grouped data to grouped data (#637)
11137
11146
  if (data && (processedDataLength !== (dataLength = data.length) || hasGroupedData)) {
11138
11147
  for (i = 0; i < dataLength; i++) {
11139
11148
  if (i === cropStart && !hasGroupedData) { // when has grouped data, clear all points
@@ -11171,7 +11180,7 @@ Series.prototype = {
11171
11180
  isLastSeries,
11172
11181
  allStackSeries = yAxis.series,
11173
11182
  i = allStackSeries.length;
11174
-
11183
+
11175
11184
  // Is it the last visible series?
11176
11185
  while (i--) {
11177
11186
  if (allStackSeries[i].visible) {
@@ -11181,7 +11190,7 @@ Series.prototype = {
11181
11190
  break;
11182
11191
  }
11183
11192
  }
11184
-
11193
+
11185
11194
  // Translate each point
11186
11195
  for (i = 0; i < dataLength; i++) {
11187
11196
  var point = points[i],
@@ -11191,7 +11200,7 @@ Series.prototype = {
11191
11200
  stack = yAxis.stacks[(yValue < options.threshold ? '-' : '') + series.stackKey],
11192
11201
  pointStack,
11193
11202
  pointStackTotal;
11194
-
11203
+
11195
11204
  // get the plotX translation
11196
11205
  point.plotX = mathRound(xAxis.translate(xValue, 0, 0, 0, 1) * 10) / 10; // Math.round fixes #591
11197
11206
 
@@ -11201,11 +11210,11 @@ Series.prototype = {
11201
11210
  pointStackTotal = pointStack.total;
11202
11211
  pointStack.cum = yBottom = pointStack.cum - yValue; // start from top
11203
11212
  yValue = yBottom + yValue;
11204
-
11213
+
11205
11214
  if (isLastSeries) {
11206
11215
  yBottom = options.threshold;
11207
11216
  }
11208
-
11217
+
11209
11218
  if (stacking === 'percent') {
11210
11219
  yBottom = pointStackTotal ? yBottom * 100 / pointStackTotal : 0;
11211
11220
  yValue = pointStackTotal ? yValue * 100 / pointStackTotal : 0;
@@ -11217,17 +11226,17 @@ Series.prototype = {
11217
11226
  }
11218
11227
 
11219
11228
  // Set translated yBottom or remove it
11220
- point.yBottom = defined(yBottom) ?
11229
+ point.yBottom = defined(yBottom) ?
11221
11230
  yAxis.translate(yBottom, 0, 1, 0, 1) :
11222
11231
  null;
11223
-
11232
+
11224
11233
  // general hook, used for Highstock compare mode
11225
11234
  if (hasModifyValue) {
11226
11235
  yValue = series.modifyValue(yValue, point);
11227
11236
  }
11228
11237
 
11229
11238
  // Set the the plotY value, reset it for redraws
11230
- point.plotY = (typeof yValue === 'number') ?
11239
+ point.plotY = (typeof yValue === 'number') ?
11231
11240
  mathRound(yAxis.translate(yValue, 0, 1, 0, 1) * 10) / 10 : // Math.round fixes #591
11232
11241
  UNDEFINED;
11233
11242
 
@@ -11308,7 +11317,7 @@ Series.prototype = {
11308
11317
  xDateFormat = tooltipOptions.xDateFormat || '%A, %b %e, %Y',
11309
11318
  xAxis = series.xAxis,
11310
11319
  isDateTime = xAxis && xAxis.options.type === 'datetime';
11311
-
11320
+
11312
11321
  return tooltipOptions.headerFormat
11313
11322
  .replace('{point.key}', isDateTime ? dateFormat(xDateFormat, key) : key)
11314
11323
  .replace('{series.name}', series.name)
@@ -11635,7 +11644,7 @@ Series.prototype = {
11635
11644
 
11636
11645
  // remove all events
11637
11646
  removeEvent(series);
11638
-
11647
+
11639
11648
  // erase from axes
11640
11649
  each(['xAxis', 'yAxis'], function (AXIS) {
11641
11650
  axis = series[AXIS];
@@ -11695,11 +11704,11 @@ Series.prototype = {
11695
11704
  * Draw the data labels
11696
11705
  */
11697
11706
  drawDataLabels: function () {
11698
-
11707
+
11699
11708
  var series = this,
11700
11709
  seriesOptions = series.options,
11701
11710
  options = seriesOptions.dataLabels;
11702
-
11711
+
11703
11712
  if (options.enabled || series._hasPointLabels) {
11704
11713
  var x,
11705
11714
  y,
@@ -11728,8 +11737,8 @@ Series.prototype = {
11728
11737
 
11729
11738
  if (isBarLike) {
11730
11739
  var defaultYs = {
11731
- top: fontBaseline,
11732
- middle: fontBaseline - fontLineHeight / 2,
11740
+ top: fontBaseline,
11741
+ middle: fontBaseline - fontLineHeight / 2,
11733
11742
  bottom: -fontLineHeight + fontBaseline
11734
11743
  };
11735
11744
  if (stacking) {
@@ -11746,12 +11755,12 @@ Series.prototype = {
11746
11755
  // In non stacked series the default label placement is on top of the bars
11747
11756
  if (vAlignIsNull) {
11748
11757
  options = merge(options, {verticalAlign: 'top'});
11749
-
11758
+
11750
11759
  // If no y delta is specified, try to create a good default (like default bar)
11751
11760
  } else if (yIsNull) {
11752
11761
  options = merge(options, { y: defaultYs[options.verticalAlign]});
11753
11762
  }
11754
-
11763
+
11755
11764
  }
11756
11765
  }
11757
11766
 
@@ -11769,13 +11778,13 @@ Series.prototype = {
11769
11778
  } else {
11770
11779
  dataLabelsGroup.translate(groupLeft, groupTop);
11771
11780
  }
11772
-
11781
+
11773
11782
  // make the labels for each point
11774
11783
  generalOptions = options;
11775
11784
  each(points, function (point) {
11776
-
11785
+
11777
11786
  dataLabel = point.dataLabel;
11778
-
11787
+
11779
11788
  // Merge in individual options from point
11780
11789
  options = generalOptions; // reset changes from previous points
11781
11790
  pointOptions = point.options;
@@ -11783,52 +11792,52 @@ Series.prototype = {
11783
11792
  options = merge(options, pointOptions.dataLabels);
11784
11793
  }
11785
11794
  enabled = options.enabled;
11786
-
11795
+
11787
11796
  // Get the positions
11788
11797
  if (enabled) {
11789
11798
  var plotX = (point.barX && point.barX + point.barW / 2) || pick(point.plotX, -999),
11790
11799
  plotY = pick(point.plotY, -999),
11791
-
11800
+
11792
11801
  // if options.y is null, which happens by default on column charts, set the position
11793
11802
  // above or below the column depending on the threshold
11794
- individualYDelta = options.y === null ?
11795
- (point.y >= seriesOptions.threshold ?
11796
- -fontLineHeight + fontBaseline : // below the threshold
11803
+ individualYDelta = options.y === null ?
11804
+ (point.y >= seriesOptions.threshold ?
11805
+ -fontLineHeight + fontBaseline : // below the threshold
11797
11806
  fontBaseline) : // above the threshold
11798
11807
  options.y;
11799
-
11808
+
11800
11809
  x = (inverted ? chart.plotWidth - plotY : plotX) + options.x;
11801
11810
  y = mathRound((inverted ? chart.plotHeight - plotX : plotY) + individualYDelta);
11802
-
11811
+
11803
11812
  }
11804
-
11813
+
11805
11814
  // If the point is outside the plot area, destroy it. #678, #820
11806
11815
  if (dataLabel && series.isCartesian && (!chart.isInsidePlot(x, y) || !enabled)) {
11807
11816
  point.dataLabel = dataLabel.destroy();
11808
-
11809
- // Individual labels are disabled if the are explicitly disabled
11817
+
11818
+ // Individual labels are disabled if the are explicitly disabled
11810
11819
  // in the point options, or if they fall outside the plot area.
11811
11820
  } else if (enabled) {
11812
-
11821
+
11813
11822
  var align = options.align;
11814
-
11823
+
11815
11824
  // Get the string
11816
11825
  str = options.formatter.call(point.getLabelConfig(), options);
11817
-
11826
+
11818
11827
  // in columns, align the string to the column
11819
11828
  if (seriesType === 'column') {
11820
11829
  x += { left: -1, right: 1 }[align] * point.barW / 2 || 0;
11821
11830
  }
11822
-
11831
+
11823
11832
  if (!stacking && inverted && point.y < 0) {
11824
11833
  align = 'right';
11825
11834
  x -= 10;
11826
11835
  }
11827
-
11836
+
11828
11837
  // Determine the color
11829
11838
  options.style.color = pick(options.color, options.style.color, series.color, 'black');
11830
-
11831
-
11839
+
11840
+
11832
11841
  // update existing label
11833
11842
  if (dataLabel) {
11834
11843
  // vertically centered
@@ -11865,13 +11874,13 @@ Series.prototype = {
11865
11874
  .add(dataLabelsGroup)
11866
11875
  .shadow(options.shadow);
11867
11876
  }
11868
-
11877
+
11869
11878
  if (isBarLike && seriesOptions.stacking && dataLabel) {
11870
11879
  var barX = point.barX,
11871
11880
  barY = point.barY,
11872
11881
  barW = point.barW,
11873
11882
  barH = point.barH;
11874
-
11883
+
11875
11884
  dataLabel.align(options, null,
11876
11885
  {
11877
11886
  x: inverted ? chart.plotWidth - barY - barH : barX,
@@ -11880,8 +11889,8 @@ Series.prototype = {
11880
11889
  height: inverted ? barW : barH
11881
11890
  });
11882
11891
  }
11883
-
11884
-
11892
+
11893
+
11885
11894
  }
11886
11895
  });
11887
11896
  }
@@ -11962,17 +11971,17 @@ Series.prototype = {
11962
11971
  areaSegmentPath.push(L, segmentPath[1], segmentPath[2]);
11963
11972
  }
11964
11973
  if (options.stacking && series.type !== 'areaspline') {
11965
-
11966
- // Follow stack back. Todo: implement areaspline. A general solution could be to
11974
+
11975
+ // Follow stack back. Todo: implement areaspline. A general solution could be to
11967
11976
  // reverse the entire graphPath of the previous series, though may be hard with
11968
11977
  // splines and with series with different extremes
11969
11978
  for (i = segment.length - 1; i >= 0; i--) {
11970
-
11979
+
11971
11980
  // step line?
11972
11981
  if (i < segment.length - 1 && options.step) {
11973
11982
  areaSegmentPath.push(segment[i + 1].plotX, segment[i].yBottom);
11974
11983
  }
11975
-
11984
+
11976
11985
  areaSegmentPath.push(segment[i].plotX, segment[i].yBottom);
11977
11986
  }
11978
11987
 
@@ -12041,17 +12050,17 @@ Series.prototype = {
12041
12050
  group = series.group,
12042
12051
  trackerGroup = series.trackerGroup,
12043
12052
  chart = series.chart;
12044
-
12053
+
12045
12054
  // A fixed size is needed for inversion to work
12046
- function setInvert() {
12055
+ function setInvert() {
12047
12056
  var size = {
12048
12057
  width: series.yAxis.len,
12049
12058
  height: series.xAxis.len
12050
12059
  };
12051
-
12060
+
12052
12061
  // Set the series.group size
12053
12062
  group.attr(size).invert();
12054
-
12063
+
12055
12064
  // Set the tracker group size
12056
12065
  if (trackerGroup) {
12057
12066
  trackerGroup.attr(size).invert();
@@ -12065,7 +12074,7 @@ Series.prototype = {
12065
12074
 
12066
12075
  // Do it now
12067
12076
  setInvert(); // do it now
12068
-
12077
+
12069
12078
  // On subsequent render and redraw, just do setInvert without setting up events again
12070
12079
  series.invertGroups = setInvert;
12071
12080
  },
@@ -12100,7 +12109,7 @@ Series.prototype = {
12100
12109
  chart.clipRect = clipRect;
12101
12110
  }
12102
12111
  }
12103
-
12112
+
12104
12113
 
12105
12114
  // the group
12106
12115
  if (!series.group) {
@@ -12136,12 +12145,12 @@ Series.prototype = {
12136
12145
  if (series.options.enableMouseTracking !== false) {
12137
12146
  series.drawTracker();
12138
12147
  }
12139
-
12148
+
12140
12149
  // Handle inverted series and tracker groups
12141
12150
  if (chart.inverted) {
12142
12151
  series.invertGroups();
12143
12152
  }
12144
-
12153
+
12145
12154
  // Do the initial clipping. This must be done after inverting for VML.
12146
12155
  if (doClip && !series.hasRendered) {
12147
12156
  group.clip(clipRect);
@@ -12149,7 +12158,7 @@ Series.prototype = {
12149
12158
  series.trackerGroup.clip(chart.clipRect);
12150
12159
  }
12151
12160
  }
12152
-
12161
+
12153
12162
 
12154
12163
  // run the animation
12155
12164
  if (doAnimation) {
@@ -12350,26 +12359,26 @@ Series.prototype = {
12350
12359
  drawTrackerGroup: function () {
12351
12360
  var trackerGroup = this.trackerGroup,
12352
12361
  chart = this.chart;
12353
-
12362
+
12354
12363
  if (this.isCartesian) {
12355
-
12364
+
12356
12365
  // Generate it on first call
12357
- if (!trackerGroup) {
12366
+ if (!trackerGroup) {
12358
12367
  this.trackerGroup = trackerGroup = chart.renderer.g()
12359
12368
  .attr({
12360
12369
  zIndex: this.options.zIndex || 1
12361
12370
  })
12362
12371
  .add(chart.trackerGroup);
12363
-
12372
+
12364
12373
  }
12365
12374
  // Place it on first and subsequent (redraw) calls
12366
12375
  trackerGroup.translate(this.xAxis.left, this.yAxis.top);
12367
-
12376
+
12368
12377
  }
12369
-
12378
+
12370
12379
  return trackerGroup;
12371
12380
  },
12372
-
12381
+
12373
12382
  /**
12374
12383
  * Draw the tracker object that sits above all data labels and markers to
12375
12384
  * track mouse events on the graph or points. For the line type charts
@@ -12412,15 +12421,15 @@ Series.prototype = {
12412
12421
  trackerPath.push(M, singlePoint.plotX - snap, singlePoint.plotY,
12413
12422
  L, singlePoint.plotX + snap, singlePoint.plotY);
12414
12423
  }
12415
-
12416
-
12424
+
12425
+
12417
12426
 
12418
12427
  // draw the tracker
12419
12428
  if (tracker) {
12420
12429
  tracker.attr({ d: trackerPath });
12421
12430
 
12422
12431
  } else { // create
12423
-
12432
+
12424
12433
  series.tracker = renderer.path(trackerPath)
12425
12434
  .attr({
12426
12435
  isTracker: true,
@@ -12691,7 +12700,7 @@ var ColumnSeries = extendClass(Series, {
12691
12700
  r: options.borderRadius,
12692
12701
  strokeWidth: borderWidth
12693
12702
  };
12694
-
12703
+
12695
12704
  if (borderWidth % 2) { // correct for shorting in crisp method, visible in stacked columns with 1px border
12696
12705
  shapeArgs.y -= 1;
12697
12706
  shapeArgs.height += 1;
@@ -12749,7 +12758,7 @@ var ColumnSeries = extendClass(Series, {
12749
12758
  .attr(point.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE])
12750
12759
  .add(series.group)
12751
12760
  .shadow(options.shadow);
12752
-
12761
+
12753
12762
  }
12754
12763
 
12755
12764
  }
@@ -12773,7 +12782,7 @@ var ColumnSeries = extendClass(Series, {
12773
12782
  rel,
12774
12783
  plotY,
12775
12784
  validPlotY;
12776
-
12785
+
12777
12786
  each(series.points, function (point) {
12778
12787
  tracker = point.tracker;
12779
12788
  shapeArgs = point.trackerArgs || point.shapeArgs;
@@ -12844,7 +12853,7 @@ var ColumnSeries = extendClass(Series, {
12844
12853
  // start values
12845
12854
  graphic.attr({
12846
12855
  height: 0,
12847
- y: defined(threshold) ?
12856
+ y: defined(threshold) ?
12848
12857
  yAxis.getThreshold(threshold) :
12849
12858
  yAxis.translate(yAxis.getExtremes().min, 0, 1, 0, 1)
12850
12859
  });
@@ -12935,10 +12944,10 @@ var ScatterSeries = extendClass(Series, {
12935
12944
  while (i--) {
12936
12945
  graphic = points[i].graphic;
12937
12946
  if (graphic) { // doesn't exist for null points
12938
- graphic.element._i = i;
12947
+ graphic.element._i = i;
12939
12948
  }
12940
12949
  }
12941
-
12950
+
12942
12951
  // Add the event listeners, we need to do this only once
12943
12952
  if (!series._hasTracking) {
12944
12953
  series.group
@@ -13129,14 +13138,14 @@ var PieSeries = extendClass(Series, {
13129
13138
  this.generatePoints();
13130
13139
  if (pick(redraw, true)) {
13131
13140
  this.chart.redraw();
13132
- }
13141
+ }
13133
13142
  },
13134
13143
  /**
13135
13144
  * Do translation for pie slices
13136
13145
  */
13137
13146
  translate: function () {
13138
13147
  this.generatePoints();
13139
-
13148
+
13140
13149
  var total = 0,
13141
13150
  series = this,
13142
13151
  cumulative = -0.25, // start at top
@@ -13238,7 +13247,7 @@ var PieSeries = extendClass(Series, {
13238
13247
  angle < circ / 4 ? 'left' : 'right', // alignment
13239
13248
  angle // center angle
13240
13249
  ];
13241
-
13250
+
13242
13251
  // API properties
13243
13252
  point.percentage = fraction * 100;
13244
13253
  point.total = total;
@@ -13416,7 +13425,7 @@ var PieSeries = extendClass(Series, {
13416
13425
 
13417
13426
  // Only do anti-collision when we are outside the pie and have connectors (#856)
13418
13427
  if (distanceOption > 0) {
13419
-
13428
+
13420
13429
  // build the slots
13421
13430
  for (pos = centerY - radius - distanceOption; pos <= centerY + radius + distanceOption; pos += labelHeight) {
13422
13431
  slots.push(pos);
@@ -13439,7 +13448,7 @@ var PieSeries = extendClass(Series, {
13439
13448
  // */
13440
13449
  }
13441
13450
  slotsLength = slots.length;
13442
-
13451
+
13443
13452
  // if there are more values than available slots, remove lowest values
13444
13453
  if (length > slotsLength) {
13445
13454
  // create an array for sorting and ranking the points within each quarter
@@ -13457,18 +13466,18 @@ var PieSeries = extendClass(Series, {
13457
13466
  }
13458
13467
  length = points.length;
13459
13468
  }
13460
-
13469
+
13461
13470
  // The label goes to the nearest open slot, but not closer to the edge than
13462
13471
  // the label's index.
13463
13472
  for (j = 0; j < length; j++) {
13464
-
13473
+
13465
13474
  point = points[j];
13466
13475
  labelPos = point.labelPos;
13467
-
13476
+
13468
13477
  var closest = 9999,
13469
13478
  distance,
13470
13479
  slotI;
13471
-
13480
+
13472
13481
  // find the closest slot index
13473
13482
  for (slotI = 0; slotI < slotsLength; slotI++) {
13474
13483
  distance = mathAbs(slots[slotI] - labelPos[1]);
@@ -13477,7 +13486,7 @@ var PieSeries = extendClass(Series, {
13477
13486
  slotIndex = slotI;
13478
13487
  }
13479
13488
  }
13480
-
13489
+
13481
13490
  // if that slot index is closer to the edges of the slots, move it
13482
13491
  // to the closest appropriate slot
13483
13492
  if (slotIndex < j && slots[j] !== null) { // cluster at the top
@@ -13494,7 +13503,7 @@ var PieSeries = extendClass(Series, {
13494
13503
  slotIndex++;
13495
13504
  }
13496
13505
  }
13497
-
13506
+
13498
13507
  usedSlots.push({ i: slotIndex, y: slots[slotIndex] });
13499
13508
  slots[slotIndex] = null; // mark as taken
13500
13509
  }
@@ -13504,7 +13513,7 @@ var PieSeries = extendClass(Series, {
13504
13513
 
13505
13514
  // now the used slots are sorted, fill them up sequentially
13506
13515
  for (j = 0; j < length; j++) {
13507
-
13516
+
13508
13517
  var slot, naturalY;
13509
13518
 
13510
13519
  point = points[j];
@@ -13512,7 +13521,7 @@ var PieSeries = extendClass(Series, {
13512
13521
  dataLabel = point.dataLabel;
13513
13522
  visibility = point.visible === false ? HIDDEN : VISIBLE;
13514
13523
  naturalY = labelPos[1];
13515
-
13524
+
13516
13525
  if (distanceOption > 0) {
13517
13526
  slot = usedSlots.pop();
13518
13527
  slotIndex = slot.i;
@@ -13524,17 +13533,17 @@ var PieSeries = extendClass(Series, {
13524
13533
  (naturalY < y && slots[slotIndex - 1] !== null)) {
13525
13534
  y = naturalY;
13526
13535
  }
13527
-
13536
+
13528
13537
  } else {
13529
13538
  y = naturalY;
13530
13539
  }
13531
13540
 
13532
13541
  // get the x - use the natural x position for first and last slot, to prevent the top
13533
13542
  // and botton slice connectors from touching each other on either side
13534
- x = options.justify ?
13543
+ x = options.justify ?
13535
13544
  seriesCenter[0] + (i ? -1 : 1) * (radius + distanceOption) :
13536
13545
  series.getX(slotIndex === 0 || slotIndex === slots.length - 1 ? naturalY : y, i);
13537
-
13546
+
13538
13547
  // move or place the data label
13539
13548
  dataLabel
13540
13549
  .attr({
@@ -13635,6 +13644,6 @@ extend(Highcharts, {
13635
13644
  extendClass: extendClass,
13636
13645
  placeBox: placeBox,
13637
13646
  product: 'Highcharts',
13638
- version: '2.2.2'
13647
+ version: '2.2.3'
13639
13648
  });
13640
13649
  }());