Skip to content

fix: regenerate baseline with standard pypowsybl for CI compatibility - #93

Merged
marota merged 1 commit into
mainfrom
claude/update-readme-changelog-egbKA
Apr 15, 2026
Merged

marota merged 1 commit into
mainfrom
claude/update-readme-changelog-egbKA

Conversation

@marota

@marota marota commented Apr 15, 2026

Copy link
Copy Markdown
Collaborator

Previous baseline update used the local RTE pypowsybl variant, which computes significantly different reactive flow (Q) deltas from the standard pypowsybl 1.14.0 used in CircleCI. Regenerated baseline_scenario.json using standard pypowsybl 1.14.0 (Expert_op4grid_recommender venv) so the Q-delta values match what CI computes.

Previous baseline update used the local RTE pypowsybl variant, which
computes significantly different reactive flow (Q) deltas from the
standard pypowsybl 1.14.0 used in CircleCI. Regenerated baseline_scenario.json
using standard pypowsybl 1.14.0 (Expert_op4grid_recommender venv) so the
Q-delta values match what CI computes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@marota
marota merged commit 8b79d62 into main Apr 15, 2026
2 checks passed
marota pushed a commit that referenced this pull request Apr 19, 2026
…tton release

Four user-reported issues from the last screenshot batch:

## 1. Combine-modal Simulate button stuck in running mode

`simulatingActionId` was only reset in the outer try's finally, AFTER
the async action-variant-diagram fetch completed.  On big grids
that's ~5-6 seconds of stale "spinner" UI even though the action
CARD (what matters to the sidebar feed) has already landed.

Fix: call setSimulatingActionId(null) + setIsSimulatingCombined(false)
the moment the simulate response arrives and the result has been
merged.  The subsequent variant-diagram fetch continues
asynchronously — buttons release immediately, tab flips happen
naturally when the diagram is ready, matching React's perceived
responsiveness.  Applied to both handleAddManualAction and
handleSimulateCombined.

## 2. Tab switching / action diagram loading felt sluggish

Two React performance optimisations were missing on the standalone:

### 2a. `/api/network-diagram` served as plain JSON → large JSON.parse

The backend exposes a `format=text` variant that returns
`{header}\n<svg…>` instead of embedding the multi-MB SVG inside a
JSON string.  Skips a ~500 ms main-thread JSON.parse on the
PyPSA-EUR France grid (see docs/perf-loading-parallel.md).  React
has used this since PR #71.

Ported to the standalone via a new `_fetchNetworkDiagramTextFormat()`
helper that fetches + splits on the first newline, with a graceful
fallback to the JSON endpoint if the text variant 404s (older
backends).

### 2b. Base NAD fetched AFTER branches + VLs + nominal-voltages

Previously the standalone did `Promise.all([branches, VLs, nomV])`
THEN called `fetchBaseDiagram`.  Since network-diagram is by far
the slowest XHR, stacking it after the metadata round-trips adds
~1-2 s to the critical path.  React parallelises all four since
PR #88 (docs/perf-loading-parallel.md).

Ported: both call sites (applySettingsImmediate + handleLoadConfig
equivalents) now issue a 4-way Promise.all that includes the
network-diagram.  The SVG is processed synchronously after the
Promise.all resolves, matching the React flow.

## 3. Pin rendering

Prior implementation was an SVG circle rendered in a viewBox-
scaled layer, so pins shrunk / grew and drifted as the user
zoomed.  Label was the rank number, not the loading percentage.
Anchor math was fine but the visual anchoring looked off because
the pin's centroid scaled with the map.

Rewrite:

  - Pins rendered as absolutely-positioned `<div>` elements in
    SCREEN pixel space.  A `projectSvgPoint(x, y)` function maps
    each pin's SVG-local coordinates through the current
    overviewVb + overlayRect using the same `xMidYMid meet`
    projection as the SVG itself, so pins stay exactly on the
    line midpoint as the user pans + zooms.
  - Teardrop glyph: inline <svg> with a <path> for the classic
    Google-Maps pin shape (`d="M18 0 … Z"`), tip at (0, 48) so
    `translate(-50%, -100%)` on the wrapper plants the tip on
    the asset.  Inner white circle for label contrast.
  - Label is the loading percentage (rounded), falling back to
    the rank when rho isn't set — matches the React ActionOverview
    component's pin label.
  - Size is 36x48 CSS-px regardless of zoom.  A ResizeObserver
    keeps overlayRect current when the window or sidebar resizes,
    so pin projection stays accurate through responsive layout
    changes.

Combined-pair curves (React's Bézier connecting two pins) are
still omitted — it's purely cosmetic and the per-pin events +
metadata round-trip already cover replay parity.

## 4. Deselecting an action jumped to N-1 tab instead of staying on Action

React switched this behaviour in PR #93 — clicking the selected
action card again (or the × chip) now keeps the user on the
Remedial Action tab, which falls through to the
ActionOverviewDiagram pin view.  The standalone was still doing
`setActiveTab('n-1')` in the deselect branch of handleActionSelect.

Fix: drop that line.  The tab stays on 'action', selectedActionId
becomes null, and the conditional render below picks the Overview
component because it's the only branch where
`result?.actions && !selectedActionId`.

---

Parity-script impact:

  - Layer 1 still 51/51, exits 0.
  - Layer 2 unchanged (26/30 React, 30/30 standalone).
  - Layer 3a 22/22.
  - Vitest 972/972.

https://claude.ai/code/session_01LGL7gvedQLrUGGzqVm4wAG
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