Repository navigation
Clip edges to node outlines and re-lay out the activity example - #46
Merged
Merged
Conversation
Edge ends are now clipped to the drawn outline of the node they touch: ray-box for rectangles and squares, ray-ellipse for circles and ellipses, ray-rhombus for diamonds, and the bounding box otherwise. Each end heads towards its adjacent bend point, or the other node when the edge has none. Pins are clipped to their border instead of their centre, and the edge preview starts on the source outline. Bent edges are drawn as straight segments instead of a tensioned curve that overshot corners. The 2D renderer now draws the ellipse and diamond shapes it already offered, draws containers before edges so their fill no longer hides the flows between their children, honours the edge notation's labelFormat (placeholders for the name and reference attributes; an all-empty format hides the label), centres edge labels on the path, and keeps names of narrow nodes from wrapping letter by letter. A new 2D notation field, labelPosition (below, inside, hidden), is editable in the metaclass and representation notation editors. The UML activity example draws decisions as diamonds, fork and join as vertical bars, action names inside actions, and only guard labels on flows, and its two views are re-laid out left to right without edge crossings. A geometry test checks both views for crossings, edges through unrelated nodes, labels over edges, and flow direction.
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Bend-point handling can discard persisted bends, and coincident nodes can still produce endpoints inside their shapes.
3 open findings
What changed in this PR
Improves 2D activity-diagram rendering, notation, and example layout.
Changes:
- Clips edges to node outlines and improves shapes, labels, layering, and routing.
- Adds configurable node-label positioning.
- Reworks activity examples and adds geometry-focused tests.
| File | Description |
|---|---|
shared/types/index.ts |
Adds shared label-position typing. |
frontend/src/models/types.ts |
Adds frontend label-position typing. |
frontend/src/examples/data/activity-diagram-views.json |
Resizes example canvases. |
frontend/src/examples/data/activity-diagram-viewpoints.json |
Updates activity notation. |
frontend/src/examples/data/activity-diagram-model.json |
Re-lays out activity diagrams. |
frontend/src/components/viewpoints/ViewpointManager.tsx |
Adds label-position controls. |
frontend/src/components/metamodel/MetaClassNotationEditor.tsx |
Adds metaclass label controls. |
frontend/src/components/diagram/DiagramEditor.tsx |
Updates 2D rendering and edges. |
frontend/src/components/diagram/2d/utils/appearanceUtils.ts |
Adds geometry and label utilities. |
frontend/src/__tests__/services/view-projection-containers.test.ts |
Updates expected container sizes. |
frontend/src/__tests__/services/appearanceUtils.test.ts |
Tests geometry and formatting. |
frontend/src/__tests__/services/activity-example-layout.test.ts |
Validates activity layouts. |
docs/user-guide/viewpoints.md |
Documents new notation behavior. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+294
to
+295
| const sourceToward = options.sourceToward || targetGeometry.center; | ||
| const targetToward = options.targetToward || sourceGeometry.center; |
Comment on lines
+1509
to
+1512
| // Stored edge points keep placeholder ends; only the inner points are bends. | ||
| const bendPoints = Array.isArray(element.points) && element.points.length > 2 | ||
| ? element.points.slice(1, -1) | ||
| : []; |
Comment on lines
+43
to
+49
| /** Proper crossing: the segments intersect at a point interior to both. */ | ||
| const segmentsCross = ([a, b]: Segment, [c, d]: Segment): boolean => { | ||
| const d1 = cross(c, d, a); | ||
| const d2 = cross(c, d, b); | ||
| const d3 = cross(a, b, c); | ||
| const d4 = cross(a, b, d); | ||
| return ((d1 > 0 && d2 < 0) || (d1 < 0 && d2 > 0)) && ((d3 > 0 && d4 < 0) || (d3 < 0 && d4 > 0)); |
haphantran
added a commit
that referenced
this pull request
Oct 12, 2026
Room names are drawn inside the rooms (with #46), so smoke detectors and the hub move off the room centres. Device icons stay inside their room in the floor plan, hub links use the default arrow the 2D editor draws, and the generated device list has one device per line.
…e paths Edges between nodes whose centres coincide (self-references included) again leave on the right and arrive on the left instead of collapsing to the centre. Self-references are created with the stored edge-path form [source placeholder, ...bends, target placeholder], now documented on DiagramElement.points, so the renderer keeps all three bends. The activity layout test also rejects T-junctions and collinear overlaps between edges, except where edges meet at a node they share.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Fixes the 2D notation issues reviewers saw in the activity diagram (arrows ending inside nodes, line crossings, horizontal fork/join bars) and several rendering problems found while fixing them. Independent of the other open PRs.
Edge endpoints
getEdgeEndpointPairclips each end to the outline the renderer actually draws: ray-box for rectangles and squares (squares are drawn width x width from the top-left), ray-ellipse for circles and ellipses, ray-rhombus for diamonds, bounding box otherwise. Each end heads towards the first or last bend point when the edge has bends, otherwise the other node's centre. Existing parameters still work; options are added.Renderer fixes (listed per the plan)
ellipseanddiamondshapes offered in the notation editors were not drawn (they fell back to the default box with a title bar); they are drawn now.labelFormatwas editable but ignored, so every activity flow showed the label "flowsTo". It is now honoured:{name}and{attribute}placeholders, and a format whose placeholders are all empty shows no label ([{guard}]shows guards only).labelPosition(below,inside,hidden), editable in the metaclass and representation notation editors.Activity example
size2D); action names are inside actions; initial/final/fork/join/pin names are hidden; flows show only guards.Order Processing Flow,Happy Path (In Stock)) are re-laid out left to right with no edge crossings; three flows use bend points.activity-example-layout.test.tschecks both views, computed the way the renderer draws them: no crossings, no edge through an unrelated node, no edge label or node name over another edge, vertical bars, left-to-right flow. It fails on the previous layout (7 failures) and passes on the new one.Verification