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

Code before:
      .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':
            bottomXAxis.ticks(timeDay.every(every));
            break;
          case 'week':
            bottomXAxis.ticks(mapWeekdayToTimeFunction[weekday].every(every));
            break;
          case 'month':
            bottomXAxis.ticks(timeMonth.every(every));
            break;
        }
      }
    }

Review comment (bug):
The condition check logic differs between bottom axis (lines 662-669 with log warning when exceeding) and top axis (lines 724-749 with silent check). This inconsistency could make debugging harder. Consider logging the warning for the top axis as well, or extracting the validation logic to ensure both axes behave identically.

Code after:
    } 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':
              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;