From a7c276fe3c9dbddc1c13aa2ac62bba6b076ae3cc Mon Sep 17 00:00:00 2001 From: tinkle-community Date: Wed, 29 Oct 2025 21:42:34 +0800 Subject: [PATCH] Fix: Support dynamic number of traders in ComparisonChart Previously, ComparisonChart was hardcoded to only fetch equity history data for the first 2 traders, causing the 3rd and subsequent traders' data to not be displayed on the chart. Changes: - Replaced multiple individual useSWR calls with single consolidated call - Use Promise.all() to fetch all traders' equity data concurrently - Generate dynamic cache key based on all trader IDs - Maintain backward compatibility with existing component structure - Update useMemo dependencies to properly track data changes This fix allows the comparison chart to properly display any number of competing traders, not just 2. Co-Authored-By: tinkle-community --- web/src/components/ComparisonChart.tsx | 45 ++++++++++++++------------ 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/web/src/components/ComparisonChart.tsx b/web/src/components/ComparisonChart.tsx index 3c0b5999..4f489458 100644 --- a/web/src/components/ComparisonChart.tsx +++ b/web/src/components/ComparisonChart.tsx @@ -19,24 +19,32 @@ interface ComparisonChartProps { } export function ComparisonChart({ traders }: ComparisonChartProps) { - // 获取所有trader的历史数据 - 修复: 使用固定数量的Hook调用 - // 始终调用最多2个trader的useSWR,即使实际trader数量不同 - const trader1 = traders[0]; - const trader2 = traders[1]; + // 获取所有trader的历史数据 - 使用单个useSWR并发请求所有trader数据 + // 生成唯一的key,当traders变化时会触发重新请求 + const tradersKey = traders.map(t => t.trader_id).sort().join(','); - const history1 = useSWR( - trader1 ? `equity-history-${trader1.trader_id}` : null, - trader1 ? () => api.getEquityHistory(trader1.trader_id) : null, - { refreshInterval: 10000 } + const { data: allTraderHistories, isLoading } = useSWR( + traders.length > 0 ? `all-equity-histories-${tradersKey}` : null, + async () => { + // 并发请求所有trader的历史数据 + const promises = traders.map(trader => + api.getEquityHistory(trader.trader_id) + ); + return Promise.all(promises); + }, + { + refreshInterval: 10000, + revalidateOnFocus: false, + } ); - const history2 = useSWR( - trader2 ? `equity-history-${trader2.trader_id}` : null, - trader2 ? () => api.getEquityHistory(trader2.trader_id) : null, - { refreshInterval: 10000 } - ); - - const traderHistories = [history1, history2].slice(0, traders.length); + // 将数据转换为与原格式兼容的结构 + const traderHistories = useMemo(() => { + if (!allTraderHistories) { + return traders.map(() => ({ data: undefined })); + } + return allTraderHistories.map(data => ({ data })); + }, [allTraderHistories, traders.length]); // 使用useMemo自动处理数据合并,直接使用data对象作为依赖 const combinedData = useMemo(() => { @@ -115,12 +123,7 @@ export function ComparisonChart({ traders }: ComparisonChartProps) { } return combined; - }, [ - traderHistories[0]?.data, - traderHistories[1]?.data, - ]); - - const isLoading = traderHistories.some((h) => !h.data); + }, [allTraderHistories, traders]); if (isLoading) { return (