How Archify's Layout Algorithm Handles Automatic Routing: A Deep Dive into the Auto-Route Engine
Archify's automatic routing engine activates when a relationship's route field is omitted or set to "auto" and no explicit path constraints (via points, sides, or channels) are provided by the author.
The automatic routing system in tt-a1i/archify is implemented across multiple modules in the renderer pipeline. When drawing architecture diagrams, clean connection routing is essential—Archify balances flexibility (allowing manual override) with intelligence (inferring optimal paths automatically).
When "Auto" Routing Kicks In
In /archify/renderers/architecture/render-architecture.mjs (lines 79–86), the renderer checks whether to engage automatic routing:
- The
routefield is missing or explicitly"auto" - No
viapoints are specified - No
channelX/Y,fromSide,toSide, or label-position constraints exist
If all these conditions hold, Archify delegates to its automatic routing engine rather than using explicit or forced routing modes.
Inferring Endpoint Sides Automatically
Before calculating paths, Archify must determine which side of each component to connect from and to.
Default Side Selection (defaultFromSide / defaultToSide)
In /archify/renderers/shared/geometry.mjs (lines 1554–1567), the system examines the relative center positions of the two connected components. It selects the "natural" side based on geometric relationships:
// Pseudocode based on geometry.mjs implementation
function defaultFromSide(fromCenter, toCenter) {
const dx = toCenter[0] - fromCenter[0];
const dy = toCenter[1] - fromCenter[1];
// Choose side based on dominant axis and direction
if (Math.abs(dx) > Math.abs(dy)) {
return dx > 0 ? 'right' : 'left';
} else {
return dy > 0 ? 'bottom' : 'top';
}
}
Explicit Override Support (chosenSide)
Lines 1170–1172 in the same file implement chosenSide, which allows author-specified sides to override these defaults:
function chosenSide(explicit, fallback) {
return explicit !== undefined ? explicit : fallback;
}
Port Spreading for Clean Fan-Out/Fan-In
When multiple connections share the same component side, collapsing lines create visual clutter. The automaticPortSpread function (lines 1102–1154 in /archify/renderers/shared/geometry.mjs) distributes anchor points with a small pixel offset:
- Prevents overlapping connections
- Maintains visual separation without excessive gap
- Applies to both outgoing (fan-out) and incoming (fan-in) edges
The Core Routing Routine: routeVia
The automatic routing engine centers on routeVia, which handles all routing modes including "auto". Here's the implementation structure from geometry.mjs:
function routeVia(conn, from, to, start, end, fromSide, toSide) {
if (conn.via) return conn.via; // explicit control points
switch (conn.route || 'auto') {
case 'straight':
return []; // direct straight line
case 'orthogonal-h':
// forced horizontal dogleg routing
// ...
case 'orthogonal-v':
// forced vertical dogleg routing
// ...
case 'auto':
default: {
// 4-a. Check if direct line respects chosen sides
const deltaX = Math.abs(start[0] - end[0]);
const deltaY = Math.abs(start[1] - end[1]);
if ((deltaX /* condition for side-respecting direct line */)) {
// Use direct connection
}
// 4-b. Otherwise, compute minimal orthogonal path
// with appropriate doglegs to respect fromSide/toSide
}
}
}
Automatic Path Selection Logic
The "auto" case follows a decision hierarchy:
- Direct line test: If a straight connection from the calculated start and end points respects the chosen sides (doesn't require entering/exiting from wrong faces), use it
- Minimal orthogonal path: Otherwise, compute the shortest orthogonal route with one or two doglegs that properly respects
fromSideandtoSide - Dogleg preference: The algorithm biases toward solutions that minimize total wire length and number of bends
Summary
- Automatic routing triggers when
route: "auto"(or omitted) and no explicit constraints exist—checked inrender-architecture.mjs - Side inference uses relative component positions via
defaultFromSide/defaultToSideingeometry.mjs, withchosenSideallowing override - Port spreading via
automaticPortSpreadprevents overlapping lines on busy component sides - Path calculation in
routeViaprefers direct connections when valid, falling back to minimal orthogonal doglegs that respect inferred or specified side constraints
Frequently Asked Questions
What determines whether Archify uses automatic routing or manual routing?
Archify checks route field value and presence of explicit constraints in render-architecture.mjs lines 79–86. If route is "auto" or missing and no via, channelX/Y, or side specifications exist, automatic routing activates. Any explicit control point or side override disables the auto-engine for that connection.
How does Archify prevent lines from overlapping when multiple connections share a side?
The automaticPortSpread function in geometry.mjs (lines 1102–1154) automatically distributes anchor points along the shared side with small pixel offsets. This creates visual separation without requiring manual port positioning from diagram authors.
Can I override the automatically chosen side for a connection?
Yes. The chosenSide helper (lines 1170–1172) checks for explicit fromSide or toSide values before falling back to defaultFromSide/defaultToSide. Providing either side in your relationship definition overrides the geometric inference while still allowing automatic path calculation between those fixed endpoints.
What path does routeVia generate in "auto" mode?
routeVia first tests whether a direct line respects the chosen entry/exit sides (checking deltaX/deltaY in the auto case). If valid, it returns an empty via array for straight-line rendering. Otherwise, it computes a minimal orthogonal path with doglegs that properly enters from fromSide and exits to toSide.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →