Node
Nodes are defined through FlowNodeEntity
Node Core API
- id:
string
Node id
- flowNodeType:
string
| number
Node type
- bounds:
Rectangle
Get the node's x, y, width, height, equivalent to transform.bounds
- blocks:
FlowNodeEntity[]
Get child nodes, including collapsed child nodes
- parent:
FlowNodeEntity | undefined
Get the parent node (Such as loop)
- document: WorkflowDocument Document link
- transform: FlowNodeTransformData Get the node's transform data
- renderData: FlowNodeRenderData Get the node's render data, including render status
- form: NodeFormProps Get the node's form data, like getNodeForm
- scope: FlowNodeScope Get the node's variable public scope
- privateScope: FlowNodeScope Get the node's variable private scope
- lines: WorkflowNodeLinesData Get the node's lines data
- ports: WorkflowNodePortsData Get the node's ports data
- getNodeRegistry(): WorkflowNodeRegistry Get the node's registry
- getService(): Get the IOC Service, such as
node.getService(HistoryService)
- getExtInfo(): Get the node's ext info, such as
node.getExtInfo<{ test: string }>()
- updateExtInfo(): Update the node's ext info, such as
node.updateExtInfo<{ test: string }>({ test: 'test' })
- dispose(): Destroy node
- toJSON(): Get the node's json data
Node Data
Can be obtained through node.toJSON()
Basic Structure:
- id:
string
Unique identifier for the node, must be unique
- meta:
object
Node's UI configuration information, such as position
information for free layout
- type:
string | number
Node type, corresponds to type
in nodeRegistries
- data:
object
Node form data, can be customized by business
- blocks:
array
Node branches, using block
is more suitable for Gramming
free layout scenarios, used in sub-nodes of sub-canvas
- edges:
array
Edge data of sub-canvas
const nodeData: FlowNodeJSON = {
id: 'xxxx',
type: 'condition',
data: {
title: 'MyCondition',
desc: 'xxxxx'
},
}
Node Definition
In free layout scenarios, node definition is used to declare node's initial position/size, ports, form rendering, etc. For details, see Declare Node
Get Current Rendering Node
Get node-related methods through useNodeRender
function BaseNode() {
const { id, type, data, updateData, node } = useNodeRender()
}
Get Input/Output Nodes or Lines for Current Node
// get input nodes (calculated through connection lines)
node.lines.inputNodes
// get all input nodes (recursively gets all upstream nodes)
node.lines.allInputNodes
// get output nodes
node.lines.outputNodes
// get all output nodes
node.lines.allOutputNodes
// input lines (contains the line that isDrawing or isHidden)
node.lines.inputLines
// output lines (contains the line that isDrawing or isHidden)
node.lines.outputLines
// all availableLines (Doesn't contain the lines that isDrawing or isHidden)
node.lines.availableLines
Create Node
const ctx = useClientContext()
ctx.document.createWorkflowNode({
id: 'xxx', // Must be unique within the canvas
type: 'custom',
meta: {
/**
* If not provided, defaults to creating in the center of the canvas
* To get position from mouse position (e.g., creating node by clicking anywhere on canvas),
* convert using `ctx.playground.config.getPosFromMouseEvent(mouseEvent)`
*/
position: { x: 100, y: 100 } //
},
data: {}, // Form-related data
blocks: [], // Sub-canvas nodes
edges: [] // Sub-canvas edges
})
const dragService = useService<WorkflowDragService>(WorkflowDragService);
// mouseEvent here will automatically convert to canvas position
dragService.startDragCard(nodeType, mouseEvent, {
id: 'xxxx',
data: {}, // Form-related data
blocks: [], // Sub-canvas nodes
edges: [] // Sub-canvas edges
})
Delete Node
Delete node through node.dispose
function BaseNode({ node }) {
function onClick() {
node.dispose()
}
return (
<button onClick={onClick}>Delete</button>
)
}
Update Node Data
function BaseNode() {
const { form, node } = useNodeRender();
// Corresponds to node's data
// 1. form.values: Corresponds to node's data
// 2. form.setValueIn('title', 'xxxx'): Update data.title
// 3. form.getValueIn('title'): Get data.title
// 4. form.updateFormValues({ ... }) Update all form values
function onChange(e) {
form.setValueIn('title', e.target.value)
}
return <input value={form.values.title} onChange={onChange}/>
}
- Update form data through Field, see details in Form Usage
function FormRender() {
return (
<Field name="title">
<Input />
</Field>
)
}
Update Node's extInfo Data
extInfo is used to store UI states, if node engine is not enabled, node's data will be stored in extInfo by default
function BaseNode({ node }) {
const times = node.getExtInfo()?.times || 0
function onClick() {
node.updateExtInfo({ times: times ++ })
}
return (
<div>
<span>Click Times: {times}</span>
<button onClick={onClick}>Click</button>
</div>
)
}