FlowGraph
Core graph management class. Handles nodes, edges, execution, and serialization.
Overview
FlowGraph is the central class that manages your node graph. It maintains collections of nodes and edges, handles connections, and orchestrates graph execution.
Properties
| Property | Type | Description |
|---|---|---|
| NodeRegistry | FlowNodeRegistry | Registry for node types |
| CommandManager | CommandManager | Undo/redo command manager |
| TypeCompatibiltyRegistry | TypeCompatibiltyRegistry | Type compatibility rules |
| Nodes | IReadOnlyList | All nodes in the graph |
| Edges | IReadOnlyList | All edges in the graph |
| Canvas | FlowCanvas | Associated canvas component |
| ExecutionFlow | FlowGraphExecution | Execution handler |
Node Management
RegisterNode
Registers a node type for use in the graph.
Signature: void RegisterNode<T>() where T : FlowNodeBase
graph.RegisterNode<InputNode>();
graph.RegisterNode<SumNode>();
graph.RegisterNode<OutputNode>();
CreateNodeAsync
Creates a new node at the specified position.
Signatures:
ValueTask<NodeInfo> CreateNodeAsync<T>(double x, double y, Dictionary<string, object?> data)ValueTask<NodeInfo> CreateNodeAsync(Type type, double x, double y, Dictionary<string, object?> data)ValueTask<NodeInfo> CreateNodeAsync(string typeName, double x, double y, Dictionary<string, object?> data)
// Generic type
var node = await graph.CreateNodeAsync<SumNode>(100, 100, []);
// With custom data
var nodeWithData = await graph.CreateNodeAsync<InputNode>(200, 100, new()
{
["Value"] = 42
});
// By Type
var nodeByType = await graph.CreateNodeAsync(typeof(SumNode), 300, 100, []);
RemoveNodeAsync
Removes a node and all connected edges.
Signature: ValueTask RemoveNodeAsync(string id)
await graph.RemoveNodeAsync("node-id-123");
RemoveAllNodes
Clears all nodes from the graph.
Signature: void RemoveAllNodes()
graph.RemoveAllNodes();
GetNodeById
Gets a node by its ID.
Signature: FlowNodeBase? GetNodeById(string id)
var node = graph.GetNodeById("node-id-123");
if (node != null)
{
Console.WriteLine($"Node at ({node.X}, {node.Y})");
}
GetNodeInfoById
Gets node info (including unrendered nodes).
Signature: NodeInfo? GetNodeInfoById(string id)
var nodeInfo = graph.GetNodeInfoById("node-id-123");
Edge Management
ConnectAsync
Creates a connection between sockets.
Signatures:
ValueTask<(EdgeInfo? Edge, string? Error)> ConnectAsync(FlowSocket from, FlowSocket to, bool checkDataType = true)ValueTask<(EdgeInfo? Edge, string? Error)> ConnectAsync(string fromNodeId, string toNodeId, string fromSocketName, string toSocketName, bool checkDataType = true)
// Connect by node IDs and socket names
var (edge, error) = await graph.ConnectAsync(
"node1-id",
"node2-id",
"Output",
"Input"
);
if (error != null)
{
Console.WriteLine($"Connection failed: {error}");
}
// Connect by socket references
var fromSocket = node1.GetSocketByName("Output", SocketType.Output);
var toSocket = node2.GetSocketByName("Input", SocketType.Input);
await graph.ConnectAsync(fromSocket!, toSocket!);
RemoveEdgeAsync
Removes an edge.
Signature: ValueTask RemoveEdgeAsync(string id)
await graph.RemoveEdgeAsync("edge-id-123");
RemoveAllEdges
Clears all edges from the graph.
Signature: void RemoveAllEdges()
graph.RemoveAllEdges();
GetEdgeById
Gets an edge by its ID.
Signature: FlowEdge? GetEdgeById(string id)
var edge = graph.GetEdgeById("edge-id-123");
Selection Management
SelectNodesAsync
Selects nodes in the canvas.
Signature: ValueTask SelectNodesAsync(params string[] nodeIds)
await graph.SelectNodesAsync("node1", "node2", "node3");
ClearNodeSelectionAsync
Clears the node selection.
Signature: ValueTask ClearNodeSelectionAsync()
await graph.ClearNodeSelectionAsync();
GetSelectedNodesAsync
Gets IDs of selected nodes.
Signature: ValueTask<string[]> GetSelectedNodesAsync()
var selectedIds = await graph.GetSelectedNodesAsync();
Console.WriteLine($"Selected: {string.Join(", ", selectedIds)}");
Execution
ExecuteAsync
Executes the entire graph.
Signature: ValueTask ExecuteAsync(bool branchTracking = true, CancellationToken cancellationToken = default)
// Simple execution
await graph.ExecuteAsync();
// With cancellation
var cts = new CancellationTokenSource();
await graph.ExecuteAsync(true, cts.Token);
// Without branch tracking (execute all nodes)
await graph.ExecuteAsync(branchTracking: false);
Serialization
SerializeAsync
Serializes the graph to JSON.
Signature: ValueTask<string> SerializeAsync()
string json = await graph.SerializeAsync();
await File.WriteAllTextAsync("graph.json", json);
DeserializeAsync
Deserializes a graph from JSON.
Signatures:
ValueTask DeserializeAsync(string data)ValueTask DeserializeAsync(GraphData graphData)
// From JSON string
string json = await File.ReadAllTextAsync("graph.json");
await graph.DeserializeAsync(json);
// From GraphData object
GraphData data = GetGraphData();
await graph.DeserializeAsync(data);
GetSerializableObjectAsync
Gets serializable graph data.
Signature: async ValueTask<GraphData> GetSerializableObjectAsync()
var data = await graph.GetSerializableObjectAsync();
Console.WriteLine($"Graph has {data.Nodes.Count} nodes");
ClearAsync
Clears the entire graph including nodes, edges, and resets canvas.
Signature: ValueTask ClearAsync()
await graph.ClearAsync();
Events
NodeAdded
Fired when a node is added.
Type: EventHandler<NodeAddedEventArgs>
graph.NodeAdded += (sender, e) =>
{
Console.WriteLine($"Node added: {e.NodeId} at ({e.X}, {e.Y})");
};
NodeRemoved
Fired when a node is removed.
Type: EventHandler<NodeRemovedEventArgs>
graph.NodeRemoved += (sender, e) =>
{
Console.WriteLine($"Node removed: {e.NodeId}");
};
EdgeAdded
Fired when an edge is added.
Type: EventHandler<EdgeAddedEventArgs>
graph.EdgeAdded += (sender, e) =>
{
Console.WriteLine($"Edge: {e.FromNodeId}.{e.FromSocketName} → {e.ToNodeId}.{e.ToSocketName}");
};
EdgeRemoved
Fired when an edge is removed.
Type: EventHandler<EdgeRemovedEventArgs>
graph.EdgeRemoved += (sender, e) =>
{
Console.WriteLine($"Edge removed: {e.EdgeId}");
};
AllNodesCleared
Fired when all nodes are cleared.
Type: EventHandler<EventArgs>
graph.AllNodesCleared += (sender, e) =>
{
Console.WriteLine("All nodes cleared");
};
AllEdgesCleared
Fired when all edges are cleared.
Type: EventHandler<EventArgs>
graph.AllEdgesCleared += (sender, e) =>
{
Console.WriteLine("All edges cleared");
};
ForcedRequestDomStateChanged
Internal event for DOM updates.
Type: EventHandler<EventArgs>
Complete Example
using FlowState.Models;
using FlowState.Models.Events;
// Create graph
var graph = new FlowGraph();
// Register node types
graph.RegisterNode<InputNode>();
graph.RegisterNode<SumNode>();
graph.RegisterNode<OutputNode>();
// Set up type compatibility
graph.TypeCompatibiltyRegistry.Register<float>(typeof(int));
// Subscribe to events
graph.NodeAdded += (s, e) => Console.WriteLine($"Node added: {e.NodeId}");
graph.EdgeAdded += (s, e) => Console.WriteLine($"Edge added: {e.EdgeId}");
// Create nodes
var input1 = await graph.CreateNodeAsync<InputNode>(50, 100, []);
var input2 = await graph.CreateNodeAsync<InputNode>(50, 200, []);
var sum = await graph.CreateNodeAsync<SumNode>(300, 150, []);
var output = await graph.CreateNodeAsync<OutputNode>(550, 150, []);
// Connect nodes
await graph.ConnectAsync(input1.Id, sum.Id, "Output", "A");
await graph.ConnectAsync(input2.Id, sum.Id, "Output", "B");
await graph.ConnectAsync(sum.Id, output.Id, "Result", "Input");
// Execute
await graph.ExecuteAsync();
// Save
string json = await graph.SerializeAsync();
await File.WriteAllTextAsync("my-graph.json", json);
// Load
string loadedJson = await File.ReadAllTextAsync("my-graph.json");
await graph.ClearAsync();
await graph.DeserializeAsync(loadedJson);
// Undo/Redo
await graph.CommandManager.UndoAsync();
await graph.CommandManager.RedoAsync();
See Also
- FlowCanvas - Canvas component
- FlowExecutionContext - Execution context
- CommandManager - Undo/redo system
- Serialization - Save/load details