fix: add missing FundingChart component
This commit is contained in:
parent
44e07eabb2
commit
be64df99a2
95
frontend/components/FundingChart.tsx
Normal file
95
frontend/components/FundingChart.tsx
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { HistoryResponse } from "@/lib/api";
|
||||||
|
import {
|
||||||
|
LineChart,
|
||||||
|
Line,
|
||||||
|
XAxis,
|
||||||
|
YAxis,
|
||||||
|
Tooltip,
|
||||||
|
Legend,
|
||||||
|
ResponsiveContainer,
|
||||||
|
ReferenceLine,
|
||||||
|
} from "recharts";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
history: HistoryResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function FundingChart({ history }: Props) {
|
||||||
|
// 合并BTC和ETH数据,按时间对齐
|
||||||
|
const btcMap = new Map(
|
||||||
|
history.BTC.map((p) => [p.timestamp.slice(0, 13), p.fundingRate * 100])
|
||||||
|
);
|
||||||
|
const ethMap = new Map(
|
||||||
|
history.ETH.map((p) => [p.timestamp.slice(0, 13), p.fundingRate * 100])
|
||||||
|
);
|
||||||
|
|
||||||
|
const allTimes = Array.from(
|
||||||
|
new Set([...btcMap.keys(), ...ethMap.keys()])
|
||||||
|
).sort();
|
||||||
|
|
||||||
|
const data = allTimes.map((t) => ({
|
||||||
|
time: t.slice(5).replace("T", " "), // "02-26 12"
|
||||||
|
BTC: btcMap.get(t) ?? null,
|
||||||
|
ETH: ethMap.get(t) ?? null,
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 只显示最近 42 条(7天×6次/天)
|
||||||
|
const displayData = data.slice(-42);
|
||||||
|
|
||||||
|
const CustomTooltip = ({ active, payload, label }: any) => {
|
||||||
|
if (!active || !payload?.length) return null;
|
||||||
|
return (
|
||||||
|
<div className="bg-slate-800 border border-slate-600 rounded-lg p-3 text-xs">
|
||||||
|
<p className="text-slate-400 mb-2">{label}</p>
|
||||||
|
{payload.map((p: any) => (
|
||||||
|
<p key={p.dataKey} style={{ color: p.color }}>
|
||||||
|
{p.dataKey}: {p.value !== null ? `${p.value.toFixed(4)}%` : "--"}
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ResponsiveContainer width="100%" height={240}>
|
||||||
|
<LineChart data={displayData} margin={{ top: 4, right: 8, bottom: 4, left: 8 }}>
|
||||||
|
<XAxis
|
||||||
|
dataKey="time"
|
||||||
|
tick={{ fill: "#64748b", fontSize: 10 }}
|
||||||
|
tickLine={false}
|
||||||
|
interval="preserveStartEnd"
|
||||||
|
/>
|
||||||
|
<YAxis
|
||||||
|
tick={{ fill: "#64748b", fontSize: 10 }}
|
||||||
|
tickLine={false}
|
||||||
|
axisLine={false}
|
||||||
|
tickFormatter={(v) => `${v.toFixed(3)}%`}
|
||||||
|
width={60}
|
||||||
|
/>
|
||||||
|
<Tooltip content={<CustomTooltip />} />
|
||||||
|
<Legend
|
||||||
|
wrapperStyle={{ fontSize: 12, color: "#94a3b8" }}
|
||||||
|
/>
|
||||||
|
<ReferenceLine y={0} stroke="#475569" strokeDasharray="4 2" />
|
||||||
|
<Line
|
||||||
|
type="monotone"
|
||||||
|
dataKey="BTC"
|
||||||
|
stroke="#06b6d4"
|
||||||
|
strokeWidth={1.5}
|
||||||
|
dot={false}
|
||||||
|
connectNulls
|
||||||
|
/>
|
||||||
|
<Line
|
||||||
|
type="monotone"
|
||||||
|
dataKey="ETH"
|
||||||
|
stroke="#8b5cf6"
|
||||||
|
strokeWidth={1.5}
|
||||||
|
dot={false}
|
||||||
|
connectNulls
|
||||||
|
/>
|
||||||
|
</LineChart>
|
||||||
|
</ResponsiveContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user