MCPcopy Create free account
hub / github.com/AmazingAng/PolyWorld / ChartPanelInner

Function ChartPanelInner

src/components/ChartPanel.tsx:137–627  ·  view source on GitHub ↗
({ selectedMarket, lineOnly = false }: ChartPanelProps)

Source from the content-addressed store, hash-verified

135}
136
137function ChartPanelInner({ selectedMarket, lineOnly = false }: ChartPanelProps) {
138 const { t } = useI18n();
139 const [timeRange, setTimeRange] = useState<TimeRange>("24h");
140 const [chartMode, setChartMode] = useState<ChartMode>("candle");
141 const [showMA, setShowMA] = useState(true);
142 const [showMACD, setShowMACD] = useState(true);
143 const [loading, setLoading] = useState(false);
144 const [error, setError] = useState<string | null>(null);
145 const [crosshairData, setCrosshairData] = useState<CrosshairData | null>(null);
146 const [chartData, setChartData] = useState<ChartData | null>(null);
147 const [useUTC, setUseUTC] = useState(true);
148 const retryCount = useRef(0);
149
150 const chartContainerRef = useRef<HTMLDivElement>(null);
151 const macdContainerRef = useRef<HTMLDivElement>(null);
152 const chartInstanceRef = useRef<ReturnType<typeof import("lightweight-charts").createChart> | null>(null);
153 const macdChartRef = useRef<ReturnType<typeof import("lightweight-charts").createChart> | null>(null);
154
155 const isMulti = useMemo(() => {
156 if (!selectedMarket) return false;
157 return selectedMarket.markets.filter(m => m.active !== false).length > 1;
158 }, [selectedMarket]);
159
160 const effectiveMode = lineOnly ? "line" : (isMulti && chartMode === "candle" ? "line" : chartMode);
161
162 // ────────────────────────────────────────────────────────
163 // Step 1: FETCH DATA — only when market or timeRange changes
164 // ────────────────────────────────────────────────────────
165 useEffect(() => {
166 if (!selectedMarket) { setChartData(null); return; }
167
168 const cacheKey = `${selectedMarket.id}:${timeRange}`;
169 // Already have this data cached?
170 if (chartData?.key === cacheKey) return;
171
172 let cancelled = false;
173 setLoading(true);
174
175 const hours = TIME_HOURS[timeRange];
176 const baseUrl = `/api/snapshots?eventId=${encodeURIComponent(selectedMarket.id)}&hours=${hours}`;
177 const bucketMs = BUCKET_MS[timeRange];
178
179 (async () => {
180 try {
181 if (isMulti) {
182 const res = await fetch(`${baseUrl}&perMarket=1`);
183 const result = await res.json();
184 const seriesList: SeriesData[] = (result?.series || []).filter((s: SeriesData) => s.data.length >= 2);
185 const sorted = [...seriesList].sort((a, b) => {
186 const aLast = a.data[a.data.length - 1]?.prob ?? 0;
187 const bLast = b.data[b.data.length - 1]?.prob ?? 0;
188 return bLast - aLast;
189 });
190 const multi = sorted.map(s => ({
191 label: s.label,
192 points: dedupByTime(s.data.map(d => ({
193 time: Math.floor(new Date(d.recorded_at).getTime() / 1000),
194 value: d.prob,

Callers

nothing calls this directly

Calls 10

useI18nFunction · 0.90
dedupByTimeFunction · 0.85
getLightweightChartsFunction · 0.85
fmtTsFunction · 0.85
computeMAFunction · 0.85
computeMACDFunction · 0.85
fmtPctFunction · 0.85
fmtVolFunction · 0.85
getMethod · 0.45
setMethod · 0.45

Tested by

no test coverage detected