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

如何在react-chartjs-2中自定义Chart.js的tooltip提示框?

解决方案

你需要使用Chart.js的外部自定义Tooltip能力来实现预期效果,默认内置的Tooltip样式扩展性不足,无法直接实现你要的分层展示、自定义排版效果,具体调整步骤如下:

1. 调整Tooltip基础配置

首先关闭默认Tooltip渲染,开启外部渲染模式,修改你的options.tooltips配置如下:

tooltips: {
  // 关闭默认渲染
  enabled: false,
  // 开启自定义外部Tooltip
  custom: function(tooltipModel) {
    // 先获取或者创建Tooltip的DOM容器
    let tooltipEl = document.getElementById('chartjs-custom-tooltip');
    if (!tooltipEl) {
      tooltipEl = document.createElement('div');
      tooltipEl.id = 'chartjs-custom-tooltip';
      tooltipEl.style.position = 'absolute';
      tooltipEl.style.background = '#6E759F';
      tooltipEl.style.color = '#fff';
      tooltipEl.style.borderRadius = '8px';
      tooltipEl.style.padding = '12px 16px';
      tooltipEl.style.pointerEvents = 'none';
      tooltipEl.style.transition = 'all 0.1s ease';
      document.body.appendChild(tooltipEl);
    }
    // 如果Tooltip隐藏,设置不可见
    if (tooltipModel.opacity === 0) {
      tooltipEl.style.opacity = 0;
      return;
    }
    // 处理Tooltip内容
    const index = tooltipModel.dataPoints[0].index;
    // 取所需的各指标数据
    const sysMin = bloodPressureData?.sysMin?.data[index];
    const sysMax = bloodPressureData?.sysMax?.data[index];
    const sysAvg = bloodPressureData?.systolicAvarageLine?.data[index];
    const diaMin = bloodPressureData?.diaMin?.data[index];
    const diaMax = bloodPressureData?.diaMax?.data[index];
    const diaAvg = bloodPressureData?.diastolicAvarageLine?.data[index];
    // 生成标题(复用你原来的title逻辑)
    let title = '';
    if (selectedTimeSpan === TimeSpan.TODAY) {
      title = `${data.labels[index]}:00`;
    } else if (selectedTimeSpan === TimeSpan.WEEK) {
      title = `${getWeekHoverTitle(data.labels[index])} ${moment(selectedDateTime).format('MMMM').slice(0,3)} ${data.labels[index]}`;
    } else if (selectedTimeSpan === TimeSpan.MONTH) {
      title = `${data.labels[index]} ${moment(selectedDateTime).format('MMMM')}`;
    } else {
      title = `${moment(`${data.labels[index]}`, 'MM').format('MMMM')}`;
    }
    // 拼接Tooltip内部HTML
    tooltipEl.innerHTML = `
      <div style="font-size: 16px; font-weight: bold; margin-bottom: 10px;">${title}</div>
      <div style="margin-bottom: 8px;">
        <div style="margin-bottom: 4px;">Systolic</div>
        <div style="padding-left: 12px;">
          <div>Min: ${sysMin} ${measurementValueKey}</div>
          <div>Avg: ${sysAvg} ${measurementValueKey}</div>
          <div>Max: ${sysMax} ${measurementValueKey}</div>
        </div>
      </div>
      <div>
        <div style="margin-bottom: 4px;">Diastolic</div>
        <div style="padding-left: 12px;">
          <div>Min: ${diaMin} ${measurementValueKey}</div>
          <div>Avg: ${diaAvg} ${measurementValueKey}</div>
          <div>Max: ${diaMax} ${measurementValueKey}</div>
        </div>
      </div>
    `;
    // 计算Tooltip位置
    const position = this._chart.canvas.getBoundingClientRect();
    tooltipEl.style.opacity = 1;
    tooltipEl.style.left = position.left + window.pageXOffset + tooltipModel.caretX + 'px';
    tooltipEl.style.top = position.top + window.pageYOffset + tooltipModel.caretY + 'px';
    // 可以根据需要调整偏移,避免Tooltip超出视口
  },
  // 保留原来的触发模式配置
  mode: 'index',
  intersect: false,
}

2. 额外样式优化(可选)

如果需要和你预期效果完全对齐,可以自行调整tooltipEl的内联样式,比如字体大小、行高、色块标识等,如果需要展示对应颜色的标识,可以在每个指标前面加对应颜色的小圆点span元素即可。

3. 注意事项

  • 页面销毁时记得手动移除创建的Tooltip DOM元素,避免内存泄漏
  • 如果你的Chart是放在滚动容器内,需要额外计算滚动偏移量修正Tooltip位置
  • 数据判空逻辑可以根据你的实际业务场景补充,避免出现undefined渲染

内容的提问来源于stack exchange,提问作者Oğuzhan Yıldırım

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 01:36:00