docs(guide): add section on removing nodes & edges

This commit is contained in:
braks
2023-11-05 20:07:54 +01:00
parent c35c2dbcc0
commit 4786e7ab5e
2 changed files with 367 additions and 224 deletions
+180 -133
View File
@@ -164,9 +164,7 @@ through [useVueFlow](/typedocs/functions/useVueFlow), allowing you to add edges
What's more, this action isn't limited to the component rendering the graph; it can be utilized elsewhere, like in a What's more, this action isn't limited to the component rendering the graph; it can be utilized elsewhere, like in a
Sidebar or Toolbar. Sidebar or Toolbar.
::: code-group ```vue
```vue [<LogosJavascript />]
<script setup> <script setup>
import { VueFlow, useVueFlow } from '@vue-flow/core' import { VueFlow, useVueFlow } from '@vue-flow/core'
@@ -206,12 +204,17 @@ onMounted(() => {
</template> </template>
``` ```
```vue [<LogosTypescript />] ## Removing Edges from the Graph
<script setup lang="ts">
import type { Node } from '@vue-flow/core'
import { VueFlow, useVueFlow } from '@vue-flow/core'
const initialNodes = ref<Node[]>([ Similar to adding edges, edges can be removed from the graph by removing them from the `mode-value` (using `v-model`) or from the `edges` prop of the Vue Flow component.
```vue
<script setup>
import { ref, onMounted } from 'vue'
import { VueFlow } from '@vue-flow/core'
const elements = ref([
{ {
id: '1', id: '1',
position: { x: 50, y: 50 }, position: { x: 50, y: 50 },
@@ -221,29 +224,158 @@ const initialNodes = ref<Node[]>([
id: '2', id: '2',
position: { x: 50, y: 250 }, position: { x: 50, y: 250 },
label: 'Node 2', label: 'Node 2',
},
{
id: 'e1-2',
source: '1',
target: '2',
} }
]) ]);
const { addEdges } = useVueFlow()
onMounted(() => { onMounted(() => {
// add an edge after mount elements.value.splice(2, 1)
addEdges([
{
source: '1',
target: '2',
// if a node has multiple handles of the same type,
// you should specify which handle to use by id
sourceHandle: null,
targetHandle: null,
}
])
}) })
</script> </script>
<template> <template>
<VueFlow :nodes="initialNodes" /> <VueFlow v-model="elements"/>
</template>
```
When working with complex graphs with extensive state access, you should use the useVueFlow composable.
The [`removeEdges`](/typedocs/interfaces/Actions#removeEdges) action is available through [useVueFlow](/typedocs/functions/useVueFlow),
allowing you to remove edges straight from the state.
What's more, this action isn't limited to the component rendering the graph; it can be utilized elsewhere, like in a
Sidebar, Toolbar or the Edge itself.
```vue
<script setup>
import { VueFlow, useVueFlow } from '@vue-flow/core'
const elements = ref([
{
id: '1',
position: { x: 50, y: 50 },
label: 'Node 1',
},
{
id: '2',
position: { x: 50, y: 250 },
label: 'Node 2',
},
{
id: 'e1-2',
source: '1',
target: '2',
}
])
const { removeEdges } = useVueFlow()
onMounted(() => {
// remove an edge after mount
removeEdges('e1-2')
// or remove multiple edges
removeEdges(['e1-2', 'e2-3'])
})
</script>
<template>
<VueFlow v-model="elements" />
</template>
```
## Updating Edge Data
Since edges are reactive object, you can update their data at any point by simply mutating it.
This allows you to change the label, or even add new properties to the data object at any point in time.
There are multiple ways of achieving this, here are some examples:
::: code-group
```vue [useEdge]
<!-- CustomEdge.vue -->
<script setup>
import { useEdge } from '@vue-flow/core'
// `useEdge` returns us the edge object straight from the state
// since the node obj is reactive, we can mutate it to update our edges' data
const { edge } = useEdge()
function onSomeEvent() {
edge.data = {
...edge.data,
hello: 'world',
}
// you can also mutate properties like `selectable` or `animated`
edge.selectable = !edge.selectable
edge.animated = !edge.animated
}
</script>
```
```ts [useVueFlow]
import { useVueFlow } from '@vue-flow/core'
const instance = useVueFlow()
// find the node in the state by its id
const edge = instance.findEdge(edgeId)
edge.data = {
...edge.data,
hello: 'world',
}
// you can also mutate properties like `selectable` or `animated`
edge.selectable = !edge.selectable
edge.animated = !edge.animated
```
```vue [v-model]
<script setup>
import { ref } from 'vue'
const elements = ref([
{
id: '1',
label: 'Node 1',
position: { x: 50, y: 50 },
data: {
hello: 'world',
}
},
{
id: '2',
label: 'Node 2',
position: { x: 50, y: 250 },
},
{
id: 'e1-2',
source: '1',
target: '2',
},
])
function onSomeEvent(edgeId) {
const edge = elements.value.find((edge) => edge.id === edgeId)
edge.data = {
...elements.value[0].data,
hello: 'world',
}
// you can also mutate properties like `selectable` or `animated`
edge.selectable = !edge.selectable
edge.animated = !edge.animated
}
</script>
<template>
<VueFlow v-model="elements" />
</template> </template>
``` ```
@@ -388,7 +520,7 @@ export const edges = ref<CustomEdge[]>([
id: 'e1-2', id: 'e1-2',
source: '1', source: '1',
target: '2', target: '2',
type: 'not-defined', type: 'not-defined', // should be 'custom' | 'special'
} }
]) ])
``` ```
@@ -517,33 +649,29 @@ const elements = ref([
Your custom edges are enclosed so that fundamental functions like selecting operate. Your custom edges are enclosed so that fundamental functions like selecting operate.
But you may wish to expand on these features or implement your business logic inside edges, thus your edges receive the following properties: But you may wish to expand on these features or implement your business logic inside edges, thus your edges receive the following properties:
| Name | Definition | Type | Optional | | Prop Name | Description | Type | Optional |
|---------------------|-------------------------------|------------------------------------------------|--------------------------------------------| |------------------|--------------------------------------------|----------------------------------------------|--------------------------------------------|
| id | Edge id | string | <Close class="text-red-500" /> | | id | Unique edge id | string | <Close class="text-red-500" /> |
| source | The source node id | string | <Close class="text-red-500" /> | | sourceNode | The originating node | [GraphNode](/typedocs/interfaces/GraphNode) | <Close class="text-red-500" /> |
| target | The target node id | string | <Close class="text-red-500" /> | | targetNode | The destination node | [GraphNode](/typedocs/interfaces/GraphNode) | <Close class="text-red-500" /> |
| sourceNode | The source node | GraphNode | <Close class="text-red-500" /> | | source | ID of the source node | string | <Close class="text-red-500" /> |
| targetNode | The target node | GraphNode | <Close class="text-red-500" /> | | target | ID of the target node | string | <Close class="text-red-500" /> |
| sourceX | X position of source handle | number | <Close class="text-red-500" /> | | type | Edge Type | string | <Close class="text-red-500" /> |
| sourceY | Y position of source handle | number | <Close class="text-red-500" /> | | label | Edge label, can be a string or a VNode | string \| VNode \| Component \| Object | <Check class="text-[var(--vp-c-brand)]" /> |
| targetX | X position of target handle | number | <Close class="text-red-500" /> | | style | CSS properties | CSSProperties | <Check class="text-[var(--vp-c-brand)]" /> |
| targetY | Y position of target handle | number | <Close class="text-red-500" /> | | selected | Is edge selected | boolean | <Check class="text-[var(--vp-c-brand)]" /> |
| type | Edge type | string | <Check class="text-[var(--vp-c-brand)]" /> | | sourcePosition | Source position | [Position](/typedocs/enums/Position) | <Close class="text-red-500" /> |
| sourceHandleId | Source handle id | string | <Check class="text-[var(--vp-c-brand)]" /> | | targetPosition | Target position | [Position](/typedocs/enums/Position) | <Close class="text-red-500" /> |
| targetHandleId | Target handle id | string | <Check class="text-[var(--vp-c-brand)]" /> | | sourceHandleId | ID of the source handle | string | <Check class="text-[var(--vp-c-brand)]" /> |
| data | Custom data object | Any object | <Check class="text-[var(--vp-c-brand)]" /> | | targetHandleId | ID of the target handle | string | <Check class="text-[var(--vp-c-brand)]" /> |
| events | Edge events and custom events | [EdgeEventsOn](/typedocs/types/EdgeEventsOn) | <Check class="text-[var(--vp-c-brand)]" /> | | animated | Is edge animated | boolean | <Check class="text-[var(--vp-c-brand)]" /> |
| label | Edge label | string, Component | <Check class="text-[var(--vp-c-brand)]" /> | | updatable | Is edge updatable | boolean | <Check class="text-[var(--vp-c-brand)]" /> |
| labelStyle | Additional label styles | CSSProperties | <Check class="text-[var(--vp-c-brand)]" /> | | markerStart | Start marker | string | <Close class="text-red-500" /> |
| labelShowBg | Enable/Disable label bg | boolean | <Check class="text-[var(--vp-c-brand)]" /> | | markerEnd | End marker | string | <Close class="text-red-500" /> |
| labelBgPadding | Edge label bg padding | number | <Check class="text-[var(--vp-c-brand)]" /> | | curvature | The curvature of the edge | number | <Check class="text-[var(--vp-c-brand)]" /> |
| labelBgBorderRadius | Edge label bg border radius | number | <Check class="text-[var(--vp-c-brand)]" /> | | interactionWidth | Width of the interaction area for the edge | number | <Check class="text-[var(--vp-c-brand)]" /> |
| selected | Is edge selected | boolean | <Check class="text-[var(--vp-c-brand)]" /> | | data | Additional data of edge | any object | <Close class="text-red-500" /> |
| animated | Is edge animated | boolean | <Check class="text-[var(--vp-c-brand)]" /> | | events | Contextual and custom events of edge | [EdgeEventsOn](/typedocs/types/EdgeEventsOn) | <Close class="text-red-500" /> |
| updatable | Is edge updatable | [EdgeUpdatable](/typedocs/types/EdgeUpdatable) | <Check class="text-[var(--vp-c-brand)]" /> |
| markerEnd | Edge marker id | string | <Check class="text-[var(--vp-c-brand)]" /> |
| markerStart | Edge marker id | string | <Check class="text-[var(--vp-c-brand)]" /> |
| curvature | Edge path curvature | number | <Check class="text-[var(--vp-c-brand)]" /> |
## Edge Events ## Edge Events
@@ -678,84 +806,3 @@ const elements = ref([
::: tip ::: tip
To override the styles of the default theme, visit the [Theming section](/guide/theming). To override the styles of the default theme, visit the [Theming section](/guide/theming).
::: :::
## Updating Edge Data
Since edges are reactive object, you can update their data at any point by simply mutating it.
This allows you to change the label, or even add new properties to the data object at any point in time.
There are multiple ways of achieving this, here are some examples:
::: code-group
```vue [useEdge]
<!-- CustomEdge.vue -->
<script setup>
import { useEdge } from '@vue-flow/core'
// `useEdge` returns us the edge object straight from the state
// since the node obj is reactive, we can mutate it to update our edges' data
const { edge } = useEdge()
function onSomeEvent() {
edge.data = {
...edge.data,
hello: 'world',
}
}
</script>
```
```ts [useVueFlow]
import { useVueFlow } from '@vue-flow/core'
const instance = useVueFlow()
// find the node in the state by its id
const edge = instance.findEdge(edgeId)
edge.data = {
...edge.data,
hello: 'world',
}
```
```vue [v-model]
<script setup>
import { ref } from 'vue'
const elements = ref([
{
id: '1',
label: 'Node 1',
position: { x: 50, y: 50 },
data: {
hello: 'world',
}
},
{
id: '2',
label: 'Node 2',
position: { x: 50, y: 250 },
},
{
id: 'e1-2',
source: '1',
target: '2',
},
])
function onSomeEvent() {
elements.value[2].data = {
...elements.value[0].data,
hello: 'world',
}
}
</script>
<template>
<VueFlow v-model="elements" />
</template>
```
:::
+186 -90
View File
@@ -218,6 +218,172 @@ function onAddNodes() {
::: :::
## Removing Nodes from the Graph
Similar to adding nodes, nodes can be removed from the graph by removing them from the `mode-value` (using `v-model`) or from the `nodes` prop of the Vue Flow component.
```vue
<script setup>
import { ref } from 'vue'
const elements = ref([
{
id: '1',
position: { x: 50, y: 50 },
label: 'Node 1',
},
{
id: '2',
position: { x: 150, y: 50 },
label: 'Node 2',
}
])
function onRemoveNode() {
elements.value.pop()
}
</script>
<template>
<VueFlow v-model="elements" />
<button type="button" @click="onRemoveNode">Remove a node</button>
</template>
```
When working with complex graphs with extensive state access, you should use the useVueFlow composable.
The [`removeNodes`](/typedocs/interfaces/Actions#removeNodes) action is available through [useVueFlow](/typedocs/functions/useVueFlow),
allowing you to remove nodes straight from the state.
What's more, this action isn't limited to the component rendering the graph; it can be utilized elsewhere, like in a
Sidebar, Toolbar or the Edge itself.
```vue
<script setup>
import { ref } from 'vue'
import { VueFlow, useVueFlow } from '@vue-flow/core'
const initialNodes = ref([
{
id: '1',
position: { x: 50, y: 50 },
label: 'Node 1',
},
{
id: '2',
position: { x: 150, y: 50 },
label: 'Node 2',
}
])
const { removeNodes } = useVueFlow()
// remove a single node from the graph
function onRemoveNode() {
removeNodes('1')
}
// remove multiple nodes from the graph
function onRemoveNodes() {
removeNodes(['1', '2'])
}
</script>
<template>
<VueFlow :nodes="initialNodes" />
<button type="button" @click="onRemoveNode">Remove a node</button>
<button type="button" @click="onRemoveNodes">Remove multiple nodes</button>
</template>
```
## Updating Node Data
Since nodes are reactive object, you can update their data at any point by simply mutating it.
This allows you to disable or enable handles, change the label, or even add new properties to the data object at any point in time.
There are multiple ways of achieving this, here are some examples:
::: code-group
```vue [useNode]
<!-- CustomNode.vue -->
<script setup>
import { useNode } from '@vue-flow/core'
// `useNode` returns us the node object straight from the state
// since the node obj is reactive, we can mutate it to update our nodes' data
const { node } = useNode()
function onSomeEvent() {
node.data = {
...node.data,
hello: 'world',
}
// you can also mutate properties like `selectable` or `draggable`
node.selectable = false
node.draggable = false
}
</script>
```
```ts [useVueFlow]
import { useVueFlow } from '@vue-flow/core'
const instance = useVueFlow()
// find the node in the state by its id
const node = instance.findNode(nodeId)
node.data = {
...node.data,
hello: 'world',
}
// you can also mutate properties like `selectable` or `draggable`
node.selectable = false
node.draggable = false
```
```vue [v-model]
<script setup>
import { ref } from 'vue'
const elements = ref([
{
id: '1',
label: 'Node 1',
position: { x: 50, y: 50 },
data: {
hello: 'world',
}
},
])
function onSomeEvent(nodeId) {
const node = elements.value.find((node) => node.id === nodeId)
node.data = {
...elements.value[0].data,
hello: 'world',
}
// you can also mutate properties like `selectable` or `draggable`
node.selectable = false
node.draggable = false
}
</script>
<template>
<VueFlow v-model="elements" />
</template>
```
:::
## [Predefined Node-Types](/typedocs/types/DefaultNodeTypes) ## [Predefined Node-Types](/typedocs/types/DefaultNodeTypes)
Vue Flow provides several built-in node types that you can leverage immediately. Vue Flow provides several built-in node types that you can leverage immediately.
@@ -501,25 +667,26 @@ const elements = ref([
Your custom nodes are enclosed so that fundamental functions like dragging or selecting operate. Your custom nodes are enclosed so that fundamental functions like dragging or selecting operate.
But you may wish to expand on these features or implement your business logic inside nodes, thus your nodes receive the following properties: But you may wish to expand on these features or implement your business logic inside nodes, thus your nodes receive the following properties:
| Name | Definition | Type | Optional | | Prop Name | Description | Type | Optional |
|------------------|--------------------------------------------------|------------------------------------------------------------|--------------------------------------------| |-------------------------------------------------------------|---------------------------------------------------------------------|------------------------------------------------------------|--------------------------------------------|
| id | Node id | string | <Close class="text-red-500" /> | | id | Unique node id | string | <Close class="text-red-500" /> |
| type | Node type | string | <Close class="text-red-500" /> | | type | Node Type | string | <Close class="text-red-500" /> |
| selected | Is node selected | boolean | <Close class="text-red-500" /> | | selected | Is node selected | boolean | <Close class="text-red-500" /> |
| dragging | Is node dragging | boolean | <Close class="text-red-500" /> | | connectable | Can node handles be connected | [HandleConnectable](/typedocs/types/HandleConnectable) | <Close class="text-red-500" /> |
| connectable | Is node connectable | boolean | <Close class="text-red-500" /> | | position | Node's x, y (relative) position on the graph | [XYPosition](/typedocs/interfaces/XYPosition) | <Close class="text-red-500" /> |
| position | Relative position of a node | [XYPosition](/typedocs/interfaces/XYPosition) | <Close class="text-red-500" /> | | dimensions | Dom element dimensions (width, height) | [Dimensions](/typedocs/interfaces/Dimensions) | <Close class="text-red-500" /> |
| zIndex | Node z-index | number | <Close class="text-red-500" /> | | label | Node label, either a string or a VNode. `h('div', props, children)` | string \| VNode \| Component \| Object | <Check class="text-[var(--vp-c-brand)]" /> |
| dimensions | Node size | [Dimensions](/typedocs/interfaces/Dimensions) | <Close class="text-red-500" /> | | isValidTargetPos <Badge type="warning" text="deprecated" /> | Called when used as target for new connection | [ValidConnectionFunc](/typedocs/types/ValidConnectionFunc) | <Check class="text-[var(--vp-c-brand)]" /> |
| data | Custom data object | Any object | <Check class="text-[var(--vp-c-brand)]" /> | | isValidSourcePos <Badge type="warning" text="deprecated" /> | Called when used as the source for a new connection | [ValidConnectionFunc](/typedocs/types/ValidConnectionFunc) | <Check class="text-[var(--vp-c-brand)]" /> |
| events | Node events and custom events | [NodeEventsOn](/typedocs/types/NodeEventsOn) | <Check class="text-[var(--vp-c-brand)]" /> | | parent | Parent node id | string | <Check class="text-[var(--vp-c-brand)]" /> |
| label | Node label | string, Component | <Check class="text-[var(--vp-c-brand)]" /> | | dragging | Is node currently dragging | boolean | <Close class="text-red-500" /> |
| isValidTargetPos | Called when target handle is used for connection | [ValidConnectionFunc](/typedocs/types/ValidConnectionFunc) | <Check class="text-[var(--vp-c-brand)]" /> | | resizing | Is node currently resizing | boolean | <Close class="text-red-500" /> |
| isValidSourcePos | Called when source handle is used for connection | [ValidConnectionFunc](/typedocs/types/ValidConnectionFunc) | <Check class="text-[var(--vp-c-brand)]" /> | | zIndex | Node z-index | number | <Close class="text-red-500" /> |
| parentNode | Parent node id | string | <Check class="text-[var(--vp-c-brand)]" /> | | targetPosition | Handle position | [Position](/typedocs/enums/Position) | <Check class="text-[var(--vp-c-brand)]" /> |
| targetPosition | Target handle position | [Position](/typedocs/enums/Position) | <Check class="text-[var(--vp-c-brand)]" /> | | sourcePosition | Handle position | [Position](/typedocs/enums/Position) | <Check class="text-[var(--vp-c-brand)]" /> |
| sourcePosition | Source handle position | [Position](/typedocs/enums/Position) | <Check class="text-[var(--vp-c-brand)]" /> | | dragHandle | Drag handle query selector | string | <Check class="text-[var(--vp-c-brand)]" /> |
| dragHandle | Node drag handle class | string | <Check class="text-[var(--vp-c-brand)]" /> | | data | Additional data of node | any object | <Close class="text-red-500" /> |
| events | Contextual and custom events of node | [NodeEventsOn](/typedocs/types/NodeEventsOn) | <Close class="text-red-500" /> |
## [Node Events](/typedocs/types/NodeEventsHandler) ## [Node Events](/typedocs/types/NodeEventsHandler)
@@ -649,77 +816,6 @@ User-created nodes don't have any default styles associated and thus need custom
} }
``` ```
## Updating Node Data
Since nodes are reactive object, you can update their data at any point by simply mutating it.
This allows you to disable or enable handles, change the label, or even add new properties to the data object at any point in time.
There are multiple ways of achieving this, here are some examples:
::: code-group
```vue [useNode]
<!-- CustomNode.vue -->
<script setup>
import { useNode } from '@vue-flow/core'
// `useNode` returns us the node object straight from the state
// since the node obj is reactive, we can mutate it to update our nodes' data
const { node } = useNode()
function onSomeEvent() {
node.data = {
...node.data,
hello: 'world',
}
}
</script>
```
```ts [useVueFlow]
import { useVueFlow } from '@vue-flow/core'
const instance = useVueFlow()
// find the node in the state by its id
const node = instance.findNode(nodeId)
node.data = {
...node.data,
hello: 'world',
}
```
```vue [v-model]
<script setup>
import { ref } from 'vue'
const elements = ref([
{
id: '1',
label: 'Node 1',
position: { x: 50, y: 50 },
data: {
hello: 'world',
}
},
])
function onSomeEvent() {
elements.value[0].data = {
...elements.value[0].data,
hello: 'world',
}
}
</script>
<template>
<VueFlow v-model="elements" />
</template>
```
:::
## Implementing Scrolling within Nodes ## Implementing Scrolling within Nodes
Sometimes, a node might contain a large amount of content, making it difficult for users to view everything without the aid of a scroll function. Sometimes, a node might contain a large amount of content, making it difficult for users to view everything without the aid of a scroll function.