cosmo/docs/火箭发送模拟/src/components/DashboardChart.tsx

104 lines
2.8 KiB
TypeScript

import {
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
} from "recharts";
import { DataPoint } from "../types";
interface ChartProps {
data: DataPoint[];
dataKey: keyof DataPoint;
color: string;
unit: string;
title: string;
}
export function DashboardChart({
data,
dataKey,
color,
unit,
title,
}: ChartProps) {
// Simple formatter for Y Axis
const formatYAxis = (tickItem: number) => {
if (tickItem > 1000) {
return `${(tickItem / 1000).toFixed(1)}k`;
}
return tickItem.toFixed(0);
};
return (
<div className="flex flex-col bg-black/40 backdrop-blur-md border border-white/10 rounded-2xl p-5 w-full h-full shadow-2xl">
<h3 className="text-white/70 text-[11px] font-bold tracking-widest uppercase mb-4 drop-shadow-sm">
{title}
</h3>
<div className="flex-grow min-h-0">
<ResponsiveContainer width="100%" height="100%">
<LineChart
data={data}
margin={{ top: 5, right: 5, left: -20, bottom: 0 }}
>
<CartesianGrid
strokeDasharray="3 3"
stroke="rgba(255,255,255,0.1)"
vertical={false}
/>
<XAxis
dataKey="time"
type="number"
domain={["dataMin", "dataMax"]}
tickFormatter={(t) => `${t.toFixed(0)}s`}
stroke="rgba(255,255,255,0.4)"
fontSize={10}
tickMargin={8}
tickLine={false}
axisLine={false}
/>
<YAxis
tickFormatter={formatYAxis}
stroke="rgba(255,255,255,0.4)"
fontSize={10}
width={45}
tickLine={false}
axisLine={false}
/>
<Tooltip
contentStyle={{
backgroundColor: "rgba(0,0,0,0.8)",
borderColor: "rgba(255,255,255,0.15)",
borderRadius: "12px",
backdropFilter: "blur(8px)",
}}
itemStyle={{ color: color, fontSize: "12px", fontWeight: "bold" }}
labelStyle={{
color: "rgba(255,255,255,0.6)",
marginBottom: "4px",
fontSize: "10px",
textTransform: "uppercase",
}}
formatter={(value: number) => [
`${value.toFixed(1)} ${unit}`,
title,
]}
labelFormatter={(label: number) => `T+ ${label.toFixed(1)}s`}
/>
<Line
type="monotone"
dataKey={dataKey}
stroke={color}
strokeWidth={2.5}
dot={false}
isAnimationActive={false}
/>
</LineChart>
</ResponsiveContainer>
</div>
</div>
);
}