You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chart.js+React实现项目工时展示 解决Y轴时间12小时上限问题

问题根源

time类型坐标轴是为真实日历时间场景设计的,你配置的HH:mm格式属于单日时间格式化规则,底层会按24小时为周期做进位处理,天然不支持无上限的累计时长展示,不管怎么调整time轴的配置,都没法突破日期时间的循环逻辑,完全不适合工时统计这种累计值场景。

解决方案

直接放弃time轴,改用linear线性轴,自行处理时长数值和展示格式的转换,即可实现无上限的工时展示,原有堆叠、30分钟步长的效果都可以完全保留:

  • 数据层统一把所有工时值转成总分钟数的纯数值格式存储/传入图表,比如13小时15分就传13*60 +15 = 795,不要传时间格式字符串。如果你的存量数据是HH:mm格式,可以用这个函数转换:
    const parseDuration = (timeStr) => {
      const [h, m] = timeStr.split(':').map(Number);
      return h * 60 + m;
    };
    
  • 替换Y轴配置,用线性轴+自定义刻度回调实现和之前一致的HH:mm展示效果,支持任意小时数:
    scales: {
      x: {
        stacked: true,
      },
      y: {
        stacked: true,
        type: "linear",
        beginAtZero: true,
        ticks: {
          stepSize: 30, // 保持原配置30分钟一个刻度
          callback: (val) => {
            const hours = Math.floor(val / 60);
            const mins = val % 60;
            return `${hours}:${mins.toString().padStart(2, '0')}`;
          }
        },
      },
    }
    
  • 补充tooltip的格式化配置,替换原time轴自带的tooltip格式:
    options: {
      // 上述scales配置放在此处
      plugins: {
        tooltip: {
          callbacks: {
            label: (ctx) => {
              const totalMins = ctx.parsed.y;
              const hours = Math.floor(totalMins / 60);
              const mins = totalMins % 60;
              return `${ctx.dataset.label}: ${hours}小时${mins.toString().padStart(2, '0')}分钟`;
            }
          }
        }
      }
    }
    

这个方案没有时长上限,不管是十几小时还是上百小时的累计工时都能正常渲染,不会出现时间循环、数值截断的问题。


内容的提问来源于stack exchange,提问作者Med EL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 10:21:23