Skip to content

Add support for sticky Manhattan Routing and rounded Edges#486

Open
martin-fleck-at wants to merge 8 commits intomasterfrom
issues/1652
Open

Add support for sticky Manhattan Routing and rounded Edges#486
martin-fleck-at wants to merge 8 commits intomasterfrom
issues/1652

Conversation

@martin-fleck-at
Copy link
Copy Markdown
Contributor

@martin-fleck-at martin-fleck-at commented Apr 19, 2026

What it does

Add sticky Manhattan edge router

Preserves intermediate bend points when a connected node moves and only slides the corner adjacent to the moved endpoint, instead of recomputing the full route like the standard Manhattan router does.

Ported from Ralph Soika's BPMNManhattanRouter in Open-BPMN, see eclipse-glsp/glsp#1642. Opt-in per edge via edge.routerKind = 'sticky-manhattan'. Per-edge state lives in a
WeakMap keyed on the edge instance. Dedicated anchor computers are registered so the router coexists with the standard Manhattan router.

Add rounded-corner edge view

RoundedCornerEdgeView extends GEdgeView and overrides createPathForSegments to emit SVG quadratic curves at every right-angle bend, producing smooth corners on Manhattan-style routes. The radius is clamped per corner to a fraction of the shorter adjacent segment to avoid visual artifacts on short segments.

Ported from Ralph Soika's BPMNEdgeView, contributed alongside the sticky Manhattan router via the same discussion. The view works with any router that emits right-angle corners; combining it with GLSPStickyManhattanEdgeRouter reproduces the look-and-feel of the original Open-BPMN setup.

sticky-routing

Resolves eclipse-glsp/glsp#1652

How to test

  • There is a test commit on here that should not be merged but it does adapt the workflow example.

Follow-ups

Changelog

  • This PR should be mentioned in the changelog
  • This PR introduces a breaking change (if yes, provide more details below for the changelog and the migration guide)

Preserves intermediate bend points when a connected node moves and only
slides the corner adjacent to the moved endpoint, instead of
recomputing the full route like the standard Manhattan router does.

Ported from Ralph Soika's `BPMNManhattanRouter` in Open-BPMN, see
eclipse-glsp/glsp#1642. Opt-in per edge
via `edge.routerKind = 'sticky-manhattan'`. Per-edge state lives in a
`WeakMap` keyed on the edge instance. Dedicated anchor computers are
registered so the router coexists with the standard Manhattan router.

Adds `Point.isVertical` and `Point.isHorizontal` helpers to the
existing `sprotty-geometry-point` augmentation so axis-alignment
checks read as one-liners across the router.
`RoundedCornerEdgeView` extends `GEdgeView` and overrides
`createPathForSegments` to emit SVG quadratic curves at every
right-angle bend, producing smooth corners on Manhattan-style routes.
The radius is clamped per corner to a fraction of the shorter adjacent
segment to avoid visual artifacts on short segments.

Ported from Ralph Soika's `BPMNEdgeView`, contributed alongside the
sticky Manhattan router via the same discussion. The view works with
any router that emits right-angle corners; combining it with
`GLSPStickyManhattanEdgeRouter` reproduces the look-and-feel of the
original Open-BPMN setup.
Temporary reviewer aid: routes every workflow edge through the
`sticky-manhattan` router and renders it with `RoundedCornerEdgeView`,
so reviewers can drag connected nodes and observe bend-point
preservation and rounded-corner rendering in the standalone example.
Revert before merging to master.
@martin-fleck-at
Copy link
Copy Markdown
Contributor Author

Test failures probably related to the change of the workflow example. Once the code is reviewed, I'll remove that commit and make sure the CI passes.

Copy link
Copy Markdown
Contributor

@tortmayr tortmayr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@martin-fleck-at Thanks for preparing this contribution.
In manual testing everything looks fine and seems to work as expected.
Overall the new router provides a way better UX (at least for my taste) than the default manhattan router.

We should mark the router as experimental. And maybe add a follow-up to reiterate over the initial implementation to see if there is potential for improvements/cleanups.

