Edge Ports & Routing
Edges no longer have to run centre-to-centre. Specs can attach edges to specific node sides or named ports, exit container walls cleanly, route around obstacles, and fan out parallel edges.
Ports: attach to a side
Suffix an endpoint with a port: n / e / s / w (or top / right /
bottom / left) map to the built-in side ports:
edges: [
{ from: 'amplify.e', to: 'hooks.n', style: 'orthogonal' },
{ from: 'amplify.s', to: 'hooks.w', style: 'orthogonal' },
],
Named ports work too — declare them on the node and reference them the same
way (from: 'gateway.out-1'):
nodes: [
{
id: 'gateway',
x: 100, y: 100,
ports: [{ id: 'out-1', x: 60, y: 10 }], // offset from the node centre
},
],
edges: [{ from: 'gateway.out-1', to: 'svc' }],
Node ids containing dots keep working: the suffix is only treated as a port
when the full string is not itself a node id. The declarative fromPort /
toPort fields are equivalent to the suffix syntax.
Boundary-aware container exits
When an edge starts inside a group and
ends outside it, VizCraft stubs the edge to the container wall and exits
orthogonally — no more diagonals cutting through the frame. This is automatic
for boundary-crossing edges (set style: 'straight' or 'curved' explicitly
to opt out).
Signals follow the routed geometry, so the animated dot below exits the wall cleanly too:
edges: [
{ from: 'hooks', to: 'amplify', animate: 'flow' },
{ from: 'gha', to: 'slack' },
],
autoSignals: [
{ id: 'deploy', chain: ['hooks', 'amplify'], loop: true },
],
Obstacle avoidance
routing: 'avoid' routes an orthogonal path around other nodes and
containers instead of through them, using a deterministic A* router:
edges: [{ from: 'a', to: 'c', routing: 'avoid' }],
Parallel edge separation
Multiple edges between the same pair of nodes fan out automatically with consistent gap spacing — no overlap, in both directions:
edges: [
{ from: 'svc', to: 'db', id: 'write', label: 'write' },
{ from: 'svc', to: 'db', id: 'read', label: 'read' },
{ from: 'db', to: 'svc', id: 'events', label: 'events' },
],
autoSignals chains and steps[].signals can reference group ids directly —
the edge (and the travelling dot) terminates on the group boundary. Step
highlight entries naming a group highlight the frame and every
descendant.