Add diurnal fingerprint plot to the readout panel (#28)#68
Conversation
Add a fingerprint view: an hour-of-day (0 at the bottom) by day heatmap of the pixel's flux, colored by a diverging scale centered on zero so midday uptake separates from nighttime respiration. It sits behind a Line | Fingerprint toggle in the readout and reuses the same series, history slider, and loading/error states as the line chart. The plot is a pure consumer of the existing time series: the reader already returns the full flat [day x 24] Float32Array per pixel, so no data-layer change is needed. Rendering is a canvas cell grid (no new dependency), with NaN cells left transparent for ocean/missing pixels.
|
🚀 Vercel preview deployed Preview URL: https://earth-prints-gesuh3t9b-anastasiia-s-projects10.vercel.app |
Swap the teal/orange poles for the geoscience-standard "vik" convention (Crameri's perceptually uniform, colourblind-safe scientific colour maps): blue for uptake, red for release, neutral gray at zero. This is the palette flux and climate scientists expect for signed anomaly fields, with warm reading as CO2 emission.
- Flip axes: toggle to swap the hour and day axes. - Single out a year: a button group of the calendar years the loaded window spans; pick one to view just that year. The color scale stays global so years remain comparable. - Hover tooltip: read the date, hour, and value under the cursor. Axis labels now use real calendar dates, derived from the store's time coordinate origin (days since 2001-01-01), added as a constant alongside the other time facts. All view logic is client-side over the already loaded series, so no extra fetch is needed.
|
@lazarusA thanks for the review, all three points are addressed in 1000c20:
All view logic is client-side over the already-loaded series, so no extra fetch. Also note the colors changed since your screenshot: the ramp is now the geoscience-standard vik diverging scale (blue = uptake, red = release), so the Vercel preview will look different from the earlier teal/orange. |
|
there is not new preview, because build was skipped. |
The effect that reset a stale year selection called setState synchronously inside a useEffect, which the lint rule flags as a cascading-render risk (and failed CI). Remove it: the active day range is already derived defensively during render, so a selection outside the current window reads as "All" with no effect needed.
# Conflicts: # src/components/map/MapReadout.tsx
|
Heads-up: CI is green again on the latest commit (
(The earlier preview had skipped because a lint error failed the build, and the branch had also drifted into a conflict with |

Closes #28.
What
Adds a fingerprint plot: the flux-community view of a diurnal cycle. An hour-of-day (0-23, 0 at the bottom) by day heatmap of the pixel's flux, colored by a diverging scale centered on zero so midday uptake (negative NEE) separates cleanly from nighttime/seasonal release (positive NEE). Reference: Fig. 4 of the FLUXCOM-X data paper (hal-04138821 / Biogeosciences 21, 5079, 2024).
It sits behind a
Line | Fingerprinttoggle in the readout panel and shares the same series, history slider, and loading/error states as the existing line chart.How
[day x 24]Float32Arrayper pixel (the hour axis is only collapsed downstream inTimeSeriesPlotviadailyMeanSeries). The fingerprint plot indexesvalues[day * 24 + hour]instead of averaging, so there is no data-layer change.isLight, matching the existingtimeSeriesChartThemepattern. NaN cells (ocean / missing pixels) render transparent so gaps read as gaps.New / changed files
src/lib/map/fingerprintScale.ts(new) +fingerprintScale.test.ts(new) - diverging scale,symmetricAbsMax(NaN-safe), axis tick helpers.src/components/map/FingerprintPlot.tsx(new) - canvas heatmap with hour/day axes and a color legend.src/components/map/FingerprintPlotLoading.tsx(new) - skeleton matching the canvas footprint.src/components/map/MapReadout.tsx-Line | Fingerprinttoggle; renders the matching plot/skeleton per view.Verification
npx vitest run: 53 pass, 8 new).npx tsc --noEmitclean on touched files;npx next buildsmoke test passes.🤖 Generated with Claude Code