iced_nodegraph 0.4.0

High-performance node graph editor widget for Iced with SDF-based rendering
Documentation

Nodes are ordinary iced widgets - sliders, text inputs, whatever your view builds - placed on an infinite zoom/pan canvas and wired together through typed pins. The widget holds no graph state: your application owns the data model, and connections, moves, and deletes arrive as messages, like any other iced widget. Everything on the canvas is drawn by a single WGPU pipeline as signed distance fields, so it stays sharp at every zoom level and handles graphs with hundreds of nodes.

Getting started

cargo add iced_nodegraph
cargo add iced --features wgpu
use iced_nodegraph::prelude::*;
use iced_nodegraph::{edge, node};
use iced::{Element, Point};

fn view(&self) -> Element<Message> {
    let mut ng = node_graph()
        .on_connect(|from, to| Message::Connected(from, to))
        .on_move(|delta, node_ids| Message::Moved(delta, node_ids));

    // A node is an id, a position, and any iced widget as content.
    ng.push_node(node(0, Point::new(200.0, 150.0), my_node_widget()));
    ng.push_node(node(1, Point::new(525.0, 175.0), another_node()));

    // An edge connects two pins, addressed as (node id, pin id).
    ng.push_edge(edge!(PinRef::new(0, 0), PinRef::new(1, 0)));

    ng.into()
}

node(..) and edge!(..) are builders: chain .style(..) for per-node and per-edge looks, starting from presets like NodeStyle::input() or EdgeStyle::error(). The crate docs cover styling, connection validation, and the callback contract in detail.

Demos

Every demo runs natively and in the browser.

Demo Live Shows
hello_world run Command palette, theme switching, selection, clone/delete, persistence
styling run Style presets and live node styling controls
interaction run Pin direction and type rules, connection validation, snap feedback
500_nodes run 500 nodes / 640 edges stress test with a runtime stats overlay
shader_editor run Visual WGSL editor: the graph compiles to a running shader
cargo run -p demo_hello_world             # also: demo_styling, demo_interaction, demo_shader_editor
cargo run --release -p demo_500_nodes

Controls

Action Mouse / Keyboard Touch
Pan Right mouse drag One-finger drag on empty canvas, or two-finger drag
Zoom Scroll wheel (zooms at cursor) Two-finger pinch
Connect Drag from pin to pin Drag from pin to pin
Disconnect Click a connected pin to unplug Tap a connected pin to unplug
Fork edge Shift+drag from a connected pin -
Move node Drag node Drag node
Box select Left drag on empty canvas - (empty-canvas drag pans)
Add to selection Shift+click -
Select all Ctrl+A -
Clone selection Ctrl+D (web: Alt+D) -
Delete selection Delete / Backspace (web: Delete) -
Cut edges Ctrl+click an edge, or Ctrl+drag across edges -

Ctrl is Cmd on macOS. On the web, clone avoids Ctrl/Cmd+D (the browser's bookmark shortcut) and delete drops the Backspace alternative (legacy back-navigation). Every binding is host-rebindable through NodeGraph::keymap - see the Keymap type. Connections snap while dragging near a compatible pin - like plugging in a cable - rather than on mouse release, and compatible targets pulse during the drag.

How it works

Your app owns the graph. The widget is stateless between frames: it renders the nodes and edges you pass in and reports intent (on_connect, on_move, on_delete, ...) through callbacks. Your update logic applies the change and the next view reflects it - the plain iced loop, no hidden state to sync.

One GPU pipeline. Node bodies, edges, pins, shadows, and the background grid are compiled into a single signed-distance-field scene and rendered by the in-tree iced_nodegraph_sdf crate. A compute-shader tile index culls per pixel, and animated stroke patterns drive their own redraws. Details in ARCHITECTURE.md.

Typed coordinates. Screen space and world space are distinct euclid types, so mixing them up is a compile error.

Compatibility

  • Targets iced 0.14 with the wgpu renderer (the SDF pipeline has no tiny-skia fallback).
  • Native: Windows, macOS, Linux. Web: WebAssembly on WebGPU-capable browsers - there is no WebGL fallback, so Chrome/Chromium is recommended.
  • Pre-1.0: minor releases may change the API. See the CHANGELOG.

Development

The workspace contains the widget (iced_nodegraph), the SDF renderer (iced_nodegraph_sdf), and the demos.

cargo test --workspace
cargo clippy --workspace -- -D warnings
cargo bench -p iced_nodegraph      # CPU frame-prep cost at 100/500/2000 nodes
./build_docs.sh                    # rustdoc + all demos as WASM (needs wasm-pack)

License

MIT