Skip to content

feat(library): arrange diagrams automatically - #836

Draft
FelixTJDietrich wants to merge 1 commit into
mainfrom
feat/automatic-diagram-layout
Draft

feat(library): arrange diagrams automatically#836
FelixTJDietrich wants to merge 1 commit into
mainfrom
feat/automatic-diagram-layout

Conversation

@FelixTJDietrich

Copy link
Copy Markdown
Contributor

Summary

Closes #128.

This PR adds a single Arrange diagram action to the default editor chrome, the composable React controls, and the imperative ApollonEditor API. It supports every flat Apollon diagram type, including Use Case, Petri Net, and Syntax Tree diagrams whose relationships are rendered as straight connections.

Arrange runs outside the main thread and judges deterministic placement candidates with Apollon's existing edge-routing and label geometry. It applies a result only when it is a material readability improvement, fits moved nodes into the usable viewport, and commits positions plus any approved routing resets as one undoable change.

Manual edge routes remain authoritative by default. If visible edges contain authored bends or pinned endpoints, Arrange asks for explicit confirmation once and then replaces all affected visible routes atomically; hidden routes are untouched.

Release note

Arrange flat diagrams of every type automatically, including diagrams with straight connections. The result now favors clear routing, readable labels, cycle-aware flow, and balanced UML inheritance groups, then fits moved elements into view. Larger diagrams use an adaptive performance budget, while cancellation, stale-result protection, manual-route confirmation, and one-step Undo keep the operation safe.

Implementation notes

Layout and quality model

  • Generates bounded layered and structure-aware radial placements, packs disconnected components deterministically, and snaps results to the editor grid.
  • Reuses the canonical Apollon edge solver for exact scoring; no layout or routing dependency was added.
  • Prioritizes hard validity, node/label collisions, crossings, clearance, directed flow, straight-route preservation, routing cost, bends, footprint, and displacement.
  • Adds positive UML-specific quality measures for centered inheritance fan-outs and compact sibling groups.
  • Scores flow on the strongly connected component condensation graph, so unavoidable edges inside a directed cycle are not incorrectly treated as backward.
  • Accepts a semantic-only improvement only behind strict no-regression and route/footprint guards.

UX, safety, and API

  • Adds the built-in layoutControl() / <Apollon.Layout /> and ApollonEditor.arrangeDiagram() APIs.
  • Runs each solve in a one-shot Worker with cancellation, protocol validation, finite/grid-aligned output validation, and a hard deadline.
  • Rejects stale results if the model, measurements, diagram type, or active interaction changed while solving.
  • Reports actual moved-node and replaced-route counts.
  • Fits only after a successful result that moved nodes. The fit respects overlay insets, device safe areas, a maxZoom of 1, and reduced-motion preferences; viewport state is local and is not part of Undo.
  • Returns unchanged for an empty/single-node canvas instead of treating it as a failure.

Performance and scope

  • Small diagrams evaluate at most six exact routed candidates; the budget decreases with graph size.
  • The production safety profile supports up to 120 visible nodes and 240 visible relationships. A 120-node sparse regression graph completes below the Worker's deadline.
  • The reported diagram from Auto-layout to arrange diagram elements #128 is included byte-for-byte as a regression fixture. It selects the radial placement with zero crossings and zero bends and substantially reduces its footprint.
  • Bundle budgets cover the new lazy Worker explicitly: 46.63 kB brotli against a 50 kB limit. The main entry remains below its 124 kB budget.
  • Nested/container diagrams remain intentionally unavailable. Their child positions are relative, and a correct implementation needs type-specific container padding, resizing, lane, and cross-hierarchy policies; flattening them would corrupt both geometry and UML meaning.
  • Communication message stacks, SFC transition annotations, and the implicit «include» / «extend» text are rendered by specialized components and are not yet transported into the generic label objective. Their edges and explicit labels are still routed and scored.
  • PR feat(library): route straight edges and tidy syntax trees #835 overlaps in straight-edge routing and Syntax Tree layout. If it merges first, this branch will need a deliberate rebase so Apollon keeps one coherent Arrange UX rather than two competing layout policies.

Steps for testing

  1. Open the Class Diagram regression fixture in standalone/webapp/tests/fixtures/automatic-layout-star.json.

  2. Select Arrange diagram. Confirm that the nodes form a compact star, relationships remain clear, and the result is fitted into view.

  3. Add a manual bend or pin an endpoint, then select Arrange diagram. Cancel the confirmation and verify that nothing changes; repeat and confirm replacement.

  4. Select Undo once and verify that both positions and manual routing are restored.

  5. Repeat with flat Activity, Communication, Object, Flowchart, Reachability, Petri Net, SFC, and Syntax Tree fixtures.

  6. Verify that a nested diagram explains why Arrange is unavailable and that read-only or active-drag states cannot mutate the model.

  7. Run:

    pnpm lint
    pnpm format:check
    pnpm build
    pnpm test
    pnpm --filter @tumaet/apollon run size
  8. Run the focused Chromium production-bundle suite:

    PLAYWRIGHT_BUILT=1 pnpm --filter @tumaet/webapp exec playwright test \
      tests/e2e/automatic-layout.spec.ts --project=chromium

Local validation:

  • 89 unit-test files passed: 1,857 tests passed, 1 skipped.
  • 10/10 focused Chromium tests passed against both the development server and a fresh production bundle.
  • Lint, formatting, TypeScript/build, tests, Changesets status, and all published bundle-size limits passed.

Screenshots / screencasts

Draft follow-up: attach a before/after capture of the #128 regression fixture before marking this PR ready for review.

Checklist

  • Linked to a related issue (if applicable)
  • Added a changeset whose summary is written in the user's voice (pnpm changeset, how) — or this PR doesn't touch a Changesets-tracked package (@tumaet/apollon, @tumaet/webapp, @tumaet/server)
  • PR title's Conventional Commit type (feat/fix/…) matches the kind of change — it groups the release note
  • Tests added or updated
  • Ran pnpm lint && pnpm format:check && pnpm build && pnpm test locally — green
  • Documentation updated (if applicable)
  • Screenshots or screencasts attached (required before moving out of draft)

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

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

Auto-layout to arrange diagram elements

1 participant