astock-agent/frontend/src/components/capital-flow.tsx
2026-04-11 08:24:50 +08:00

87 lines
2.6 KiB
TypeScript

"use client";
import { useEffect, useRef } from "react";
import { useTheme } from "next-themes";
interface FlowData {
trade_date: string;
main_net_inflow: number;
net_mf_amount: number;
}
export default function CapitalFlowChart({ data }: { data: FlowData[] }) {
const chartRef = useRef<HTMLDivElement>(null);
const { theme } = useTheme();
useEffect(() => {
if (!chartRef.current || !data.length) return;
let chart: ReturnType<typeof import("echarts")["init"]> | null = null;
import("echarts").then((ec) => {
if (!chartRef.current) return;
const isDark = theme !== "light";
chart = ec.init(chartRef.current, isDark ? "dark" : undefined);
const isLight = theme === "light";
const axisLineColor = isLight ? "#d1d5db" : "#475569";
const axisLabelColor = isLight ? "#6b7280" : "#94a3b8";
const splitLineColor = isLight ? "#f3f4f6" : "#1e293b";
const dates = data.map((d) => d.trade_date);
const values = data.map((d) => d.main_net_inflow);
chart.setOption({
backgroundColor: "transparent",
tooltip: {
trigger: "axis",
formatter: (params: { name: string; value: number }[]) => {
const p = params[0];
return `${p.name}<br/>主力净流入: ${p.value.toFixed(0)}`;
},
},
grid: { left: "12%", right: "5%", top: "10%", bottom: "15%" },
xAxis: {
type: "category",
data: dates,
axisLine: { lineStyle: { color: axisLineColor } },
axisLabel: { fontSize: 10, color: axisLabelColor, rotate: 30 },
},
yAxis: {
type: "value",
splitLine: { lineStyle: { color: splitLineColor } },
axisLabel: {
fontSize: 10,
color: axisLabelColor,
formatter: (v: number) => (Math.abs(v) >= 10000 ? (v / 10000).toFixed(1) + "亿" : v + "万"),
},
},
series: [
{
type: "bar",
data: values.map((v) => ({
value: v,
itemStyle: { color: v > 0 ? "#ef4444" : "#22c55e" },
})),
},
],
});
const handleResize = () => chart?.resize();
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
});
return () => {
chart?.dispose();
};
}, [data, theme]);
return (
<div className="bg-bg-card rounded-xl p-4">
<h2 className="text-sm font-medium text-text-secondary mb-2"></h2>
<div ref={chartRef} className="w-full h-48" />
</div>
);
}