diff --git a/frontend/src/components/ChartjsHistoricalPlot.jsx b/frontend/src/components/ChartjsHistoricalPlot.jsx index 93d93f4..98c50cc 100644 --- a/frontend/src/components/ChartjsHistoricalPlot.jsx +++ b/frontend/src/components/ChartjsHistoricalPlot.jsx @@ -291,6 +291,25 @@ const ChartjsHistoricalPlot = ({ currentTimeRange }); + // Calculate intelligent decimation based on canvas width + const canvasWidth = canvasRef.current?.clientWidth || 800; // Default fallback + const maxPointsPerDataset = data.datasets.reduce((max, dataset) => + Math.max(max, dataset.data.length), 0); + + // Decimation should activate when we have more than 2x points than pixels + const pixelRatio = 2; // 2 points per pixel + const decimationThreshold = canvasWidth * pixelRatio; + const shouldDecimate = maxPointsPerDataset > decimationThreshold; + const samples = Math.max(Math.floor(canvasWidth * 0.8), 200); // 80% of canvas width, min 200 + + console.log('📊 Decimation analysis:', { + canvasWidth, + maxPointsPerDataset, + decimationThreshold, + shouldDecimate, + samples + }); + const config = { type: 'line', data: data, @@ -305,12 +324,12 @@ const ChartjsHistoricalPlot = ({ mode: 'index' }, plugins: { - // Configure decimation for better performance with large datasets + // Configure intelligent decimation based on pixel density decimation: { - enabled: true, + enabled: shouldDecimate, algorithm: 'min-max', - samples: 500, - threshold: 1000 // Enable decimation when more than 1000 points + samples: samples, + threshold: decimationThreshold }, title: { display: !!plotConfig.name, @@ -517,11 +536,21 @@ const ChartjsHistoricalPlot = ({ {dataPointsCount.toLocaleString()} data points - {dataPointsCount > 1000 && ( - - (Min/Max decimation active) - - )} + {(() => { + const canvasWidth = canvasRef.current?.clientWidth || 800; + const maxPoints = dataPointsCount; + const decimationThreshold = canvasWidth * 2; + const shouldDecimate = maxPoints > decimationThreshold; + + if (shouldDecimate) { + return ( + + (Min/Max decimation: {canvasWidth} px ÷ {maxPoints} pts) + + ); + } + return null; + })()} {dataPointsCount === 0 && chartRef.current && ( No data in current view - use pan/zoom to navigate diff --git a/frontend/src/components/PlotHistoricalSession.jsx b/frontend/src/components/PlotHistoricalSession.jsx index 53271f8..d752a3b 100644 --- a/frontend/src/components/PlotHistoricalSession.jsx +++ b/frontend/src/components/PlotHistoricalSession.jsx @@ -371,8 +371,21 @@ export default function PlotHistoricalSession({ console.log('📊 Zoom: New central time:', newCentralTime, 'Range seconds:', newRangeSeconds) - // Use debounced update to sync all components - debouncedTimeChange(newCentralTime, newRangeSeconds) + // Para zoom-in (agrandar), solo actualizar el rango de visualización + // No recargar datos ya que tenemos suficientes datos en memoria + const currentRangeSeconds = timeRangeSeconds + const rangeRatio = newRangeSeconds / currentRangeSeconds + + if (rangeRatio < 1.0) { // Zoom-in (agrandar imagen) + console.log('📊 Zoom-in detected: Updating display range without reloading data') + // Solo actualizar el estado local para el rango de visualización + setCentralTime(newCentralTime) + setTimeRangeSeconds(newRangeSeconds) + // NO llamar debouncedTimeChange para evitar recarga de datos + } else { // Zoom-out, usar lógica normal + console.log('📊 Zoom-out detected: Using debounced update') + debouncedTimeChange(newCentralTime, newRangeSeconds) + } } const handlePanToTimeRange = (start, end) => {