docs: function (secondPass) {
              var axis = this,
                chart = axis.chart,
                options = axis.options,
                startOnTick = options.startOnTick,
                endOnTick = options.endOnTick,
                isLog = axis.isLog,
                isDatetimeAxis = axis.isDatetimeAxis,
                isXAxis = axis.isXAxis,
                isLinked = axis.isLinked,
                tickPositioner = axis.options.tickPositioner,
                maxPadding = options.maxPadding,
                minPadding = options.minPadding,
                length,
                linkedParentExtremes,
                tickIntervalOption = options.tickInterval,
                minTickIntervalOption = options.minTickInterval,
                tickPixelIntervalOption = options.tickPixelInterval,
                tickPositions,
                keepTwoTicksOnly,
                categories = axis.categories;
  
              // linked axis gets the extremes from the parent axis
              if (isLinked) {
                  axis.linkedParent = chart[axis.coll][options.linkedTo];
                  linkedParentExtremes = axis.linkedParent.getExtremes();
                  axis.min = pick(linkedParentExtremes.min, linkedParentExtremes.dataMin);
                  axis.max = pick(linkedParentExtremes.max, linkedParentExtremes.dataMax);
                  if (options.type !== axis.linkedParent.options.type) {
                      error(11, 1); // Can't link axes of different type
                  }
              } else { // initial min and max from the extreme data values
                  axis.min = pick(axis.userMin, options.min, axis.dataMin);
                  axis.max = pick(axis.userMax, options.max, axis.dataMax);
              }
  
              if (isLog) {
                  if (!secondPass && mathMin(axis.min, pick(axis.dataMin, axis.min)) <= 0) { // #978
                      error(10, 1); // Can't plot negative values on log axis
                  }
                  axis.min = correctFloat(log2lin(axis.min)); // correctFloat cures #934
                  axis.max = correctFloat(log2lin(axis.max));
              }
  
              // handle zoomed range
              if (axis.range && defined(axis.max)) {
                  axis.userMin = axis.min = mathMax(axis.min, axis.max - axis.range); // #618
                  axis.userMax = axis.max;
  
                  axis.range = null;  // don't use it when running setExtremes
              }
  
              // Hook for adjusting this.min and this.max. Used by bubble series.
              if (axis.beforePadding) {
                  axis.beforePadding();
              }
  
              // adjust min and max for the minimum range
              axis.adjustForMinRange();
  
              // Pad the values to get clear of the chart's edges. To avoid tickInterval taking the padding
              // into account, we do this after computing tick interval (#1337).
              if (!categories && !axis.axisPointRange && !axis.usePercentage && !isLinked && defined(axis.min) && defined(axis.max)) {
                  length = axis.max - axis.min;
                  if (length) {
                      if (!defined(options.min) && !defined(axis.userMin) && minPadding && (axis.dataMin < 0 || !axis.ignoreMinPadding)) {
                          axis.min -= length * minPadding;
                      }
                      if (!defined(options.max) && !defined(axis.userMax)  && maxPadding && (axis.dataMax > 0 || !axis.ignoreMaxPadding)) {
                          axis.max += length * maxPadding;
                      }
                  }
              }
  
              // Stay within floor and ceiling
              if (isNumber(options.floor)) {
                  axis.min = mathMax(axis.min, options.floor);
              }
              if (isNumber(options.ceiling)) {
                  axis.max = mathMin(axis.max, options.ceiling);
              }
  
              // get tickInterval
              if (axis.min === axis.max || axis.min === undefined || axis.max === undefined) {
                  axis.tickInterval = 1;
              } else if (isLinked && !tickIntervalOption &&
                tickPixelIntervalOption === axis.linkedParent.options.tickPixelInterval) {
                  axis.tickInterval = axis.linkedParent.tickInterval;
              } else {
                  axis.tickInterval = pick(
                    tickIntervalOption,
                    categories ? // for categoried axis, 1 is default, for linear axis use tickPix
                      1 :
                        // don't let it be more than the data range
                    (axis.max - axis.min) * tickPixelIntervalOption / mathMax(axis.len, tickPixelIntervalOption)
                  );
                  // For squished axes, set only two ticks
                  if (!defined(tickIntervalOption) && axis.len < tickPixelIntervalOption && !this.isRadial &&
                    !this.isLog && !categories && startOnTick && endOnTick) {
                      keepTwoTicksOnly = true;
                      axis.tickInterval /= 4; // tick extremes closer to the real values
                  }
              }
  
              // Now we're finished detecting min and max, crop and group series data. This
              // is in turn needed in order to find tick positions in ordinal axes.
              if (isXAxis && !secondPass) {
                  each(axis.series, function (series) {
                      series.processData(axis.min !== axis.oldMin || axis.max !== axis.oldMax);
                  });
              }
  
              // set the translation factor used in translate function
              axis.setAxisTranslation(true);
  
              // hook for ordinal axes and radial axes
              if (axis.beforeSetTickPositions) {
                  axis.beforeSetTickPositions();
              }
  
              // hook for extensions, used in Highstock ordinal axes
              if (axis.postProcessTickInterval) {
                  axis.tickInterval = axis.postProcessTickInterval(axis.tickInterval);
              }
  
              // In column-like charts, don't cramp in more ticks than there are points (#1943)
              if (axis.pointRange) {
                  axis.tickInterval = mathMax(axis.pointRange, axis.tickInterval);
              }
  
              // Before normalizing the tick interval, handle minimum tick interval. This applies only if tickInterval is not defined.
              if (!tickIntervalOption && axis.tickInterval < minTickIntervalOption) {
                  axis.tickInterval = minTickIntervalOption;
              }
  
              // for linear axes, get magnitude and normalize the interval
              if (!isDatetimeAxis && !isLog) { // linear
                  if (!tickIntervalOption) {
                      axis.tickInterval = normalizeTickInterval(
                        axis.tickInterval,
                        null,
                        getMagnitude(axis.tickInterval),
                        // If the tick interval is between 1 and 5 and the axis max is in the order of
                        // thousands, chances are we are dealing with years. Don't allow decimals. #3363.
                        pick(options.allowDecimals, !(axis.tickInterval > 1 && axis.tickInterval < 5 && axis.max > 1000 && axis.max < 9999))
                      );
                  }
              }
  
              // get minorTickInterval
              axis.minorTickInterval = options.minorTickInterval === 'auto' && axis.tickInterval ?
              axis.tickInterval / 5 : options.minorTickInterval;
  
              // find the tick positions
              axis.tickPositions = tickPositions = options.tickPositions ?
                [].concat(options.tickPositions) : // Work on a copy (#1565)
                (tickPositioner && tickPositioner.apply(axis, [axis.min, axis.max]));
              if (!tickPositions) {
  
                  // Too many ticks
                  if (!axis.ordinalPositions && (axis.max - axis.min) / axis.tickInterval > mathMax(2 * axis.len, 200)) {
                      error(19, true);
                  }
  
                  if (isDatetimeAxis) {
                      tickPositions = axis.getTimeTicks(
                        axis.normalizeTimeTickInterval(axis.tickInterval, options.units),
                        axis.min,
                        axis.max,
                        options.startOfWeek,
                        axis.ordinalPositions,
                        axis.closestPointRange,
                        true
                      );
                  } else if (isLog) {
                      tickPositions = axis.getLogTickPositions(axis.tickInterval, axis.min, axis.max);
                  } else {
                      tickPositions = axis.getLinearTickPositions(axis.tickInterval, axis.min, axis.max);
                  }
  
                  if (keepTwoTicksOnly) {
                      tickPositions.splice(1, tickPositions.length - 2);
                  }
  
                  axis.tickPositions = tickPositions;
              }
  
              if (!isLinked) {
  
                  // reset min/max or remove extremes based on start/end on tick
                  var roundedMin = tickPositions[0],
                    roundedMax = tickPositions[tickPositions.length - 1],
                    minPointOffset = axis.minPointOffset || 0,
                    singlePad;
  
                  if (startOnTick) {
                      axis.min = roundedMin;
                  } else if (axis.min - minPointOffset > roundedMin) {
                      tickPositions.shift();
                  }
  
                  if (endOnTick) {
                      axis.max = roundedMax;
                  } else if (axis.max + minPointOffset < roundedMax) {
                      tickPositions.pop();
                  }
  
                  // If no tick are left, set one tick in the middle (#3195)
                  if (tickPositions.length === 0 && defined(roundedMin)) {
                      tickPositions.push((roundedMax + roundedMin) / 2);
                  }
  
                  // When there is only one point, or all points have the same value on this axis, then min
                  // and max are equal and tickPositions.length is 0 or 1. In this case, add some padding
                  // in order to center the point, but leave it with one tick. #1337.
                  if (tickPositions.length === 1) {
                      singlePad = mathAbs(axis.max) > 10e12 ? 1 : 0.001; // The lowest possible number to avoid extra padding on columns (#2619, #2846)
                      axis.min -= singlePad;
                      axis.max += singlePad;
                  }
              }
          }