Skip to content

Commit 308a9a2

Browse files
committed
Downsample in Plots only >30s
1 parent c82bc11 commit 308a9a2

2 files changed

Lines changed: 42 additions & 44 deletions

File tree

pecan/src/components/PlotManager.tsx

Lines changed: 39 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,10 @@ const PLOT_COLORS = [
1515
"#00bbcc",
1616
];
1717

18-
// Helper to calculate downsample resolution based on time window
19-
function calculateDownsampleResolution(windowMs: number): number {
20-
// Under 3s (3000ms), use 200ms resolution
21-
if (windowMs <= 3000) return 200;
22-
// Above 20s (20000ms), use 1000ms resolution
23-
if (windowMs >= 20000) return 1000;
24-
25-
// Linear interpolation between 3000ms and 20000ms
26-
// Range: 17000ms. Value range: 800ms.
27-
return 200 + ((windowMs - 3000) / 17000) * 800;
18+
// Returns downsample resolution in ms, or null for no downsampling (raw points).
19+
function calculateDownsampleResolution(windowMs: number): number | null {
20+
if (windowMs <= 30000) return null;
21+
return 100;
2822
}
2923

3024
export interface PlotSignal {
@@ -171,43 +165,44 @@ function PlotManager({
171165
const yData: number[] = [];
172166

173167
if (history.length > 0) {
174-
let currentBinStart =
175-
Math.floor(history[0].timestamp / resolution) * resolution;
176-
let currentSum = 0;
177-
let currentCount = 0;
178-
179-
for (const sample of history) {
180-
const signalData = sample.data[signal.signalName];
181-
if (signalData === undefined) continue;
182-
183-
const sampleBin =
184-
Math.floor(sample.timestamp / resolution) * resolution;
185-
186-
if (sampleBin === currentBinStart) {
187-
currentSum += signalData.sensorReading;
188-
currentCount++;
189-
} else {
190-
// Finalize previous bin
191-
if (currentCount > 0) {
192-
const avg = currentSum / currentCount;
193-
const x = (currentBinStart - windowEndMs) / 1000;
194-
xData.push(x);
195-
yData.push(avg);
168+
if (resolution === null) {
169+
for (const sample of history) {
170+
const signalData = sample.data[signal.signalName];
171+
if (signalData === undefined) continue;
172+
xData.push((sample.timestamp - windowEndMs) / 1000);
173+
yData.push(signalData.sensorReading);
174+
}
175+
} else {
176+
let currentBinStart =
177+
Math.floor(history[0].timestamp / resolution) * resolution;
178+
let currentSum = 0;
179+
let currentCount = 0;
180+
181+
for (const sample of history) {
182+
const signalData = sample.data[signal.signalName];
183+
if (signalData === undefined) continue;
184+
185+
const sampleBin =
186+
Math.floor(sample.timestamp / resolution) * resolution;
187+
188+
if (sampleBin === currentBinStart) {
189+
currentSum += signalData.sensorReading;
190+
currentCount++;
191+
} else {
192+
if (currentCount > 0) {
193+
xData.push((currentBinStart - windowEndMs) / 1000);
194+
yData.push(currentSum / currentCount);
195+
}
196+
currentBinStart = sampleBin;
197+
currentSum = signalData.sensorReading;
198+
currentCount = 1;
196199
}
197-
198-
// Move to new bin
199-
currentBinStart = sampleBin;
200-
currentSum = signalData.sensorReading;
201-
currentCount = 1;
202200
}
203-
}
204201

205-
// Finalize last bin
206-
if (currentCount > 0) {
207-
const avg = currentSum / currentCount;
208-
const x = (currentBinStart - windowEndMs) / 1000;
209-
xData.push(x);
210-
yData.push(avg);
202+
if (currentCount > 0) {
203+
xData.push((currentBinStart - windowEndMs) / 1000);
204+
yData.push(currentSum / currentCount);
205+
}
211206
}
212207
}
213208

pecan/src/pages/Dashboard.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,9 @@ function Dashboard() {
863863
<label className="text-gray-300 text-sm">
864864
Time Window (seconds, max 120):
865865
</label>
866+
{plotTimeWindow > 30000 && (
867+
<p className="text-yellow-400 text-xs">Downsampling to 100ms bins (window &gt; 30s)</p>
868+
)}
866869
<input
867870
type="number"
868871
min="1"

0 commit comments

Comments
 (0)