Expand description
§iced_nodegraph
A high-performance node graph editor widget for the Iced GUI framework, featuring SDF-based rendering and type-safe coordinate transformations.
§Features
- Nodes - Draggable containers for your custom widgets
- Pins - Connection points on nodes with type checking and visual feedback
- Edges - Connect pins to build data flow graphs with type-safe
PinReference - Interactive Connections - Drag to connect, click edges to re-route (cable-like unplugging)
- Selection - Multi-select with box selection, clone (Ctrl+D), delete (Delete key)
- Zoom & Pan - Smooth infinite canvas navigation with
Camera2D - GPU Rendering - High-performance visualization with custom WGPU shaders
- Smooth Animations - Monitor-synchronized pin pulsing and transitions
- Theme Support - Integrates with Iced’s theming system
§Quick Start
use iced_nodegraph::{NodeGraph, PinRef, node_graph};
use iced::{Element, Theme, Point};
use iced::widget::text;
use iced_wgpu::Renderer;
#[derive(Debug, Clone)]
enum Message {
EdgeConnected { from: PinRef<usize, usize>, to: PinRef<usize, usize> },
NodeMoved { node_id: usize, position: Point },
}
fn view(edges: &[(PinRef<usize, usize>, PinRef<usize, usize>)]) -> Element<'_, Message, Theme, Renderer> {
let mut ng = node_graph()
.on_connect(|from, to| Message::EdgeConnected { from, to })
.on_move(|node_id, position| Message::NodeMoved { node_id, position });
// Add nodes with IDs
ng.push_node(0, Point::new(100.0, 100.0), text("Node A"));
ng.push_node(1, Point::new(300.0, 100.0), text("Node B"));
// Add edges using type-safe PinRef
for (from, to) in edges {
ng.push_edge(*from, *to);
}
ng.into()
}§Core Types
§PinReference
Type-safe identifier for pin connections:
use iced_nodegraph::PinReference;
let pin = PinReference::new(0, 1); // node 0, pin 1
assert_eq!(pin.node_id, 0);
assert_eq!(pin.pin_id, 1);§NodeGraphEvent
Unified event enum for all graph interactions:
EdgeConnected/EdgeDisconnected- Connection changesNodeMoved/GroupMoved- Position changesSelectionChanged- Selection updatesCloneRequested/DeleteRequested- Edit operations
§Camera2D
Programmatic access to zoom and pan state.
§Demonstration Projects
§hello_world
Basic node graph with command palette:
- Node creation and positioning
- Pin connections with type colors
- Camera controls (pan/zoom)
- Theme switching with live preview
- Email processing workflow example
cargo run -p demo_hello_world§styling
Visual customization showcase:
- Custom node styles (colors, borders, opacity)
- Live style controls with sliders
- Preset styles (Input, Process, Output, Comment)
- Theme switching
cargo run -p demo_styling§500_nodes
Performance benchmark with 500+ nodes:
- Procedural shader graph generation
- Stress tests GPU rendering pipeline
- Multiple node types and connection patterns
cargo run -p demo_500_nodes§shader_editor
Visual WGSL shader editor:
- Math, Vector, Color, Texture nodes
- Real-time shader compilation
- Command palette for node spawning
cargo run -p demo_shader_editor§Platform Support
§Native (Windows, macOS, Linux)
Full WGPU with custom shaders for high-performance rendering.
§WebAssembly (Browser)
WebGPU acceleration with fallback to WebGL where needed.
§Architecture
§Coordinate System
The widget uses two distinct coordinate spaces with compile-time type safety via the
euclid crate:
- Screen Space - Pixel coordinates from user input (mouse, viewport)
- World Space - Virtual infinite canvas where nodes exist
Transformations use mathematically consistent formulas:
- Screen -> World:
world = screen / zoom - position - World -> Screen:
screen = (world + position) * zoom - Zoom at Cursor:
new_pos = old_pos + cursor_screen * (1/new_zoom - 1/old_zoom)
See Camera2D for implementation details and comprehensive test coverage.
§Custom Rendering
Uses WGPU shaders for high-performance rendering:
- Background/Foreground layers for proper rendering order
- GPU-accelerated with custom vertex/fragment shaders
- Cross-platform support (native WGPU + WebGPU)
§Interaction
| Action | Input |
|---|---|
| Pan canvas | Middle mouse drag |
| Zoom | Mouse wheel (maintains cursor position) |
| Connect pins | Left-click source pin, drag to target |
| Re-route edge | Click on edge endpoint to unplug |
| Move node | Left-click and drag node |
| Box select | Left-click on empty space, drag |
| Clone selection | Ctrl+D |
| Delete selection | Delete key |
| Add to selection | Shift+click |
§Plug Behavior
Edge connections behave like physical plugs:
- Snap: When dragging an edge close to a compatible pin, it “snaps” and
EdgeConnectedfires immediately (not on mouse release) - Unsnap: Moving away from the snapped pin fires
EdgeDisconnected - Release: Releasing the mouse while snapped keeps the connection; releasing while not snapped discards the drag
§State Query Methods
let graph: NodeGraph = ...;
// Query graph state
let count = graph.node_count();
let edges = graph.edge_count();
let pos = graph.node_position(0); // Option<Point>
// Iterate edges
for (from, to, style) in graph.edges() {
println!("Edge: {:?} -> {:?}", from, to);
}Re-exports§
pub use content::NodeContentStyle;pub use content::node_header;pub use content::simple_node;pub use helpers::CloneResult;pub use helpers::DeleteResult;pub use helpers::NodeHandle;pub use helpers::PinHandle;pub use helpers::SelectionHelper;pub use helpers::clone_nodes;pub use helpers::delete_nodes;pub use ids::EdgeId;pub use ids::IdMap;pub use ids::IdMaps;pub use ids::NodeId;pub use ids::PinId;pub use style::EdgeConfig;pub use style::EdgeCurve;pub use style::EdgeStyle;pub use style::EdgeStyleFn;pub use style::EdgeBorder;pub use style::EdgeShadow;pub use style::GraphConfig;pub use style::GraphStyle;pub use style::NodeBorder;pub use style::NodeConfig;pub use style::NodeShadow;pub use style::NodeStyle;pub use style::NodeStyleFn;pub use style::PinConfig;pub use style::PinShape;pub use style::PinStatus;pub use style::PinStyle;pub use style::PinStyleFn;pub use style::STANDARD_THEMES;pub use style::EdgeStatus;pub use style::NodeStatus;pub use style::SelectionConfig;pub use style::SelectionStyle;pub use style::ShadowConfig;pub use style::is_dark_theme;pub use style::relative_luminance;pub use style::theme_name;pub use iced;
Modules§
- content
- Node content styling helpers.
- helpers
- Helper utilities for common node graph operations.
- ids
- Generic ID types for user-defined node, pin, and edge identification.
- prelude
- Convenience re-exports for common usage.
- style
- Style definitions for NodeGraph visual customization.
Macros§
- pin
- Macro for creating pins with concise syntax.
Structs§
- Camera2D
- Node
Graph - Node graph widget with generic ID types.
- NodePin
- A transparent wrapper used as a marker within
NodeGraph. - Pattern
- Pattern configuration for SDF rendering.
- PinRef
- Generic pin reference with user-defined ID types.
- PinReference
- A reference to a specific pin on a specific node.
- SdfDebug
- Per-layer SDF tile debug toggles.
Enums§
- Node
Graph Event - Events emitted by the NodeGraph widget.
- Node
Graph Message - Generic message enum for graph interactions with user-defined ID types.
- PinDirection
- Direction of data flow for a pin.
- PinSide
- Which side of a node this pin attaches to. Determines the tangent direction for edge bezier curves.
- SdfPattern
Type - Pattern type for stroke rendering.
Functions§
- node_
graph - Creates a new NodeGraph with default usize-based IDs.
- node_
pin