diff --git a/src/components/report/TrendLineChart/TrendLineChart.tsx b/src/components/report/TrendLineChart/TrendLineChart.tsx
index accf021..f92cd2a 100644
--- a/src/components/report/TrendLineChart/TrendLineChart.tsx
+++ b/src/components/report/TrendLineChart/TrendLineChart.tsx
@@ -38,18 +38,232 @@ function TrendLineChart({ data, title = '收支趋势', loading = false }: Trend
trigger: 'axis',
confine: true, // Keep tooltip inside chart area
backgroundColor: 'rgba(255, 255, 255, 0.8)',
- // ... (keep existing properties) ...
+ borderColor: '#e2e8f0',
+ borderWidth: 1,
+ textStyle: {
+ color: '#1e293b',
+ },
+ extraCssText: 'backdrop-filter: blur(8px); border-radius: 8px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);',
+ axisPointer: {
+ type: 'cross',
+ label: {
+ backgroundColor: '#6a7985',
+ },
+ },
+ formatter: (params: any) => {
+ let result = `
${params[0].axisValue}
`;
+
+ let income = 0;
+ let expense = 0;
+
+ params.forEach((param: any) => {
+ const color = param.color;
+ const value = param.value;
+ if (param.seriesName === '收入') income = value;
+ if (param.seriesName === '支出') expense = value;
+
+ result += `
+
+
+ ${param.seriesName}
+
+ ¥${value.toLocaleString('zh-CN', {
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 2,
+ })}
+
`;
+ });
+
+ const net = income - expense;
+ const isSurplus = net >= 0;
+ const netColor = isSurplus ? '#10b981' : '#ef4444';
+ const netLabel = isSurplus ? '结余' : '赤字';
+
+ result += `
+ 本日${netLabel}
+
+ ${isSurplus ? '+' : ''}¥${net.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
+
+
`;
+
+ return result;
+ },
},
- // ...
- return(
-
-
-
+ dataZoom: [
+ {
+ type: 'slider',
+ show: true,
+ xAxisIndex: [0],
+ start: 0,
+ end: 100,
+ bottom: 0,
+ borderColor: 'transparent',
+ fillerColor: 'rgba(99, 102, 241, 0.1)',
+ handleStyle: {
+ color: '#6366f1',
+ },
+ },
+ {
+ type: 'inside',
+ xAxisIndex: [0],
+ start: 0,
+ end: 100,
+ },
+ ],
+ legend: {
+ data: ['收入', '支出', '结余'],
+ top: 40,
+ left: 'center',
+ },
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ top: 80,
+ containLabel: true,
+ },
+ xAxis: {
+ type: 'category',
+ boundaryGap: false,
+ data: data.map((item) => formatDate(item.date)),
+ axisLabel: {
+ rotate: 45,
+ fontSize: 11,
+ },
+ },
+ yAxis: {
+ type: 'value',
+ axisLabel: {
+ formatter: (value: number) => {
+ if (value >= 10000) {
+ return `${(value / 10000).toFixed(1)}万`;
+ }
+ return value.toFixed(0);
+ },
+ },
+ },
+ series: [
+ {
+ name: '收入',
+ type: 'line',
+ smooth: true,
+ data: data.map((item) => item.income),
+ itemStyle: {
+ color: '#10b981',
+ },
+ areaStyle: {
+ color: {
+ type: 'linear',
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ colorStops: [
+ { offset: 0, color: 'rgba(16, 185, 129, 0.3)' },
+ { offset: 1, color: 'rgba(16, 185, 129, 0.05)' },
+ ],
+ },
+ },
+ },
+ {
+ name: '支出',
+ type: 'line',
+ smooth: true,
+ data: data.map((item) => item.expense),
+ itemStyle: {
+ color: '#ef4444',
+ },
+ areaStyle: {
+ color: {
+ type: 'linear',
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ colorStops: [
+ { offset: 0, color: 'rgba(239, 68, 68, 0.3)' },
+ { offset: 1, color: 'rgba(239, 68, 68, 0.05)' },
+ ],
+ },
+ },
+ markPoint: {
+ data: [
+ { type: 'max', name: '最大支出' },
+ ],
+ symbol: 'pin',
+ symbolSize: 45,
+ itemStyle: {
+ color: '#ef4444'
+ },
+ label: {
+ color: '#fff',
+ fontSize: 10,
+ formatter: 'Max'
+ }
+ },
+ },
+ {
+ name: '结余',
+ type: 'line',
+ smooth: true,
+ showSymbol: false,
+ data: data.map((item) => item.balance),
+ itemStyle: {
+ color: '#3b82f6',
+ },
+ lineStyle: {
+ width: 2,
+ type: 'dashed',
+ },
+ markPoint: {
+ data: [
+ { type: 'max', name: 'Max' },
+ { type: 'min', name: 'Min' },
+ ],
+ symbol: 'pin',
+ symbolSize: 40,
+ label: {
+ color: '#fff',
+ fontSize: 10,
+ formatter: '{c}'
+ }
+ },
+ markLine: {
+ data: [{ type: 'average', name: 'Avg' }],
+ precision: 0,
+ label: {
+ formatter: '均值: {c}'
+ }
+ },
+ },
+ ],
+ };
+
+ if (loading) {
+ return (
+
+ );
+ }
+
+ if (!data || data.length === 0) {
+ return (
+
+ );
+ }
+
+ return (
+
+
+
);
}