feat: Normalize timestamps for chart data and update time window for plot configuration

This commit is contained in:
Miguel 2025-08-15 12:13:42 +02:00
parent addd9fa6bc
commit 3514218ff2
2 changed files with 57 additions and 7 deletions

View File

@ -21,7 +21,7 @@
"point_hover_radius": 4,
"point_radius": 1,
"stepped": true,
"time_window": 60,
"time_window": 10,
"trigger_enabled": false,
"trigger_on_true": true
}

View File

@ -314,6 +314,38 @@ const ChartjsPlot = ({ session, height = '400px' }) => {
}
}, []);
// Helper function to normalize timestamps for consistent chart data
const normalizeTimestamp = useCallback((timestamp) => {
if (timestamp instanceof Date) {
return timestamp.getTime();
}
let raw = timestamp;
if (typeof raw === 'string') {
const asNum = Number(raw);
if (Number.isFinite(asNum)) {
raw = asNum;
} else {
const parsed = Date.parse(raw);
if (Number.isFinite(parsed)) {
raw = parsed;
} else {
console.warn('⚠️ Invalid timestamp string:', timestamp);
return Date.now(); // fallback to current time
}
}
}
if (typeof raw !== 'number' || !Number.isFinite(raw)) {
console.warn('⚠️ Invalid timestamp value:', timestamp);
return Date.now(); // fallback to current time
}
// Normalize seconds to milliseconds
const normalized = raw < 1e12 ? raw * 1000 : raw;
return normalized;
}, []);
const createStreamingChart = useCallback(async () => {
const cfg = resolvedConfigRef.current || session?.config;
if (!canvasRef.current || !cfg) return;
@ -600,7 +632,7 @@ const ChartjsPlot = ({ session, height = '400px' }) => {
dataByVariable[variable] = [];
}
dataByVariable[variable].push({
x: new Date(timestamp),
x: normalizeTimestamp(timestamp),
y: value
});
});
@ -612,6 +644,12 @@ const ChartjsPlot = ({ session, height = '400px' }) => {
// Sort points by timestamp to ensure proper order
historicalPoints.sort((a, b) => a.x - b.x);
datasets[index].data = historicalPoints;
// Update lastPushedX tracking for streaming continuity
const lastPoint = historicalPoints[historicalPoints.length - 1];
if (lastPoint && typeof lastPoint.x === 'number') {
sessionDataRef.current.lastPushedXByDataset.set(index, lastPoint.x);
}
}
});
@ -844,7 +882,7 @@ const ChartjsPlot = ({ session, height = '400px' }) => {
setError(error.message);
setIsLoading(false);
}
}, [isZoomEnabled]);
}, [isZoomEnabled, normalizeTimestamp]);
const onStreamingRefresh = useCallback(async (chart) => {
const sessionId = sessionDataRef.current.sessionId;
@ -1081,7 +1119,7 @@ const ChartjsPlot = ({ session, height = '400px' }) => {
dataByVariable[variable] = [];
}
dataByVariable[variable].push({
x: new Date(timestamp),
x: normalizeTimestamp(timestamp),
y: value
});
});
@ -1093,6 +1131,12 @@ const ChartjsPlot = ({ session, height = '400px' }) => {
// Sort points by timestamp to ensure proper order
historicalPoints.sort((a, b) => a.x - b.x);
chart.data.datasets[index].data = historicalPoints;
// Update lastPushedX tracking for streaming continuity
const lastPoint = historicalPoints[historicalPoints.length - 1];
if (lastPoint && typeof lastPoint.x === 'number') {
sessionDataRef.current.lastPushedXByDataset.set(index, lastPoint.x);
}
}
});
@ -1129,7 +1173,7 @@ const ChartjsPlot = ({ session, height = '400px' }) => {
sessionData.ingestPaused = false;
sessionData.isPaused = false;
sessionData.userOverrideUntil = Date.now() + 3000;
}, [startManualRefresh, loadHistoricalData, getEnabledVariables, session?.config, setIsLoadingHistorical, setDataPointsCount]);
}, [startManualRefresh, loadHistoricalData, getEnabledVariables, session?.config, setIsLoadingHistorical, setDataPointsCount, normalizeTimestamp]);
const clearChart = useCallback(() => {
if (!chartRef.current) return;
@ -1201,7 +1245,7 @@ const ChartjsPlot = ({ session, height = '400px' }) => {
dataByVariable[variable] = [];
}
dataByVariable[variable].push({
x: new Date(timestamp),
x: normalizeTimestamp(timestamp),
y: value
});
});
@ -1213,6 +1257,12 @@ const ChartjsPlot = ({ session, height = '400px' }) => {
// Sort points by timestamp to ensure proper order
historicalPoints.sort((a, b) => a.x - b.x);
chartRef.current.data.datasets[index].data = historicalPoints;
// Update lastPushedX tracking for streaming continuity
const lastPoint = historicalPoints[historicalPoints.length - 1];
if (lastPoint && typeof lastPoint.x === 'number') {
sessionDataRef.current.lastPushedXByDataset.set(index, lastPoint.x);
}
}
});
@ -1238,7 +1288,7 @@ const ChartjsPlot = ({ session, height = '400px' }) => {
} catch (error) {
console.error('❌ Error during zoom reset with data reload:', error);
}
}, [session, getEnabledVariables, loadHistoricalData]);
}, [session, getEnabledVariables, loadHistoricalData, normalizeTimestamp]);
// Update configuration directly (for real-time style changes)
const updateConfig = useCallback(async (newConfig) => {