Published
Edited
Sep 29, 2021
2 forks
25 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
categories = [
{max: 50, color: "green", name: "Good"},
{max: 100, color: "yellow", name: "Moderate"},
{max: 150, color: "orange", name: "Unhealthy for sensitive groups"},
{max: 200, color: "red", name: "Unhealthy"},
{max: 300, color: "purple", name: "Very unhealthy"},
{max: 500, color: "maroon", name: "Hazardous"}
]
Insert cell
Insert cell
function pm25_aqi(pm25) {
const c = Math.floor(10 * pm25) / 10;
const a = c < 0 ? 0 // values below 0 are considered beyond AQI
: c < 12.1 ? lerp( 0, 50, 0.0, 12.0, c)
: c < 35.5 ? lerp( 51, 100, 12.1, 35.4, c)
: c < 55.5 ? lerp(101, 150, 35.5, 55.4, c)
: c < 150.5 ? lerp(151, 200, 55.5, 150.4, c)
: c < 250.5 ? lerp(201, 300, 150.5, 250.4, c)
: c < 350.5 ? lerp(301, 400, 250.5, 350.4, c)
: c < 500.5 ? lerp(401, 500, 350.5, 500.4, c)
: 500; // values above 500 are considered beyond AQI
return Math.round(a);
}
Insert cell
Insert cell
function aqi_pm25(aqi) {
const a = Math.round(aqi);
const c = a < 0 ? 0 // values below 0 are considered beyond AQI
: a <= 50 ? lerp( 0.0, 12.0, 0, 50, a)
: a <= 100 ? lerp( 12.1, 35.4, 51, 100, a)
: a <= 150 ? lerp( 35.5, 55.4, 101, 150, a)
: a <= 200 ? lerp( 55.5, 150.4, 151, 200, a)
: a <= 300 ? lerp(150.5, 250.4, 201, 300, a)
: a <= 400 ? lerp(250.5, 350.4, 301, 400, a)
: a <= 500 ? lerp(350.5, 500.4, 401, 500, a)
: 500; // values above 500 are considered beyond AQI
return Math.floor(10 * c) / 10;
}
Insert cell
Insert cell
function lerp(ylo, yhi, xlo, xhi, x) {
return ((x - xlo) / (xhi - xlo)) * (yhi - ylo) + ylo;
}
Insert cell
Insert cell
function bind(target, source, {
invalidation = Inputs.disposal(target),
transform = d => d,
invert = d => d
} = {}) {
const onsource = (event) => {
if (!event.isTrusted) return;
target.value = transform(source.value);
};
const ontarget = (event) => {
if (!event.isTrusted) return;
source.value = invert(target.value);
source.dispatchEvent(new Event("input", {bubbles: true}));
};
target.value = transform(source.value);
target.addEventListener("input", ontarget);
source.addEventListener("input", onsource);
invalidation.then(() => source.removeEventListener("input", onsource));
return target;
}
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