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

React+Chart.js 4.3.0图表配置项不生效及类型错误问题求助

React + TypeScript + Chart.js 柱状图问题解决指南

问题概述

在React 18.2.0 + TypeScript 4.9.3环境下,使用Chart.js 4.3.0和react-chartjs-2 5.2.0开发柱状图时遇到以下问题:

  • 坐标轴文字颜色、日期格式配置未生效,图表无视options设置
  • 安装chartjs-adapter-date-fns 3.0.0后出现类型声明缺失错误,且无对应@types包
  • 传递options给<Bar>组件时触发TypeScript类型不匹配
  • 删除代码顶部的console.warn(ChartJS)会触发Canvas复用错误:Canvas is already in use. Chart with ID '0' must be destroyed before the canvas with ID '' can be reused.
  • React严格模式下原生JS处理日期会出现无效日期,改用date-fns后仍有上述问题

需求目标:

  • 将坐标轴刻度文字改为白色
  • X轴日期显示为03:00格式

原代码

数据定义

const DetailsData: {
  time: string;
  loadPower: string;
}[] = [
  {
    time: '2023-01-18T02:00:00Z',
    loadPower: '2.6',
  },
  {
    time: '2023-01-18T02:15:00Z',
    loadPower: '2.4',
  },
  {
    time: '2023-01-18T02:30:00Z',
    loadPower: '2.3',
  },
]

组件代码

import 'chartjs-adapter-date-fns';
import { Chart as ChartJS } from 'chart.js/auto';
import { Bar } from 'react-chartjs-2';
import DetailsData from './Data';

// Keep warn to avoid error "Canvas is already in use. Chart with ID '0' must be destroyed before the canvas with ID '' can be reused.""
// eslint-disable-next-line no-console
console.warn(ChartJS);

function PowerChart() {
  const barData = {
    labels: DetailsData.map((data) => data.time),
    datasets: [
      {
        label: 'Load Power in KwH',
        data: DetailsData.map((data) => data.loadPower),
        backgroundColor: '#00aae1',
        borderColor: '#00aae1',
        borderWidth: 1,
        color: '#ffffff',
        font: 'Arial, "Helvetica Neue", Helvetica, sans-serif !default;',
      },
    ],
  };
  const barOptions = {
    options: {
      plugins: {
        scales: {
          x: {
            ticks: {
              color: '#ffffff',
            },
          },
          y: {
            type: 'time',
            time: {
              unit: 'hour',
            },
            ticks: {
              color: 'white',
            },
          },
        },
      },
    },
  };

  return (
    <div className="chartBox">
      <Bar
        options={barOptions}
        data={barData}
      />
    </div>
  );
}

export default PowerChart;

解决方案

1. 修复Options嵌套错误(核心问题)

原代码中barOptions多嵌套了一层options对象,导致Chart.js无法读取配置。直接将配置项作为barOptions的顶层属性即可。

2. 正确配置时间坐标轴

  • X轴应设置为time类型(原代码错误地将Y轴设为time)
  • 使用time.displayFormats指定日期格式为HH:mm(对应03:00)
  • 确保坐标轴刻度颜色配置在scales下的对应轴中,而非plugins内(原代码位置错误)

3. 解决类型声明缺失问题

由于chartjs-adapter-date-fns无官方@types包,可在项目根目录创建src/types/chartjs-adapter-date-fns.d.ts文件,添加以下声明:

declare module 'chartjs-adapter-date-fns';

4. 修复Canvas复用错误

移除console.warn(ChartJS),改用useRef和useEffect手动管理图表实例的销毁,避免严格模式下双渲染导致的冲突:

const chartRef = useRef<ChartJS | null>(null);

useEffect(() => {
  return () => {
    if (chartRef.current) {
      chartRef.current.destroy();
    }
  };
}, []);

5. 修复TypeScript类型不匹配

导入Chart.js的BarOptions类型,明确标注barOptions的类型,确保配置符合规范。

修改后的完整组件代码

import 'chartjs-adapter-date-fns';
import { Chart as ChartJS, BarOptions } from 'chart.js/auto';
import { Bar } from 'react-chartjs-2';
import { useRef, useEffect } from 'react';
import DetailsData from './Data';

function PowerChart() {
  const chartRef = useRef<ChartJS | null>(null);

  // 清理图表实例,避免Canvas复用错误
  useEffect(() => {
    return () => {
      if (chartRef.current) {
        chartRef.current.destroy();
      }
    };
  }, []);

  const barData = {
    labels: DetailsData.map((data) => new Date(data.time)), // 转换为Date对象,确保时间轴正确解析
    datasets: [
      {
        label: 'Load Power in KwH',
        data: DetailsData.map((data) => parseFloat(data.loadPower)), // 转换为数值类型
        backgroundColor: '#00aae1',
        borderColor: '#00aae1',
        borderWidth: 1,
      },
    ],
  };

  const barOptions: BarOptions = {
    scales: {
      x: {
        type: 'time',
        time: {
          unit: 'minute', // 匹配数据的15分钟粒度
          displayFormats: {
            minute: 'HH:mm', // 指定显示格式为小时:分钟
          },
        },
        ticks: {
          color: '#ffffff', // X轴刻度文字颜色
        },
        grid: {
          color: 'rgba(255,255,255,0.1)', // 可选:调整网格线透明度
        },
      },
      y: {
        ticks: {
          color: '#ffffff', // Y轴刻度文字颜色
        },
        grid: {
          color: 'rgba(255,255,255,0.1)',
        },
      },
    },
    plugins: {
      legend: {
        labels: {
          color: '#ffffff', // 图例文字颜色
        },
      },
    },
  };

  return (
    <div className="chartBox">
      <Bar ref={chartRef} options={barOptions} data={barData} />
    </div>
  );
}

export default PowerChart;

关键修改说明

  • 将labels转换为Date对象,而非字符串,确保时间轴正确解析
  • 将loadPower转换为数值类型,Chart.js需要数值而非字符串来渲染柱状图
  • 调整scales配置结构,将时间轴放在X轴,数值轴放在Y轴
  • 添加displayFormats指定日期显示格式为HH:mm
  • 通过useRef和useEffect在组件卸载时销毁图表,解决Canvas复用问题
  • 明确标注barOptions的类型为BarOptions,解决TypeScript类型错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:32:51