How Route Probing Traces Paths in the Archify Viewer
Route probing in the Archify viewer uses a breadth-first search (BFS) algorithm to discover and highlight the shortest directed path between two user-selected nodes, rendering the result as an interactive SVG overlay with animated journey controls.
The Archify viewer provides an interactive route probing feature that enables users to trace dependencies and connections within rendered diagrams. This functionality is implemented in viewer/route-probe.js and combines graph traversal logic with DOM manipulation to provide visual path analysis.
Initialization and Source Selection
When a user initiates route tracing, the process begins with Archify.routeProbe.begin() at lines 7-14 of viewer/route-probe.js. This method clears existing UI states, resets the internal mode to source, and prepares the SVG container for node selection.
To select a starting node, users click or activate a node via keyboard, triggering chooseStart(id). According to the source code at lines 90-99, this function:
- Assigns
data-route-startanddata-route-matchattributes to the selected node - Computes the set of reachable nodes using
reachableFrom(id) - Transitions the UI to target mode, displaying the source label and a destination selection hint
Only nodes reachable from the source remain interactive in this mode, guiding users toward valid destinations.
Path Discovery Algorithm (BFS Implementation)
The core pathfinding logic relies on breadth-first search (BFS) operations performed on the SVG's graph structure. When a destination node is selected via choose(id), the system invokes shortestDirectedPath(startId, id) at lines 107-124.
Building the Graph from SVG Elements
Before traversal begins, outgoingByNode() (lines 66-74) constructs an adjacency map by parsing the SVG edge elements. This function examines the diagram's current state to build a directed graph representation in memory, mapping each node ID to its outgoing connections.
Computing Reachability
The reachableFrom(source) method (lines 78-88) executes an initial BFS to identify all nodes accessible from the selected source. This step both validates potential destinations and filters the interactive elements in the UI, ensuring users cannot select unreachable targets.
Shortest Path Calculation
Once a destination is confirmed, shortestDirectedPath performs a second BFS to trace the optimal route. As implemented at lines 108-133, this method:
- Records predecessor relationships (
previous) for each visited node - Terminates when reaching the target node
- Back-tracks through the predecessor chain to assemble an ordered list of node IDs and corresponding edge elements
This approach guarantees the shortest path in terms of hop count for directed graphs.
Rendering the Route Overlay
With the path calculated, showResult(result) handles visualization at lines 127-138. This function receives arrays of nodes and edges, then:
- Applies
data-route-matchanddata-route-stepattributes for CSS styling - Calls
renderOverlay(result.edges)(lines 59-72) to generate a dedicated SVG layer highlighting the path geometry - Invokes
renderPath(lines 98-124) to construct an interactive textual representation where each hop appears as a focusable button
The separation of concerns between geometry rendering (renderOverlay) and textual navigation (renderPath) allows for multiple visualization modes of the same underlying path data.
Journey Navigation and Visual Feedback
The route probe provides interactive traversal controls including previous, next, play, and overview modes. These update the journey state via applyJourneyState(index) at lines 95-106, which:
- Updates node and edge attributes (
data-route-journey-state) to distinguish past, current, and future steps - Triggers
renderJourneyPulse(lines 60-68) to create an animated pulse effect along the current edge when auto-play is active
This state management enables users to step through complex paths incrementally while maintaining visual context of their position within the overall route.
URL Synchronization for Deep Linking
Archify persists route states in the URL fragment identifier using the format #route=start~end. The replaceRouteHash function updates the URL whenever a result displays, while syncFromHash can restore a route from a bookmarked or shared URL (lines 86-95).
This synchronization enables:
- Sharing specific paths via copied URLs
- Browser back/forward navigation through route history
- Deep linking to predefined routes in documentation or bug reports
Programmatic Route Control
Developers can interact with the route probing system programmatically through the public API exposed on the Archify.routeProbe object:
// Initiate route probing mode
Archify.routeProbe.begin();
// Select source and destination programmatically
Archify.routeProbe.choose('node-42'); // Sets source (when in source mode)
Archify.routeProbe.choose('node-87'); // Sets target and renders path
// Access current route data for analytics or export
const routeInfo = Archify.routeProbe.result();
// Returns: { source, target, nodes, hops, ... }
// Animate automatic traversal
Archify.routeProbe.playJourney(); // Starts auto-advance with pulse effects
Related Implementation Files
While viewer/route-probe.js contains the core logic, several adjacent modules integrate with the probing system:
viewer/template.source.html— Defines the HTML panel structure and button containers manipulated by the route probe UIviewer/semantic-lens.js— Clears conflicting visual previews when route probing activatesviewer/viewer-camera.js— Adjusts camera focus and reveals nodes duringshowResultandshowJourneyOverviewoperationsviewer/intent-trace.js— Disables intent tracing displays to prevent UI conflicts during route selection
Summary
- Route probing in Archify traces shortest directed paths using BFS traversal of SVG-derived graph data in
viewer/route-probe.js - The two-phase selection process (source → target) filters unreachable nodes using
reachableFrom()to guide valid choices - Path calculation occurs in
shortestDirectedPath()which records predecessors and back-tracks to reconstruct the optimal route - Visual rendering separates concerns between SVG geometry overlays (
renderOverlay) and interactive textual buttons (renderPath) - Journey controls provide step-by-step navigation with state-based styling and optional pulse animations via
applyJourneyState() - URL persistence enables deep linking through fragment hash synchronization (
replaceRouteHashandsyncFromHash) - A public API exposes methods like
begin(),choose(), andresult()for toolbar integration and programmatic control
Frequently Asked Questions
How does Archify determine the shortest path between nodes?
Archify uses a breadth-first search (BFS) algorithm implemented in shortestDirectedPath() within viewer/route-probe.js (lines 108-133). The algorithm builds an adjacency map from SVG edge elements using outgoingByNode(), then traverses the graph while recording predecessor relationships. When the target node is reached, it back-tracks through the predecessor chain to assemble the ordered path, guaranteeing the shortest route in terms of connection count for directed graphs.
What file contains the core route probing implementation?
The primary implementation resides in viewer/route-probe.js, which contains the Archify.routeProbe module. This file includes graph traversal logic (shortestDirectedPath, reachableFrom), UI state management (applyJourneyState), rendering functions (renderOverlay, renderPath), and URL synchronization handlers (replaceRouteHash, syncFromHash).
Can route states be shared via URLs?
Yes. Archify encodes active routes in the URL fragment using the format #route=start~end. The replaceRouteHash function updates the URL when a route displays, and syncFromHash can restore the route when loading a bookmarked or shared link. This enables deep linking to specific paths within complex diagrams.
How does the journey animation work?
The journey animation utilizes applyJourneyState(index) (lines 95-106) to update data-route-journey-state attributes on nodes and edges, distinguishing past, present, and future steps. When playing, renderJourneyPulse (lines 60-68) creates a visual pulse effect along the current edge. Users can control playback through previous/next buttons or auto-play functionality via playJourney().
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 →