Flowgraph

D3Blocks.flowgraph(df, nodes=None, groups: dict = None, direction: str = None, layout: str = 'dagre', shape: str = 'process', color: str = 'group', cmap: str = 'Set2', edge_color: str = '#8c8c8c', nodesep: int = 40, ranksep: int = 70, edgesep: int = 20, ranker: str = 'network-simplex', curve: str = 'smooth', animate: bool = False, draggable: bool = True, show_edge_labels: bool = True, show_groups: bool = True, steps: list = None, font: dict = {'size': 13}, title: str = 'Flowgraph - D3blocks', filepath: str = 'flowgraph.html', figsize=[None, None], showfig: bool = True, overwrite: bool = True, notebook: bool = False, save_button: bool = True, show_side_panel: bool = True, show_top_panel: bool = True, dark_mode=True, color_background=None, return_html: bool = False, reset_properties: bool = True)

Flowgraph block: process flows and architecture diagrams.

Nodes are arranged in ranks along the flow direction with a layered layout, drawn as flowchart shapes and optionally nested in groups such as swimlanes, services or network boundaries. The input is either an edge list, a Mermaid flowchart or a Mermaid state diagram.

Parameters:
  • df (pd.DataFrame, str or path-like) –

    • DataFrame with the edges. Required columns: ‘source’, ‘target’. Optional columns: ‘label’ (edge text), ‘weight’ (line width), ‘variant’, ‘style’ (‘solid’, ‘dashed’, ‘dotted’), ‘color’ and ‘animation’. A ‘source’ or ‘target’ may name a group in groups (one with member nodes and no entry in nodes); the edge is then drawn to the group box.

    • str: a Mermaid flowchart, e.g. ‘flowchart LR; A[Start] –> B{Valid?}’, a Mermaid state diagram (‘stateDiagram-v2’), or Markdown text containing a fenced Mermaid code block.

    • Path to a Markdown file (.md, .markdown) with a fenced Mermaid code block, so the same diagram renders on GitHub, or to a .mmd / .mermaid file. From Markdown, the first flowchart or state diagram block is used.

    Node shapes, edge labels, dotted/thick links, (nested) subgraphs and linkStyle colours are converted; nodes, groups and direction override what it defines. State diagrams: transitions with labels, ‘[*]’ start/end (small circles), notes (shown in the state’s tooltip), direction and classDef colours; laid out ‘TB’ by default. Statements that do not parse or have no equivalent (click, links to subgraphs, …) raise a ValueError naming the line.

  • nodes (pd.DataFrame or dict, (default: None)) –

    Per-node attributes keyed by node name (a ‘name’ column or the index):
    • ’label’: display text; use ‘n’ for line breaks.

    • ’shape’: ‘process’, ‘decision’, ‘terminal’, ‘io’, ‘subprocess’, ‘database’, ‘queue’, ‘document’, ‘external’ or ‘circle’.

    • ’group’: group (swimlane / boundary) the node belongs to.

    • ’color’: node colour; overrides color.

    • ’tooltip’: extra text or HTML shown on hover below the label.

  • groups (dict, (default: None)) – Group settings: {group: {‘label’: str, ‘parent’: str, ‘color’: hex}}. Use ‘parent’ to nest groups (e.g. a subnet inside a VPC). The short form {group: parent} is also accepted.

  • direction (str, (default: None)) – Flow direction: ‘LR’, ‘TB’ (or ‘TD’), ‘RL’ or ‘BT’. None: the direction of the Mermaid header, otherwise ‘LR’.

  • layout (str, (default: 'dagre')) –

    • ‘dagre’: layered layout with smooth edges; small output (~0.5 MB).

    • ’elk’: ELK layered layout with orthogonal edge routing and native nested groups; tidier for architecture diagrams, adds ~1.5 MB to the HTML.

  • shape (str, (default: 'process')) – Default shape for nodes without one.

  • color (str, (default: 'group')) –

    • ‘group’: colour nodes by group.

    • ’shape’: colour nodes by shape.

    • ’#RRGGBB’: one colour for all nodes.

  • cmap (str, (default: 'Set2')) – Colormap for group / shape colouring.

  • edge_color (str, (default: '#8c8c8c')) – Default edge colour.

  • nodesep (int, (default: 40)) – Pixels between nodes in the same rank.

  • ranksep (int, (default: 70)) – Pixels between ranks.

  • edgesep (int, (default: 20)) – Pixels between parallel edges.

  • ranker (str, (default: 'network-simplex')) – dagre ranking algorithm: ‘network-simplex’, ‘tight-tree’ or ‘longest-path’.

  • curve (str, (default: 'smooth')) – Edge shape: ‘smooth’ (curved, or rounded corners with ELK) or ‘straight’.

  • animate (bool, (default: False)) – Animate pulses along the edges to show the direction of flow.

  • draggable (bool, (default: True)) – Nodes can be dragged; connected edges and groups follow.

  • show_edge_labels (bool, (default: True)) – Draw edge labels.

  • show_groups (bool, (default: True)) – Draw groups as containers (and keep their members together).

  • steps (list of dict, (default: None)) – Captioned walkthrough; “Walk through” in the top panel steps through it: [{‘title’: str, ‘caption’: str, ‘highlight’: {‘nodes’: […], ‘edges’: [(source, target), …]}}]. Each step highlights its nodes and edges, dims the rest and zooms to them. None: the “Trace” button walks the flow uncaptioned.

  • font (dict, (default: {'size': 13})) – Font properties.

  • title (str, (default: 'Flowgraph - D3blocks')) – Title of the figure.

  • filepath (str, (default: 'flowgraph.html')) – File path to save the output. None: return HTML only.

  • figsize (list, (default: [None, None])) – [width, height] in pixels. None: full window.

  • showfig (bool, (default: True)) – Open the chart in the browser.

  • overwrite (bool, (default: True)) – Overwrite an existing file.

  • notebook (bool, (default: False)) – Display inline in a Jupyter notebook, isolated in an iframe sized by figsize (default: full width x 650 px). The returned HTML is then that iframe.

  • save_button (bool, (default: True)) – Show the SVG/PNG save buttons.

  • show_side_panel (bool, (default: True)) – Show the left side panels (Export / Save, Layout, Legend).

  • show_top_panel (bool, (default: True)) – Show the top bar (logo, search, fit, theme).

  • dark_mode (bool or 'auto', (default: True)) –

    Initial theme; the theme button switches at runtime in every mode.
    • True: start in the dark theme.

    • False: start in the light theme.

    • ’auto’: follow the operating system theme until the theme button is used.

  • color_background (list of str, str, or None, (default: None)) – Backgrounds for center / top / side panels as [dark_hex, light_hex]. Named themes: 'streamlit', 'darkblue'. None → ['#222222', '#ffffff'].

  • return_html (bool, (default: False)) – Return the HTML string.

  • reset_properties (bool, (default: True)) – Recompute node and edge properties from the input.

