Interactive D3.js network graph component for Streamlit with zone-clustered force layout, bidirectional state, and agent integration.
Project description
Streamlit D3 Network
Interactive D3.js network graph component for Streamlit. Rich & explorable network visualizations with bidirectional Python-JS state.
Try the live demo to understand with beautiful graphs the strategies used in Simultaneous Streaming and Translation
Installation
pip install streamlit-d3-network
Quick start
from streamlit_d3_network import st_d3_network, Node, Link
result = st_d3_network(
nodes=[
Node(id="a", label="Service A"),
Node(id="b", label="Service B"),
Node(id="c", label="Database"),
],
links=[
Link(source="a", target="b"),
Link(source="b", target="c"),
],
)
if result and result.get("selected_node"):
st.json(result["selected_node"])
Features
Graph rendering
- Force-directed layout with D3.js v7 — smooth, physics-based node positioning
- 5 layout modes — force, radial, hierarchical, grid, community
- Zone clustering — group nodes by zone with convex hull backgrounds
- 7 node shapes — circle, rect, diamond, hexagon, triangle, triangle-down, star
- Status badges — ok (green), warn (yellow), error (red), off (gray)
- Degree rings — visual indicator of node connectivity
- Animated flow particles along edges
- Edge labels and directional arrows
- Dark mode — auto-detects Streamlit theme
Interaction
- Click to select nodes — info panel with details, connections, actions
- Shift+click to multi-select — summary with type/zone breakdowns
- Shift+drag for lasso/box selection
- Drag nodes to reposition (positions persist across rerenders)
- Zoom/pan with mouse wheel and drag
- Search nodes by label (
/to focus) - Legend filtering by zone and type
- Action buttons — define custom actions per node type, results sent to Python
Keyboard shortcuts
| Key | Action |
|---|---|
? |
Help overlay |
/ |
Focus search |
F |
Fit to viewport |
Esc |
Clear selection |
Tab |
Cycle through nodes |
C |
Center on selected node |
L |
Toggle legend |
M |
Focus mode (hide all chrome) |
G |
Cycle layout mode |
N |
Cycle neighbor depth (1/2/3) |
X |
Critical path — highlight warn/error nodes |
K |
Community detection coloring |
J |
Voronoi territory overlay |
Q |
Zone flow overlay |
D |
Toggle dark mode |
H |
Heatmap overlay |
B |
Bookmark current view |
P |
Path mode |
S |
Snapshot positions |
I |
Status filter |
Z |
Collapse/expand zones |
T |
Tuning panel |
+/- |
Zoom in/out |
Ctrl+A |
Select all nodes |
Ctrl+Z |
Undo |
Bidirectional state
- Python to JS — highlight nodes, zoom to node, filter by zone/type
- JS to Python — selected node, triggered action, node positions, zoom transform
- Persistent layout — node positions and zoom state survive Streamlit rerenders
API reference
st_d3_network()
result = st_d3_network(
nodes: list[Node],
links: list[Link],
*,
zones: list[Zone] | None = None,
node_types: dict[str, NodeType] | None = None,
actions: dict[str, list[Action]] | None = None,
highlight: list[str] | None = None,
zoom_to: str = "",
filter_zone: str = "",
filter_type: str = "",
show_labels: bool = True,
show_hulls: bool = True,
show_legend: bool = True,
show_search: bool = True,
show_export: bool = False,
show_particles: bool = True,
layout: str = "force",
theme: dict[str, str] | None = None,
height: int = 600,
key: str | None = None,
)
Returns a dict with:
selected_node—{id, label, type, zone, status, data, connected}orNoneaction—{key, node_id, node_label, node_type}orNone(fire-once)node_positions—{id: {x, y, pinned}}— persisted layoutzoom_transform—{k, x, y}— persisted zoom state
Data types
Node
| Field | Type | Default | Description |
|---|---|---|---|
id |
str |
required | Unique identifier |
label |
str |
required | Display label |
type |
str |
"default" |
Node type key (maps to NodeType) |
zone |
str |
"" |
Zone name for clustering |
tooltip |
list[str] |
[] |
Extra tooltip lines |
color |
str | None |
None |
Override fill color (hex) |
border_color |
str | None |
None |
Override border color (hex) |
radius |
int |
20 |
Node radius in pixels |
status |
str |
"" |
Status badge: ok, warn, error, info, off |
image |
str |
"" |
Image URL for avatar |
opacity |
float |
1.0 |
Node opacity |
data |
dict |
{} |
Arbitrary extra data (shown in info panel) |
Link
| Field | Type | Default | Description |
|---|---|---|---|
source |
str |
required | Source node ID |
target |
str |
required | Target node ID |
label |
str |
"" |
Edge label |
color |
str |
"#adb5bd" |
Edge color (hex) |
width |
float |
1.5 |
Stroke width |
dashed |
bool |
False |
Dashed line style |
directed |
bool |
True |
Show arrow |
opacity |
float |
1.0 |
Edge opacity |
data |
dict |
{} |
Arbitrary extra data |
Zone
| Field | Type | Default | Description |
|---|---|---|---|
name |
str |
required | Unique zone key (matches Node.zone) |
label |
str |
required | Display label |
color |
str |
"#e9ecef" |
Zone hull color (hex) |
NodeType
| Field | Type | Default | Description |
|---|---|---|---|
shape |
str |
"circle" |
circle, rect, diamond, hexagon, triangle, triangle-down, star |
color |
str |
"#e9ecef" |
Default fill color (hex) |
border_color |
str | None |
None |
Default border color (hex) |
icon |
str |
"" |
Emoji/text inside the node |
label |
str |
"" |
Human-readable type name (for legend) |
Action
| Field | Type | Default | Description |
|---|---|---|---|
key |
str |
required | Unique action key (returned in result["action"]) |
label |
str |
required | Button label text |
icon |
str |
"" |
Emoji/icon prefix |
Full example
import streamlit as st
from streamlit_d3_network import Action, Link, Node, NodeType, Zone, st_d3_network
zones = [
Zone(name="backend", label="Backend", color="#b2f2bb"),
Zone(name="data", label="Data Layer", color="#ffec99"),
]
node_types = {
"service": NodeType(shape="circle", color="#b2f2bb", border_color="#2f9e44", label="Service"),
"database": NodeType(shape="hexagon", color="#ffd43b", border_color="#f08c00", label="Database"),
}
nodes = [
Node(id="api", label="API Gateway", type="service", zone="backend",
status="ok", tooltip=["Version: 3.2", "CPU: 45%"]),
Node(id="auth", label="Auth Service", type="service", zone="backend",
status="warn", tooltip=["OAuth 2.0"]),
Node(id="pg", label="PostgreSQL", type="database", zone="data",
status="ok", data={"version": "16.2", "size": "245 GB"}),
]
links = [
Link(source="api", target="auth", label="JWT", color="#339af0"),
Link(source="api", target="pg", label="r/w", color="#f08c00", width=2),
Link(source="auth", target="pg", label="r/w", color="#f08c00"),
]
actions = {
"service": [Action(key="logs", label="View Logs"), Action(key="metrics", label="Metrics")],
"*": [Action(key="details", label="Details")],
}
result = st_d3_network(
nodes=nodes,
links=links,
zones=zones,
node_types=node_types,
actions=actions,
show_hulls=True,
show_particles=True,
height=600,
key="my_graph",
)
if result and result.get("action"):
st.success(f"Action: {result['action']['key']} on {result['action']['node_label']}")
Export
Enable export buttons with show_export=True to allow users to download the graph as PNG or SVG.
Development
git clone https://github.com/QuentinFuxa/streamlit-d3-network.git
cd streamlit-d3-network
pip install -e .
streamlit run examples/demo.py
Note: Changes to JS/CSS require a server restart (
pip install -e .+ restart Streamlit) because the frontend files are read at module import time.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file streamlit_d3_network-0.1.4.tar.gz.
File metadata
- Download URL: streamlit_d3_network-0.1.4.tar.gz
- Upload date:
- Size: 61.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3e72d500990870cfdccc7b26c535fa0fc93550130d4efa96fd824e748a70ef9
|
|
| MD5 |
06d27d3247f7589d9041d85a8398cfb2
|
|
| BLAKE2b-256 |
6865a09c400489ce9420412c8f9719b32e620237a85e28732dffe86a28713887
|
File details
Details for the file streamlit_d3_network-0.1.4-py3-none-any.whl.
File metadata
- Download URL: streamlit_d3_network-0.1.4-py3-none-any.whl
- Upload date:
- Size: 59.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c61a468a0dc57decd5c7ffc1f5a19f60f9ad147fd99f1b2792dbbc3e59789cbb
|
|
| MD5 |
626beb6e107cdb1a71b7f6c600a215b5
|
|
| BLAKE2b-256 |
105bee585a978525eceffb29fcebfd0e6c93837d1f90161812f04ea5a8ee6555
|