Align the by-season scores into a columns-aligned table (#198)
The by-season chips wrapped freely, so a metric's scores didn't line up across seasons. Render it as a table instead — seasons as rows, one aligned column per metric (plus an Overall column), tinted cells, horizontal scroll on narrow screens.
This commit is contained in:
parent
e82323f11a
commit
91a780dd55
2 changed files with 15 additions and 30 deletions
|
|
@ -122,19 +122,17 @@ function render(data) {
|
|||
const cards = METRIC_ORDER.map((k) => metricCard(annual.metrics[k])).join("");
|
||||
const wbNote = wetbulbNote(annual.metrics.wetbulb, baseYrs);
|
||||
|
||||
// ---- by-season rows ----
|
||||
// ---- by-season table (seasons × metrics, columns aligned) ----
|
||||
const seasonHead = `<tr><th></th><th>Overall</th>${METRIC_ORDER.map((k) =>
|
||||
`<th>${shortLabel(k)}</th>`).join("")}</tr>`;
|
||||
const seasonRows = SEASON_ORDER.map((sk) => {
|
||||
const sl = s.slices[sk];
|
||||
const chips = METRIC_ORDER.map((k) => seasonChip(sl.metrics[k])).join("");
|
||||
const oc = sl.overall;
|
||||
const overallChip = oc
|
||||
? `<span class="score-chip ${tintClass(oc.class)}" title="Overall">${oc.score}</span>`
|
||||
: `<span class="score-chip t-none" title="Overall">—</span>`;
|
||||
return `<div class="season-scores">
|
||||
<span class="season-scores-name">${SEASON_NAMES[sk]}</span>
|
||||
<span class="season-scores-overall">${overallChip}</span>
|
||||
<span class="season-scores-chips">${chips}</span>
|
||||
</div>`;
|
||||
const overallCell = oc
|
||||
? `<td class="${tintClass(oc.class)}"><strong>${oc.score}</strong></td>`
|
||||
: `<td class="t-none">—</td>`;
|
||||
const cells = METRIC_ORDER.map((k) => seasonCell(sl.metrics[k])).join("");
|
||||
return `<tr><th>${SEASON_NAMES[sk]}</th>${overallCell}${cells}</tr>`;
|
||||
}).join("");
|
||||
|
||||
scoreBody.innerHTML = `
|
||||
|
|
@ -142,8 +140,8 @@ function render(data) {
|
|||
${wbNote}
|
||||
<section class="score-section">
|
||||
<p class="section-title">By season</p>
|
||||
<p class="score-legend">${METRIC_ORDER.map((k) => shortLabel(k)).join(" · ")}</p>
|
||||
${seasonRows}
|
||||
<div class="score-table-wrap"><table class="score-table season-table">
|
||||
<thead>${seasonHead}</thead><tbody>${seasonRows}</tbody></table></div>
|
||||
</section>
|
||||
<button type="button" class="summary-toggle" aria-expanded="false" aria-controls="score-summary">
|
||||
Summary <span class="summary-caret" aria-hidden="true">▾</span></button>
|
||||
|
|
@ -192,9 +190,9 @@ function scoreDirection(m) {
|
|||
return `~${pts} pts ${esc(m.direction)}`;
|
||||
}
|
||||
|
||||
function seasonChip(m) {
|
||||
if (!m || m.score == null) return `<span class="score-chip t-none">—</span>`;
|
||||
return `<span class="score-chip ${tintClass(m.class)}" title="${esc(m.label)}: ${esc(m.grade)}">${m.score}</span>`;
|
||||
function seasonCell(m) {
|
||||
if (!m || m.score == null) return `<td class="t-none">—</td>`;
|
||||
return `<td class="${tintClass(m.class)}" title="${esc(m.label)}: ${esc(m.grade)}">${m.score}</td>`;
|
||||
}
|
||||
|
||||
const shortLabel = (k) => ({ precip: "Precip", tmax: "High", tmin: "Low", feels: "Feels",
|
||||
|
|
|
|||
|
|
@ -1730,7 +1730,6 @@ td.rec-date { color: var(--muted); font-size: 13px; }
|
|||
.score-note { font-size: 12px; color: var(--muted); margin: 12px 0 0; line-height: 1.4; }
|
||||
|
||||
.score-section { margin: 20px 0; }
|
||||
.score-legend { font-size: 12px; color: var(--muted); margin: -6px 0 10px; }
|
||||
|
||||
/* Wet-bulb explainer + heat-stress-day share. */
|
||||
.score-callout {
|
||||
|
|
@ -1738,19 +1737,8 @@ td.rec-date { color: var(--muted); font-size: 13px; }
|
|||
padding: 12px 14px; margin: 14px 0 4px; font-size: 13px; line-height: 1.5; color: var(--text);
|
||||
}
|
||||
|
||||
/* One row per season: name · overall · a chip per metric. */
|
||||
.season-scores {
|
||||
display: grid; grid-template-columns: 64px 40px 1fr; align-items: center;
|
||||
gap: 10px; padding: 7px 0; border-top: 1px solid var(--border);
|
||||
}
|
||||
.season-scores-name { font-size: 13px; font-weight: 600; color: var(--text); }
|
||||
.season-scores-chips { display: flex; flex-wrap: wrap; gap: 5px; }
|
||||
.score-chip {
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
min-width: 30px; padding: 3px 6px; border-radius: 7px;
|
||||
font-size: 12px; font-weight: 700; color: var(--text);
|
||||
}
|
||||
.season-scores-overall .score-chip { min-width: 34px; font-weight: 800; }
|
||||
/* By-season scores: seasons as rows, one aligned column per metric. */
|
||||
.season-table th:first-child, .season-table td:first-child { text-align: left; }
|
||||
|
||||
/* Summary reveal — pill button + caret, mirrors the season-expand pattern. */
|
||||
.summary-toggle {
|
||||
|
|
@ -1787,7 +1775,6 @@ td.rec-date { color: var(--muted); font-size: 13px; }
|
|||
@media (max-width: 640px) {
|
||||
.score-num { font-size: 40px; }
|
||||
.score-hero { padding: 14px 15px; }
|
||||
.season-scores { grid-template-columns: 56px 36px 1fr; gap: 8px; }
|
||||
}
|
||||
|
||||
/* Monthly temperature-range strip: one gradient bar per month, low→high on a shared
|
||||
|
|
|
|||
Loading…
Reference in a new issue