diff --git a/frontend/src/components/ChartjsPlot.jsx b/frontend/src/components/ChartjsPlot.jsx index b492b67..168050a 100644 --- a/frontend/src/components/ChartjsPlot.jsx +++ b/frontend/src/components/ChartjsPlot.jsx @@ -19,6 +19,7 @@ const ChartjsPlot = ({ session, height = '400px' }) => { const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); const [dataPointsCount, setDataPointsCount] = useState(0); + const [resolvedConfig, setResolvedConfig] = useState(null); const bgColor = useColorModeValue('white', 'gray.800'); const textColor = useColorModeValue('gray.600', 'gray.300'); @@ -81,7 +82,8 @@ const ChartjsPlot = ({ session, height = '400px' }) => { }, [getColor]); const createStreamingChart = useCallback(async () => { - if (!canvasRef.current || !session?.config) return; + const cfg = resolvedConfig || session?.config; + if (!canvasRef.current || !cfg) return; try { // Ensure Chart.js and plugins are loaded @@ -108,7 +110,7 @@ const ChartjsPlot = ({ session, height = '400px' }) => { chartRef.current = null; } - const config = session.config; + const config = cfg; const enabledVariables = getEnabledVariables(config.variables); const datasets = enabledVariables.map((variableInfo, index) => { @@ -265,7 +267,7 @@ const ChartjsPlot = ({ session, height = '400px' }) => { setError(error.message); setIsLoading(false); } - }, [session, getEnabledVariables, getColor]); + }, [session, resolvedConfig, getEnabledVariables, getColor]); const onStreamingRefresh = useCallback(async (chart) => { if (!session?.session_id) return; @@ -483,12 +485,53 @@ const ChartjsPlot = ({ session, height = '400px' }) => { } }, [session?.is_active, session?.is_paused, pauseStreaming, resumeStreaming]); - // Initialize chart + // Resolve config: use provided session.config or fetch from backend useEffect(() => { - if (session?.config) { - createStreamingChart(); + let cancelled = false; + async function resolveConfig() { + try { + setIsLoading(true); + setError(null); + // If config already present in session, use it + if (session?.config) { + if (!cancelled) { + setResolvedConfig(session.config); + setIsLoading(false); + } + return; + } + // Otherwise fetch it from backend + if (session?.session_id) { + const resp = await fetch(`/api/plots/${session.session_id}/config`); + if (!resp.ok) { + const txt = await resp.text().catch(() => resp.statusText); + throw new Error(`HTTP ${resp.status}: ${txt || resp.statusText}`); + } + const data = await resp.json(); + if (data?.success && data?.config) { + if (!cancelled) setResolvedConfig(data.config); + } else { + throw new Error('Plot config not available'); + } + } else { + throw new Error('Invalid session (missing session_id)'); + } + } catch (e) { + if (!cancelled) setError(e.message || 'Error loading plot config'); + } finally { + if (!cancelled) setIsLoading(false); + } } + resolveConfig(); + return () => { cancelled = true; }; + }, [session?.session_id, session?.config]); + + // Initialize chart when config is resolved + useEffect(() => { + if (resolvedConfig) { + createStreamingChart(); + } return () => { if (chartRef.current) { chartRef.current.destroy(); @@ -498,7 +541,7 @@ const ChartjsPlot = ({ session, height = '400px' }) => { clearInterval(sessionDataRef.current.manualInterval); } }; - }, [createStreamingChart]); + }, [resolvedConfig, createStreamingChart]); if (isLoading) { return (