Repository: mermaid-js/mermaid
File: packages/mermaid/src/diagrams/gantt/ganttRenderer.js (JavaScript)

Code before:
            theSidePad +
            0.5 * (timeScale(d.end) - timeScale(d.start))
          ).toString() +
          'px ' +
          (i * theGap + 0.5 * h).toString() +
          'px'
        );
      })
      .attr('class', 'exclude-range');
  }

  /**
   * Calculates the estimated number of ticks based on the time domain and tick interval.
   * Returns the count or Infinity if there would be too many ticks.
   * @param {Date} minTime - The minimum time in the domain
   * @param {Date} maxTime - The maximum time in the domain
   * @param {number} every - The interval count (e.g., 1 for "1second")
   * @param {string} interval - The interval unit (e.g., "second", "day")
   * @returns {number} The estimated number of ticks
   */
  function getEstimatedTickCount(minTime, maxTime, every, interval) {
    const timeDiffMs = maxTime - minTime;
    const intervalMs = dayjs.duration({ [interval ?? 'day']: every }).asMilliseconds();
    return Math.ceil(timeDiffMs / intervalMs);
  }

  /**
   * @param theSidePad
   * @param theTopPad
   * @param w
   * @param h
   */
  function makeGrid(theSidePad, theTopPad, w, h) {
    const dateFormat = diagObj.db.getDateFormat();
    const userAxisFormat = diagObj.db.getAxisFormat();
    let axisFormat;
    if (userAxisFormat) {
      axisFormat = userAxisFormat;
    } else if (dateFormat === 'D') {
      axisFormat = '%d';
    } else {
      axisFormat = conf.axisFormat ?? '%Y-%m-%d';
    }

    let bottomXAxis = axisBottom(timeScale)
      .tickSize(-h + theTopPad + conf.gridLineStartPadding)
      .tickFormat(timeFormat(axisFormat));

    const reTickInterval = /^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/;
    const resultTickInterval = reTickInterval.exec(
      diagObj.db.getTickInterval() || conf.tickInterval

Review comment (bug):
The `getEstimatedTickCount` function doesn't handle edge cases properly:
1. If `intervalMs` is 0 or negative (when `every` is 0 or the interval is invalid), this will return `Infinity` or a negative number
2. If `minTime > maxTime` (invalid time range), `timeDiffMs` will be negative, resulting in a negative tick count

Consider adding validation:
```javascript
function getEstimatedTickCount(minTime, maxTime, every, interval) {
  if (every <= 0 || minTime > maxTime) {
    return Infinity;
  }
  const timeDiffMs = maxTime - minTime;
  const intervalMs = dayjs.duration({ [interval ?? 'day']: every }).asMilliseconds();
  if (intervalMs <= 0) {
    return Infinity;
  }
  return Math.ceil(timeDiffMs / intervalMs);
}
```
```suggestion
  function getEstimatedTickCount(minTime, maxTime, every, interval) {
    if (every <= 0 || minTime > maxTime) {
      return Infinity;
    }
    const timeDiffMs = maxTime - minTime;
    const intervalMs = dayjs.duration({ [interval ?? 'day']: every }).asMilliseconds();
    if (intervalMs <= 0) {
      return Infinity;
    }
```

Code after:
            theSidePad +
            0.5 * (timeScale(d.end) - timeScale(d.start))
          ).toString() +
          'px ' +
          (i * theGap + 0.5 * h).toString() +
          'px'
        );
      })
      .attr('class', 'exclude-range');
  }

  /**
   * Calculates the estimated number of ticks based on the time domain and tick interval.
   * Returns the estimated number of ticks as a number.
   * @param {Date} minTime - The minimum time in the domain
   * @param {Date} maxTime - The maximum time in the domain
   * @param {number} every - The interval count (e.g., 1 for "1second")
   * @param {string} interval - The interval unit (e.g., "second", "day")
   * @returns {number} The estimated number of ticks
   */
  function getEstimatedTickCount(minTime, maxTime, every, interval) {
    if (every <= 0 || minTime > maxTime) {
      return Infinity;
    }
    const timeDiffMs = maxTime - minTime;
    const intervalMs = dayjs.duration({ [interval ?? 'day']: every }).asMilliseconds();
    if (intervalMs <= 0) {
      return Infinity;
    }
    return Math.ceil(timeDiffMs / intervalMs);
  }

  /**
   * @param theSidePad
   * @param theTopPad
   * @param w
   * @param h
   */
  function makeGrid(theSidePad, theTopPad, w, h) {
    const dateFormat = diagObj.db.getDateFormat();
    const userAxisFormat = diagObj.db.getAxisFormat();
    let axisFormat;
    if (userAxisFormat) {
      axisFormat = userAxisFormat;
    } else if (dateFormat === 'D') {
      axisFormat = '%d';
    } else {
      axisFormat = conf.axisFormat ?? '%Y-%m-%d';
    }

    let bottomXAxis = axisBottom(timeScale)