src/getNiceTickValues.js
function calculateStep(min, max, tickCount, allowDecimals, correctionFactor = 0) {
  // dirty hack (for recharts' test)
  if (!Number.isFinite((max - min) / (tickCount - 1))) {
    return {
      step: new Decimal(0),
      tickMin: new Decimal(0),
      tickMax: new Decimal(0),
    };
  }

  // The step which is easy to understand between two ticks
  const step = getFormatStep(
    new Decimal(max).sub(min).div(tickCount - 1),
    allowDecimals,
    correctionFactor,
  );

  // A medial value of ticks
  let middle;

  // When 0 is inside the interval, 0 should be a tick
  if (min <= 0 && max >= 0) {
    middle = new Decimal(0);
  } else {
    // calculate the middle value
    middle = new Decimal(min).add(max).div(2);
    // minus modulo value
    middle = middle.sub(new Decimal(middle).mod(step));
  }

  let belowCount = Math.ceil(middle.sub(min).div(step).toNumber());
  let upCount = Math.ceil(new Decimal(max).sub(middle).div(step)
    .toNumber());
  const scaleCount = belowCount + upCount + 1;

  if (scaleCount > tickCount) {
    // When more ticks need to cover the interval, step should be bigger.
    return calculateStep(min, max, tickCount, allowDecimals, correctionFactor + 1);
  } if (scaleCount < tickCount) {
    // When less ticks can cover the interval, we should add some additional ticks
    upCount = max > 0 ? upCount + (tickCount - scaleCount) : upCount;
    belowCount = max > 0 ? belowCount : belowCount + (tickCount - scaleCount);
  }

  return {
    step,
    tickMin: middle.sub(new Decimal(belowCount).mul(step)),
    tickMax: middle.add(new Decimal(upCount).mul(step)),
  };
}
function calculateStep(min, max, tickCount, allowDecimals, correctionFactor = 0) {
  // dirty hack (for recharts' test)
  if (!Number.isFinite((max - min) / (tickCount - 1))) {
    return {
      step: new Decimal(0),
      tickMin: new Decimal(0),
      tickMax: new Decimal(0),
    };
  }

  // The step which is easy to understand between two ticks
  const step = getFormatStep(
    new Decimal(max).sub(min).div(tickCount - 1),
    allowDecimals,
    correctionFactor,
  );

  // A medial value of ticks
  let middle;

  // When 0 is inside the interval, 0 should be a tick
  if (min <= 0 && max >= 0) {
    middle = new Decimal(0);
  } else {
    // calculate the middle value
    middle = new Decimal(min).add(max).div(2);
    // minus modulo value
    middle = middle.sub(new Decimal(middle).mod(step));
  }

  let belowCount = Math.ceil(middle.sub(min).div(step).toNumber());
  let upCount = Math.ceil(new Decimal(max).sub(middle).div(step)
    .toNumber());
  const scaleCount = belowCount + upCount + 1;

  if (scaleCount > tickCount) {
    // When more ticks need to cover the interval, step should be bigger.
    return calculateStep(min, max, tickCount, allowDecimals, correctionFactor + 1);
  } if (scaleCount < tickCount) {
    // When less ticks can cover the interval, we should add some additional ticks
    upCount = max > 0 ? upCount + (tickCount - scaleCount) : upCount;
    belowCount = max > 0 ? belowCount : belowCount + (tickCount - scaleCount);
  }

  return {
    step,
    tickMin: middle.sub(new Decimal(belowCount).mul(step)),
    tickMax: middle.add(new Decimal(upCount).mul(step)),
  };
}
function calculateStep ( min , max , tickCount , allowDecimals , correctionFactor = 0 ) { // dirty hack (for recharts' test) if ( ! Number . isFinite ( ( max - min ) / ( tickCount - 1 ) ) ) { return { step : new Decimal ( 0 ) , tickMin : new Decimal ( 0 ) , tickMax : new Decimal ( 0 ) , } ; } // The step which is easy to understand between two ticks const step = getFormatStep ( new Decimal ( max ) . sub ( min ) . div ( tickCount - 1 ) , allowDecimals , correctionFactor , ) ; // A medial value of ticks let middle ; // When 0 is inside the interval, 0 should be a tick if ( min <= 0 && max >= 0 ) { middle = new Decimal ( 0 ) ; } else { // calculate the middle value middle = new Decimal ( min ) . add ( max ) . div ( 2 ) ; // minus modulo value middle = middle . sub ( new Decimal ( middle ) . mod ( step ) ) ; } let belowCount = Math . ceil ( middle . sub ( min ) . div ( step ) . toNumber ( ) ) ; let upCount = Math . ceil ( new Decimal ( max ) . sub ( middle ) . div ( step ) . toNumber ( ) ) ; const scaleCount = belowCount + upCount + 1 ; if ( scaleCount > tickCount ) { // When more ticks need to cover the interval, step should be bigger. return calculateStep ( min , max , tickCount , allowDecimals , correctionFactor + 1 ) ; } if ( scaleCount < tickCount ) { // When less ticks can cover the interval, we should add some additional ticks upCount = max > 0 ? upCount + ( tickCount - scaleCount ) : upCount ; belowCount = max > 0 ? belowCount : belowCount + ( tickCount - scaleCount ) ; } return { step , tickMin : middle . sub ( new Decimal ( belowCount ) . mul ( step ) ) , tickMax : middle . add ( new Decimal ( upCount ) . mul ( step ) ) , } ; }
Calculate the step

@param  {Number}  min              The minimum value of an interval
@param  {Number}  max              The maximum value of an interval
@param  {Integer} tickCount        The count of ticks
@param  {Boolean} allowDecimals    Allow the ticks to be decimals or not
@param  {Number}  correctionFactor A correction factor
@return {Object}  The step, minimum value of ticks, maximum value of ticks
Calculate the step