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
 2
 3require imgui/imgui_harness
 4require imgui/imgui_node_editor_boost_v2
 5require imgui/imgui_node_editor_live
 6
 7// =============================================================================
 8// TUTORIAL: first_graph — the four constructs of a node-editor canvas.
 9//
10//   create_node_editor()            -- an EditorContext owns the canvas state
11//                                      (pan / zoom / selection). Destroy it at
12//                                      shutdown.
13//   node_editor("name", (editor=))  -- the canvas container; everything inside
14//                                      is drawn in canvas space.
15//   node(id) { ... }                -- a box. Its body is plain ImGui widgets.
16//   pin(id, PinKind.Output/Input)   -- a connection point on a node.
17//   link(id, from_pin, to_pin)      -- an edge joining an output pin to an input.
18//
19// The model is ID-ONLY: nodes, pins and links are just integer ids you choose.
20// The editor tracks geometry and interaction; YOU own what the ids mean. This
21// graph is static — see connect_by_drag for making links with the mouse.
22//
23// STANDALONE: daslang.exe modules/dasImguiNodeEditor/examples/tutorial/first_graph.das
24// LIVE:       daslang-live modules/dasImguiNodeEditor/examples/tutorial/first_graph.das
25// =============================================================================
26
27var g_ed : imgui_node_editor::EditorContext? = null
28var g_seeded : bool = false
29
30[export]
31def init() {
32    harness_init("First graph", 1000, 600)
33    g_ed = create_node_editor()
34}
35
36def draw_editor() {
37    node_editor("graph", (editor = g_ed)) {
38        // Lay the two nodes out once; after this the user (or the editor) owns
39        // their positions.
40        if (!g_seeded) {
41            imgui_node_editor::SetNodePosition(1, float2(120.0, 180.0))
42            imgui_node_editor::SetNodePosition(2, float2(560.0, 180.0))
43            g_seeded = true
44        }
45        node(1) {
46            text("Input")
47            pin(11, PinKind.Output) {
48                text("value ->")
49            }
50        }
51        node(2) {
52            text("Output")
53            pin(21, PinKind.Input) {
54                text("-> value")
55            }
56        }
57        // One edge: node 1's output pin (11) feeds node 2's input pin (21).
58        link(100, 11, 21)
59    }
60}
61
62[export]
63def update() {
64    if (!harness_begin_frame()) return
65    harness_new_frame()
66    let io & = unsafe(GetIO())
67    SetNextWindowPos(float2(0.0, 0.0), ImGuiCond.Always)
68    SetNextWindowSize(io.DisplaySize, ImGuiCond.Always)
69    let flags = (ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoResize |
70                 ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoScrollbar |
71                 ImGuiWindowFlags.NoScrollWithMouse | ImGuiWindowFlags.NoSavedSettings |
72                 ImGuiWindowFlags.NoBringToFrontOnFocus)
73    window(MAIN_WIN, (text = "First graph", closable = false, flags = flags)) {
74        draw_editor()
75    }
76    harness_end_frame()
77}
78
79[export]
80def shutdown() {
81    destroy_node_editor(g_ed)
82    harness_shutdown()
83}
84
85[export]
86def main() {
87    init()
88    while (!exit_requested()) {
89        update()
90    }
91    shutdown()
92}

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.