claude/vigorous-stonebraker-41cc2d
needs attentionviewing older commit754a65d · incrementalpre-PRreviewed 2026-07-10 16:39 UTC0H · 3M · 4L · 4I- Purpose
- Iterative improvements to the standalone Mexico energy atlas static tool (apps/web/public/atlas/)
- Goal
- Add filter shortcuts (Todas/Ninguna) and collapsible side panel to the atlas UI, switch the DG chart from cumulative stacked-area to annual-additions stacked-bar, and fix visual artifacts (donut holes) in CFE region polygons
- Sub-goals
- feat: Add 'Todas'/'Ninguna' generation-source filter shortcuts to the side panel
- feat: Add collapsible side panel (desktop) with side-toggle recovery on all screen widths
- feat: Default chart view to 'Anual' (annual additions) instead of cumulative
- feat: Default DG view to 'size' breakdown (now showing annual MW additions per size band)
- fix: Fill donut holes in region polygons by discarding interior rings from mis-geocoded municipios
- What
- index.html: new CSS for collapse button and h4 row layout; collapse button inside #side panel; Todas/Ninguna shortcut anchors; drawDGSize() refactored from cumulative stacked-area to annual-additions stacked-bar (year-over-year delta, slot-based x-positions, stride-based label thinning); default T.agg changed to 'ann', EVO.dgview to 'size'. atlas.json: polygon geometry updated to remove interior rings (donut holes) from all region polygons.
- Why
- Prior cumulative area chart made year-to-year growth rate hard to read; polygon holes rendered as stray outlines inside region fills; filter shortcuts save multiple clicks to select/clear all source types.
- Areas
- apps/web/public/atlas/index.html+30−15apps/web/public/atlas/data/atlas.json+1−1
- Blast
- 2 files, +31/-16 lines; entirely self-contained static tool — no Next.js app code, no backend, no Drizzle, no shared packages touched.
Findings · 11
correctness1
Annual-delta chart spikes on non-contiguous year data
apps/web/public/atlas/index.html
The delta formula `(c[y]||0) - (i ? (c[yrs[i-1]]||0) : 0)` treats a missing year as zero capacity. If years in E.years are non-contiguous, the first year after a gap gets a bar equal to the full cumulative total rather than the true annual addition. Math.max(0,...) prevents negative bars but not false spikes. Low risk if the data is always annually contiguous, but worth a guard comment or a sparse-data assertion.
security1
innerHTML interpolates JSON-sourced year string
apps/web/public/atlas/index.html
e_read.innerHTML interpolates yrs[cur] from a same-origin JSON file. All other interpolated values are numbers (Math.round). Under the current same-origin, static-file threat model the risk is negligible, but using Number(yrs[cur]) before interpolation (or textContent on a child span) would eliminate the class entirely at zero cost.
conventions2
data-v="size" button now labeled 'Anual' — attribute and label semantically diverge
apps/web/public/atlas/index.html
The DG-view button carries data-v="size" but its label was renamed from 'Tamaño' to 'Anual' to reflect the new annual-additions chart. The internal attribute value and the displayed label now have different semantics, which can confuse future maintainers. Consider renaming data-v to 'ann' to match the label, or adding a comment explaining the divergence.
src_all / src_none are <a> tags without href — not keyboard-focusable by default
apps/web/public/atlas/index.html
<a> without href is not in the tab order and is not announced as interactive by screen readers. Using <button> elements (with appropriate styling) would be semantically correct for these click-only controls.
tests2
drawDGSize() delta computation has no unit tests
apps/web/public/atlas/index.html
The year-over-year delta logic (sparse years, negative clamping, first-year base) is non-trivial. The project has Vitest — extracting the delta computation as a pure function and adding a test for edge cases (sparse years, single-year, all-zero, decommissioning) would prevent silent regressions.
No Playwright smoke test for Atlas UI behaviours
apps/web/public/atlas/index.html
The collapsible panel toggle, Todas/Ninguna shortcuts, and default chart state (annual view, size view) are untested. A minimal Playwright test loading the static page would catch regressions at low incremental cost given the project already has Playwright configured.
improvement5
SVG letterboxing: stacked-bar chart missing preserveAspectRatio="none"
apps/web/public/atlas/index.html
drawDGSize() switched from preserveAspectRatio="none" to the SVG default (xMidYMid meet). With viewBox="0 0 860 190" and style="width:100%;height:190px", on containers narrower than 860px the chart will shrink to maintain aspect ratio, leaving blank space and a visually tiny chart. Add preserveAspectRatio="none" to restore the fill-width behaviour the old area chart had.
Filter shortcut DOM state maintained independently of f.src — desync risk
apps/web/public/atlas/index.html
src_all and src_none imperatively toggle the .off class on rows, mirroring what individual row handlers do. If any future code path mutates f.src without touching the DOM (or vice versa), the visual checkbox state diverges from the actual filter. A more robust pattern: derive .off from f.src inside applyFilters() or a dedicated syncSrcUI() so the DOM is always a pure function of state.
Accessibility: side-collapse relies on title, not aria-label
apps/web/public/atlas/index.html
The collapse button uses title="Ocultar panel" which is not reliably announced by screen readers and is invisible on touch devices. Add aria-label="Ocultar panel" alongside title.
Redundant CSS rule: body.side-hidden #side-collapse already hidden by parent
apps/web/public/atlas/index.html
#side-collapse is a child of #side. When body.side-hidden sets #side to display:none, all descendants (including #side-collapse) are already hidden. The explicit body.side-hidden #side-collapse{display:none} rule is dead CSS and can be removed.
src_all/src_none duplicate the row-toggle DOM logic
apps/web/public/atlas/index.html
Both shortcuts inline querySelectorAll + classList manipulation that mirrors each row's onclick handler. Extracting a setSrcFilter(keys) helper that updates both f.src and the .off classes in one place would eliminate the duplication and make future changes (e.g. renaming the CSS class) a single edit.
History · 10 commits
- a081002safeincremental0H · 0M · 0L2026-07-14 01:23
- 64dc83dneeds attentionincremental0H · 1M · 7L2026-07-13 20:03
- ec4eea3needs attentionincremental1H · 3M · 7L2026-07-13 18:42
- f4b4129safeincremental0H · 0M · 3L2026-07-13 04:34
- 8ea0c8asafeincremental0H · 0M · 3L2026-07-13 04:21
- 37ce28asafeincremental0H · 2M · 3L2026-07-10 17:22
- d28c6daneeds attentionincremental0H · 3M · 10L2026-07-10 16:59
- 754a65dneeds attentionincremental0H · 3M · 4L2026-07-10 16:39current
- a9190b2safeincremental0H · 0M · 5L2026-07-10 16:14
- 0bf12a0blockedfull1H · 2M · 4L2026-07-10 16:06