Returns:

  • d3.node_properties (DataFrame of dictionary) – Node properties; edit and call d3.show() to update.

  • d3.edge_properties (DataFrame) – Edge properties; edit and call d3.show() to update.

  • d3.config (dictionary) – Configuration. d3.config[‘groups’] holds the group settings (merged with Mermaid subgraphs); edit and call d3.show(). Labels, nesting and colours are resolved from it on every draw.

Examples

>>> # Edge list with shapes and edge labels
>>> import pandas as pd
>>> from d3blocks import D3Blocks
>>> d3 = D3Blocks(frame=False)
>>> df = pd.DataFrame({'source': ['Start', 'Valid?', 'Valid?', 'Fix'],
...                    'target': ['Valid?', 'Done', 'Fix', 'Valid?'],
...                    'label': ['', 'yes', 'no', 'retry']})
>>> nodes = {'Start': {'shape': 'terminal'}, 'Valid?': {'shape': 'decision'},
...          'Done': {'shape': 'terminal'}}
>>> d3.flowgraph(df, nodes=nodes, direction='TB')
>>> # Change a node and redraw
>>> d3.node_properties['Fix']['color'] = '#e15759'
>>> d3.show()
>>>
>>> # Mermaid diagram kept in a Markdown file (renders on GitHub too)
>>> d3.flowgraph('docs/process.md')
>>>
>>> # Mermaid flowchart with a subgraph, laid out with ELK
>>> d3.flowgraph('''
... flowchart LR
...   subgraph api [API]
...     gw[Gateway] --> svc[Orders]
...   end
...   svc --> db[(Postgres)]
...   svc -.->|events| q[[Worker]]
... ''', layout='elk')