Comment thread packages/client/src/features/routing/sticky-manhattan-edge-router.spec.ts Outdated
Comment thread packages/client/src/features/routing/sticky-manhattan-edge-router.spec.ts Outdated
* Based on the original `BPMNManhattanRouter` by Ralph Soika (Imixs Software
* Solutions GmbH), contributed via https://github.com/eclipse-glsp/glsp/discussions/1642.
*/
@injectable()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should explicitly mention that the router is currently experimental i.e.
API surface and implementation details might change with future improvements (also potentially breaking)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I marked it experimental!

Comment thread packages/client/src/features/routing/sticky-manhattan-edge-router.ts Outdated
Comment thread packages/client/src/views/rounded-corner-edge-view.spec.ts Outdated
Comment thread packages/protocol/src/sprotty-geometry-point.ts Outdated
- Mark `GLSPStickyManhattanEdgeRouter` as `@experimental` in the JSDoc:
  API and implementation may change in future releases.
- Drop the trivial `KIND` constant test and the anchor-registration DI
  wiring test from the sticky-router spec — the first exercises a string
  literal, the second tests `routingModule` hookup rather than router
  behavior.
- Trim the noisy historical comment in `applyFollowLogic` down to the
  single sentence that actually explains the current behavior.
- Delete `rounded-corner-edge-view.spec.ts`: per review, unit-testing
  views on a string-render level is brittle and diverges from the rest
  of the repository, which covers views via e2e tests.
- Introduce `axisTolerance` on `StickyManhattanRouterOptions`
  (defaulting to `1` px) and thread it through the sticky-router call
  sites to `Point.isVertical` / `Point.isHorizontal`. `manhattanify`
  now takes the `edge` so it resolves the tolerance via `getOptions`,
  consistent with the other protected helpers.
- Change the `Point.isVertical` / `Point.isHorizontal` default
  tolerance from `1` to the new `ALMOST_EQUAL_EPSILON` constant
  (`1e-3`), matching sprotty's `almostEquals` convention. The 1-pixel
  tolerance is a sticky-router concern and now lives in its options,
  not as a default on a general-purpose geometry helper.
- Make route() side-effect free; refresh baseline in commitRoute
  and on persistence cleanup (updateHandles=true)
- Preserve sub-pixel precision (drop Math.round)
- Clear baseline on fresh-default fallback
- Thread DefaultAnchors through follow/cleanup helpers
- Note simpler tier-3 fallback vs sprotty
- Rename to RoundedCornerManhattanEdgeView; reflect Manhattan-only
  contract in JSDoc
- Tighten right-angle check via Point.isHorizontalAligned /
  isVerticalAligned
- Promote shortSegmentThreshold / shortSegmentRadiusFactor to fields
- Drop decorative Math.round(radius * 10) / 10
- Add GEdgeViewWithGapsOnIntersections: parallel to GEdgeView on top
  of sprotty's PolylineEdgeViewWithGapsOnIntersections
- Extend RoundedCornerManhattanEdgeView from it; merge corner
  rounding and intersection-path splicing in one builder
- Route via edgeRouterRegistry.route(edge, args) so the postprocessor
  pipeline populates intersection data
- Skip gap fragments inside rounded-corner zones to avoid backward
  strokes into the curve
@martin-fleck-at
Copy link
Copy Markdown
Contributor Author

@martin-fleck-at Thanks for preparing this contribution. In manual testing everything looks fine and seems to work as expected. Overall the new router provides a way better UX (at least for my taste) than the default manhattan router.

We should mark the router as experimental. And maybe add a follow-up to reiterate over the initial implementation to see if there is potential for improvements/cleanups.

Thank you! I also like the new router a lot and I already re-worked the code a bit for some clean up. Overall let's see what adopters report.

@martin-fleck-at
Copy link
Copy Markdown
Contributor Author

@tortmayr Test failure is just for the workflow example override and will be fixed once we remove that agian.

@tortmayr tortmayr self-requested a review April 22, 2026 14:25
Copy link
Copy Markdown
Contributor

@tortmayr tortmayr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 👍🏼

@tortmayr
Copy link
Copy Markdown
Contributor

Please remove the temp changes to the workflow example so that the ci passes again.

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.

Sticky Manhattan Router

2 participants