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-fns3.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
相关产品推荐
相关产品推荐