References

Input Data

The input is either an edge list (DataFrame) or a Mermaid flowchart (string). The edge list needs the columns source and target; all other columns are optional.

#        source         target  label   variant animation
# 0       start          check                       None
# 1       check           pick    yes  emphasis     comet
# 2       check      backorder     no     error      None
# 3   backorder          check  retry     async      dots

Per-node attributes (label, shape, group, color, tooltip) are passed with nodes, and group settings (label, parent, color) with groups.

  • Shapes: process, decision, terminal, io, subprocess, database, queue, document, external, circle.

  • Edge variants: default, emphasis, security, async, error. Each sets a colour, line style and width; an edge’s own color and style override it.

  • Animations: pulse, dash, dots, comet for the whole chart (animate=) or per edge (animation column).

Process flow

import pandas as pd
from d3blocks import D3Blocks

edges = pd.DataFrame({
    'source': ['start', 'check', 'check', 'fix'],
    'target': ['check', 'done', 'fix', 'check'],
    'label':  ['', 'yes', 'no', 'retry'],
})
nodes = {
    'start': {'label': 'Start', 'shape': 'terminal'},
    'check': {'label': 'Valid?', 'shape': 'decision'},
    'fix':   {'label': 'Fix input'},
    'done':  {'label': 'Done', 'shape': 'terminal'},
}

d3 = D3Blocks(frame=False)
d3.flowgraph(edges, nodes=nodes, direction='TB')

# Change a node and redraw
d3.node_properties['fix']['color'] = '#e15759'
d3.show()

Mermaid input

Node shapes, edge labels, dotted (-.->) and thick (==>) links, &, chains, nested subgraphs, links to and from subgraphs, node colours from style / classDef and edge colours and dashes from linkStyle are converted.

Mermaid errors

