You will build: an order-approval flowchart, generate C# from it, and step through it with the simulator. Time: about 20 minutes. Prerequisites: a project that references Beep.Skia and Beep.Skia.FlowChart (see Installation).

1. Create the canvas

Everything hangs off a DrawingManager. When you are ready to show it, attach a host control (see the WinForms controls page); for now render to a surface.

using Beep.Skia;
using Beep.Skia.Flowchart;
using SkiaSharp;

var manager = new DrawingManager
{
    ShowGrid = true,
    GridSpacing = 20,
    SnapToGrid = true
};

2. Add the nodes

Flowchart nodes derive from FlowchartControl. Use StartEndNode for terminals, ProcessNode for steps and DecisionNode for branches; every component exposes X, Y, Width and Height.

var start = new StartEndNode { Label = "Order received", X = 340, Y = 40, Width = 160, Height = 48 };
var validate = new ProcessNode { Label = "Validate order", X = 340, Y = 140, Width = 160, Height = 60 };
var decision = new DecisionNode { Label = "Valid?", X = 350, Y = 250, Width = 140, Height = 80 };
var approve = new ProcessNode { Label = "Approve", X = 340, Y = 380, Width = 160, Height = 60 };
var reject = new ProcessNode
{
    Label = "Reject",
    X = 560, Y = 260, Width = 140, Height = 60,
    CustomFillColor = new SKColor(0xFF, 0xEB, 0xEE),
    CustomStrokeColor = new SKColor(0xC6, 0x28, 0x28)
};
var end = new StartEndNode { Label = "Done", X = 340, Y = 480, Width = 160, Height = 48 };

foreach (var node in new SkiaComponent[] { start, validate, decision, approve, reject, end })
    manager.AddComponent(node);

3. Connect and label the flow

ConnectComponents creates the line with automatic port assignment; enumerate GetLines() to style it.

manager.ConnectComponents(start, validate);
manager.ConnectComponents(validate, decision);
manager.ConnectComponents(decision, approve);
manager.ConnectComponents(approve, end);
manager.ConnectComponents(decision, reject);

foreach (var line in manager.GetLines())
{
    line.RoutingMode = LineRoutingMode.Orthogonal;
    line.Paint.StrokeWidth = 2;
    line.ShowEndArrow = true;
}

var yes = manager.GetLines().First(l => l.Start.Component == decision && l.End.Component == approve);
yes.Label1 = "Yes";
var no = manager.GetLines().First(l => l.Start.Component == decision && l.End.Component == reject);
no.Label1 = "No";
no.LineColor = SKColors.Firebrick;

4. Generate code

The generator walks the graph from the start node and emits nested constructs for loops and decisions. Pseudocode is the default; C# and Python are also supported.

var generator = new FlowchartCodeGenerator();
string csharp = generator.Generate(manager, CodeLanguage.CSharp);
Console.WriteLine(csharp);

Expect a structure like ValidateOrder(); if (Valid) { Approve(); } else { Reject(); } derived from the node labels and the graph shape.

5. Simulate the flow

The simulator runs the same graph step by step. BranchSelector decides which outgoing edge to take at a decision node; return null to stop.

var simulator = new FlowchartSimulator();
simulator.Reset(manager.GetComponents().ToList(), manager.GetLines());

simulator.BranchSelector = (node, edges) =>
    node is DecisionNode && node.Label == "Valid?"
        ? edges.FirstOrDefault(e => e.Line?.Label1 == "Yes")
        : edges.FirstOrDefault();

simulator.Run(maxSteps: 200);

Console.WriteLine($"finished={simulator.IsFinished}, steps={simulator.StepCount}");
Console.WriteLine(string.Join(" -> ", simulator.Trace));

The trace shows the visited nodes in order, which is exactly what a test would assert on.

6. Save the diagram

The same DTO round-trip used everywhere else:

var json = System.Text.Json.JsonSerializer.Serialize(manager.ToDto());
File.WriteAllText("approval-flow.json", json);

Next steps