1.7.4
Made temprature cells more deeper colour ranges
This commit is contained in:
+41
-29
@@ -503,29 +503,41 @@ ${isPro && (activeProfile === 'custom' || activeCols['air']) && html`<button cla
|
||||
const b = parseInt(h.slice(4,6),16);
|
||||
return `rgba(${r},${g},${b},${a})`;
|
||||
};
|
||||
// Returns a very light background tint based on temperature value.
|
||||
// Cold → faint blue, cool → faint green, warm → faint amber, hot → faint red.
|
||||
// Returns a background tint based on temperature value - all share the same
|
||||
// Thermal Stress Bands colors with 50% alpha for consistency. Uses exact legend ranges.
|
||||
const tempBg = (t) => {
|
||||
if (t == null) return 'transparent';
|
||||
if (t < 0) return 'rgba(100,160,230,0.10)';
|
||||
if (t < 10) return 'rgba(140,200,200,0.10)';
|
||||
if (t < 18) return 'rgba(140,200,150,0.10)';
|
||||
if (t < 26) return 'rgba(100,190,100,0.10)';
|
||||
if (t < 32) return 'rgba(230,200, 80,0.10)';
|
||||
if (t < 40) return 'rgba(230,140, 50,0.10)';
|
||||
if (t < 50) return 'rgba(210, 70, 50,0.10)';
|
||||
return 'rgba(160, 30, 30,0.10)';
|
||||
if (t == null || t <= -27) return 'transparent';
|
||||
if (t <= -13) return `rgba(63,115,196,0.5)`; // Arctic: -27 to -13 (from #3f73c4)
|
||||
if (t <= 0) return `rgba(126,176,224,0.5)`; // Freezing: -13 to 0 (from #7eb0e0)
|
||||
if (t <= 9) return `rgba(188,217,236,0.5)`; // Cold: 0 to 9 (from #bcd9ec)
|
||||
if (t <= 18) return `rgba(200,220,192,0.5)`; // Chilled: 9 to 18 (from #c8dcc0)
|
||||
if (t <= 26) return `rgba(74,138,58,0.5)`; // Comfortable: 18 to 26 (from #4a8a3a)
|
||||
if (t <= 32) return `rgba(232,197,71,0.5)`; // Mod heat: 26 to 32 (from #e8c547)
|
||||
if (t <= 38) return `rgba(220,138,58,0.5)`; // Strong heat: 32 to 38 (from #dc8a3a)
|
||||
if (t <= 46) return `rgba(196,74,58,0.5)`; // V. strong: 38 to 46 (from #c44a3a)
|
||||
return `rgba(122,26,26,0.5)`; // Extreme heat: >46 (from #7a1a1a)
|
||||
};
|
||||
const tempBgStrong = (t) => {
|
||||
if (t == null) return 'transparent';
|
||||
if (t < 0) return 'rgba(100,160,230,0.20)';
|
||||
if (t < 10) return 'rgba(140,200,200,0.20)';
|
||||
if (t < 18) return 'rgba(140,200,150,0.20)';
|
||||
if (t < 26) return 'rgba(100,190,100,0.20)';
|
||||
if (t < 32) return 'rgba(230,200, 80,0.20)';
|
||||
if (t < 40) return 'rgba(230,140, 50,0.20)';
|
||||
if (t < 50) return 'rgba(210, 70, 50,0.20)';
|
||||
return 'rgba(160, 30, 30,0.20)';
|
||||
if (t == null || t <= -27) return 'transparent';
|
||||
if (t <= -13) return `rgba(63,115,196,0.5)`; // Arctic: -27 to -13
|
||||
if (t <= 0) return `rgba(126,176,224,0.5)`; // Freezing: -13 to 0
|
||||
if (t <= 9) return `rgba(188,217,236,0.5)`; // Cold: 0 to 9
|
||||
if (t <= 18) return `rgba(200,220,192,0.5)`; // Chilled: 9 to 18
|
||||
if (t <= 26) return `rgba(74,138,58,0.5)`; // Comfortable: 18 to 26
|
||||
if (t <= 32) return `rgba(232,197,71,0.5)`; // Mod heat: 26 to 32
|
||||
if (t <= 38) return `rgba(220,138,58,0.5)`; // Strong heat: 32 to 38
|
||||
if (t <= 46) return `rgba(196,74,58,0.5)`; // V. strong: 38 to 46
|
||||
return `rgba(122,26,26,0.5)`; // Extreme heat: >46
|
||||
};
|
||||
const tempFontColor = (t) => {
|
||||
if (t == null) return '#4a3218';
|
||||
if (t <= -13) return '#fff'; // Arctic (-27 to -13)
|
||||
if (t <= 0) return '#111'; // Freezing (-13 to 0)
|
||||
if (t <= 9) return '#111'; // Cold (0 to 9)
|
||||
if (t <= 18) return '#111'; // Chilled (9 to 18)
|
||||
if (t <= 26) return '#fff'; // Comfortable (18 to 26)
|
||||
if (t <= 38) return '#111'; // Mod heat/Strong heat (26 to 38)
|
||||
return '#fff'; // V. strong/Extreme (38+)
|
||||
};
|
||||
const scaleBg = (v, min, max, rgb, maxAlpha = 0.14) => {
|
||||
if (v == null || isNaN(v)) return 'transparent';
|
||||
@@ -660,10 +672,10 @@ ${isPro && (activeProfile === 'custom' || activeCols['air']) && html`<button cla
|
||||
<span class="wind-dir-label" style=${{ fontFamily: 'Manrope, sans-serif', fontSize: '11px', fontWeight: 700 }}>${r.compass.label}</span>
|
||||
</span>
|
||||
</td>`}
|
||||
${visibleCols.air && html`<td class=${groupStart('air')} style=${{ background: tempBg(r.Ta) }}>${r.Ta.toFixed(1)}</td>`}
|
||||
${visibleCols.air && html`<td class=${groupStart('air')} style=${{ background: tempBg(r.Ta), color: tempFontColor(r.Ta) }}>${r.Ta.toFixed(1)}</td>`}
|
||||
${visibleCols.rh && html`<td class=${groupStart('rh')} style=${{ background: scaleBg(r.RH, 30, 100, '70,145,200') }}>${Math.round(r.RH)}</td>`}
|
||||
${visibleCols.dew && html`<td class=${groupStart('dew')} style=${{ background: tempBg(r.dew) }}>${r.dew != null ? r.dew.toFixed(1) : '—'}</td>`}
|
||||
${visibleCols.tmrt && html`<td class=${groupStart('tmrt')} style=${{ background: tempBg(r.Tmrt) }}>${r.Tmrt.toFixed(1)}</td>`}
|
||||
${visibleCols.dew && html`<td class=${groupStart('dew')} style=${{ background: tempBg(r.dew), color: tempFontColor(r.dew) }}>${r.dew != null ? r.dew.toFixed(1) : '—'}</td>`}
|
||||
${visibleCols.tmrt && html` <td class=${groupStart('tmrt')} style=${{ background: tempBg(r.Tmrt), color: tempFontColor(r.Tmrt) }}>${r.Tmrt.toFixed(1)}</td>`}
|
||||
${visibleCols.utci && html`
|
||||
<td class=${groupStart('utci')} style=${{ background: hexToRgba(cat.bg, 0.22), color: cat.fg === '#fff' ? cat.fg : '#2a1a08', fontWeight: 600 }}>
|
||||
${r.utci.toFixed(1)}°
|
||||
@@ -681,25 +693,25 @@ ${isPro && (activeProfile === 'custom' || activeCols['air']) && html`<button cla
|
||||
${r.utciAdj.toFixed(1)}°
|
||||
</td>`}
|
||||
${visibleCols.concreteT && html`
|
||||
<td class=${groupStart('concreteT')} style=${{ color: r.concreteT != null && r.concreteT > 40 ? '#c0392b' : r.concreteT != null && r.concreteT > 30 ? '#e67e22' : '#7f8c8d', fontWeight: 'bold', background: tempBg(r.concreteT) }}>
|
||||
<td class=${groupStart('concreteT')} style=${{ color: tempFontColor(r.concreteT), fontWeight: 'bold', background: tempBg(r.concreteT) }}>
|
||||
${r.concreteT != null ? r.concreteT.toFixed(1) : '—'}
|
||||
</td>`}
|
||||
${visibleCols.vehicleT && html`
|
||||
<td class=${groupStart('vehicleT')} style=${{ color: r.vehicleT != null && r.vehicleT > 45 ? '#c0392b' : r.vehicleT != null && r.vehicleT > 35 ? '#e67e22' : '#7f8c8d', fontWeight: 'bold', background: tempBgStrong(r.vehicleT) }}>
|
||||
<td class=${groupStart('vehicleT')} style=${{ color: tempFontColor(r.vehicleT), fontWeight: 'bold', background: tempBgStrong(r.vehicleT) }}>
|
||||
${r.vehicleT != null ? r.vehicleT.toFixed(1) : '—'}
|
||||
</td>`}
|
||||
${indoorMode === 'on' && !indoorManaged && html`
|
||||
<td class=${groupStart('indoorT')} style=${{ color: r.indoorT != null && r.indoorT > 32 ? '#c0392b' : r.indoorT != null && r.indoorT > 26 ? '#e67e22' : '#4a7a4a', fontWeight: 'bold', background: tempBgStrong(r.indoorT) }}>
|
||||
<td class=${groupStart('indoorT')} style=${{ color: tempFontColor(r.indoorT), fontWeight: 'bold', background: tempBgStrong(r.indoorT) }}>
|
||||
${r.indoorT != null ? r.indoorT.toFixed(1) : '—'}
|
||||
</td>`}
|
||||
${indoorMode === 'on' && indoorManaged && html`
|
||||
<td class=${groupStart('managedT')} style=${{ color: r.managedT != null && r.managedT > 32 ? '#c0392b' : r.managedT != null && r.managedT > 26 ? '#e67e22' : '#4a7a4a', fontWeight: 'bold', background: tempBgStrong(r.managedT) }}>
|
||||
<td class=${groupStart('managedT')} style=${{ color: tempFontColor(r.managedT), fontWeight: 'bold', background: tempBgStrong(r.managedT) }}>
|
||||
${r.managedT != null ? r.managedT.toFixed(1) : '—'}
|
||||
</td>`}
|
||||
${visibleCols.soilT && html`
|
||||
<td class=${groupStart('soilT')} style=${{ color: '#6b4a1c', background: tempBg(r.soilT0) }}>${r.soilT0 != null ? r.soilT0.toFixed(1) : '—'}</td>`}
|
||||
<td class=${groupStart('soilT')} style=${{ color: tempFontColor(r.soilT0), background: tempBg(r.soilT0) }}>${r.soilT0 != null ? r.soilT0.toFixed(1) : '—'}</td>`}
|
||||
${visibleCols.soilT6 && html`
|
||||
<td class=${groupStart('soilT6')} style=${{ color: '#6b4a1c', background: tempBg(r.soilT6) }}>${r.soilT6 != null ? r.soilT6.toFixed(1) : '—'}</td>`}
|
||||
<td class=${groupStart('soilT6')} style=${{ color: tempFontColor(r.soilT6), background: tempBg(r.soilT6) }}>${r.soilT6 != null ? r.soilT6.toFixed(1) : '—'}</td>`}
|
||||
${visibleCols.soilM && html`
|
||||
<td class=${groupStart('soilM')} style=${{ color: '#2a6a90', background: scaleBg(r.soilM, 0.12, 0.45, '50,125,190') }}>${r.soilM != null ? r.soilM.toFixed(3) : '—'}</td>`}
|
||||
${visibleCols.precip && html`
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ export const FILTER_PROFILES = {
|
||||
label: 'Custom',
|
||||
icon: '⚙️',
|
||||
proOnly: true,
|
||||
cols: { hour: true, air: true, rh: false, dew: false, wind: true, dir: false, cloud: false, sun: false, direct: false, diffuse: false, tmrt: false, delta: false, utci: false, uvA: false, uvB: false, burn: false, utciP: true, precip: true, soilT: false, soilT6: false, soilM: false, concreteT: false, vehicleT: false, indoorT: false, managedT: false, vis: false, aqi: false, pollen: false },
|
||||
cols: { hour: true, air: true, rh: true, dew: true, wind: true, dir: true, cloud: true, sun: true, direct: true, diffuse: true, tmrt: true, delta: true, utci: true, uvA: true, uvB: true, burn: true, utciP: true, precip: true, soilT: true, soilT6: true, soilM: true, concreteT: true, vehicleT: true, indoorT: true, managedT: true, vis: true, aqi: true, pollen: true },
|
||||
// -- FUTURE FEATURE v2: Saved Custom Profiles (Pro) -----------------------
|
||||
// Expand 'Custom' into a fully user-owned profile system. Pro users can:
|
||||
//
|
||||
|
||||
@@ -134,6 +134,10 @@ export function useAppState() {
|
||||
?? FILTER_PROFILES.outdoors.cols;
|
||||
return { ...variantCols };
|
||||
}
|
||||
// For 'custom' profile, always use the configured custom cols (all 25 columns)
|
||||
if (saved === 'custom') {
|
||||
return { ...FILTER_PROFILES.custom?.cols ?? FILTER_PROFILES.basic.cols };
|
||||
}
|
||||
return { ...(FILTER_PROFILES[saved]?.cols ?? FILTER_PROFILES.basic.cols) };
|
||||
} catch (e) { return { ...FILTER_PROFILES.basic.cols }; }
|
||||
});
|
||||
@@ -149,6 +153,15 @@ export function useAppState() {
|
||||
const hasIndoor = profile.cols['indoorT'] || profile.cols['managedT'];
|
||||
setIndoorMode(hasIndoor ? 'on' : 'off');
|
||||
setIndoorManaged(false);
|
||||
} else {
|
||||
// Custom profile ALWAYS initializes from config - with all 25 columns active
|
||||
const customCols = FILTER_PROFILES.custom?.cols;
|
||||
if (customCols) {
|
||||
setVisibleCols({ ...customCols });
|
||||
const hasIndoor = customCols['indoorT'] || customCols['managedT'];
|
||||
setIndoorMode(hasIndoor ? 'on' : 'off');
|
||||
setIndoorManaged(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user