simplify viz
This commit is contained in:
parent
beafd5bc8b
commit
16e65d522b
95
docs/viz.md
95
docs/viz.md
|
|
@ -7,68 +7,35 @@ nav_order: 3
|
||||||
|
|
||||||
# Visualization
|
# Visualization
|
||||||
|
|
||||||
Visualizing the flow and node structure can greatly help understanding. While we do **not** include built-in visualization tools, we provide an example of how to create one using **Mermaid**.
|
Visualizing the nested graph can help understanding. While we **don’t** include built-in visualization tools, we provide an example using **Mermaid**.
|
||||||
|
|
||||||
### Example: Visualization of Node with Mermaid
|
### Example: Visualization of Node with Mermaid
|
||||||
|
|
||||||
{% raw %}
|
{% raw %}
|
||||||
```python
|
```python
|
||||||
# Generate Mermaid diagram code for a Flow or Node structure
|
|
||||||
def build_mermaid(start):
|
def build_mermaid(start):
|
||||||
node_ids, visited = {}, set()
|
ids, visited, lines = {}, set(), ["graph LR"]
|
||||||
lines = ["graph LR"]
|
ctr = 1
|
||||||
counter = [1] # Counter for unique node IDs
|
def get_id(n):
|
||||||
|
nonlocal ctr
|
||||||
def get_id(node):
|
return ids[n] if n in ids else (ids.setdefault(n, f"N{ctr}"), (ctr := ctr + 1))[0]
|
||||||
if node not in node_ids:
|
def link(a, b):
|
||||||
node_ids[node] = f"N{counter[0]}"
|
lines.append(f" {a} --> {b}")
|
||||||
counter[0] += 1
|
def walk(node, parent=None):
|
||||||
return node_ids[node]
|
|
||||||
|
|
||||||
def connect(src, tgt):
|
|
||||||
lines.append(f" {src} --> {tgt}")
|
|
||||||
|
|
||||||
def walk(node, parent_id=None):
|
|
||||||
if node in visited:
|
if node in visited:
|
||||||
if parent_id:
|
return parent and link(parent, get_id(node))
|
||||||
connect(parent_id, get_id(node))
|
|
||||||
return
|
|
||||||
visited.add(node)
|
visited.add(node)
|
||||||
|
|
||||||
if isinstance(node, Flow):
|
if isinstance(node, Flow):
|
||||||
# Handle Flow nodes
|
node.start and parent and link(parent, get_id(node.start))
|
||||||
if parent_id and node.start:
|
|
||||||
connect(parent_id, get_id(node.start))
|
|
||||||
|
|
||||||
lines.append(f"\n subgraph sub_flow_{get_id(node)}[{type(node).__name__}]")
|
lines.append(f"\n subgraph sub_flow_{get_id(node)}[{type(node).__name__}]")
|
||||||
|
node.start and walk(node.start)
|
||||||
if node.start:
|
for nxt in node.successors.values():
|
||||||
walk(node.start)
|
node.start and walk(nxt, get_id(node.start)) or (parent and link(parent, get_id(nxt))) or walk(nxt)
|
||||||
|
|
||||||
for succ_node in node.successors.values():
|
|
||||||
if node.start:
|
|
||||||
walk(succ_node, get_id(node.start))
|
|
||||||
else:
|
|
||||||
if parent_id:
|
|
||||||
connect(parent_id, get_id(succ_node))
|
|
||||||
walk(succ_node)
|
|
||||||
|
|
||||||
lines.append(" end\n")
|
lines.append(" end\n")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Handle simple Nodes
|
lines.append(f" {(nid := get_id(node))}['{type(node).__name__}']")
|
||||||
curr_id = get_id(node)
|
parent and link(parent, nid)
|
||||||
label = f'{curr_id}["{type(node).__name__}"]'
|
[walk(nxt, nid) for nxt in node.successors.values()]
|
||||||
|
|
||||||
if parent_id:
|
|
||||||
lines.append(f" {label}")
|
|
||||||
connect(parent_id, curr_id)
|
|
||||||
else:
|
|
||||||
lines.append(f" {label}")
|
|
||||||
|
|
||||||
for succ_node in node.successors.values():
|
|
||||||
walk(succ_node, curr_id)
|
|
||||||
|
|
||||||
walk(start)
|
walk(start)
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
```
|
```
|
||||||
|
|
@ -76,40 +43,28 @@ def build_mermaid(start):
|
||||||
|
|
||||||
### Usage Example
|
### Usage Example
|
||||||
|
|
||||||
Here, we define some example Nodes and Flows to generate a Mermaid diagram:
|
Here, we define some example Nodes and Flows:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class DataPrepBatchNode(BatchNode):
|
class DataPrepBatchNode(BatchNode): pass
|
||||||
pass
|
class ValidateDataNode(Node): pass
|
||||||
|
class FeatureExtractionNode(Node): pass
|
||||||
class ValidateDataNode(Node):
|
class TrainModelNode(Node): pass
|
||||||
pass
|
class EvaluateModelNode(Node): pass
|
||||||
|
class ModelFlow(Flow): pass
|
||||||
class FeatureExtractionNode(Node):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class TrainModelNode(Node):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class EvaluateModelNode(Node):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class ModelFlow(Flow):
|
|
||||||
pass
|
|
||||||
|
|
||||||
feature_node = FeatureExtractionNode()
|
feature_node = FeatureExtractionNode()
|
||||||
train_node = TrainModelNode()
|
train_node = TrainModelNode()
|
||||||
evaluate_node = EvaluateModelNode()
|
evaluate_node = EvaluateModelNode()
|
||||||
feature_node >> train_node >> evaluate_node
|
feature_node >> train_node >> evaluate_node
|
||||||
model_flow = ModelFlow(start=feature_node)
|
model_flow = ModelFlow(start=feature_node)
|
||||||
|
|
||||||
data_prep_node = DataPrepBatchNode()
|
data_prep_node = DataPrepBatchNode()
|
||||||
validate_node = ValidateDataNode()
|
validate_node = ValidateDataNode()
|
||||||
data_prep_node >> validate_node >> model_flow
|
data_prep_node >> validate_node >> model_flow
|
||||||
build_mermaid(start=data_prep_node)
|
build_mermaid(start=data_prep_node)
|
||||||
```
|
```
|
||||||
|
|
||||||
The above code produces a Mermaid diagram (e.g., use the [Mermaid Live Editor](https://mermaid.live/) to render it):
|
The code generates a Mermaid diagram:
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
graph LR
|
graph LR
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue