Skip to content

GraphView ​

GraphView is the low-level editable UI for NGT graphs.

It contains a header, a pannable canvas, graph elements, the item library, blackboard, inspector, preview panel, history stack, command handling, and diagnostics footer.

TIP

Prefer GraphEditorView for real graph editors. It wraps GraphView and adds save handling, dirty state, breadcrumbs, subgraph dive, and external subgraph editing support.

GraphView with its header, canvas, blackboard, inspector, and graph log
GraphView / GraphEditorView panels with the header toggles, canvas, blackboard, inspector, preview, and graph log.

Direct Loading ​

java
var graphView = new GraphView();
graphView.loadGraph(graph);

This is useful for test screens, previews, or embedded graph displays.

Inside a normal UI:

java
root.addChild(graphView.layout(layout -> {
    layout.widthPercent(100);
    layout.heightPercent(100);
}));

For a full editor view:

java
var editorView = new GraphEditorView();
editorView.loadGraph(graph, savedTag -> saveGraph(savedTag));

Built-in Tools ​

GraphView creates these tools:

ToolFieldDescription
Item LibraryitemLibraryPopup for creating nodes, constants, blocks, and subgraphs.
BlackboardblackboardVariable declarations.
InspectorinspectorSelected model properties.
PreviewpreviewGraph-level preview tool.
Dock ManagerdockManagerFloating and corner-docked graph panels.
HistoryhistoryStackUndo and redo for graph commands.

The default panels are placed around the canvas:

  • Blackboard: top-left.
  • Inspector: top-right.
  • Preview: bottom-right.

Item Library Recommendations ​

Since 2.2.38

Dragging a wire from a port into empty canvas opens the item library with a recommendation list of every node that has a compatible port. Nodes with a port of exactly the wire's type are listed first, then nodes whose ports only accept the type through assignability. Both groups keep the item library's normal order.

Commands and History ​

Most graph edits are commands dispatched through GraphView.dispatchCommand(...).

Commands are recorded in the view history stack when they are undoable. The header provides undo, redo, snap-to-grid, align-to-nearby-elements, and fit buttons. Since 2.2.40, the undo and redo tooltips show the shortcut currently bound in the editor keymap.

GraphView handles common editor actions:

  • create node,
  • create wire,
  • delete,
  • cut/copy/paste,
  • duplicate,
  • move,
  • rename,
  • recolor,
  • create placemat,
  • create subgraph from selection,
  • convert wires to portals,
  • insert a reroute point on a wire,
  • auto layout.

Subgraph dive is handled by GraphEditorView, not by using a bare GraphView alone.

Keyboard Shortcuts ​

ShortcutAction
Ctrl+ASelect every canvas element. The blackboard is not included. Since 2.2.42
Ctrl+C / Ctrl+X / Ctrl+VCopy, cut, and paste the selection.
Ctrl+DDuplicate the selection.
Ctrl+ZUndo.
Ctrl+Y / Ctrl+Shift+ZRedo.
Ctrl+SSave, when the view is inside a GraphEditorView.
DeleteDelete the selection.
Hold Alt while draggingPlace elements exactly at the cursor, without grid or element snapping.
Double-click a wireInsert a reroute point.

Inside the LDLib2 Editor, the Ctrl chords come from the editor keymap and can be rebound. See Keymap. Delete is handled by GraphView itself.

Layers ​

Graph elements are rendered into named layers.

java
graphView.setLayers(List.of(
        PlacematElement.PLACEMAT_LAYER,
        WireElement.WIRE_LAYER,
        NodeElement.NODE_LAYER,
        StickyNoteElement.STICKY_NOTE_LAYER
));

Use getLayer(name) when a custom element needs a specific canvas layer.

View Preferences ​

Since 2.2.41

Snap-to-grid, grid size, element snapping, and wire style are remembered per graph type. They are stored in config/ldlib2/graph_view.json, keyed by the graph's class name, and are not part of the graph file.

WARNING

loadGraph(...) applies the remembered preferences for the graph's type.

  • Setters called before loadGraph(...) are overwritten.
  • Setters called after loadGraph(...) change the user's saved preferences for that graph type.

To set up a view without writing to the preferences file, call applyPreferences(...) after loadGraph(...).

java
graphView.loadGraph(graph);
graphView.applyPreferences(new GraphViewPreferences.Entry(
        true,                    // snap to grid
        16f,                     // grid size
        true,                    // snap to nearby elements
        WireRouteStyle.CURVED));

currentPreferences() returns the view's current setup. GraphViewPreferences.Entry.DEFAULTS is grid snapping on, size 16, element snapping on, and WireRouteStyle.DEFAULT.

Snap and Fit ​

Snap to grid is enabled by default.

java
graphView.setSnapToGrid(true);
graphView.setGridSnapSize(16f);

