102 lines
3.8 KiB
TypeScript
102 lines
3.8 KiB
TypeScript
import {
|
|
Bar,
|
|
BarChart,
|
|
Cell,
|
|
Legend,
|
|
ResponsiveContainer,
|
|
Tooltip,
|
|
XAxis,
|
|
YAxis,
|
|
} from 'recharts';
|
|
import type { HydrogenMonthlyPoint } from '../../types';
|
|
import { formatYuan as fmtYuan } from '../model';
|
|
|
|
type MonthlyChartPoint = HydrogenMonthlyPoint & { monthLabel: string };
|
|
|
|
interface MonthlyChartsProps {
|
|
activeYear: number;
|
|
monthly: HydrogenMonthlyPoint[];
|
|
monthlyDual: MonthlyChartPoint[];
|
|
}
|
|
|
|
export function MonthlyCharts({ activeYear, monthly, monthlyDual }: MonthlyChartsProps) {
|
|
return (
|
|
<>
|
|
{monthly.length > 0 && (
|
|
<div className="bg-white rounded-2xl border border-slate-100 shadow-sm p-3 md:p-4">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<span className="text-sm font-bold text-slate-700">{activeYear} 年月度加氢量</span>
|
|
<span className="text-[11px] text-slate-400 font-bold">单位 Kg</span>
|
|
</div>
|
|
<ResponsiveContainer width="100%" height={140}>
|
|
<BarChart data={monthlyDual} margin={{ top: 8, right: 4, bottom: 0, left: 0 }}>
|
|
<XAxis
|
|
dataKey="monthLabel"
|
|
tick={{ fontSize: 10, fill: '#94a3b8' }}
|
|
tickLine={false}
|
|
axisLine={false}
|
|
interval={0}
|
|
/>
|
|
<YAxis hide />
|
|
<Tooltip
|
|
formatter={(v) => [`${Number(v ?? 0).toLocaleString('zh-CN', { maximumFractionDigits: 0 })} Kg`, '加氢量']}
|
|
labelFormatter={(d) => `${d}`}
|
|
contentStyle={{ borderRadius: 12, fontSize: 12 }}
|
|
cursor={{ fill: 'rgba(34, 211, 238, 0.06)' }}
|
|
/>
|
|
<Bar dataKey="kg" radius={[4, 4, 0, 0]}>
|
|
{monthlyDual.map((_, i) => (
|
|
<Cell key={i} fill="url(#monthlyBarGrad)" />
|
|
))}
|
|
</Bar>
|
|
<defs>
|
|
<linearGradient id="monthlyBarGrad" x1="0" x2="0" y1="0" y2="1">
|
|
<stop offset="0%" stopColor="#22d3ee" />
|
|
<stop offset="100%" stopColor="#3b82f6" />
|
|
</linearGradient>
|
|
</defs>
|
|
</BarChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
)}
|
|
|
|
{monthly.length > 0 && (
|
|
<div className="bg-white rounded-2xl border border-slate-100 shadow-sm p-3 md:p-4">
|
|
<div className="flex items-center justify-between mb-2">
|
|
<span className="text-sm font-bold text-slate-700">{activeYear} 年月度收支对比</span>
|
|
<span className="text-[11px] text-slate-400 font-bold">单位 元</span>
|
|
</div>
|
|
<ResponsiveContainer width="100%" height={180}>
|
|
<BarChart data={monthlyDual} margin={{ top: 8, right: 4, bottom: 0, left: 0 }}>
|
|
<XAxis
|
|
dataKey="monthLabel"
|
|
tick={{ fontSize: 10, fill: '#94a3b8' }}
|
|
tickLine={false}
|
|
axisLine={false}
|
|
interval={0}
|
|
/>
|
|
<YAxis hide />
|
|
<Legend
|
|
verticalAlign="top"
|
|
height={20}
|
|
iconSize={8}
|
|
wrapperStyle={{ fontSize: 11, paddingBottom: 4 }}
|
|
/>
|
|
<Tooltip
|
|
formatter={(v, name) => {
|
|
const f = fmtYuan(Number(v ?? 0));
|
|
return [`¥${f.value} ${f.unit}`, name];
|
|
}}
|
|
contentStyle={{ borderRadius: 12, fontSize: 12 }}
|
|
cursor={{ fill: 'rgba(148, 163, 184, 0.06)' }}
|
|
/>
|
|
<Bar dataKey="fee" name="成本支出" fill="#f59e0b" radius={[3, 3, 0, 0]} />
|
|
<Bar dataKey="revenue" name="客户收入" fill="#10b981" radius={[3, 3, 0, 0]} />
|
|
</BarChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|