Skip to content

Add diurnal fingerprint plot to the readout panel (#28)#68

Open
aivanchenk wants to merge 5 commits into
mainfrom
feat/fingerprint-plot
Open

Add diurnal fingerprint plot to the readout panel (#28)#68
aivanchenk wants to merge 5 commits into
mainfrom
feat/fingerprint-plot

Conversation

@aivanchenk

Copy link
Copy Markdown
Collaborator

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 | Fingerprint toggle in the readout panel and shares the same series, history slider, and loading/error states as the existing line chart.

How

  • Pure consumer of the existing time series. The reader already returns the full flat [day x 24] Float32Array per pixel (the hour axis is only collapsed downstream in TimeSeriesPlot via dailyMeanSeries). The fingerprint plot indexes values[day * 24 + hour] instead of averaging, so there is no data-layer change.
  • Canvas cell grid, no new dependency. Draw cost is bounded by the destination pixel width (nearest-sampled along the day axis), so multi-year windows (~184k cells) render without jank.
  • Diverging color scale keyed on isLight, matching the existing timeSeriesChartTheme pattern. 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 | Fingerprint toggle; renders the matching plot/skeleton per view.

Verification

  • Unit tests for the scale + helpers (npx vitest run: 53 pass, 8 new).
  • npx tsc --noEmit clean on touched files; npx next build smoke test passes.
  • Manual: selected a land pixel, confirmed the midday uptake band is visible with hour 0 at the bottom, the diverging legend is symmetric around 0, and the ramp updates in both light and dark themes. Switching back to Line leaves the existing chart unchanged.

🤖 Generated with Claude Code

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.
@aivanchenk
aivanchenk requested a review from lazarusA July 25, 2026 09:43
@github-actions

github-actions Bot commented Jul 25, 2026

Copy link
Copy Markdown

🚀 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.
@lazarusA

Copy link
Copy Markdown
Member
  • Usually the axes are flipped, could we add an option to do that?
  • Also, we will need another option to single-out years, like a button group, showing available years, and from there click select just one to see.
  • Also, we need a hover tooltip to show values in the finger print.
Screenshot 2026-07-25 at 12 02 51

- 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.
@aivanchenk

Copy link
Copy Markdown
Collaborator Author

@lazarusA thanks for the review, all three points are addressed in 1000c20:

  • Flip axes — a toggle that swaps the hour and day axes.
  • Single out a year — a button group of the calendar years the loaded window spans (All 2016 … 2021); pick one to view just that year. The color scale stays global so years remain comparable. Axis labels now use real calendar dates, derived from the store's time origin (days since 2001-01-01).
  • Hover tooltip — reads the date, hour, and value under the cursor (e.g. 2019-07-11 · 17:00 · -0.21 umolCO2 m-2 s-1).

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.

@lazarusA

Copy link
Copy Markdown
Member

there is not new preview, because build was skipped.

Anastasiia Ivanchenko added 2 commits July 26, 2026 00:16
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
@aivanchenk

Copy link
Copy Markdown
Collaborator Author

Heads-up: CI is green again on the latest commit (e4a492a) and the Vercel preview has been rebuilt and redeployed, so it now reflects the vik ramp plus the three new controls (flip axes, year single-out, hover tooltip).

(The earlier preview had skipped because a lint error failed the build, and the branch had also drifted into a conflict with main after #67 merged; both are resolved now.)

@lazarusA

Copy link
Copy Markdown
Member

I just noticed, that when displaying more than one year, tick labels should be just year, not month, because months are now actually within each year.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fingerprint plot

2 participants