11# Declare Node & Edge Types
22
3- Node and edge types are lightweight descriptors that tell Panel-ReactFlow
4- ** what kind of data a node or edge carries** . A type defines a name, an
5- optional display label, optional input/output ports (for nodes), and an
6- optional JSON Schema for its ` data ` payload.
3+ Node and edge types are lightweight descriptors that define ** what data each
4+ kind of node/edge carries** . A type can provide:
75
8- Types are separate from editors. A type says "a * task* node has a
9- * status* string and a * priority* integer"; an editor says "render a
10- dropdown and a number input for those fields." This separation lets you
11- reuse the same type with different editors, or rely on the auto-generated
12- form.
6+ - a type name (` type ` )
7+ - a display label (` label ` )
8+ - node handles (` inputs ` / ` outputs ` )
9+ - a schema for the ` data ` payload (` schema ` )
10+
11+ Types are separate from editors. A type defines structure; an editor defines
12+ the UI used to edit it.
1313
1414![ Screenshot: multiple node types with different schemas] ( ../assets/screenshots/declare-types.png )
1515
1616---
1717
18- ## Node types
18+ ## Complete runnable example
19+
20+ This script is a minimal, working example that produces the visualization
21+ shown above.
22+
23+ ``` python
24+ import param
25+ import panel as pn
26+
27+ from panel_reactflow import EdgeType, NodeType, ReactFlow
28+
29+ pn.extension(" jsoneditor" )
30+
31+
32+ class Job (param .Parameterized ):
33+ status = param.Selector(objects = [" idle" , " running" , " done" ])
34+ retries = param.Integer(default = 0 )
35+
36+
37+ decision_schema = {
38+ " type" : " object" ,
39+ " properties" : {
40+ " question" : {" type" : " string" , " title" : " Question" },
41+ " outcome" : {
42+ " type" : " string" ,
43+ " enum" : [" yes" , " no" , " maybe" ],
44+ " title" : " Outcome" ,
45+ },
46+ },
47+ }
48+
49+ node_types = {
50+ " job" : NodeType(type = " job" , label = " Job" , schema = Job, inputs = [" in" ], outputs = [" out" ]),
51+ " decision" : NodeType(
52+ type = " decision" ,
53+ label = " Decision" ,
54+ schema = decision_schema,
55+ inputs = [" in" ],
56+ outputs = [" yes" , " no" ],
57+ ),
58+ }
59+
60+ edge_types = {
61+ " flow" : EdgeType(
62+ type = " flow" ,
63+ label = " Flow" ,
64+ schema = {
65+ " type" : " object" ,
66+ " properties" : {" weight" : {" type" : " number" , " title" : " Weight" }},
67+ },
68+ ),
69+ }
70+
71+ nodes = [
72+ {
73+ " id" : " j1" ,
74+ " type" : " job" ,
75+ " label" : " Fetch Data" ,
76+ " position" : {" x" : 0 , " y" : 0 },
77+ " data" : {" status" : " idle" , " retries" : 0 },
78+ },
79+ {
80+ " id" : " d1" ,
81+ " type" : " decision" ,
82+ " label" : " Valid?" ,
83+ " position" : {" x" : 300 , " y" : 250 },
84+ " data" : {" question" : " Is data valid?" , " outcome" : " yes" },
85+ },
86+ {
87+ " id" : " j2" ,
88+ " type" : " job" ,
89+ " label" : " Process" ,
90+ " position" : {" x" : 600 , " y" : 400 },
91+ " data" : {" status" : " running" , " retries" : 1 },
92+ },
93+ ]
94+
95+ edges = [
96+ {" id" : " e1" , " source" : " j1" , " target" : " d1" , " type" : " flow" , " data" : {" weight" : 1.0 }},
97+ {" id" : " e2" , " source" : " d1" , " target" : " j2" , " type" : " flow" , " data" : {" weight" : 0.8 }},
98+ ]
99+
100+ TASK_NODE_CSS = """
101+ .react-flow__node-job {
102+ background-color: white;
103+ border-radius: 8px;
104+ border: 1.5px solid #7c3aed;
105+ }
106+
107+ .react-flow__node-decision {
108+ background-color: white;
109+ border-radius: 8px;
110+ border: 1.5px solid green;
111+ }
112+ """
113+
114+ flow = ReactFlow(
115+ nodes = nodes,
116+ edges = edges,
117+ node_types = node_types,
118+ edge_types = edge_types,
119+ editor_mode = " node" ,
120+ sizing_mode = " stretch_both" ,
121+ stylesheets = [TASK_NODE_CSS ]
122+ )
123+
124+ pn.Column(flow, sizing_mode = " stretch_both" ).servable()
125+ ```
126+
127+ ## How this code maps to the visualization
128+
129+ - ` node_types["job"] ` and ` node_types["decision"] ` define the two node kinds you see.
130+ - ` inputs ` and ` outputs ` define the left/right handles rendered on each node.
131+ - ` edge_types["flow"] ` defines the edge payload schema used by both connections.
132+ - ` nodes ` controls labels (` Fetch Data ` , ` Valid? ` , ` Process ` ) and positions.
133+ - ` editor_mode="side" ` makes selection open the schema-driven editor in the right panel.
134+
135+ ---
136+
137+ ## Node type snippet
19138
20- Use ` NodeType ` to describe a node type. Provide ` inputs ` and ` outputs ` to
21- control the handles (ports) shown on each side of the node.
139+ Use ` NodeType ` to define node handles and payload schema.
22140
23141``` python
24142from panel_reactflow import NodeType
@@ -42,12 +160,9 @@ node_types = {
42160}
43161```
44162
45- ---
46-
47- ## Edge types
163+ ## Edge type snippet
48164
49- Use ` EdgeType ` to describe an edge type. Edges with a schema get the same
50- auto-generated editor support as nodes.
165+ Use ` EdgeType ` for edge payload schema and label.
51166
52167``` python
53168from panel_reactflow import EdgeType
@@ -71,8 +186,7 @@ edge_types = {
71186
72187## Schema sources
73188
74- The ` schema ` field accepts multiple formats. All are normalized to
75- JSON Schema before being sent to the frontend or used by editors.
189+ The ` schema ` field accepts multiple inputs and normalizes them to JSON Schema.
76190
77191| Source | Example |
78192| --------| ---------|
@@ -108,9 +222,9 @@ node_types = {"config": NodeType(type="config", label="Config", schema=Config)}
108222
109223---
110224
111- ## Register on ReactFlow
225+ ## Register on ` ReactFlow `
112226
113- Pass types as dictionaries keyed by type name.
227+ Pass ` node_types ` and ` edge_types ` as dictionaries keyed by type name:
114228
115229``` python
116230flow = ReactFlow(
@@ -121,5 +235,5 @@ flow = ReactFlow(
121235)
122236```
123237
124- Types without a schema still work — the node or edge simply has no
125- schema-driven validation or auto-generated form .
238+ Types without a schema still work; they just do not get schema-driven
239+ validation or auto-generated forms .
0 commit comments