Skip to content

Wrap long feeder names at substation extremities (Issue 1)#3

Merged
marota merged 6 commits into
claude/sld-voltage-navigation-mypy-1zm3omfrom
claude/voltage-level-interactions-exht90
Jul 3, 2026
Merged

Wrap long feeder names at substation extremities (Issue 1)#3
marota merged 6 commits into
claude/sld-voltage-navigation-mypy-1zm3omfrom
claude/voltage-level-interactions-exht90

Conversation

@marota

@marota marota commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Summary

Extends the feeder-label wrapping system to handle all long equipment names at substation extremities — not just relabelled branches, but also generators, loads, and unmatched branches whose far-end VL is unnamed. This prevents the label pile-up that survived Issue 1's branch-only relabelling on dense VLs.

Key Changes

  • Enhanced wrapFeederLabel() to break long single words on separators

    • Added breakLongWord() helper that splits identifiers like virtual_relation_8423568_a_0-225 on _, -, . boundaries within a character budget
    • Preserves every character and prefers natural separators over hard cuts
    • Allows long raw IIDM ids to wrap across multiple lines instead of running off-screen
  • New applyFeederLabelWrap() function

    • Wraps every long feeder NAME label inside feeder cells (.sld-extern-cell, .sld-intern-cell, .sld-shunt-cell)
    • Skips numeric P/Q flow labels, already-relabelled feeders (which wrap themselves), and highlight clones
    • Idempotent via data-feeder-wrap / data-feeder-wrap-orig attributes
    • Restores original text on subsequent calls with no active SVG
  • VL name-box interactivity

    • Extended vlInteractions.ts to resolve clicks on VL name boxes (.nad-label-box) in addition to disk clicks
    • Single-click on name box opens the SLD directly (no double-click window)
    • Single-click on disk selects the VL (existing behavior)
    • Added fallback to document.elementsFromPoint when a branch is drawn on top of a disk, so the disk remains interactive across its whole area
    • Updated metadata index to map text-node svgIds to their VL NodeMeta via textNodesBySvgId
  • Integration in useSldFeederRelabel hook

    • Calls applyFeederLabelWrap() right after applyFeederRelabels()
    • Runs BEFORE injection-name buttons so they size their bounding box to the wrapped, multi-line name
    • Self-gate tracks both relabel and wrap state to detect reconciliation drops

Implementation Details

  • breakLongWord() scans backward from the character budget to find a separator, ensuring pieces rejoin exactly into the original word
  • wrapFeederLabel() now handles both space-separated words and long single words, applying the two-level splitting strategy
  • The elementsFromPoint fallback in vlInteractions.ts only runs on discrete pointer events (mousedown/hover), never per frame, preserving the performance contract
  • Text-node metadata resolution falls back to equipmentId when vlNode link is absent, maintaining compatibility with older metadata formats
  • All wrapping is reversible: data-feeder-wrap-orig stores the original text for restoration on subsequent calls

Tests

  • Updated wrapFeederLabel tests to verify long single-word breaking behavior
  • Added comprehensive applyFeederLabelWrap test suite covering long names, short names, numeric labels, relabelled feeders, highlight clones, and restoration
  • Added vlInteractions tests for paint-stack resolution and name-box click handling
  • Added metadataIndex tests for text-node mapping with vlNode links and fallbacks

https://claude.ai/code/session_014aLzZJp3MP3qYBr1WKGRC6

claude added 6 commits July 1, 2026 08:07
…names

Three UX fixes for the network diagram and SLD:

- Feeder names at a substation's extremities no longer overlap. Beyond
  the branch relabelling (Issue 1), a new applyFeederLabelWrap pass wraps
  EVERY long feeder name (generators, loads, and branches whose far-end
  VL is unnamed) inside each feeder cell, and wrapFeederLabel now breaks
  long single-token ids on their _/-/. separators.

- VL disks are interactive across their whole area, even where a branch
  is drawn on top: when the direct hit-test lands on an occluding edge,
  the handlers fall back to document.elementsFromPoint and pick the first
  VL disk/name box in the paint stack (discrete events only, no per-frame
  cost).

- The VL name box on the NAD is interactive too — a single click opens
  its SLD. Resolved through metadata.textNodes (new textNodesBySvgId map
  on the metadata index) that maps each label box to its VL.

Docs + unit tests updated (feederLabels, metadataIndex, vlInteractions).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aLzZJp3MP3qYBr1WKGRC6
PR #3 targets the `claude/sld-voltage-navigation-mypy-1zm3om` working
branch, but the Code Quality / Tests / Parity workflows only fired on
`pull_request` events whose base was `main`, so no CI ran for it. Broaden
each `pull_request` trigger to `branches: ['**']` so CI runs on PRs
targeting any branch. `push` stays restricted to main, and the
HuggingFace deploy workflow is left untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aLzZJp3MP3qYBr1WKGRC6
Empty commit to fire a pull_request synchronize event now that repo-level
GitHub Actions is enabled, so Code Quality / Tests / Parity run on PR #3.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aLzZJp3MP3qYBr1WKGRC6
A pull_request whose base is not `main` is matched against the base
branch's own trigger (still main-only), so broadening the head branch's
pull_request filter alone did not fire CI for PR #3. Add the `claude/**`
working branches to the push trigger so pushes to this branch get
commit-level checks that surface on the PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aLzZJp3MP3qYBr1WKGRC6
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aLzZJp3MP3qYBr1WKGRC6
The pull_request `branches: ['**']` change (read from the PR head
branch's workflow) is confirmed to trigger CI for PR #3, so the
`claude/**` push trigger is no longer needed and only produced
duplicate runs. Restore push to `main`-only; keep the broadened
pull_request filter.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014aLzZJp3MP3qYBr1WKGRC6
@marota marota merged commit cda1bb8 into claude/sld-voltage-navigation-mypy-1zm3om Jul 3, 2026
4 checks passed
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.

2 participants