如何使用useState在Chart.js中实现图表日期筛选功能?
问题:Chart.js图表日期筛选联动失效解决方法
问题根源
- 状态隔离:
ButtonDate组件的日期状态仅在内部维护,父组件LineChart无法获取筛选条件,无法联动图表数据 - 日期格式错误:HTML5
date类型输入框要求值为ISO格式(YYYY-MM-DD),原代码中的"9/1/23"格式不合法,导致初始值无法正确渲染 - 状态设计缺陷:单个
dateSelect状态无法同时存储开始/结束两个筛选日期 - 静态数据未过滤:图表数据直接使用原始JSON数据,未根据筛选条件动态生成
修复方案与代码实现
1. 父组件 LineChart.js 修改
将日期筛选状态提升到父组件,实现数据过滤逻辑,并将状态和回调传递给子组件:
/// LineChart.js import React, { useState } from 'react'; import { Line } from 'react-chartjs-2'; import './chartStyle.css'; import JSONdata from "../json-csv/csvjson.json"; import ButtonDate from '../Button/Buttonsdate'; import { Chart as ChartJS, LineElement, PointElement, CategoryScale, LinearScale, Tooltip, Legend, Colors } from 'chart.js'; ChartJS.register( LineElement, PointElement, CategoryScale, LinearScale, Tooltip, Legend, Colors ); const LineChart = () => { ChartJS.defaults.backgroundColor = '#d90731'; ChartJS.defaults.borderColor = '#000'; ChartJS.defaults.color = '#000'; // 初始化筛选日期(使用ISO格式) const [filterDates, setFilterDates] = useState({ startDate: '2023-09-01', endDate: '2023-09-12' }); // 接收子组件传递的日期更新 const handleDateChange = (type, value) => { setFilterDates(prev => ({ ...prev, [type]: value })); }; // 根据筛选日期过滤数据 const filteredData = JSONdata.filter(row => { const rowDate = new Date(row.Date); const startDate = new Date(filterDates.startDate); const endDate = new Date(filterDates.endDate); return rowDate >= startDate && rowDate <= endDate; }); // 生成动态图表数据 const labels = filteredData.map(row => row.Date); const datapoints = filteredData.map(row => row.PUSCH); const chartData = { labels: labels, datasets: [{ label: 'PUSCH', data: datapoints, borderColor: '#0975ab', tension: 0.1, backgroundColor: '#0975ab', borderWidth: 2.8, }], }; const options = { scales: { x: { grid: { color: 'gray', borderColor: 'blue', backgroundColor: 'white' } }, y: { grid: { color: 'gray', borderColor: 'blue' } } } }; return ( <div className='chartLinestyle'> <Line data={chartData} options={options} /> {/* 将状态和回调传递给子组件 */} <ButtonDate filterDates={filterDates} onDateChange={handleDateChange} /> </div> ); }; export default LineChart;
2. 子组件 ButtonsDate.js 修改
移除内部状态,通过props接收父组件的日期值和更新回调:
// ButtonsDate.js import React from 'react'; const ButtonDate = ({ filterDates, onDateChange }) => { return ( <div> <input type='date' id='startDate' value={filterDates.startDate} onChange={(e) => onDateChange('startDate', e.target.value)} /> <input type='date' id='enddate' value={filterDates.endDate} onChange={(e) => onDateChange('endDate', e.target.value)} /> </div> ); }; export default ButtonDate;
关键说明
- 状态提升:通过将筛选状态移到父组件,实现了组件间的数据共享,确保图表能响应日期变化
- 格式修正:使用ISO标准日期格式保证输入框初始值和选中值的合法性
- 动态过滤:每次日期变化时重新过滤原始数据,生成符合条件的图表数据,触发Chart.js重新渲染
- 单向数据流:子组件通过回调函数通知父组件更新状态,符合React的单向数据流设计原则
内容的提问来源于stack exchange,提问作者Shaberz
相关产品推荐
相关产品推荐

