egui_graph 0.13.0

A general-purpose node graph widget for egui.
Documentation
# egui_graph

A general-purpose node graph widget for [egui](https://github.com/emilk/egui).

Build interactive node-based editors with nodes connected by edges for visual
programming interfaces, shader editors, DSP graphs, or any graph-based UI.

**Note:** This library is the basis for
[nannou-org/gantz](https://github.com/nannou-org/gantz). For a more
sophisticated example of what can be built with egui_graph, check out
[gantz](https://nannou-org.github.io/gantz).

## Key Design Philosophy

One of the core design decisions of `egui_graph` is to avoid requiring that
users model their graph with any particular data structure. The library provides
immediate-mode widgets for rendering and interacting with graphs, but leaves
the underlying data model up to you. Store your graph however makes sense for
your application - whether that's an adjacency list, entity-component system,
or any other representation.

## Features

- **Interactive Nodes**: Drag, select, and delete nodes with intuitive controls
- **Edge Creation**: Connect nodes via input/output sockets with bezier curve edges
- **Multi-Selection**: Rectangle selection and Ctrl+click for selecting multiple nodes
- **Automatic Layout**: Optional graph layout using the `layout-rs` crate
- **Customizable**: Configure node flow direction, socket/frame appearance, and more
- **Zoom & Pan**: Navigate large graphs with mouse controls
- **Model-Agnostic**: No prescribed graph data structure - use whatever fits your needs

## Quick Start

```rust
use egui_graph::{Graph, View, Node, NodeId, Edge};

// Create a view to store node and "camera" positions.
let mut view = View::default();

// Show the graph widget
Graph::new("my_graph")
    .show(&mut view, ui, |ui, mut show| {
        // Add nodes to the graph
        show.nodes(|nctx, ui| {
            Node::new("node_1")
                .inputs(2)
                .outputs(1)
                .show(nctx, ui, |node_ctx| {
                    node_ctx.framed(|ui| {
                        ui.label("My Node");
                    })
                })
        });

        // Add edges between nodes
        show.edges(|ectx, ui| {
            let selected = false;
            Edge::new(
                (NodeId::new("node_1"), 0),  // From output 0
                (NodeId::new("node_2"), 1),  // To input 1
                &mut selected
            ).show(ectx, ui);
        });
    });
```

Visit the demo.rs example for a more thorough, up-to-date example.

## Core Components

### Graph Widget

The main widget that contains all nodes and edges:

```rust
Graph::new(id_source)
    .background(true)           // Enable background
    .dot_grid(true)             // Show dot grid
    .zoom_range(0.1..=2.0)      // Set zoom limits
    .center_view(true)          // Center the camera
    .show(&mut view, ui, |ui, show| { /* ... */ })
```

### Nodes

Nodes are containers with input/output sockets:

```rust
Node::new(id_source)
    .inputs(3)                  // Number of input sockets
    .outputs(2)                 // Number of output sockets
    .flow(Direction::LeftToRight) // Socket arrangement
    .socket_color(Color32::BLUE)
    .socket_radius(5.0)
    .show(ctx, ui, |node_ctx| {
        // Node content goes here
        node_ctx.framed(|ui| {
            ui.label("Node Content");
        })
    })
```

### Edges

Connect nodes with bezier curve edges:

```rust
Edge::new(
    (source_node_id, output_index),
    (target_node_id, input_index),
    &mut selected
)
.distance_per_point(1.0)  // Curve sampling distance
.show(ctx, ui)
```

### Automatic Layout

With the `layout` feature enabled:

```rust
use egui_graph::layout;

let positions = layout(
    nodes.iter().map(|(id, size)| (*id, size)),
    edges.iter().map(|(from, to)| (*from, *to)),
    Direction::LeftToRight,
);
view.layout = positions;
```

## Controls

### Mouse Controls
- **Left Click**: Select node/edge
- **Ctrl + Left Click**: Toggle selection
- **Shift + Left Click**: Clear selection
- **Left Drag on Background**: Rectangle selection
- **Left Drag on Node**: Move selected nodes
- **Middle Mouse Drag**: Pan view
- **Scroll Wheel**: Zoom in/out

### Keyboard Controls
- **Delete/Backspace**: Remove selected nodes/edges

### Socket Interaction
- **Click Output Socket**: Start edge creation
- **Drag to Input Socket**: Preview connection
- **Release on Input**: Create edge
- **ESC**: Cancel edge creation

## Examples

Run the included demo:

```bash
cargo run --release --example demo
```

The demo showcases:
- Multiple node types (labels, buttons, sliders)
- Dynamic node creation and deletion
- Edge creation between nodes
- Automatic layout
- Configuration options

## Architecture

The library follows egui's immediate-mode paradigm while maintaining necessary
state for graph interactions. Internal state includes:

- Node sizes
- Selection state for nodes and edges
- Active edge creation
- Socket positions for edge rendering

State is stored in egui's data store and accessed through the widget APIs.