import React, { useMemo } from 'react'; import ReactECharts from 'echarts-for-react'; import type { Transaction } from '../../types'; import { formatCurrency } from '../../utils/format'; interface SpendingTrendChartProps { transactions: Transaction[]; days?: number; } export const SpendingTrendChart: React.FC = ({ transactions, days = 7 }) => { // Process data for the chart const chartData = useMemo(() => { const today = new Date(); const data: { date: string; amount: number; fullDate: string }[] = []; for (let i = days - 1; i >= 0; i--) { const d = new Date(today); d.setDate(d.getDate() - i); const dateStr = d.toISOString().split('T')[0]; const displayDate = `${d.getMonth() + 1}/${d.getDate()}`; const dailyTotal = transactions .filter(t => t.type === 'expense' && t.transactionDate.startsWith(dateStr)) .reduce((sum, t) => sum + Math.abs(t.amount), 0); data.push({ date: displayDate, amount: dailyTotal, fullDate: dateStr }); } return data; }, [transactions, days]); const option = { tooltip: { trigger: 'axis', backgroundColor: 'rgba(255, 255, 255, 0.9)', borderColor: '#e2e8f0', textStyle: { color: '#1e293b' }, formatter: (params: any) => { const item = params[0]; return `${item.name}
支出: ${formatCurrency(item.value, 'CNY')}`; } }, grid: { left: '3%', right: '4%', bottom: '3%', top: '10%', containLabel: true }, xAxis: { type: 'category', data: chartData.map(d => d.date), axisLine: { lineStyle: { color: '#94a3b8' } }, axisTick: { show: false } }, yAxis: { type: 'value', splitLine: { lineStyle: { color: '#f1f5f9', type: 'dashed' } }, axisLabel: { color: '#94a3b8', formatter: (value: number) => { if (value >= 1000) return `${(value / 1000).toFixed(1)}k`; return value; } } }, series: [ { data: chartData.map(d => d.amount), type: 'bar', // Changed to bar for cleaner daily comparison, or line for trend smooth: true, name: '支出', itemStyle: { color: { type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: '#f59e0b' }, // Amber 500 { offset: 1, color: '#d97706' } // Amber 600 ] }, borderRadius: [4, 4, 0, 0] }, showBackground: true, backgroundStyle: { color: 'rgba(241, 245, 249, 0.5)' }, animationDuration: 1000, animationEasing: 'cubicOut' } ] }; return (

近7日支出趋势

); };