improve spike detection logic

This commit is contained in:
Erikas 2024-07-05 10:17:07 +03:00
parent 0e2b6f4da4
commit 797d181bea

View File

@ -636,42 +636,35 @@
}); });
function calculateSpikes(data, threshold) { function calculateSpikes(data, threshold) {
if (data.length < 3) { if (data.length < 6) {
throw new Error("Data length must be greater than or equal to 3."); throw new Error("Data length must be greater than or equal to 6.");
} }
let spikeCount = 0; let spikeCount = 0;
let previousWasSpike = false;
// Helper function to calculate the moving average of the last 3 points // Helper function to calculate the moving average with a minimum of 6 points
function movingAverage(arr, index, windowSize) { function movingAverage(arr, index) {
if (index < windowSize - 1) { const windowSize = Math.max(6, Math.ceil(arr.length * 0.05)); // 5 % of the data
return null; // Not enough data points to calculate the moving average const halfWindowSize = Math.floor(windowSize / 2);
} const start = Math.max(0, index - halfWindowSize);
const end = Math.min(arr.length - 1, index + halfWindowSize);
const actualWindowSize = end - start + 1;
let sum = 0; let sum = 0;
for (let i = index - windowSize + 1; i <= index; i++) { for (let i = start; i <= end; i++) {
sum += arr[i]; sum += arr[i];
} }
return sum / windowSize; return sum / actualWindowSize;
} }
for (let i = 4; i < data.length; i++) { // Start from the 3rd point for (let i = 0; i < data.length; i++) {
const currentPoint = data[i]; const currentPoint = data[i];
const movingAvg = movingAverage(data, i, 3); const movingAvg = movingAverage(data, i);
if (movingAvg === null) {
continue; // Skip if not enough data points to calculate the moving average
}
const change = Math.abs(currentPoint - movingAvg) / movingAvg * 100; const change = Math.abs(currentPoint - movingAvg) / movingAvg * 100;
if (change > threshold) { if (change > threshold) {
if (!previousWasSpike) { spikeCount++;
spikeCount++;
previousWasSpike = true;
}
} else {
previousWasSpike = false;
} }
} }