Skip to content

fix: heatmap borders above cells, no dead animation chrome, domain aspect, single plotly.js (#258) - #259

Merged
Polichinel merged 3 commits into
developmentfrom
fix/heatmap-overlay-chrome
Jul 21, 2026
Merged

fix: heatmap borders above cells, no dead animation chrome, domain aspect, single plotly.js (#258)#259
Polichinel merged 3 commits into
developmentfrom
fix/heatmap-overlay-chrome

Conversation

@Polichinel

Copy link
Copy Markdown
Contributor

Closes #258. Found in the first pipeline-generated global report; diagnosed from the artifact itself.

RED→GREEN

  1. Borders above cells. The C-205 overlay was go.Scattergl — plotly renders WebGL beneath the SVG layer, so borders vanished under land-covering cells the moment coverage went global ([Global-PGM S1] Regenerate the entity-metadata bundle at global coverage (13,110 → ~64,818 cells) #231). Now SVG go.Scatter, drawn above, matching the PNG tier. (Latent since the overlay existed; the existing overlay test checked trace presence, not layering.)
  2. No dead chrome. Single-month step figures ([Global-PGM S2] Horizon coverage: explicit month selection; +1/+6/+12/+24/+36 PNGs + interactive heatmap at +1; kill the silent times[-1] pick #232) shipped the 36-month animation UI with zero frames. Both interactive builders now skip frames/Play/Pause/slider when there is one time step; multi-month keeps them (regression-pinned).
  3. No grey polar bands. yaxis.constrain='domain' — equal aspect shrinks the plot area instead of stretching latitude past ±90°.
  4. One plotly.js. The ReportModule inlines the single library copy (plotly.offline.get_plotlyjs, C-28: inlined, never CDN); mapping + historical figures ship include_plotlyjs=False.

Verified on the regenerated real report

Borders scatter on all 3 heatmaps · zero updatemenus/sliders · constrain present · exactly 1 plotly.js marker · 46.5 → 36.8 MB (−9.7 MB) · 60 step PNGs unchanged.

Ritual

5 RED tests → GREEN; CICs updated (mapping overlay bullet, report plotly ownership); ruff clean; 408 passed (2 skipped, 1 xfailed); docs validator green.

🤖 Generated with Claude Code

Polichinel and others added 3 commits July 21, 2026 10:45
…otly.js ownership (#258)

Characterizes the four defects from the first pipeline-generated global
report: borders as WebGL scattergl render UNDER the land-covering cells;
single-month step figures carry dead Play/Pause + a one-step slider + empty
frames; equal aspect stretches latitude past ±90 into grey bands; and every
figure inlines its own plotly.js (3 copies, ~8 MB) while the report inlines
none. Five failing tests by design; a multi-month chrome regression guard
passes. Next commit turns them green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… aspect, one plotly.js (#258)

Borders: the raster overlay is now an SVG go.Scatter — plotly renders WebGL
(Scattergl) beneath the SVG layer, so the old gl borders vanished under
land-covering cells the moment coverage went global; SVG draws above, like
the PNG tier's matplotlib overlay. Chrome: single-month figures (the
ADR-021 step renders) carry no Play/Pause, slider, or frames — both
interactive builders guard on len(all_times) > 1; multi-month figures keep
their controls (regression-pinned). Aspect: yaxis constrain='domain' —
equal aspect shrinks the plot area instead of stretching latitude past ±90
into grey bands. plotly.js: the ReportModule owns the SINGLE inlined copy
(plotly.offline.get_plotlyjs, C-28 offline, no CDN); mapping + historical
figures ship include_plotlyjs=False.

Verified on the regenerated rusty_bucket report: borders trace type
'scatter' on all three heatmaps, zero animation chrome, constrain present,
exactly one plotly.js marker, 46.5 -> 36.8 MB (-9.7 MB), 60 step PNGs
unchanged. CICs updated (mapping overlay + report plotly ownership).
408 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… figures, shared chrome, slider alignment (#258)

Addresses the 9 findings of the recall review on this branch:

plotly.js ownership is now ENFORCED, not conventional: _ensure_plotly_js
injects the single library the first time Plotly content arrives (keyed on
Plotly.newPlot) via add_html OR add_to_grid — image-only reports carry no
library at all — and a figure arriving with its own inlined copy logs a
loud duplication warning. plot_map emits a FRAGMENT (full_html=False,
matching historical.py): no more nested <html> documents in reports (was
3), and the docstrings/examples in plot_map and add_html now state the
fragment-within-report contract instead of advertising standalone offline
files the code no longer produces.

The duplicated ~70-line animation chrome collapsed into one shared
_apply_animation_chrome used by both interactive builders — which also
fixed a pre-existing off-by-one: frames now exist for ALL months, so the
slider's first step animates to a real frame (both builders; regression
guard updated to pin steps==frames).

Tests: the stale 'offline' raster test rewritten as the honest fragment
contract; e2e reports now assert exactly ONE '* plotly.js v' marker in the
exported html (the real C-28 guarantee, replacing a substring check);
content-aware injection + grid-path + double-inclusion-warning tests added.
cic_report_module updated to the injection semantics and swept of 13
absolute line-number anchors (C-210 residual).

Final artifact: 1 library before all newPlots, zero nested docs, borders
scatter, 36.8 MB. 410 tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant