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.

Loading Demo...

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 optionDefaultBehavior
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.
alignment0.5Finite 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.
connectorIdsAll eligible connectorsRestricts 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.

Loading Demo...
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.

Loading Demo...

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 optionDefault / behavior
enabledfalse; opt in with true
busOmitted; set an options object to enable shared org chart buses
deferredOmitted is immediate outside previews; true schedules provisional work for later settling
clearance10; obstacle/terminal clearance
bendCost20; bend penalty
crossingCost12; occupied-route crossing penalty
separation8; crowded-route candidate spacing
bridgeRadius5; eligible crossing-bridge radius, zero disables
searchMargin100; expansion around attachment/manual-anchor bounds
maxObstacles160; floored and clamped to 1–512
maxStates16,000; floored and clamped to 1–100,000
portSidesOptional 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 statusMeaning
provisionalA temporary path awaiting settled avoidance; may cross obstacles
settledSearch completed within this candidate's constraints
fallbackUnsatisfied clearance or budget; retain an attachment/anchor-based path and diagnostics
cancelledCancelled 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.