Check out the instructions for Rete Kit
Yes, follow the Dataflow or Control flow guides
The engine only supports JS runtime. You can either bind JS into your environment or implement your own engine, similar to rete-engine
(it has a straightforward implementation)
In short, yes. Refer to the Licensing for details
It can be used in JS code, but not recommended because of poor DX
Yes, follow the Import/export guide
Replace zoom handler with null
or use a custom one
const area = new AreaPlugin(container)
area.area.setZoomHandler(null)
Replace the zoom handler with null
on some event and restore it on opposite (e.g. Ctrl press/release)
import { Zoom } from 'rete-area-plugin'
// call on init
area.area.setZoomHandler(null)
// call on Ctrl press
area.area.setZoomHandler(new Zoom(0.1))
// call on Ctrl release
area.area.setZoomHandler(null)
Replace the drag handler for a specific area by calling setDragHandler
import { Drag } from 'rete-area-plugin';
area.area.setDragHandler(new Drag({
down: e => {
if (e.pointerType === 'mouse' && e.button !== 1) return false
e.preventDefault()
return true
},
move: () => true
}))
The position is stored within a NodeView
instance.
const view = area.nodeViews.get(nodeId)
if (view) {
view.position // { x, y }
}
Keep in mind that the NodeView
instance may not exist, for example if it hasn't yet been added. In such cases, it's preferable to handle this gracefully (throw an exception only when necessary)
area.translate(nodeId, { x: 0, y: 0 })
Follow the Arrange nodes guide
Call the following methods for the corresponding nodes or controls after making changes to the state
const area = new AreaPlugin(container)
area.update('node', node.id)
area.update("control", control.id);
Check out the Combining render plugins in the Integration article
Use the methods of content
property of the area plugin
const area = new AreaPlugin(container)
area.content.add(element)
area.content.remove(element)
It's also possible to make this element draggable
const dragHandler = new Drag()
dragHandler.initialize(element, { /* getters */ }, { /* events */ })
By default, a node is configured with the CSS property user-select: none
to prevent conflict between text selection and node dragging.
Therefore, to enable text selection within a custom node component, you need to specify user-select: all
property for the desired element within the node. Additionally, ensure you call e.stopPropagation()
on the `pointerdown`` event to prevent text selection interruptions while dragging.
Whenever a user clicks on the node, the nodepicked
event is fired:
area.addPipe(context => {
if (context.type === 'nodepicked') {
const node = editor.getNode(context.data.id)
}
return context
})
In case you need to track not only click, but also node selections, you have the option to extend the selector to observe selected elements (not just nodes) within the editor
You can add them as usual using the addInput
/addOutput
/AddControl
methods, and then force a node update
const area = new AreaPlugin(container)
area.update('node', node.id)
You can use the classic preset with custom nodes and a unified socket for both input and output port.
Check out the Undirected example
Check out the Vertical flow example
The classic rendering preset offers the flexibility to specify an optional index
field for inputs, outputs or controls. This feature enables you to change the order of these elements within their lists.
const input = new ClassicPreset.Input(socket)
const output = new ClassicPreset.Output(socket)
const control = new ClassicPreset.InputControl('text')
input.index = 0;
output.index = 0;
control.index = 0;
In short, it is possible, but there is no plugin available for this approach since it doesn't offer significant advantages in comparison to the development costs
If you don't want to update all of your dependencies at once with npm update
, you can selectively update those that begin with rete
using a regular expression
npx npm-check-updates /^rete/ --target @latest -u
All available rendering plugins can display a loop connection if it has specified isLoop
property
class Connection extends ClassicPreset.Connection {
isLoop = false
}
const connection = new Connection(source, output, target, input)
connection.isLoop = true
The minimum required TypeScript version is 4.7.
Otherwise, you might encounter the error Type instantiation is excessively deep and possibly infinite. ts(2589)
when using the use
method. If you can't use a later version for some reason, the only solution is to use @ts-ignore
.
For example, when creating an Angular 12 application with Rete Kit, a version 4.7 higher than the officially supported one is installed.
Using the area.zoom
method enables you to specify the desired zoom level and the offset points for aligning the zoom
await area.area.zoom(0.8, 0, 0);
In the given example, the zoom will be decreased with respect to the top left boundary. If you want to modify the zoom relative to the center of the viewport, refer to the following code
const delta = 0.2;
const { k } = area.area.transform;
const box = area.container.getBoundingClientRect();
const x = box.width / 2 / k;
const y = box.height / 2 / k;
area.area.zoom(k * (1 - delta), x * delta, y * delta);
By utilizing the area.translate
method, you can change the coordinates as follows
await area.area.translate(100, 20)
Change in position relative to current coordinates
const { x, y } = area.area.transform
await area.area.translate(x + 100, y + 20)
Change the editor's position considering the zoom factor
const { k } = area.area.transform
await area.area.translate(100 * k, 20 * k)
In case you're using a framework other than React.js, Vue.js, Angular, Svelte or Lit (for which Rete.js provides a rendering plugin), you have the option to utilize the React.js plugin to render nodes and other editor elements.
For a quick start, you can create a React.js application using Rete Kit, copy the code of the editor from src/rete/default.tsx
, install the relevant dependencies in your project and call createEditor
, providing the HTMLElement container created by your application.
First of all, you need to obtain the viewport center in screen coordinates using getBoundingClientRect
. Afterward, you should transform them into editor coordinates by applying the zoom factor k
and offset it relative to area's position.
const area = new AreaPlugin<Schemes, AreaExtra>(container)
const { x, y, k } = area.area.transform
const box = area.container.getBoundingClientRect()
const halfWidth = box.width / 2 / k
const halfHeight = box.height / 2 / k
return { x: halfWidth - x / k, y: halfHeight - y / k }
The warning "Found more than one element for socket with same key and side" means that there are duplicate sockets in the editor that were not properly removed after an update, or due to an asynchronous approach when unmounting components by different UI frameworks, the lifecycle of old and new ones overlaps.
In the first case, when the number of these warnings constantly accumulates, you most likely have a memory leak problem because some custom node was not correctly unmounted.
In the second case, the warning can be avoided by adding a delay between removing the scheme/node and mounting a new one with the same identifiers. In the worst case, this warning should not indicate memory leak issues, so you can ignore it.
The framework does not have a reserved event for this. Instead, you can [/docs/guides/selectable#extend-selector](extend the selector) by triggering events in the relevant methods.
area.addPipe(context => {
if (context.type === 'zoom' && context.data.source === 'dblclick') return
return context
})