FlowCanvas
The main canvas component for rendering and managing flow graphs. This is the primary container for your node editor.
Overview
FlowCanvas provides the interactive surface where nodes are displayed, connected, and manipulated. It handles panning, zooming, node selection, and all user interactions with the graph.
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| Graph | FlowGraph | required | The graph instance to display |
| BackgroundContent | RenderFragment | required | Background/grid content |
| Panels | RenderFragment | null | Overlay UI panels (zoom controls, etc.) |
| Height | string | “100%” | Canvas height (CSS value) |
| Width | string | “100%” | Canvas width (CSS value) |
| Style | string | ”” | Custom inline CSS styles |
| GridStyle | string | ”” | Background grid inline CSS |
| Class | string | “flow-canvas” | CSS class for canvas element |
| SelectionRectangleClass | string | “flow-selection-rectangle” | CSS class for rectangle selection |
| NodeSelectionClass | string | “selected” | CSS class applied to selected nodes |
| ExecutingEdgeClass | string | “edge-executing” | CSS class for edges during execution |
| IsReadOnly | bool | false | Read-only mode (pan/zoom only, no editing) |
| Zoom | double | 1.0 | Initial zoom level |
| MinZoom | double | 0.2 | Minimum zoom level |
| MaxZoom | double | 2.0 | Maximum zoom level |
| PanKey | string | “alt” | Modifier key for panning: “shift”, “ctrl”, “alt”, “meta” |
| AutoUpdateSocketColors | bool | true | Automatically update socket colors based on connections |
| EdgeShouldMatchDataType | bool | true | Validate type compatibility when connecting sockets |
| JsEdgePathFunctionName | string | null | Custom JavaScript function name for edge rendering |
Methods
SetZoomAsync
Sets the canvas zoom level.
Signature: ValueTask SetZoomAsync(double zoom)
await canvas.SetZoomAsync(1.5); // 150% zoom
SetOffsetAsync
Sets the canvas pan offset.
Signature: ValueTask SetOffsetAsync(double offsetX, double offsetY)
await canvas.SetOffsetAsync(100, 50);
SetReadOnlyAsync
Enables or disables read-only mode.
Signature: ValueTask SetReadOnlyAsync(bool isReadOnly)
await canvas.SetReadOnlyAsync(true); // Lock canvas
SetCanvasModeAsync
Sets the canvas interaction mode.
Signature: ValueTask SetCanvasModeAsync(CanvasMode mode)
// CanvasMode.Select - Click to select nodes, Alt+drag to pan
await canvas.SetCanvasModeAsync(CanvasMode.Select);
// CanvasMode.Pan - Always pan mode
await canvas.SetCanvasModeAsync(CanvasMode.Pan);
GetViewportPropertiesAsync
Gets the current viewport state.
Signature: ValueTask<CanvasProperties> GetViewportPropertiesAsync()
var props = await canvas.GetViewportPropertiesAsync();
Console.WriteLine($"Zoom: {props.Zoom}, Offset: ({props.OffsetX}, {props.OffsetY})");
SetViewportPropertiesAsync
Sets viewport properties (zoom, offset, etc.).
Signature: ValueTask SetViewportPropertiesAsync(CanvasProperties props)
await canvas.SetViewportPropertiesAsync(new CanvasProperties
{
Zoom = 1.0,
OffsetX = 0,
OffsetY = 0,
MinZoom = 0.2,
MaxZoom = 2.0,
IsReadOnly = false
});
ClearAsync
Clears all nodes and edges, resets viewport.
Signature: ValueTask ClearAsync()
await canvas.ClearAsync();
SelectNodesAsync
Selects nodes by their IDs.
Signature: ValueTask SelectNodesAsync(params string[] nodeIds)
await canvas.SelectNodesAsync("node1", "node2", "node3");
ClearNodeSelectionAsync
Clears the current node selection.
Signature: ValueTask ClearNodeSelectionAsync()
await canvas.ClearNodeSelectionAsync();
GetSelectedNodesAsync
Gets IDs of currently selected nodes.
Signature: ValueTask<string[]> GetSelectedNodesAsync()
var selectedIds = await canvas.GetSelectedNodesAsync();
Refresh
Triggers a component re-render.
Signature: void Refresh()
canvas.Refresh();
Events
OnCanvasLoaded
Fired when the canvas finishes loading.
Type: EventCallback<CanvasLoadedEventArgs>
<FlowCanvas OnCanvasLoaded="HandleLoaded" ...>
@code {
void HandleLoaded(CanvasLoadedEventArgs e)
{
Console.WriteLine($"Canvas loaded with zoom: {e.Zoom}");
}
}
OnPanned
Fired when the canvas is panned.
Type: EventCallback<PanEventArgs>
void HandlePanned(PanEventArgs e)
{
Console.WriteLine($"Panned to: ({e.OffsetX}, {e.OffsetY})");
}
OnZoomed
Fired when the zoom level changes.
Type: EventCallback<ZoomEventArgs>
void HandleZoomed(ZoomEventArgs e)
{
Console.WriteLine($"Zoomed to: {e.Zoom}");
}
OnNodeMoved
Fired when a node is moved.
Type: EventCallback<NodeMovedArgs>
void HandleNodeMoved(NodeMovedArgs e)
{
Console.WriteLine($"Node {e.NodeId} moved to ({e.X}, {e.Y})");
}
OnNodeSelected
Fired when a node is selected.
Type: EventCallback<NodeSelectedEventArgs>
void HandleNodeSelected(NodeSelectedEventArgs e)
{
Console.WriteLine($"Node selected: {e.NodeId}");
}
OnNodeDeselected
Fired when a node is deselected.
Type: EventCallback<NodeDeselectedEventArgs>
void HandleNodeDeselected(NodeDeselectedEventArgs e)
{
Console.WriteLine($"Node deselected: {e.NodeId}");
}
OnSelectionChanged
Fired when the selection changes (multiple nodes).
Type: EventCallback<SelectionChangedEventArgs>
void HandleSelectionChanged(SelectionChangedEventArgs e)
{
Console.WriteLine($"Selected {e.SelectedNodeIds.Length} nodes");
}
OnNotifyNodesCleared
Fired when all nodes are cleared from the canvas.
Type: EventCallback<NodesClearedEventArgs>
void HandleNodesCleared(NodesClearedEventArgs e)
{
Console.WriteLine($"Cleared {e.ClearedCount} nodes");
}
OnEdgeConnectRequest
Fired when an edge connection is requested. Can be handled to customize connection logic.
Type: EventCallback<ConnectRequestArgs>
async Task HandleConnectRequest(ConnectRequestArgs e)
{
// Custom validation
if (ShouldAllowConnection(e.FromSocket, e.ToSocket))
{
// Let it proceed (don't set Handled)
}
else
{
e.Handled = true; // Block the connection
}
}
OnSocketLongPress
Fired when a socket is long-pressed (held for 1 second).
Type: EventCallback<SocketLongPressEventArgs>
void HandleSocketLongPress(SocketLongPressEventArgs e)
{
Console.WriteLine($"Long press on socket: {e.Socket.Name}");
}
OnContextMenu
Fired when the canvas is right-clicked.
Type: EventCallback<CanvasContextMenuEventArgs>
async Task HandleContextMenu(CanvasContextMenuEventArgs e)
{
// Show context menu
await contextMenu.ShowAsync(e.ClientX, e.ClientY, e.X, e.Y);
}
OnKeyDown
Fired when a key is pressed while the canvas has focus.
Type: EventCallback<KeyboardEventArgs>
void HandleKeyDown(KeyboardEventArgs e)
{
if (e.Key == "Escape")
{
// Handle escape key
}
}
Complete Example
@using FlowState.Components
@using FlowState.Models
@using FlowState.Models.Events
<FlowCanvas @ref="canvas"
Graph="graph"
Height="100vh"
Width="100vw"
MinZoom="0.5"
MaxZoom="3.0"
Zoom="1.0"
PanKey="alt"
IsReadOnly="false"
OnCanvasLoaded="OnLoaded"
OnNodeMoved="OnNodeMoved"
OnContextMenu="ShowContextMenu">
<BackgroundContent>
<FlowBackground class="custom-grid"/>
</BackgroundContent>
<Panels>
<FlowPanels>
<button @onclick="ZoomIn">+</button>
<button @onclick="ZoomOut">-</button>
</FlowPanels>
</Panels>
</FlowCanvas>
@code {
FlowCanvas? canvas;
FlowGraph graph = new();
async Task OnLoaded(CanvasLoadedEventArgs e)
{
// Canvas is ready
await graph.CreateNodeAsync<MyNode>(100, 100, []);
}
void OnNodeMoved(NodeMovedArgs e)
{
Console.WriteLine($"Node moved to ({e.X}, {e.Y})");
}
async Task ShowContextMenu(CanvasContextMenuEventArgs e)
{
// Show your context menu
}
async Task ZoomIn()
{
var props = await canvas!.GetViewportPropertiesAsync();
await canvas.SetZoomAsync(Math.Min(props.Zoom + 0.1, props.MaxZoom));
}
async Task ZoomOut()
{
var props = await canvas!.GetViewportPropertiesAsync();
await canvas.SetZoomAsync(Math.Max(props.Zoom - 0.1, props.MinZoom));
}
}
See Also
- FlowBackground - Background customization
- FlowPanels - Overlay UI panels
- FlowGraph - Graph management
- Getting Started - Complete working example