Engineering Journal
Table Formatter
Table Formatter

A Visual DAG Runner for Multi-Source Data Joins in the Browser

2026-06-04

TLDR

Relying on fragile VLOOKUP formulas to merge datasets in the browser breaks whenever columns shift. Replacing cell formulas with a Visual Directed Acyclic Graph (DAG) pipeline resolves dependencies deterministically using topological sorting and isolated node handler dispatch.
Data Joining ModelDependency ManagementResilience to Column ShiftsExecution Location
Cell VLOOKUP FormulasFragile cell-coordinate rangesFails when columns moveIn-cell formula engine
Visual DAG Pipeline EngineTopological Sort DAG Execution100% Column Shift ProofClient-Side In-Memory Runner

Structural column shifts break positional cell formulas in multi-sheet workflows

Joining data across multiple sheets in traditional web spreadsheets usually involves VLOOKUP or XLOOKUP formulas. These formulas break easily when users insert or reorder columns because they rely on positional column index arguments rather than named data attributes.

To establish reproducible data processing pipelines without backend servers, we designed a client-side Visual Directed Acyclic Graph (DAG) executor.


Topological dependency sorting ensures deterministic order-of-operation execution

Each pipeline node represents an isolated data step (Source, Filter, Formula, Join), while wires define directed dependencies. The execution engine performs a topological sort before processing nodes:

   VISUAL NODE GRAPH:
   ┌───────────────┐
   │ CSV Source A  │ ──┐
   └───────────────┘   │
                       ├──> ┌───────────────┐        ┌───────────────┐
                       │    │ Inner Join    │ ─────> │ Clean CSV     │
                       ├──> └───────────────┘        └───────────────┘
   ┌───────────────┐   │
   │ CSV Source B  │ ──┘
   └───────────────┘

TOPOLOGICAL SORTED EXECUTION PIPELINE: [Step 1: Load Source A] ───► Dataset A ──┐ ├──► [Step 3: Inner Join] ───► [Step 4: Clean Output] [Step 2: Load Source B] ───► Dataset B ──┘

Here is the implementation of topological sorted pipeline execution:

// Execute visual DAG nodes in topological dependency order
export function executeDagPipeline(nodesMap, edgesArray) {
  const sortedNodeIds = topologicalSort(nodesMap, edgesArray);
  const nodeResults = new Map(); // nodeId -> rowObjects[]

for (const nodeId of sortedNodeIds) { const node = nodesMap.get(nodeId); // Resolve upstream inputs for current node const inputDataSets = getUpstreamNodeIds(nodeId, edgesArray) .map(id => nodeResults.get(id) || []);

// Dispatch handler and store isolated dataset output const outputRows = runNodeHandler(node, inputDataSets); nodeResults.set(nodeId, outputRows); }

return nodeResults; }

By passing immutable datasets between isolated node handlers, execution remains completely deterministic and independent of UI presentation choices.

Rule of thumb: Process multi-source data dependencies using topologically sorted pipeline nodes instead of relying on position-based cell formulas.
Read this post in the full Engineering Journal →