thermograph/static/calendar.html

85 lines
3.4 KiB
HTML
Raw Normal View History

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Thermograph — 2-year calendar</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<link rel="stylesheet" href="style.css" />
</head>
<body>
<header>
<div class="brand">
<span class="logo"></span>
<div>
<h1>Thermograph · Calendar</h1>
<p class="tag">Two years of daily grades vs local climate history</p>
</div>
<nav class="view-nav" aria-label="Views">
<a href="./" data-view="map">Weekly</a>
<a href="calendar" data-view="calendar" class="active">Calendar</a>
<a href="day" data-view="day">Day</a>
Scope app to /thermograph, free the domain root for a portfolio (#10) - Drop the app-level "/" redirect so the FastAPI app no longer claims the domain root; it stays scoped to THERMOGRAPH_BASE (/thermograph). Root now 404s at the app, leaving it for another service behind the proxy. - Caddyfile: serve a static portfolio at / and reverse-proxy /thermograph* to uvicorn, on emigriffith.dev with automatic Let's Encrypt TLS. - Default THERMOGRAPH_BASE to /thermograph in the env example to match. (#11) * Add dev CI/CD pipeline deploying to a LAN server (#6) * Weekly page: no-rain visuals adopt the dry-streak look On the Weekly page, no-rain (0") days now warm with the dry-streak ramp (tan→red, deepening to a 14-day cap) instead of a flat blue/tan, matching the Dry chart and calendar's dry-period language: - Precip trend chart: no-rain day dots colored by drynessColor(dsr). - "Daily, graded" timeline strip: Rain-row dry cells tinted by dsr via a new optional color override on rdCell. Rain days keep their intensity-tier colors; unknown streaks fall back to the prior flat color, so nothing regresses. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019VP23wKmjS2ozk1g5a9g1Z * Calendar totals: compact per-category status lines Replace the stacked share bar + labeled percentage chips above the calendar grid with a compact deviation strip: one thin status-colored line per category (height scaled to the tallest non-median category), with each share printed above it in that category's own status color. The median tier — the neutral "Normal" center of the diverging temperature scale — draws no line, just a faint baseline tick, so it reads as the reference the other categories deviate from. Precip and dry-streak have no natural median, so every category there keeps a line. Percentage text is lifted toward the theme text color (color-mix) so even the darkest/lightest tiers stay legible in both light and dark. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Calendar totals strip: wider bars, 0.1%-precision small shares (#5) Widen the per-category deviation bars (3px→10px) so each reads clearly, and print sub-1% shares as e.g. "0.4%" instead of "<1%". Claude-Session: https://claude.ai/code/session_019VP23wKmjS2ozk1g5a9g1Z Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * Weekly timeline: label dry streak instead of a dot On the precip row of the recent/forecast timeline, dry days now show the running dry-streak count ("3d" = 3 days since measurable rain), tinted by the same dryness ramp as the chart, rather than a bare "·". Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * Add dev CI/CD pipeline deploying to a LAN server PRs into dev run a build + boot/health check, auto-merge on green, and deploy the merged branch to a self-hosted runner on the LAN box, which runs the app as a sudo-free systemd --user service on 0.0.0.0:8137. - ci-cd.yml: build -> auto-merge -> deploy (self-hosted) - deploy-dev.yml: deploy on direct pushes / manual dispatch - deploy-dev.sh + thermograph-dev.service + provision-dev-lan.sh - CLAUDE.md: dev is the PR base branch; commit/PR message conventions - DEPLOY-DEV.md: pipeline docs * Match runner service name in docs to the installed user unit * Pin CI Python to 3.12 for prebuilt pyarrow/pandas wheels --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> * Build LAN dev venv on pinned Python 3.12 via uv (#7) This machine's default python3 is 3.14, which has no prebuilt pyarrow/pandas wheels, so plain venv + pip fell back to a failing source build. Use uv to pin the interpreter (fetching a managed CPython 3.12 if needed), independent of the runner's PATH and pyenv state. * Add comfort-temperature compare view; simplify Feels calendar filter (#9) Compare page (frontend/compare.{html,js} + /thermograph/compare route): line up several places over a date range and rank which best matches a comfort temperature. Per location it pulls the same daily record the Calendar uses and, per day, takes a chosen temperature (daytime high / daily mean / overnight low / feels-like) against the comfort target. A day "hits comfort" when it lands within an adjustable band; otherwise it counts as colder or warmer and the average miss is tracked. Results are ranked by comfort-day share (tie-broken by the smaller typical miss), with a diverging below/comfort/above bar and per-bucket stats. Comfort, band and judged temperature re-rank instantly client-side; only the location set or date range trigger a data load (shared calendar cache). Feels calendar filter: drop the comfort-temperature slider and the client-side felt-high/felt-low re-pick. The Feels metric now colors by the server's combined feels-like value like the other metrics, so its tab matches the rest of the metric selector. * Scope app to /thermograph, free the domain root for a portfolio (#10) - Drop the app-level "/" redirect so the FastAPI app no longer claims the domain root; it stays scoped to THERMOGRAPH_BASE (/thermograph). Root now 404s at the app, leaving it for another service behind the proxy. - Caddyfile: serve a static portfolio at / and reverse-proxy /thermograph* to uvicorn, on emigriffith.dev with automatic Let's Encrypt TLS. - Default THERMOGRAPH_BASE to /thermograph in the env example to match. --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-11 03:03:39 +00:00
<a href="compare" data-view="compare">Compare</a>
</nav>
</div>
</header>
<main>
<section class="controls">
<div class="find-bar">
<button type="button" id="find-btn" class="find-btn"></button>
<span id="loc-label" class="loc-label" hidden></span>
</div>
</section>
<div id="cal-head" class="cal-head" hidden></div>
<!-- Time filters: month/year range + season + year, each a compact dropdown. -->
<div id="cal-filters" class="cal-filters" hidden>
<div class="cal-range" id="cal-range">
<div class="cal-range-head">
<span class="cal-filter-label">Range</span>
<span class="hint">longer spans load 2 years at a time</span>
</div>
<label>From <input id="range-start" type="month" /></label>
<label>To <input id="range-end" type="month" /></label>
<button type="button" id="range-refresh" class="range-refresh" hidden>Refresh dates ↻</button>
</div>
<div id="cal-seasonyear" class="cal-seasonyear"></div>
</div>
<!-- Metric selector sits below the time filters, right above the grid it colors. -->
<div id="metric-block" class="metric-block" hidden>
<span class="cal-filter-label">Color the calendar by</span>
<div class="metric-toggle" id="metric-toggle" role="group" aria-label="Color the calendar by">
<button type="button" data-metric="tmax" class="active">High</button>
<button type="button" data-metric="tmin">Low</button>
<button type="button" data-metric="feels">Feels</button>
<button type="button" data-metric="humid">Humid</button>
<button type="button" data-metric="wind">Wind</button>
<button type="button" data-metric="gust">Gust</button>
<button type="button" data-metric="precip">Precip</button>
<button type="button" data-metric="dsr">Dry streak</button>
</div>
</div>
<!-- Category totals for the current metric across the shown (and weather-
filtered) days: a stacked share bar + per-category percentages. -->
<div id="cal-totals" class="cal-totals" hidden></div>
<div class="placeholder" id="cal-placeholder">
<p>Search a place — or open this from a graded location on the map — to see how
every day of the last two years graded against that spot's own climate history.</p>
</div>
<div id="calendar" class="calendar"></div>
<div id="cal-key"></div>
<div id="cal-tip" class="chart-tip" hidden></div>
</main>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="nav.js"></script>
<script src="mappicker.js"></script>
<script src="calendar.js"></script>
</body>
</html>