First graph
The four constructs of a node-editor canvas: node_editor (the canvas),
node (a box), pin (a connection point), and link (an edge). The
model is id-only — nodes, pins, and links are integer ids you choose; the
editor tracks geometry and interaction, you own what the ids mean.
g_ed = create_node_editor() // owns pan / zoom / selection
node_editor("graph", (editor = g_ed)) {
node(1) {
text("Input")
pin(11, PinKind.Output) { text("value ->") }
}
node(2) {
text("Output")
pin(21, PinKind.Input) { text("-> value") }
}
link(100, 11, 21) // output pin 11 -> input pin 21
}
Source: examples/tutorial/first_graph.das.
Walkthrough
The recording is voiced and self-verifying: it tours each construct in turn and
asserts every one rendered, then closes by pulsing the link with flow() to
watch data travel from output pin 11 to input pin 21.
1options gen2
2options _comment_hygiene = true
3
4require imgui/imgui_harness
5require imgui/imgui_node_editor_boost_v2
6require imgui/imgui_node_editor_live
7
8// =============================================================================
9// TUTORIAL: first_graph — the four constructs of a node-editor canvas.
10//
11// create_node_editor() -- an EditorContext owns the canvas state
12// (pan / zoom / selection). Destroy it at
13// shutdown.
14// node_editor("name", (editor=)) -- the canvas container; everything inside
15// is drawn in canvas space.
16// node(id) { ... } -- a box. Its body is plain ImGui widgets.
17// pin(id, PinKind.Output/Input) -- a connection point on a node.
18// link(id, from_pin, to_pin) -- an edge joining an output pin to an input.
19//
20// The model is ID-ONLY: nodes, pins and links are just integer ids you choose.
21// The editor tracks geometry and interaction; YOU own what the ids mean. This
22// graph is static — see connect_by_drag for making links with the mouse.
23//
24// STANDALONE: daslang.exe modules/dasImguiNodeEditor/examples/tutorial/first_graph.das
25// LIVE: daslang-live modules/dasImguiNodeEditor/examples/tutorial/first_graph.das
26// =============================================================================
27
28var g_ed : imgui_node_editor::EditorContext? = null
29var g_seeded : bool = false
30
31[export]
32def init() {
33 harness_init("First graph", 1000, 600)
34 g_ed = create_node_editor()
35}
36
37def draw_editor() {
38 node_editor("graph", (editor = g_ed)) {
39 // Lay the two nodes out once; after this the user (or the editor) owns
40 // their positions.
41 if (!g_seeded) {
42 imgui_node_editor::SetNodePosition(1, float2(120.0, 180.0))
43 imgui_node_editor::SetNodePosition(2, float2(560.0, 180.0))
44 g_seeded = true
45 }
46 node(1) {
47 text("Input")
48 pin(11, PinKind.Output) {
49 text("value ->")
50 }
51 }
52 node(2) {
53 text("Output")
54 pin(21, PinKind.Input) {
55 text("-> value")
56 }
57 }
58 // One edge: node 1's output pin (11) feeds node 2's input pin (21).
59 link(100, 11, 21)
60 }
61}
62
63[export]
64def update() {
65 if (!harness_begin_frame()) return
66 harness_new_frame()
67 let io & = unsafe(GetIO())
68 SetNextWindowPos(float2(0.0, 0.0), ImGuiCond.Always)
69 SetNextWindowSize(io.DisplaySize, ImGuiCond.Always)
70 let flags = (ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoResize |
71 ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoScrollbar |
72 ImGuiWindowFlags.NoScrollWithMouse | ImGuiWindowFlags.NoSavedSettings |
73 ImGuiWindowFlags.NoBringToFrontOnFocus)
74 window(MAIN_WIN, (text = "First graph", closable = false, flags = flags)) {
75 draw_editor()
76 }
77 harness_end_frame()
78}
79
80[export]
81def shutdown() {
82 destroy_node_editor(g_ed)
83 harness_shutdown()
84}
85
86[export]
87def main() {
88 init()
89 while (!exit_requested()) {
90 update()
91 }
92 shutdown()
93}
EditorContext
create_node_editor() returns an EditorContext? that holds the canvas
state — pan, zoom, selection, and node positions. Create it once in init
and destroy_node_editor it at shutdown. Everything drawn inside
node_editor(...) is positioned in canvas space.
Nodes and pins
node(id) { ... } draws a box; its body is plain ImGui (here a single
text label). pin(id, PinKind.Output|Input) { ... } adds a connection
point, its body being the pin’s label. SetNodePosition seeds a node’s
canvas position once; after that the editor — and the user — own it.
Links
link(id, from_pin, to_pin) draws an edge from an output pin to an input
pin. This graph hard-codes the one link; Connecting by drag
makes links with the mouse.
flow(ctx, link_id) fires a one-shot data-flow pulse along a link — a marker
that travels the edge and fades over style.FlowDuration. The walkthrough
re-pulses it so the link visibly carries data; from a live host it is the
flow command (ne_flow in the playwright helpers).