Diagram - Connector routing
Share org chart buses, avoid obstacles and inspect derived routes and fallback diagnostics.
#Usage
import { Diagram } from '@primeui/vue-diagram';<Diagram.Root :store="store" page-id="page" :scene-options="{ routing: { enabled: true, deferred: true, clearance: 10 } }">
<Diagram.Viewport label="Workflow editor" style="height: 24rem" />
</Diagram.Root>This skeleton assumes an initialized store with page page. Use First Diagram for model creation, style imports and store disposal.
Obstacle avoidance is opt-in. A saved orthogonal connector keeps its endpoints and manual waypoints while the scene derives a route around visible geometry. The derived path is runtime state; it does not replace the saved waypoint array.
#Shared org chart buses
Use a shared bus for an org chart or another reporting tree. Connections from the same parent share one stem, a perpendicular bus, and a drop into each report. The routes update together during dragging and after layout changes. Routing leaves node positions unchanged and stores no bend coordinates.
import type { DiagramSceneOptions } from '@primeui/vue-diagram';
const sceneOptions: DiagramSceneOptions = {
routing: {
bus: {}
}
};Bind this object to :scene-options="sceneOptions" on the root. bus: {} enables shared buses
with direction: 'down'. It works independently of routing.enabled, which
enables obstacle avoidance.
Use ordinary orthogonal connectors with node endpoints and empty waypoints.
The participating connections must form a directed forest, with one parent per
report and no cycles. Explicit ports keep their attachment points; body endpoints
dock on the sides that face the flow. Authored waypoints, sceneOptions.routes,
and connectorKinds overrides keep their geometry and do not join a bus.
Drag a report and watch its sibling's route update before release. Change Direction to compare horizontal and vertical buses. Change Alignment to move the bus within the gap. Choose Block bus to move a report behind its manager and inspect the fallback, then use Undo or Reset to restore the chart.
| Bus option | Default | Behavior |
|---|---|---|
direction | 'down' | Accepts down, up, right, or left. Down and Up use a horizontal bus; Right and Left use a vertical bus. Pass the same direction to your layout when arranging nodes. |
alignment | 0.5 | Finite fraction from 0 to 1 through the available gap. Zero prefers the parent side; one prefers the report side. Routing preserves a stem and drop and respects clearance when avoidance is enabled. |
connectorIds | All eligible connectors | Restricts bus participation to these connector IDs. An empty array disables participation. This option does not hide connectors. |
Use connectorIds when only part of a diagram contains reporting connections.
Hidden reports do not extend a bus. One remaining report uses an ordinary
orthogonal connection. CSS dimming, profile selection, and zoom preserve bus
membership. Container collapse follows existing containment and proxy rules;
it does not collapse a reporting subtree merely because connectors link it.
If the group cannot form a shared bus, its connectors use current ordinary
routes with routing.status: 'fallback'. The bus-constraint diagnostic reports
incompatible topology, ports, clipping, options, or a missing forward corridor.
With obstacle avoidance enabled, blocked or budget can also explain failure.
These routes do not retain a stale bus, and fallback does not guarantee obstacle
avoidance. Read each connector's routing.diagnostics to show the reason.
#Enable avoidance on a small flow
Choose Across the route, then Place Review desk. Compare Routing on/off to see the derived detour versus basic orthogonal geometry. Move the desk beside the route, or choose Block target approach to inspect an unsatisfied terminal clearance and its fallback diagnostic.
import type { DiagramSceneOptions } from '@primeui/vue-diagram';
const sceneOptions: DiagramSceneOptions = {
routing: {
enabled: true,
deferred: true,
clearance: 10,
portSides: new Map([
['source-output', 'right'],
['target-input', 'left']
])
}
};Bind this stable object to the root's sceneOptions. Routing applies to visible
saved orthogonal connectors whose route/kind is not externally supplied.
Straight, polyline and Bézier paths retain their own geometry. A hidden connector
is not routed as a visible obstacle-avoidance path.
Port-side preferences are local to their node. They rotate with it and resolve to a world cardinal direction. Ports retain their exact attachment points; node-body endpoints can dock on a boundary in the chosen world direction. Clearance uses transformed world geometry, not an HTML element's margin.
#Retain manual anchors and inspect ownership
Choose Add manual anchors. The saved connector gains two parent-local waypoints. The router treats their world projections as required anchors and searches between them; it does not move them to escape an impossible constraint. Undo removes the authored edit. Routing option switches remain preferences outside model history.
An obstacle move changes the saved node, which invalidates affected derived routes. Dragging an obstacle or editing path geometry can show a provisional route until the gesture ends. Reset restores the original nodes, empty manual waypoints, routing preferences and fitted view.
For an entirely application-owned route, provide sceneOptions.routes with a
continuous world-space DiagramPath agreeing with resolved endpoints. That
entry takes precedence over built-in routing and rejects manual path edits.
connectorKinds can similarly own the kind. Release those entries before editing
manually; see Edit connectors.
Basic path geometry, derived obstacle routing, and automatic node layout solve different tasks. Routing leaves node positions unchanged.
#Separate parallel routes and show crossings
This fixture has two Request received → Approve request edges and one Audit → Archive edge. Toggle Extra spacing on/off and Crossing bridges to compare route preparation on three saved connectors.
separation introduces candidate spacing for crowded/parallel routes;
crossingCost penalizes crossings against already prepared paths. A deterministic
preparation order helps keep results repeatable, but cannot make every crowded
route non-overlapping. Zero disables the extra candidate spacing; it does not
guarantee coincident or unseparated routes. Manual anchors and endpoint attachment still constrain it.
bridgeRadius adds a visual bridge at eligible crossings. Zero disables bridges.
A bridge is a derived path graphic, not a junction or semantic relationship.
Bridge preparation is best effort: unsafe or ineligible crossings are silently
omitted, including those constrained by clearance or clipping. A missing bridge
does not imply a diagnostic. The graphic does not edit saved waypoints or endpoints.
#Tune bounded search options
All numeric options must be finite and nonnegative. Values use scene/world units or search costs, not CSS pixels. Budgets are integer counts after normalization.
| Routing option | Default / behavior |
|---|---|
enabled | false; opt in with true |
bus | Omitted; set an options object to enable shared org chart buses |
deferred | Omitted is immediate outside previews; true schedules provisional work for later settling |
clearance | 10; obstacle/terminal clearance |
bendCost | 20; bend penalty |
crossingCost | 12; occupied-route crossing penalty |
separation | 8; crowded-route candidate spacing |
bridgeRadius | 5; eligible crossing-bridge radius, zero disables |
searchMargin | 100; expansion around attachment/manual-anchor bounds |
maxObstacles | 160; floored and clamped to 1–512 |
maxStates | 16,000; floored and clamped to 1–100,000 |
portSides | Optional port-ID map to left/right/top/bottom in node-local orientation |
The search region is bounded. A route can fail even when a much longer detour outside the region might exist. Increasing a budget or region may help a particular graph, but adds work; it is not a guarantee for arbitrary density. The scene router also bounds manual-anchor and clip input (at most 256 manual anchors and 64 clip points for this derived-routing preparation).
#Read pending and fallback state
The examples read session.value.geometry.routingPending and
session.value.geometry.routingWork from descendant useDiagramContext(), plus
each scene connector's routing.status, and its first diagnostic. These are
current state, not timing or speed measurements. To keep a Vue readout reactive,
derive it in computed from the context's geometryVersion and interaction
refs, then read the current session.value.geometry. Do not capture a previous
session through a root ref for live UI.
| Route status | Meaning |
|---|---|
provisional | A temporary path awaiting settled avoidance; may cross obstacles |
settled | Search completed within this candidate's constraints |
fallback | Unsatisfied clearance or budget; retain an attachment/anchor-based path and diagnostics |
cancelled | Cancelled portable route request |
Diagnostic codes include blocked, budget, cancelled, provisional,
congestion-budget, and bus-constraint. A fallback is not proof that the path
avoids all obstacles. Display its reason and let the user change geometry,
anchors or search settings rather than silently presenting it as a successful detour.
The root schedules deferred routing after rendering and cancels obsolete
work during session changes/teardown. The public session geometry cache exposes
prepareRouting, settleRouting and cancelRouting for hosts that own scheduling;
tickets carry page ID, model revision, geometry revision and generation. Do
not apply an old ticket to a new model/geometry generation. Deferred routing
is separate from application connection approval and controlled-store acknowledgement.