# In-house graph engine

Apr 2023 – Oct 2023 · Lead · Shipped

The product’s asset relationship graph ran on a commercial graph library licensed at about $50K a year. I compared three alternatives, built an in-house engine on low-level D3 primitives that draws straight to SVG, and removed the licensed library once every graph view was covered. It ran in production until mid-2025, and part of its layout code is still in use.

**Scale:** ~$50K/yr saved · 3 layouts · 30 PRs

- Layouts: a force-directed view that nests assets inside their groups with collision forces so nodes never overlap, a tree view and a general network view.
- Interaction by hand: centred initial zoom with scale limits, panning, dragging, selection, arrowheads and link colours by connection type.
- Product features on top: root-cause emphasis, data-asset highlighting, owned-by relations and loading states.

**Stack:** React, D3 v7, SVG

**My role:** Lead: evaluated the options, designed and built the engine, and removed the licensed library.

## Context

A licence is a recurring cost, and a library the team cannot change. The question was build or buy: could an in-house engine cover every graph view the product needed, without breaking any of them on the way?

## Timeline

- **Nov 2022:** Node labels, layouts and the icon pipeline, still on the licensed library.
- **Apr 2023:** Prototype of the in-house engine.
- **May 2023:** Engine merged.
- **Aug 2023:** Licensed library removed.
- **Oct 2023:** Last refactor; dead graph code cleaned up in Mar 2024.
- **Jun 2025:** Another developer moved the view to React Flow; part of my layout code is still in use.

## Architecture

Three layouts on low-level D3 primitives feed one SVG renderer; interaction is written by hand on top.

- **Data:** Asset graph (Assets, groups and their connections)
- **Layout · D3 v7:** Nested force layout (Assets inside groups, with collision forces); Tree (d3-hierarchy); Network (General connections)
- **Rendering · SVG:** Icon font (Generated from cloud and security-product SVGs); SVG renderer (Nodes, links, arrowheads, colours by type); Interaction (Zoom, pan, drag, select)

Flows:

1. Asset graph → Nested force layout: Assets nested inside their groups
2. Asset graph → Tree: The same data as a hierarchy
3. Asset graph → Network: Connections between assets
4. Nested force layout → SVG renderer: Positions on every simulation tick
5. Tree → SVG renderer: Tree positions
6. Network → SVG renderer: Network positions
7. Icon font → SVG renderer: One glyph per node type
8. Interaction → SVG renderer: Centred start, scale limits, selection

## Inside the system

### Three layouts

- A force-directed “enclosure” view that nests assets inside their groups, with collision forces so nodes never overlap.
- A tree view and a general network view, with switching between them.

### Interaction by hand

- Centred initial zoom with scale limits, panning, dragging and selection.
- Arrowheads and link colours by connection type; link and arrow geometry from custom trigonometry.

### Product features on top

- Root-cause emphasis, data-asset highlighting, “owned by” relations and loading states.

### Icons for every node

- A separate generator turns cloud and security-product SVG icons into an icon font and a stylesheet for the graph’s nodes.

## Hard problems

### Replacing a dependency without breaking the product

**Problem.** Every graph view in the product depended on the licensed library.

**What I did.**

- Compared three alternatives first.
- Built the engine on low-level D3 primitives (force, hierarchy, zoom) that draw straight to SVG.
- Moved the views over and removed the library only once every view was covered.

**Result.** The licensed library was removed in Aug 2023, saving about $50K a year (owner-stated).

### Groups that hold their shape

**Problem.** Assets sit inside their groups. A plain force layout lets nodes collide and drift out of the group they belong to.

**What I did.**

- A nested-group force layout with collision forces per node.
- Link and arrow geometry computed with custom trigonometry.

**Result.** Nodes never overlap, and each stays inside its group.

## Decisions

- **Build or buy:** chose an in-house engine on D3 v7, over renewing the licence, or another library. Three alternatives were compared; low-level D3 primitives covered every view with nothing to license.
- **Abstraction level:** chose low-level primitives (d3-force, d3-hierarchy, d3-zoom), over a higher-level graph framework. Full control of layout and interaction, which the nested-group view needed.

## Outcomes

- About $50K a year in licensing removed (owner-stated figure).
- 3 layouts, 36 files in the graph module, 30 pull requests.
- In production from 2023 until mid-2025.

## Limits

- No rendering-performance benchmark is quoted.
