Graph commands¶
On this page¶
- When to use commands
- Mutation commands
- Viewport commands
- Validation and application
- Synchronization pattern
When to use commands¶
Commands patch an existing browser graph without resending every element. Use
them for progressive loading, CRUD, streaming updates, or large graphs. For
small graphs, full elements_sync="always" reconciliation is simpler.
Each command has a non-empty scalar command_id and an operation. The browser
applies a command ID once, which makes Streamlit reruns idempotent.
Mutation commands¶
| Builder | Operation | Behavior |
|---|---|---|
add_elements_command |
add_elements |
Adds only IDs not already present |
upsert_elements_command |
upsert_elements |
Adds or updates by data.id |
update_data_command |
update_data |
Merges or replaces one element's data |
delete_elements_command |
delete_elements |
Removes selected IDs and optional incident edges |
set_elements_command |
set_elements |
Replaces the full live graph |
clear_graph_command |
clear |
Removes every live node and edge |
“Browser command” means a JSON dictionary sent as a component prop and applied to the already mounted Cytoscape instance. It is not a shell command, network request, or JavaScript string.
Viewport commands¶
viewport_command() accepts fit, center, pan, zoom, set_viewport,
set_zoom_bounds, and run_layout.
fit = viewport_command("fit-case", "fit", padding=60, duration=180)
zoom = viewport_command(
"zoom-camera",
"zoom",
level=1.8,
renderedPosition={"x": 480, "y": 260},
duration=180,
)
Durations and padding are finite non-negative numbers. Pan dictionaries and
zoom anchors require finite numeric x and y. Zoom bounds follow the same
rules as component options.
Validation and application¶
validate_graph_commands(commands, elements=...) checks command shape,
operations, IDs, endpoint references, update identity, delete safety, layout
names, and viewport values.
apply_graph_command() and apply_graph_commands() return new Python elements
dictionaries after applying mutation commands. Viewport commands leave Python
elements unchanged.
Synchronization pattern¶
import streamlit as st
from st_graph_workbench import (
apply_graph_command,
graph_workbench,
upsert_elements_command,
)
if "elements" not in st.session_state:
st.session_state.elements = {"nodes": [], "edges": []}
if "commands" not in st.session_state:
st.session_state.commands = []
if st.button("Load sighting"):
command = upsert_elements_command(
"load-sighting-1",
nodes=[
{"data": {"id": "ABC123", "label": "VEHICLE", "name": "ABC123"}},
{"data": {"id": "gate-4", "label": "LOCATION", "name": "Gate 4"}},
],
edges={
"data": {
"id": "ABC123-gate-4",
"label": "SEEN_AT",
"source": "ABC123",
"target": "gate-4",
}
},
)
st.session_state.elements = apply_graph_command(st.session_state.elements, command)
st.session_state.commands = [command]
graph_workbench(
st.session_state.elements,
graph_commands=st.session_state.commands,
elements_sync="initial",
key="command-driven-graph",
)
Always update Python state and the browser from the same command. Clear or replace the one-item command queue when a later action occurs, and never reuse a command ID for different content.
Conclusion¶
Commands optimize transport and preserve the live viewport. They do not remove the need for authoritative Python state or graph validation.