Skip to content

GridQuantizer: opt-in grid snapping for flowchart layouts - #63

Merged
clintecker merged 1 commit into
mainfrom
feat/grid-quantizer-flowchart
Aug 12, 2026
Merged

GridQuantizer: opt-in grid snapping for flowchart layouts#63
clintecker merged 1 commit into
mainfrom
feat/grid-quantizer-flowchart

Conversation

@clintecker

@clintecker clintecker commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

The transform the grid-alignment metric was built to guard — the "then snap" half of the lint-first plan. Flowchart first (highest value, hardest edges); other box families follow.

What

GridQuantizer.quantize(_ layout: FlowchartLayout, unit:), opt in with DiagramSpacing(gridSnap: 4).

  • One seam — applied inside DiagramLayoutEngine.layout(_ chart: Flowchart, …), the single dispatch both render paths (CoreGraphics + RenderScene) and the lint IR call. All three inherit identical snapped geometry, so the draw-vs-scene conformance ratchet stays green with zero per-path work.
  • Boxes grow, never clip — origin rounds down, far corner up; w/h become grid multiples.
  • Edges stay attached — endpoints are re-anchored onto the snapped node borders (a grown box moves its right/bottom edge independently of the endpoint), interior waypoints snap to nearest (preserving orthogonal routing).
  • Cache-safegridSnap is in DiagramSpacing.fingerprint, so snapped/unsnapped renders don't collide.

Verification

  • Snapping drives node-coord alignment to 100% (through the metric).
  • Snapped layout stays lint-clean — no edge-endpoint-detached / edge-occludes-node / nodes-overlap on the (subgraph-bearing) flowchart fixture.
  • Boxes never shrink; gridSnap off is a strict identity.
  • Rendered snapped vs plain: visually intact (containers, back-edges, arrows all correct), moves ≤4pt.
  • 416 tests (+5). Off by default → no gallery/perf impact.

Scope

Flowchart only; block/C4/architecture/ER/class/state extend the same pattern next, then the metric floors get raised.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

The transform the grid-alignment metric was built to guard. `GridQuantizer`
snaps a laid-out flowchart onto a pixel grid; opt in with
`DiagramSpacing(gridSnap: 4)`.

- Applied inside `DiagramLayoutEngine.layout(_ chart: Flowchart, …)` — the single
  dispatch both render paths (CoreGraphics + RenderScene) and the lint IR call —
  so all three inherit identical snapped geometry and the draw-vs-scene
  conformance ratchet stays green with no per-path work.
- Node/container frames snap origin-down / far-corner-up, so a box only ever
  grows (never clips its measured label) and its w/h are grid multiples. Edge
  endpoints are re-anchored onto the snapped node borders — a grown box moves its
  right/bottom edge independently of the endpoint, so snapping the point alone
  would detach the arrow — and interior waypoints snap to the nearest grid line,
  preserving orthogonal routing (a segment's shared coordinate snaps identically
  at both ends).
- `DiagramSpacing.gridSnap` is off by default and included in `fingerprint`, so
  snapped and unsnapped renders never collide in the render cache.

Tests: snapping drives node-coord alignment to 100% (via the metric), keeps the
layout lint-clean (no edge-endpoint-detached / edge-occludes-node / nodes-overlap
on the subgraph-bearing fixture), never shrinks a box, and is a strict identity
when off. 416 tests pass (+5). Default output unchanged → no gallery/perf impact.

Other box families (block, C4, architecture, ER, class, state) extend the same
pattern in follow-ups; then the metric floors get raised.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014CJYAapHgDn2PWGNABnFtv
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 1 minute

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 38a3bf8e-3aa0-4b23-a1c0-d2c93f926b14

📥 Commits

Reviewing files that changed from the base of the PR and between 0150f2a and 116334a.

📒 Files selected for processing (5)
  • Sources/MermaidLayout/DiagramLayoutFlowchart.swift
  • Sources/MermaidLayout/DiagramSpacing.swift
  • Sources/MermaidLayout/GridQuantizer.swift
  • Sources/MermaidLayout/MermaidLayout.docc/SceneGeometryAndLinting.md
  • Tests/MermaidLayoutTests/GridQuantizerTests.swift

Comment @coderabbitai help to get the list of available commands.

@clintecker
clintecker merged commit c5d781c into main Aug 12, 2026
16 checks passed
@clintecker
clintecker deleted the feat/grid-quantizer-flowchart branch August 12, 2026 19:14
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