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

Code before:
    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
    );

    if (resultTickInterval !== null) {
      const every = parseInt(resultTickInterval[1], 10);
      const interval = resultTickInterval[2];
      const weekday = diagObj.db.getWeekday() || conf.weekday;

      // Get the time domain to check tick count
      const domain = timeScale.domain();
      const minTime = domain[0];
      const maxTime = domain[1];
      const estimatedTicks = getEstimatedTickCount(minTime, maxTime, every, interval);

      if (estimatedTicks > MAX_TICK_COUNT) {
        log.warn(
          `The tick interval "${every}${interval}" would generate ${estimatedTicks} ticks, ` +
            `which exceeds the maximum allowed (${MAX_TICK_COUNT}). ` +
            `This may indicate an invalid date or time range. Skipping custom tick interval.`
        );
        // D3 using its default automatic tick generation
      } else {
        switch (interval) {
          case 'millisecond':
            bottomXAxis.ticks(timeMillisecond.every(every));
            break;
          case 'second':
            bottomXAxis.ticks(timeSecond.every(every));
            break;
          case 'minute':
            bottomXAxis.ticks(timeMinute.every(every));
            break;
          case 'hour':
            bottomXAxis.ticks(timeHour.every(every));
            break;
          case 'day':

Review comment (suggestion):
The `parseInt` call should validate that the result is not `NaN`. If `resultTickInterval[1]` contains non-numeric characters, `parseInt` will return `NaN`, which will then be passed to `getEstimatedTickCount` and `dayjs.duration`, potentially causing issues. Consider adding validation:
```javascript
const every = parseInt(resultTickInterval[1], 10);
if (isNaN(every) || every <= 0) {
  log.warn(`Invalid tick interval value: "${resultTickInterval[1]}". Skipping custom tick interval.`);
  // Skip applying custom ticks
} else {
  // ... rest of the logic
}
```

Code after:
   * @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
    );

    if (resultTickInterval !== null) {
      const every = parseInt(resultTickInterval[1], 10);
      if (isNaN(every) || every <= 0) {
        log.warn(
          `Invalid tick interval value: "${resultTickInterval[1]}". Skipping custom tick interval.`
        );
        // Skip applying custom ticks
      } else {
        const interval = resultTickInterval[2];
        const weekday = diagObj.db.getWeekday() || conf.weekday;

        // Get the time domain to check tick count
        const domain = timeScale.domain();
        const minTime = domain[0];
        const maxTime = domain[1];
        const estimatedTicks = getEstimatedTickCount(minTime, maxTime, every, interval);

        if (estimatedTicks > MAX_TICK_COUNT) {
          log.warn(
            `The tick interval "${every}${interval}" would generate ${estimatedTicks} ticks, ` +
              `which exceeds the maximum allowed (${MAX_TICK_COUNT}). ` +
              `This may indicate an invalid date or time range. Skipping custom tick interval.`
          );
          // D3 will use its default automatic tick generation
        } else {
          switch (interval) {
            case 'millisecond':