Public
Edited
May 12, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
series = (await fetchMeasurements(2178)).map(o => o.value);
Insert cell
Insert cell
max = d3.max(series);
Insert cell
min = d3.min(series);
Insert cell
Insert cell
range = max - min
Insert cell
Insert cell
scaledRateOfChange = range/max
Insert cell
Insert cell
weightFactor = 1 - scaledRateOfChange < 0.5 ? 0.5 : 1 - scaledRateOfChange
Insert cell
Insert cell
weighted = series.map((o,i) => o * Math.pow(weightFactor,i))
Insert cell
Insert cell
weightedSum = weighted.reduce((a,b) => a + b)
Insert cell
Insert cell
weightFactorSum = series.map((o,i) => Math.pow(weightFactor,i)).reduce((a,b) => a + b)
Insert cell
Insert cell
nowCastConcentration = parseFloat((weightedSum / weightFactorSum).toFixed(1))
Insert cell
nowCastAqi = Math.round(concentrationToAqi(nowCastConcentration))
Insert cell
function concentrationToAqi(concentration) {
const concentrationBreakpoints = [0,12.0,35.4,150,200,300,500];
const AqiBreakpoints = [0,50,100,150,200,300,500];
const concHi = concentrationBreakpoints.find(o => concentration <= o)
const concHiIdx = concentrationBreakpoints.indexOf(concHi)
const concLo = concentrationBreakpoints[concentrationBreakpoints.indexOf(concHi) -1]
const aqi = ((AqiBreakpoints[concHiIdx] - AqiBreakpoints[concHiIdx - 1])/(concHi - concLo)) * (concentration - concLo) + AqiBreakpoints[concHiIdx - 1]
return aqi
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more