From 62706cdb42c3a240637c5b0629a8646e45d771e1 Mon Sep 17 00:00:00 2001 From: Boki Date: Wed, 2 Jul 2025 20:10:56 -0400 Subject: [PATCH] chart kinda done --- .../web-app/src/features/charts/ChartPage.tsx | 17 ++++- .../charts/components/SymbolChart.tsx | 69 ++++++++++--------- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/apps/stock/web-app/src/features/charts/ChartPage.tsx b/apps/stock/web-app/src/features/charts/ChartPage.tsx index b60dd4f..8499dc3 100644 --- a/apps/stock/web-app/src/features/charts/ChartPage.tsx +++ b/apps/stock/web-app/src/features/charts/ChartPage.tsx @@ -169,9 +169,20 @@ export function ChartPage() { }; const handleToggleIndicatorVisibility = (id: string) => { - setActiveIndicators(prev => prev.map(i => - i.id === id ? { ...i, visible: !i.visible } : i - )); + setActiveIndicators(prev => { + const updated = prev.map(i => + i.id === id ? { ...i, visible: !i.visible } : i + ); + // Force chart update by also updating config + if (id === 'VOLUME') { + const volumeIndicator = updated.find(i => i.id === 'VOLUME'); + setConfig(prevConfig => ({ + ...prevConfig, + showVolume: volumeIndicator?.visible ?? true + })); + } + return updated; + }); }; const handleIndicatorSettings = (id: string) => { diff --git a/apps/stock/web-app/src/features/charts/components/SymbolChart.tsx b/apps/stock/web-app/src/features/charts/components/SymbolChart.tsx index f047f08..36137f8 100644 --- a/apps/stock/web-app/src/features/charts/components/SymbolChart.tsx +++ b/apps/stock/web-app/src/features/charts/components/SymbolChart.tsx @@ -102,8 +102,8 @@ export function SymbolChart({ chartRef.current = chart; - // Clear previous indicator series references - indicatorSeriesRef.current.clear(); + // Create a new map for this chart instance + indicatorSeriesRef.current = new Map(); // Create main series based on chart type if (chartConfig.chartType === 'candlestick') { @@ -134,14 +134,18 @@ export function SymbolChart({ }); } - // Create volume series if enabled - if (chartConfig.showVolume && data.some(d => d.volume)) { + // Create volume series if data has volume + if (data.some(d => d.volume)) { + const volumeIndicator = activeIndicators.find(i => i.id === 'VOLUME'); + const volumeVisible = volumeIndicator ? volumeIndicator.visible : chartConfig.showVolume; + volumeSeriesRef.current = chart.addHistogramSeries({ color: '#3b82f680', priceFormat: { type: 'volume', }, priceScaleId: 'volume', + visible: volumeVisible, }); volumeSeriesRef.current.priceScale().applyOptions({ scaleMargins: { @@ -311,6 +315,7 @@ export function SymbolChart({ // Cleanup return () => { window.removeEventListener('resize', handleResize); + setChartInitialized(false); if (chart) { chart.remove(); } @@ -348,42 +353,38 @@ export function SymbolChart({ // Handle indicator visibility changes without recreating chart useEffect(() => { - if (!chartRef.current) return; + if (!chartRef.current || !chartInitialized) return; - // Small delay to ensure chart is fully initialized - const timeoutId = setTimeout(() => { - // Update volume visibility - if (volumeSeriesRef.current) { - const volumeVisible = chartConfig.showVolume; - volumeSeriesRef.current.applyOptions({ - visible: volumeVisible, - }); - } + // Update volume visibility + if (volumeSeriesRef.current) { + const volumeIndicator = activeIndicators.find(i => i.id === 'VOLUME'); + const volumeVisible = volumeIndicator ? volumeIndicator.visible : chartConfig.showVolume; + volumeSeriesRef.current.applyOptions({ + visible: volumeVisible, + }); + } - // Update indicator visibility - activeIndicators.forEach(indicator => { - if (indicator.id === 'VOLUME') return; // Skip volume, handled above - - // For indicators with multiple series (like Bollinger Bands) - if (indicator.id === 'BB') { - ['BB_upper', 'BB_middle', 'BB_lower'].forEach(seriesId => { - const series = indicatorSeriesRef.current.get(seriesId); - if (series) { - series.applyOptions({ visible: indicator.visible }); - } - }); - } else { - // For single series indicators - const series = indicatorSeriesRef.current.get(indicator.id); + // Update indicator visibility + activeIndicators.forEach(indicator => { + if (indicator.id === 'VOLUME') return; // Skip volume, handled above + + // For indicators with multiple series (like Bollinger Bands) + if (indicator.id === 'BB') { + ['BB_upper', 'BB_middle', 'BB_lower'].forEach(seriesId => { + const series = indicatorSeriesRef.current.get(seriesId); if (series) { series.applyOptions({ visible: indicator.visible }); } + }); + } else { + // For single series indicators + const series = indicatorSeriesRef.current.get(indicator.id); + if (series) { + series.applyOptions({ visible: indicator.visible }); } - }); - }, 100); - - return () => clearTimeout(timeoutId); - }, [chartConfig.showVolume, visibilityKey]); + } + }); + }, [chartConfig.showVolume, visibilityKey, chartInitialized]); // Prepare indicator info for overlay - include all indicators const indicatorInfo = activeIndicators.map(indicator => ({