Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Formula DAG Workspace

An interactive, clean-room TypeScript web demo that makes a small spreadsheet-like calculation inspectable: edit inputs, evaluate formula dependencies, explore the graph, trace a selected result, and import or export the workbook as JSON.

Clean-room portfolio demonstration. Everything in this repository is independently implemented with synthetic, generic data. It contains no proprietary code, company data, customer data, domain rules, or formulas from any private project.

Run it

Requires Node.js 22+.

npm install
npm run dev

Open the local URL printed by Vite (normally http://localhost:5173).

For checks:

npm run typecheck
npm test
npm run build

Interactive features

  • Edit the synthetic numeric inputs (length, width, and unit_cost), then select Evaluate to normalize and recalculate the workbook.
  • Add or edit formula and result nodes with a small, validated form.
  • Inspect the SVG dependency graph; selecting a node updates the provenance trace and canonical JSON panel.
  • Switch between three synthetic presets: healthy calculation, missing dependency, and circular dependency.
  • Import a local JSON workbook, export the current normalized workbook, copy JSON, or reset to the healthy demo.
  • Adapt a generic node-export JSON shape with numeric ids, name, type/isFormula, description, and spreadsheet-style cell references into a focused dependency graph.
  • See clear per-node errors for invalid inputs, invalid formulas, missing references, and circular dependencies.

Pipeline and architecture

Editable inputs / formula editor / JSON import
                    |
                    v
        normalizeWorkbook (canonical JSON)
                    |
                    v
 buildDependencyGraph -> cycle detection -> topological evaluation
                    |
                    v
  results, SVG dependency graph, selected-node provenance trace
Module Responsibility
src/workbook.ts Normalizes JSON-shaped input, validates ids/value types, and serializes/deserializes workbooks.
src/formula.ts Tokenizes and safely evaluates the small arithmetic language without eval.
src/graph.ts Builds graph directions, detects cycles, orders nodes, and returns values/errors.
src/trace.ts Produces a readable depth-first source chain for any selected node.
src/demo-presets.ts Creates fresh synthetic healthy, missing-reference, and circular examples.
src/main.ts Owns explicit browser state and renders the interactive workspace.

The UI deliberately has no graphing dependency: SVG blocks and connectors are rendered directly from buildDependencyGraph, which keeps the example easy to review in a portfolio.

Import compatibility

The primary import format is the portfolio JSON schema below. For a common generic node-export shape, the importer also adapts numeric node ids to text ids, reads formula text after a Formula: marker in node metadata, and resolves dependencies from either named references or spreadsheet-style cell references such as $B$2 and Sheet!B2.

This compatibility path is graph-first: formulas outside the documented arithmetic subset remain visible in the graph and trace, but are reported as non-evaluable rather than being assigned an invented numeric result. Imported source data stays local; it is never added to this repository.

Workbook JSON

There are three generic node kinds:

Kind Required fields Purpose
input id, kind, value Numeric source value.
formula id, kind, formula Intermediate calculation.
result id, kind, formula Calculation presented as an outcome.
{
  "nodes": [
    { "id": "length", "kind": "input", "label": "Length", "value": 12 },
    { "id": "width", "kind": "input", "label": "Width", "value": 10 },
    { "id": "total_area", "kind": "formula", "label": "Total Area", "formula": "=length * width" },
    { "id": "unit_cost", "kind": "input", "label": "Unit Cost", "value": 50 },
    { "id": "estimated_cost", "kind": "result", "label": "Estimated Cost", "formula": "=total_area * unit_cost" }
  ]
}

Normalization derives each formula node's dependencies from its formula. The healthy demo evaluates to estimated_cost = 6000 and its trace is:

estimated_cost = total_area * unit_cost
<- total_area = length * width
  <- length = 12
  <- width = 10
<- unit_cost = 50

Error examples

The Missing dependency preset contains:

=base_rate * missing_multiplier

It yields Missing dependency "missing_multiplier". on that result node. The Circular dependency preset has first_step -> second_step -> first_step; the evaluator reports the cycle and prevents dependent results from being calculated.

Formula limits

The intentionally small formula language supports numeric literals, node references, +, -, *, /, unary signs, and parentheses. Node ids can be any non-empty text value (for example a UUID). References that are ordinary identifiers can be written directly (=length * width); ids with punctuation must be bracketed (=[input-uuid-1] * 2). Formulas may begin with =. It does not support arbitrary JavaScript, spreadsheet functions, ranges, strings, macros, or external data.

Tests

The Node test suite covers core behavior and demo states: normalization, dependency extraction, evaluation order, invalid syntax, missing dependencies, cycles, trace output, JSON round trips, all presets, edited-input normalization, and intermediate-node tracing.

About

Clean-room portfolio demo of spreadsheet-to-JSON formula dependency graphs

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages