Skip to content

feat: add cycle shape - #2929

Open
Furox-Art wants to merge 1 commit into
d2lang:masterfrom
Furox-Art:feat/shape-cycle
Open

Furox-Art wants to merge 1 commit into
d2lang:masterfrom
Furox-Art:feat/shape-cycle

Conversation

@Furox-Art

Copy link
Copy Markdown

Design summary

shape: cycle turns a container into a ring: its direct children are placed with their centers on a circle (first child at 12 o'clock), and edges between them are routed along that circle as exact circular arcs whose endpoints are trimmed to each child's visible border.

Layout (d2layouts/d2cycle):

  • The core layout engine (dagre/elk/tala) runs first, so any nested content inside the children is fully laid out. Each child is then moved onto the ring together with its descendants, and internal/cross-child edge routes are translated along so nothing detaches.
  • Arcs are built as cubic Bezier chains with the canonical circular-arc control offset k = 4/3·tan(Δθ/4), split into segments of at most 90°, so the drawn path is a perfect circle through the existing IsCurve path renderer (no renderer changes needed).
  • Endpoints are computed by intersecting the ring with the child shape's geometry: rectangular children exit at the box border (bisection), non-rectangular children (circle, hexagon, diamond, ...) at their actual perimeter, with a TraceToShapeBorder fallback. Arrowheads therefore land exactly on the visible outline, which is what shape: cycle #1578 asks for.
  • Edges take the shorter way around the ring. On a two-node cycle, opposite edges take opposite semicircles instead of overlapping.
  • The container renders like a normal container (rounded rect), so style.fill, style.stroke, multiple, 3d, double-border, fill patterns, labels and icons all work unchanged.

The name follows the issue discussion (cycle, not radial, keeping radial reserved).

Reviewing

New e2e fixture (e2etests/txtar.txtcycle-diagram), goldens for dagre, elk and tala:

  • e2etests/testdata/txtar/cycle-diagram/dagre/{board.exp.json,sketch.exp.svg}
  • e2etests/testdata/txtar/cycle-diagram/elk/{board.exp.json,sketch.exp.svg}
  • e2etests/testdata/txtar/cycle-diagram/tala/{board.exp.json,sketch.exp.svg}

The fixture covers: a 4-node ring (the case from the issue), a ring of circle/hexagon/diamond children plus a reverse edge, a ring with nested content (x: {p -> q}), a cross-child edge (x.p -> y), container styling, and a two-node ring with edges in both directions. Reviewers can re-render with TA=1 go test ./e2etests -run 'TestE2E/txtar/cycle-diagram' -v, or paste the fixture board into the playground.

Unit tests: d2layouts/d2cycle/layout_test.go (radius sizing, ring placement, arc circularity + border trimming, nested-content preservation, cross-child edge attachment, two-node semicircles).

How this differs from #2760 and #2806

Both rival PRs share the same core approach (circle layout + circular arcs); this PR is a superset of the stronger one (#2806) with the following differences:

Validation

  • go build ./..., go vet on touched packages, gofmt clean
  • go test ./d2layouts/d2cycle/ -v — 5/5 pass
  • go test ./e2etests -run 'TestE2E/txtar$' — pass (all fixtures, dagre+elk+tala)
  • go test ./e2etests — full e2e suite passes

/claim #1578

Disclosure: This PR was authored by @Furox-Art (AI-assisted). Happy to adjust anything.

shape: cycle arranges its children with their centers on a circle and
routes edges between them along that circle as exact circular arcs
(cubic Bezier chains using the canonical arc control offset), with
endpoints trimmed to each child's visible border so arrowheads touch
rectangles, circles, polygons alike.

- children keep their internal layout: the core layout runs first and
  containers are moved onto the ring together with their descendants,
  translating internal and cross-child edge routes along
- root-level edges take the shorter way around the ring; on a two-node
  cycle opposite edges take opposite semicircles
- the container renders like a container (styles apply), in both d2svg
  and d2scenebuild
- e2e txtar fixture cycle-diagram with dagre, elk and tala goldens
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