Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions components/D3-Force-Graph/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# ForceGraphComponent

An interactive D3 force-directed graph custom component for Retool. Visualises node-link data with dynamic grouping, multiple themes, zoom controls, and a detail panel.

---

## Features

- `Force-directed layout` via D3 with drag, zoom, and pan
- `Auto node grouping` β€” detects a model, category, or any suitable key and colour-codes nodes accordingly
- `4 preset themes` β€” Arctic, Midnight, Rose Gold, Slate Pro
- `Custom theme editor` β€” live colour pickers for background, grid, edges, labels, node strokes, per-group node colours, and tooltip
- `Info panel` β€” click any node to inspect all its fields; shows a graph summary when nothing is selected
- `Hover tooltip` β€” displays node name, group value, and a prompt to click
- `Zoom controls` β€” zoom in, zoom out, reset
- `Stable rendering` β€” data identity is tracked by content, not object reference, so the simulation only rebuilds when data actually changes
- `Persisted preferences` β€” active theme and custom colour overrides survive page refresh via localStorage

---

## Input
The component accepts a single Retool state object named `graphData`.

Schema
```json
{
"nodes": [
{
"id": "string | number",
"name": "string",
"model": "string (optional)",
"category": "string (optional)",
"avgLatency": "number (optional)",
"avgCost": "number (optional)",
"numCalls": "number (optional)",
"performanceScore": "number (optional)"
}
],
"links": [
{
"source": "string | number (node id)",
"target": "string | number (node id)",
"weight": "number (optional, default 1)"
}
]
}
```

---


Any additional fields on a node are displayed in the `All Fields` section of the info panel.

Example
```json
{
"nodes": [
{ "id": "1", "name": "Classifier", "model": "GPT-4", "numCalls": 120, "avgLatency": 340 },
{ "id": "2", "name": "Summariser", "model": "Claude", "numCalls": 80, "avgCost": 0.002 },
{ "id": "3", "name": "Embedder", "model": "GPT-3.5", "numCalls": 200 }
],
"links": [
{ "source": "1", "target": "2", "weight": 2 },
{ "source": "2", "target": "3" }
]
}
```


---


## Automatic grouping

The component scans all node keys in order β€” model, category, then any other key β€” and picks the first one that has between 2 and 20 distinct values. That key becomes the group key, used to colour nodes and populate the legend in the info panel.
To disable grouping, ensure no key on your nodes produces 2–20 distinct values

---

# Theming

## Preset themes

Select from the theme bar at the bottom of the component: `Arctic, Midnight, Rose Gold, Slate Pro`.

## Custom theme

Click ✏️ `Custom` to open the colour editor. Changes to background, grid, edges, labels, node stroke, and tooltip colours apply instantly. Edits to per-group node colours also apply immediately and automatically activate the custom theme β€” no need to click Apply Custom Theme first.
Click `β†Ί Reset` to restore the last selected preset and clear all custom colour overrides.
Binary file added components/D3-Force-Graph/cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions components/D3-Force-Graph/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"id": "d3-force-graph",
"title": "D3 Force Graph",
"author": "@widlestudiollp",
"shortDescription": "An interactive D3 force-directed graph with zoom, themes, node grouping, and detailed insights panel.",
"tags": [
"D3",
"Graph",
"Visualization",
"Force Layout",
"Analytics",
"Interactive",
"Network",
"React"
]
}
48 changes: 48 additions & 0 deletions components/D3-Force-Graph/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "my-react-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@tryretool/custom-component-support": "latest",
"d3": "^7.9.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"engines": {
"node": ">=20.0.0"
},
"scripts": {
"dev": "npx retool-ccl dev",
"deploy": "npx retool-ccl deploy",
"test": "vitest"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/react": "^18.2.55",
"@typescript-eslint/eslint-plugin": "^7.3.1",
"@typescript-eslint/parser": "^7.3.1",
"eslint": "^8.57.0",
"eslint-plugin-react": "^7.34.1",
"postcss-modules": "^6.0.0",
"prettier": "^3.0.3",
"vitest": "^4.0.17"
},
"retoolCustomComponentLibraryConfig": {
"name": "D3Graph",
"label": "D3 Graph",
"description": "D3 Conversation Flow Graph",
"entryPoint": "src/index.tsx",
"outputPath": "dist"
}
}
Loading
Loading