From d891b1d46c668cf1211db9e7a43dff9c1affa826 Mon Sep 17 00:00:00 2001 From: Tudor Sitaru Date: Tue, 6 Jan 2026 15:49:57 +0000 Subject: [PATCH] standard deviation for comparison table --- frontend/app.js | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/frontend/app.js b/frontend/app.js index cbf42cd..eb8c1cc 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -468,7 +468,6 @@ async function updateComparisonChart() { } function updateComparisonTable(comparison, metric, years) { - const firstYear = years[0]; const lastYear = years[years.length - 1]; const prevYear = years.length > 1 ? years[years.length - 2] : null; @@ -477,11 +476,11 @@ function updateComparisonTable(comparison, metric, years) { years.forEach(year => { headerHtml += `${year}`; }); - if (prevYear && prevYear !== firstYear) { + if (prevYear) { headerHtml += `Δ 1yr`; } - if (years.length > 1) { - headerHtml += `Δ ${firstYear}→${lastYear}`; + if (years.length > 2) { + headerHtml += `Variability`; } elements.tableHeader.innerHTML = headerHtml; @@ -496,7 +495,6 @@ function updateComparisonTable(comparison, metric, years) { yearlyMap[d.year] = d[metric]; }); - const firstValue = yearlyMap[firstYear]; const lastValue = yearlyMap[lastYear]; const prevValue = prevYear ? yearlyMap[prevYear] : null; @@ -505,10 +503,16 @@ function updateComparisonTable(comparison, metric, years) { const oneYearChangeStr = oneYearChange !== null ? oneYearChange.toFixed(1) : 'N/A'; const oneYearClass = oneYearChange !== null ? (oneYearChange >= 0 ? 'positive' : 'negative') : ''; - // Calculate total change - const totalChange = firstValue != null && lastValue != null ? (lastValue - firstValue) : null; - const totalChangeStr = totalChange !== null ? totalChange.toFixed(1) : 'N/A'; - const totalChangeClass = totalChange !== null ? (totalChange >= 0 ? 'positive' : 'negative') : ''; + // Calculate variability (standard deviation) - exclude null/0 values + const values = years.map(y => yearlyMap[y]).filter(v => v != null && v !== 0); + let variabilityStr = 'N/A'; + if (values.length >= 2) { + const mean = values.reduce((a, b) => a + b, 0) / values.length; + const squaredDiffs = values.map(v => Math.pow(v - mean, 2)); + const variance = squaredDiffs.reduce((a, b) => a + b, 0) / values.length; + const stdDev = Math.sqrt(variance); + variabilityStr = '±' + stdDev.toFixed(1); + } const color = CHART_COLORS[index % CHART_COLORS.length]; @@ -518,11 +522,11 @@ function updateComparisonTable(comparison, metric, years) { const value = yearlyMap[year]; bodyHtml += `${value != null ? formatMetricValue(value, metric) : '-'}`; }); - if (prevYear && prevYear !== firstYear) { + if (prevYear) { bodyHtml += `${oneYearChangeStr !== 'N/A' ? (oneYearChange >= 0 ? '+' : '') + oneYearChangeStr : oneYearChangeStr}`; } - if (years.length > 1) { - bodyHtml += `${totalChangeStr !== 'N/A' ? (totalChange >= 0 ? '+' : '') + totalChangeStr : totalChangeStr}`; + if (years.length > 2) { + bodyHtml += `${variabilityStr}`; } bodyHtml += ``; });