feat: dual-axis Delta+price chart, show vwap price overlay on delta chart

This commit is contained in:
root 2026-02-27 14:08:45 +00:00
parent f27fdca6ac
commit 4a6232ed05

View File

@ -5,7 +5,7 @@ import { authFetch } from "@/lib/auth";
import { useAuth } from "@/lib/auth";
import Link from "next/link";
import {
AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer, ReferenceLine, CartesianGrid
ComposedChart, Area, Line, XAxis, YAxis, Tooltip, ResponsiveContainer, ReferenceLine, CartesianGrid, Legend
} from "recharts";
// ─── Types ───────────────────────────────────────────────────────
@ -253,44 +253,55 @@ function FlowAnalysis({ symbol }: { symbol: Symbol }) {
</div>
</div>
{/* Delta折线图 */}
{/* Delta + 价格双Y轴图 */}
<div>
<p className="text-xs text-slate-500 mb-2 font-medium"> Delta==</p>
<ResponsiveContainer width="100%" height={160}>
<AreaChart data={chartData} margin={{ top: 4, right: 8, bottom: 0, left: 8 }}>
<p className="text-xs text-slate-500 mb-2 font-medium"> Delta==+ </p>
<ResponsiveContainer width="100%" height={200}>
<ComposedChart data={chartData} margin={{ top: 4, right: 60, bottom: 0, left: 8 }}>
<CartesianGrid strokeDasharray="3 3" stroke="#f1f5f9" />
<XAxis dataKey="time" tick={{ fill: "#94a3b8", fontSize: 10 }} tickLine={false} interval="preserveStartEnd" />
<YAxis tick={{ fill: "#94a3b8", fontSize: 10 }} tickLine={false} axisLine={false} width={50} />
{/* 左轴Delta */}
<YAxis yAxisId="delta" tick={{ fill: "#94a3b8", fontSize: 10 }} tickLine={false} axisLine={false} width={55} />
{/* 右轴:价格 */}
<YAxis yAxisId="price" orientation="right" tick={{ fill: "#f59e0b", fontSize: 10 }} tickLine={false} axisLine={false} width={65}
tickFormatter={(v: number) => v >= 1000 ? `$${(v/1000).toFixed(1)}k` : `$${v.toFixed(0)}`}
/>
<Tooltip
// eslint-disable-next-line @typescript-eslint/no-explicit-any
formatter={(v: any) => [`${Number(v).toFixed(2)}`, "Delta"]}
formatter={(v: any, name: any) => {
if (name === "price") return [`$${Number(v).toLocaleString("en-US", { minimumFractionDigits: 1, maximumFractionDigits: 1 })}`, "币价(VWAP)"];
return [`${Number(v).toFixed(2)}`, "Delta"];
}}
contentStyle={{ background: "#fff", border: "1px solid #e2e8f0", borderRadius: 8, fontSize: 11 }}
/>
<ReferenceLine y={0} stroke="#94a3b8" strokeDasharray="4 2" />
<Area type="monotone" dataKey="delta"
stroke="#2563eb" fill="#eff6ff" strokeWidth={1.5}
dot={false} connectNulls
<Legend wrapperStyle={{ fontSize: 11 }} />
<ReferenceLine yAxisId="delta" y={0} stroke="#94a3b8" strokeDasharray="4 2" />
<Area yAxisId="delta" type="monotone" dataKey="delta" name="Delta"
stroke="#2563eb" fill="#eff6ff" strokeWidth={1.5} dot={false} connectNulls
/>
</AreaChart>
<Line yAxisId="price" type="monotone" dataKey="vwap" name="price"
stroke="#f59e0b" strokeWidth={1.5} dot={false} connectNulls strokeDasharray="4 2"
/>
</ComposedChart>
</ResponsiveContainer>
</div>
{/* 买卖量柱状图 */}
{/* 买卖量图 */}
<div>
<p className="text-xs text-slate-500 mb-2 font-medium"> vs </p>
<ResponsiveContainer width="100%" height={160}>
<AreaChart data={chartData} margin={{ top: 4, right: 8, bottom: 0, left: 8 }}>
<ComposedChart data={chartData} margin={{ top: 4, right: 8, bottom: 0, left: 8 }}>
<CartesianGrid strokeDasharray="3 3" stroke="#f1f5f9" />
<XAxis dataKey="time" tick={{ fill: "#94a3b8", fontSize: 10 }} tickLine={false} interval="preserveStartEnd" />
<YAxis tick={{ fill: "#94a3b8", fontSize: 10 }} tickLine={false} axisLine={false} width={50} />
<YAxis yAxisId="vol" tick={{ fill: "#94a3b8", fontSize: 10 }} tickLine={false} axisLine={false} width={50} />
<Tooltip
// eslint-disable-next-line @typescript-eslint/no-explicit-any
formatter={(v: any, name: any) => [`${Number(v).toFixed(2)}`, name === "buy" ? "主动买" : "主动卖"]}
contentStyle={{ background: "#fff", border: "1px solid #e2e8f0", borderRadius: 8, fontSize: 11 }}
/>
<Area type="monotone" dataKey="buy" stroke="#16a34a" fill="#f0fdf4" strokeWidth={1.5} dot={false} connectNulls />
<Area type="monotone" dataKey="sell" stroke="#dc2626" fill="#fef2f2" strokeWidth={1.5} dot={false} connectNulls />
</AreaChart>
<Area yAxisId="vol" type="monotone" dataKey="buy" name="buy" stroke="#16a34a" fill="#f0fdf4" strokeWidth={1.5} dot={false} connectNulls />
<Area yAxisId="vol" type="monotone" dataKey="sell" name="sell" stroke="#dc2626" fill="#fef2f2" strokeWidth={1.5} dot={false} connectNulls />
</ComposedChart>
</ResponsiveContainer>
</div>