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 view is automatic — fit and centered, re-fitted on every host resize or graph change, so a graph built inside a hidden or not-yet-sized tab, accordion, or drawer fits when it is shown — until the user pans or zooms or a node is focused; a reset, or the fit() method (Invoke(by_id("graph"), "fit")), makes it automatic again.

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.3

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.3
File Size Uploaded
spaday_dagre-0.2.3.tar.gz 191.8 kB Details

Built distribution (wheel)

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

Total release size: 328.4 kB

Release files / spaday_dagre-0.2.3.tar.gz

Download URL spaday_dagre-0.2.3.tar.gz
Size 191.8 kB
Tags Source
SHA-256 checksum
How to use checksums
7436a2bf3158e647fe9e3822cb78d9e510d019c5a28d4205fc9d91cdd01da1e7
BLAKE2b-256 checksum
How to use checksums
01cbc063f47658c0b25a32af755c2f93683e0586300ea262c7783827fe3ec18d
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.3-py3-none-any.whl

Download URL spaday_dagre-0.2.3-py3-none-any.whl
Size 136.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
be8fdf72d3f0f015a9eb951a48744c378f9b9e3ae3e42968c54862b7a8118149
BLAKE2b-256 checksum
How to use checksums
e9f7d7a360819e523f20e9c73cff82fdeeb863b55b4f9791b7d19772f9f4da40
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

This release

0.2.3 This release

2 release files

0.2.2

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