Skip to main content
spaday-dagre logo, a layered directed graph inside a browser window

dagre graph rendering for spaday

Build Status codecov License PyPI

Overview

spaday-dagre renders directed graphs in spaday from a serializable node/edge config, laid out by @dagrejs/dagre and drawn as light-DOM SVG. Colors ride the spaday shell's --spa-* tokens, so bind_root_class("wa-dark", ...) re-themes the graph with the rest of the page, and application CSS reaches every shape. dagre-node-click bubbles {id, label, x, y} and dagre-edge-click bubbles {source, target, label, x, y} — the graph context plus the pointer position — so SetField("selected", event_value("id")) selects and open_popup(..., x=event_value("x"), y=event_value("y")) positions. Right-clicking a node or edge bubbles dagre-node-contextmenu / dagre-edge-contextmenu with the same shape, pairing with spaday's open_popup for context menus.

Navigation is dagre-d3-class: cursor-anchored wheel zoom, drag pan (clamped so the graph can never be dragged out of view), double-click reset, and an optional GitHub-mermaid-style D-pad (controls) with pan arrows around a center reset circle.

The host draws into an absolutely positioned frame and contributes no intrinsic height: give <spaday-dagre> or an ancestor an explicit height (e.g. style="height: 32rem"). An unsized host falls back to the graph's natural height, with a one-time console warning.

Quick example

from spaday import element
from spaday.backends.starlette import serve
from spaday_dagre import Dagre, package

graph = Dagre(
    graph={
        "nodes": [{"id": "a", "label": "Alpha"}, {"id": "b", "shape": "diamond"}],
        "edges": [{"source": "a", "target": "b", "label": "flow"}],
    },
    layout={"rankdir": "LR"},
    controls=True,
)
app = serve(element("main").child(graph), packages=[package])

Node sizes default from label measurement; per-node width/height/class/shape (rect, diamond, ellipse) and per-edge label/class override. The maxLabelWidth prop (px) caps label-driven width: wider labels are ellipsized, with the full label as a native tooltip. layout passes through to dagre (rankdir, align, nodesep, ranksep, edgesep, marginx/marginy, ranker). Installing the package registers the dagre entry point, so packages=["dagre"] also works.

A node with parent nests inside the cluster named by another node's id (dagre's compound layout): the cluster renders as a rounded container behind its children, labeled along its top edge, and clicks/right-clicks on it dispatch the node events with the same detail shape. Parentless nodes mix freely with clustered ones; graphs without parents keep the flat layout path.

The emphasis prop (a list of node ids; a single id string works too, null clears) toggles the .emphasis class on the matching rendered nodes by pure class reconciliation — no re-layout, no graph rebuild — and re-applies after re-renders, so a live selection binds directly: .bind("emphasis", "selected"). The focusNode(id) method (declared in the manifest for spaday's Invoke) pans — and zooms to a comfortable level when needed — so the node or cluster is centered in the view; the bindable focus prop is a property spelling that calls it on set, with the method as the primary API.

Theming

Component-scoped tokens layer over the shell's --spa-* tokens, so an application can theme the graph from the host (or any ancestor) without knowing its internals — a token set once wins in both light and dark page modes:

Token Themes
--dagre-node-fill node shape fill
--dagre-node-stroke node shape outline
--dagre-node-text node and cluster label text
--dagre-edge-stroke edge lines and arrowheads
--dagre-edge-label edge label text
--dagre-cluster-fill cluster container fill
--dagre-cluster-stroke cluster container outline
--dagre-accent hover, connected-endpoint, and emphasis affordances

Node and edge class values are forwarded onto the rendered <g> groups (alongside spaday-dagre-node / spaday-dagre-edge), so custom classes are CSS-targetable directly. One variant is built in: a node or edge whose class includes emphasis gets an accent outline.

Run the local example

python -m spaday_dagre.example

Open http://127.0.0.1:8016: a pipeline DAG live over a transports wire — the server sweeps an active-stage highlight through the graph while node/edge selection rides back as model edits — with direction switching, mixed node shapes, a "modeling" cluster grouping the middle stages, selection mirrored into the emphasis prop, a right-click menu for nodes and edges (its Focus item centers via focusNode), view controls, and the dark-mode toggle.

[!NOTE] This library was generated using copier from the Base Python Project Template repository.

Metadata

Release files for spaday-dagre 0.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spaday-dagre 0.2.2
File Size Uploaded
spaday_dagre-0.2.2.tar.gz 190.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for spaday-dagre 0.2.2
File Interpreter ABI Platform
spaday_dagre-0.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 326.5 kB

Release files / spaday_dagre-0.2.2.tar.gz

Download URL spaday_dagre-0.2.2.tar.gz
Size 190.5 kB
Tags Source
SHA-256 checksum
How to use checksums
d0c1b3f3da0b5c436c66b08111cce964212ed9f00a8f3b21a595e7f6a436524f
BLAKE2b-256 checksum
How to use checksums
4c14ecd72cddbcf1beea91d7210e70f9f9e361736ce9d85969f568686e18762f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / spaday_dagre-0.2.2-py3-none-any.whl

Download URL spaday_dagre-0.2.2-py3-none-any.whl
Size 136.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8dcb675a280634b8e365581cc9979ccc1e0ee40607a82d86e3997f2a0cb4ffc2
BLAKE2b-256 checksum
How to use checksums
0b97bbecd89e37b615f25c79f77c416b79110dc2218c87a34d06bb75c7c7bb59
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release history Release notifications | RSS feed

0.3.0

2 release files

0.2.4

2 release files

0.2.3

2 release files

This release

0.2.2 This release

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page