All d3blocks Mermaid readers (flowcharts, state diagrams, sequence and erd) follow one rule: every statement is understood, explicitly ignored, or raises a ValueError that names the line, before any HTML is written. Nothing is dropped silently.

  • Ignored: blank lines, %% comments, %%{init}%% directives and the accessibility metadata accTitle / accDescr.

  • Errors: statements that do not parse (for example A[Start] --> B{ok?), a wrong first statement, an end without subgraph (or a subgraph without end), a link between a subgraph and its own content, a linked subgraph id that is also given a label, shape, style or class, and Mermaid features without an equivalent here, such as click and a direction inside a subgraph.

Line numbers count from the first line of the diagram (in Markdown: of the fenced block).

d3.flowgraph('flowchart LR\n  A[Start] --> B{ok?')
# ValueError: Mermaid flowchart line 2 could not be parsed: 'A[Start] --> B{ok?' (...)
d3.flowgraph('''
flowchart LR
    start([Order received]) --> check{In stock?}
    check -->|yes| pick[Pick & pack]
    check -- no --> back[[Backorder]] -.->|restocked| check
    subgraph wh [Warehouse]
        pick --> ship[/Ship parcel/]
    end
    ship ==> done([Delivered])
''')

The diagram can also live in a Markdown file as a fenced mermaid block, so GitHub renders it too; pass the file path (.md, .markdown, .mmd or .mermaid). From Markdown, the first flowchart block is used.

d3.flowgraph('docs/order_process.md')

State diagrams

Mermaid stateDiagram and stateDiagram-v2 are read too, so lifecycle diagrams render with the same layout, interaction and export as flowcharts. [*] becomes one start and one end pseudo-state (small circles), transition labels are kept (everything after the first :), notes are added to the state’s tooltip and classDef / class colours are applied. State diagrams are laid out top to bottom unless the diagram has a direction statement or direction is passed. Composite states, <<choice>>, state "x" as A and A : description raise a ValueError naming the line.

d3.flowgraph('''
stateDiagram-v2
    [*] --> pending : Signal created
    pending --> awaiting_approval : Risk checks pass
    pending --> cancelled : Strategy disabled
    awaiting_approval --> approved : Operator approves
    awaiting_approval --> rejected : Operator rejects
    approved --> executed : Order sent to broker
    executed --> [*]
    rejected --> [*]
    cancelled --> [*]

    note right of awaiting_approval
        Agent-generated signals
        enter here directly
    end note

    classDef review fill:#e0f2fe,stroke:#0284c7
    class awaiting_approval review
''')

From Markdown, the first flowchart or state diagram block is used; other diagram types are skipped.

Architecture diagram

Groups can be nested with parent. layout='elk' uses ELK’s layered layout with orthogonal edge routing; it suits nested architecture diagrams but adds about 1.5 MB to the HTML file.

groups = {
    'Cloud': {'label': 'Cloud account'},
    'VPC': {'parent': 'Cloud'},
    'App subnet': {'parent': 'VPC'},
    'Data subnet': {'parent': 'VPC'},
}
nodes = {
    'api': {'label': 'API', 'group': 'App subnet'},
    'worker': {'label': 'Worker', 'group': 'App subnet'},
    'db': {'label': 'PostgreSQL', 'shape': 'database', 'group': 'Data subnet'},
    'bus': {'label': 'Event bus', 'shape': 'queue', 'group': 'Data subnet'},
    'users': {'label': 'Users', 'shape': 'circle'},
}
edges = pd.DataFrame({
    'source':  ['users', 'api', 'api', 'bus'],
    'target':  ['api', 'db', 'bus', 'worker'],
    'label':   ['HTTPS', 'SQL', 'publish', 'consume'],
    'variant': ['emphasis', 'default', 'async', 'async'],
})
d3.flowgraph(edges, nodes=nodes, groups=groups, layout='elk', animate='dots')

Jupyter and Streamlit

In a notebook, pass notebook=True; the chart is shown inline, isolated in an iframe sized by figsize (default: full width x 650 px). See notebooks/flowgraph.ipynb.

d3 = D3Blocks(frame=False)
d3.flowgraph(edges, nodes=nodes, notebook=True, filepath=None, figsize=[None, 520])

In Streamlit, generate the HTML with return_html=True and embed it with st.iframe. streamlit/flowgraph_streamlit_demo.py edits a Mermaid flowchart in the sidebar and re-renders it with the chosen layout, direction and animation.

html = D3Blocks().flowgraph(flowchart, filepath=None, showfig=False, return_html=True)
st.iframe(html, height=700, width="stretch")

Walkthrough

steps adds a captioned walkthrough. ▶ Walk through in the top panel opens a caption bar with the step title, the caption, “Step 3 of 9”, a row of step stops and Prev / Play / Next. Each step highlights its nodes and edges, dims the rest and zooms to them. Keys: ← and → move, Space plays or pauses, Esc closes. Play advances every 3 seconds and stops on the last step.

steps = [
    {'title': 'Check', 'caption': 'Every order is validated first.',
     'highlight': {'nodes': ['check'], 'edges': [('start', 'check')]}},
    {'title': 'Retry', 'caption': 'Invalid input is fixed and checked again.',
     'highlight': {'edges': [('check', 'fix'), ('fix', 'check')]}},
]
d3.flowgraph(edges, nodes=nodes, steps=steps)

Without steps the button is ▶ Trace, the uncaptioned walk through the flow. Unknown nodes or edges and unsupported keys raise a ValueError with the step index. The same walkthrough is used by sequence and erd.

Theme

The theme button (last on the right of the top panel) switches between dark and light at runtime. dark_mode=True (default) starts dark, False starts light, and dark_mode='auto' follows the operating system theme, also when it changes, until the theme button is used. In 'auto' mode a ?theme=light or ?theme=dark URL parameter picks the theme. Exports keep the theme shown.

Interaction

  • Hover a node to trace everything upstream and downstream; click to pin.

  • ▶ Trace walks through the flow step by step (from the pinned node, or from all start nodes); with steps it is ▶ Walk through, the captioned walkthrough.

  • Drag nodes; edges and groups follow. Reset layout recomputes the layout.

  • The Layout panel changes direction, spacing, font size, edge curve and animation.

  • The Legend panel lists groups and the edge variants in use.

  • Export to SVG, PNG or JSON (including computed positions).