// Temperature units — the shared °C/°F toggle and unit-aware formatting. // The API always speaks Fahrenheit; the unit is a pure display concern. Pages // format temps through `fmtTemp`/`toUnit` and re-render on `onUnitChange`, so the // stored/plotted values stay in °F and only the numbers shown flip. const UNIT_KEY = "thermograph:unit"; let _unit = (localStorage.getItem(UNIT_KEY) === "C") ? "C" : "F"; const _unitCbs = []; export function getUnit() { return _unit; } // A Fahrenheit value as a number in the active unit. export function toUnit(vF) { return _unit === "C" ? (vF - 32) * 5 / 9 : vF; } // A Fahrenheit value formatted as a rounded temperature in the active unit. // `withLetter` appends the C/F letter (off by default — the nav toggle shows it). export function fmtTemp(vF, withLetter) { if (vF == null || isNaN(vF)) return "—"; return `${Math.round(toUnit(vF))}°${withLetter ? _unit : ""}`; } // A Fahrenheit-degree *difference* (a span or tolerance, not an absolute // reading) formatted in the active unit. Differences scale by 5/9 with no 32° // offset, so they can't go through toUnit/fmtTemp. export function fmtDelta(dF, withLetter) { if (dF == null || isNaN(dF)) return "—"; const d = _unit === "C" ? dF * 5 / 9 : dF; return `${Math.round(d)}°${withLetter ? _unit : ""}`; } export function onUnitChange(cb) { _unitCbs.push(cb); } export function setUnit(u) { const nu = (u === "C") ? "C" : "F"; if (nu === _unit) return; _unit = nu; try { localStorage.setItem(UNIT_KEY, _unit); } catch (e) {} document.querySelectorAll(".unit-toggle").forEach(syncUnitToggle); _unitCbs.forEach((cb) => { try { cb(_unit); } catch (e) {} }); } function syncUnitToggle(wrap) { wrap.querySelectorAll("button[data-unit]").forEach((b) => { const on = b.dataset.unit === _unit; b.classList.toggle("active", on); b.setAttribute("aria-pressed", on ? "true" : "false"); }); } // Drop a segmented °F/°C control into the header's top-right, ahead of the view // switcher. A page opts out with data-no-unit-toggle on . (function buildUnitToggle() { const brand = document.querySelector(".brand"); if (!brand || brand.querySelector(".unit-toggle")) return; if (document.body.dataset.noUnitToggle != null) return; const wrap = document.createElement("div"); wrap.className = "unit-toggle"; wrap.setAttribute("role", "group"); wrap.setAttribute("aria-label", "Temperature units"); wrap.innerHTML = '' + ''; wrap.addEventListener("click", (e) => { const b = e.target.closest("button[data-unit]"); if (b) setUnit(b.dataset.unit); }); const anchor = brand.querySelector(".nav-menu") || brand.querySelector(".view-nav"); brand.insertBefore(wrap, anchor); // sits just left of the nav (top-right) syncUnitToggle(wrap); })();