Use the fit button or call:

java
graphView.fitGraphChildren();

Snapping and Alignment ​

Since 2.2.41

When elements are dragged, the whole selection moves by one offset. Its nearest edge snaps to the grid, and lines up with the edges and centers of nearby elements. A guide line shows each alignment. Hold Alt to drop the selection exactly at the cursor.

The magnet button in the header toggles element alignment. In code:

java
graphView.setSnapToElements(true);
graphView.setElementSnapThreshold(7f); // screen pixels, default 7
graphView.setElementSnapRange(600f);   // screen pixels, default 600

Both distances are in screen pixels and are divided by the canvas zoom, so snapping feels the same at any zoom level.

Wire Styles ​

Since 2.2.41

Right-click the canvas and open Wire Style to choose how every wire in the view is routed.

WireRouteStyleLook
DEFAULTStraight run with a short stub at each port, rounded corners.
CURVEDCubic Bézier leaving each port along its axis.
OCTILINEARAxis-aligned runs joined by 45° cuts.
ORTHOGONALAxis-aligned segments with rounded square corners.
STRAIGHTPort to port, with no stubs.
Curved wire styleOctilinear wire style
CURVEDOCTILINEAR
Orthogonal wire styleStraight wire style
ORTHOGONALSTRAIGHT

The style is view-wide: one graph view draws all wires the same way.

java
graphView.setWireRouteStyle(WireRouteStyle.ORTHOGONAL);

Auto Layout ​

Since 2.2.41

Right-click the canvas and open Auto Layout:

EntryGraphLayoutAlgorithmUse
Layered (Sugiyama)LAYEREDDataflow graphs. Arranges nodes in columns along the wire flow.
GridGRIDEven grid that ignores wires.
Force DirectedFORCE_DIRECTEDGraphs without a clear flow. Each connected cluster is laid out separately.

With a selection, only the selected elements are arranged. With nothing selected, the whole graph is arranged. The flow direction comes from the ports on the wires involved: mostly vertical ports lay out top to bottom, otherwise left to right.

Placemats change what counts as one unit:

  • A placemat is selected: the placemat and everything inside it move as one box and keep their relative arrangement.
  • Only nodes inside a placemat are selected: those nodes are arranged inside the placemat. The placemat grows to fit the result, but never shrinks.

Auto layout is a normal undoable command:

java
graphView.dispatchCommand(new LayoutCommands.AutoLayoutCommand(
        selectedElements, GraphLayoutAlgorithm.LAYERED));

Wire Reroute Points ​

Since 2.2.37

A reroute point bends a wire through a fixed position. It changes only how the wire is drawn. The wire still connects the same two ports.

Wires bent through reroute points, with one point branching into two wires
Wires routed through reroute points. Each point has an input dot on the left and an output dot on the right.
ActionResult
Double-click a wire, or right-click it and choose Add Reroute PointInserts a reroute point at the cursor.
Drag from a point's right (output) dot to an input portAdds a branch that shares the trunk before the point.
Drag from a point's left (input) dot to an output port, or drop a wire from an output port on itRe-sources every wire passing through the point from that port.
Drag a point's bodyMoves the point; every wire through it follows.
Delete a pointRemoves the bend. The wires stay connected.

Because routing is separate from topology, WireModel.getFromPort() and getToPort() are unchanged, and graph execution code does not need to know about reroute points.

Useful APIs:

APIUse
WireModel.getReroutePoints()Points the wire passes through, from the output port to the input port.
GraphModel.insertReroutePointOnWire(wire, index, position)Bends a wire at a segment index.
WireCommands.InsertReroutePointCommandUndoable insert.
WireCommands.ReSourceReroutePointCommandUndoable re-source.

Reroute points are saved in the graph NBT under reroutePoints, and are included in copy and paste.

Read-only Views ​

Since 2.2.38

setReadOnly(true) turns a graph view into a viewer.

java
var graphView = new GraphView();
graphView.setReadOnly(true);
graphView.loadGraph(graph);

WARNING

Call setReadOnly(...) before loadGraph(...). Inline port editors read the flag while the UI tree is built, so changing it later leaves the editors already on screen editable.

In a read-only view:

  • dispatchCommand(...) refuses every command,
  • the blackboard and inspector still display but take no input,
  • undo and redo are disabled,
  • right-click does not open a context menu, and only pans the canvas,
  • only Ctrl+A and Ctrl+C still work, so users can copy a built-in graph into their own.

GraphEditorView.setReadOnly(...) does the same for every level of the subgraph stack and hides the save button. Graph resources open this way when their provider cannot edit them; see Editor Resources.

Graph.onGraphChanged(GraphLogger) feeds the graph log footer.

Use it for graph validation messages that should be visible while editing but not serialized.

Released under the MIT License.