Scopes - Rete.js

Scopes

This guide is based on the Basic guide. It is recommended to review it for a comprehensive understanding of this guide.

ScopesArrange nodesPlugin

The rete-scopes-plugin plugin provides features for building a node editor with nested nodes, also known as a subgraph. This plugin is categorized as advanced.

This approach involves using nodes as parent elements for other nodes. This enables the movement of a parent node to trigger the movement of all of its child nodes, and the movement of child nodes to adjust the size of their parent nodes. The nesting can extend to more than one level.

Install dependencies

bash
npm i rete-scopes-plugin

Prepare nodes

The plugin requires node sizes to be explicitly specified:

ts
class Node extends ClassicPreset.Node {
  width = 190;
  height = 120;
  parent?: string
}
class Connection<N extends Node> extends ClassicPreset.Connection<N, N> {}

type Schemes = GetSchemes<Node, Connection<Node>>;

The purpose of this is to enable dynamic resizing of the node's sizes if it has nested nodes.

Additionally, it's suggested to specify an optional parent field to programmatically designate parent nodes.

Plugin connection

ts
import { ScopesPlugin, Presets as ScopesPresets } from 'rete-scopes-plugin'

const scopes = new ScopesPlugin<Schemes>()

scopes.addPreset(ScopesPresets.classic.setup())

area.use(scopes)

This code relies on a classic preset that offers functionality for user-scope interactions. To select a node and assign it as a parent, the user may long-press the node and drag it over another node.

Adding nodes

Let's add a couple of nodes, with one serving as a parent:

ts
const node1 = new Node('A');
const parent1 = new Node('Parent');

node1.parent = parent1.id; // specify node1 as nested into parent1

await editor.addNode(parent1); // make sure to add the parent node before adding its child
await editor.addNode(node1);

Nodes order

Bu default, the plugin is set up to use its own node ordering. If you followed the Basic guide, you need to remove AreaExtensions.simpleNodesOrder

ts
AreaExtensions.simpleNodesOrder(area);

The ordering of nested nodes is a bit different as parent nodes shouldn't overlap its child nodes. When bringing node to front or adding child nodes to it, the order of child nodes is adapted (by reordered event)

Arrange nodes

The same Arrange nodes guide can be used for automated positioning of nodes in relation to one another, as the plugin used within also supports nested nodes.

Dynamically changing relationships

After the nodes have been added to the editor, to change the bindings between nodes, in addition to changing node.parent you need to explicitly call the update method

ts
// previously parent1.id was assigned
node1.parent = undefined;
await scopes.update(parent1.id)

Check out the complete result on the Scopes example page.