Fix vehicle day tabs
This commit is contained in:
fraxle
2026-08-04 03:05:07 +01:00
parent 8f161dc8cb
commit a94cdea9b2
3 changed files with 19 additions and 27 deletions
+7 -1
View File
@@ -1312,9 +1312,15 @@ export function UTCIForecast() {
color: feelLum > 165 ? '#1a1a1a' : '#ffffff', color: feelLum > 165 ? '#1a1a1a' : '#ffffff',
...(cat.fontWeight ? { fontWeight: cat.fontWeight } : {}), ...(cat.fontWeight ? { fontWeight: cat.fontWeight } : {}),
}; };
// Card wears the same hue as its feel tag, washed right back so
// the tag still reads as the strong swatch on top of it.
const cardRgb = fscRgb(dispTemp, 0.70) || [245, 245, 245];
return html` return html`
<div key=${r.iso} class=${'fsc-card' + (isNow ? ' fsc-card--now' : '')} <div key=${r.iso} class=${'fsc-card' + (isNow ? ' fsc-card--now' : '')}
style=${fscPlot && { gridColumn: fscPlot.cardCol(fscPlot.landing[ri]) }}> style=${{
background: `rgb(${cardRgb[0]},${cardRgb[1]},${cardRgb[2]})`,
...(fscPlot ? { gridColumn: fscPlot.cardCol(fscPlot.landing[ri]) } : {}),
}}>
<div class="fsc-time">${localHHMMs}</div> <div class="fsc-time">${localHHMMs}</div>
<div class="fsc-scope-wrap"> <div class="fsc-scope-wrap">
<${SkyScope} elev=${r.elev} dt=${r.dt} glob=${r.glob} size=${42} /> <${SkyScope} elev=${r.elev} dt=${r.dt} glob=${r.glob} size=${42} />
+9 -21
View File
@@ -22,8 +22,8 @@
// activeProfile - current filter profile key // activeProfile - current filter profile key
// outdoorsVariant - current outdoors sub-variant key // outdoorsVariant - current outdoors sub-variant key
// openPanel - opens the profile/config nav dropdown // openPanel - opens the profile/config nav dropdown
// vehicleType/vehicleSpeed - current vehicle config (vehicle-cabin day-tab // vehicleType - current vehicle config, for the "Viewing" row
// reference calc + row label) // label
// buildingType/indoorManaged/utciEnv/furColor - current config values, // buildingType/indoorManaged/utciEnv/furColor - current config values,
// for the "Viewing" row label // for the "Viewing" row label
// dayTabsRef - ref for the scrollable tab strip element // dayTabsRef - ref for the scrollable tab strip element
@@ -33,9 +33,8 @@
import { h, Fragment } from '../../vendor/preact.js'; import { h, Fragment } from '../../vendor/preact.js';
import htm from '../../vendor/htm.js'; import htm from '../../vendor/htm.js';
import { confidenceBand, utciCategory, petCategory, hexToRgb, mixRgb, rainTint, cloudTint, snowTint, VEHICLE_SPEEDS, VEHICLE_TYPES, BUILDING_TYPES, FUR_COLORS } from '../utils.js'; import { confidenceBand, utciCategory, petCategory, hexToRgb, mixRgb, rainTint, cloudTint, snowTint, VEHICLE_TYPES, BUILDING_TYPES, FUR_COLORS } from '../utils.js';
import { FREE_DAYS, UTCI_ENVIRONMENTS, deriveProfileMain, FILTER_PROFILES, variantIcons } from '../config.js'; import { FREE_DAYS, UTCI_ENVIRONMENTS, deriveProfileMain, FILTER_PROFILES, variantIcons } from '../config.js';
import { calcVehicleInteriorTempPass } from '../physics.js';
import { CloudIcon, PrecipIcon, HouseIcon, CarIcon, FogIcon, IceIcon } from '../components.js'; import { CloudIcon, PrecipIcon, HouseIcon, CarIcon, FogIcon, IceIcon } from '../components.js';
import { SubscribeModal } from './SubscribeModal.js'; import { SubscribeModal } from './SubscribeModal.js';
@@ -124,7 +123,7 @@ export function DayTabs({
proPromptSource, setProPromptSource, proPromptSource, setProPromptSource,
activeProfile, outdoorsVariant, activeProfile, outdoorsVariant,
openPanel, openPanel,
vehicleType, vehicleSpeed, buildingType, indoorManaged, utciEnv, furColor, vehicleType, buildingType, indoorManaged, utciEnv, furColor,
dayTabsRef, canScrollLeft, canScrollRight, scrollDayTabs, dayTabsRef, canScrollLeft, canScrollRight, scrollDayTabs,
}) { }) {
// Which metric drives the day-tab's hi/lo readout depends on the active // Which metric drives the day-tab's hi/lo readout depends on the active
@@ -215,7 +214,7 @@ export function DayTabs({
<span class="utci-day-legend-icon">${isHomeOrOffice ? 'Home' : isVehicleProfile ? 'Alert' : 'Sky'}</span> <span class="utci-day-legend-icon">${isHomeOrOffice ? 'Home' : isVehicleProfile ? 'Alert' : 'Sky'}</span>
<div class="utci-day-legend-values"> <div class="utci-day-legend-values">
<span class="utci-day-legend-main" title=${mainMetricDesc}>${mainMetricLabel}</span> <span class="utci-day-legend-main" title=${mainMetricDesc}>${mainMetricLabel}</span>
${(isVehicleProfile || secondaryField) && html` ${secondaryField && html`
<span class="utci-day-legend-sep" aria-hidden="true"></span> <span class="utci-day-legend-sep" aria-hidden="true"></span>
<span class="utci-day-legend-sec" title=${secondaryMetricDesc}>${secondaryMetricLabel}</span>`} <span class="utci-day-legend-sec" title=${secondaryMetricDesc}>${secondaryMetricLabel}</span>`}
</div> </div>
@@ -233,22 +232,11 @@ export function DayTabs({
const dayHi = mainVals.length ? Math.round(Math.max(...mainVals)) : null; const dayHi = mainVals.length ? Math.round(Math.max(...mainVals)) : null;
const dayLo = mainVals.length ? Math.round(Math.min(...mainVals)) : null; const dayLo = mainVals.length ? Math.round(Math.min(...mainVals)) : null;
// Vehicle/Driver: no table column exists for the ventilated cabin // Vehicle/Driver has no secondary field — the cabin number already
// temp (ventilation is just an input toggle on the main vehicleT // reflects the selected vehicle type, ventilation and speed, so the
// calc), so run the physics model again with vent forced on, to // tab shows that alone rather than a second reference figure.
// show "if you opened the windows" as a reference hi/lo.
let shadeHi = null, shadeLo = null; let shadeHi = null, shadeLo = null;
if (isVehicleProfile) { if (secondaryField) {
const speedMph = (VEHICLE_SPEEDS[vehicleSpeed] ?? VEHICLE_SPEEDS.static).mph;
// Run the lagged pass over the whole day, not per-hour equilibrium,
// so this hi/lo is directly comparable with the vehicleT column.
const ventVals = calcVehicleInteriorTempPass(
d.rows.map(r => r.Ta), d.rows.map(r => r.glob), d.rows.map(r => r.elev),
d.rows.map(r => r.va), vehicleType, true, speedMph
).filter(v => v != null && isFinite(v));
shadeHi = ventVals.length ? Math.round(Math.max(...ventVals)) : null;
shadeLo = ventVals.length ? Math.round(Math.min(...ventVals)) : null;
} else if (secondaryField) {
const secondaryVals = d.rows.map(r => r[secondaryField]).filter(v => isFinite(v)); const secondaryVals = d.rows.map(r => r[secondaryField]).filter(v => isFinite(v));
shadeHi = secondaryVals.length ? Math.round(Math.max(...secondaryVals)) : null; shadeHi = secondaryVals.length ? Math.round(Math.max(...secondaryVals)) : null;
shadeLo = secondaryVals.length ? Math.round(Math.min(...secondaryVals)) : null; shadeLo = secondaryVals.length ? Math.round(Math.min(...secondaryVals)) : null;
+3 -5
View File
@@ -209,11 +209,9 @@ export function deriveProfileMain(activeProfile, outdoorsVariant) {
// every field matches its column key except utciAdj, whose column is utciP. // every field matches its column key except utciAdj, whose column is utciP.
const colKey = mainField === 'utciAdj' ? 'utciP' : mainField; const colKey = mainField === 'utciAdj' ? 'utciP' : mainField;
const mainMetric = COL_DESCRIPTIONS[colKey] || {}; const mainMetric = COL_DESCRIPTIONS[colKey] || {};
// Vehicle/Driver has no secondary column — the small number is a live // Vehicle/Driver has no secondary column — the day tab shows only the cabin
// re-run of the cabin model with ventilation forced on (see DayTabs). // temp for the config actually selected (vehicle type, ventilation, speed).
const secondaryMetric = isVehicleProfile const secondaryMetric = secondaryField ? (COL_DESCRIPTIONS[secondaryField] || {}) : null;
? { title: 'Windows Open', desc: 'The same vehicle interior estimate, recalculated with the windows open — how much cooler the cabin would run if it were ventilated.' }
: (secondaryField ? (COL_DESCRIPTIONS[secondaryField] || {}) : null);
return { return {
isHomeOrOffice, isVehicleProfile, isPetsProfile, isHomeOrOffice, isVehicleProfile, isPetsProfile,