feat(flow): export apply changes utilities for options api
This commit is contained in:
@@ -20,10 +20,10 @@ export {
|
|||||||
isNode,
|
isNode,
|
||||||
isEdge,
|
isEdge,
|
||||||
addEdge,
|
addEdge,
|
||||||
|
updateEdge,
|
||||||
getOutgoers,
|
getOutgoers,
|
||||||
getIncomers,
|
getIncomers,
|
||||||
getConnectedEdges,
|
getConnectedEdges,
|
||||||
updateEdge,
|
|
||||||
getTransformForBounds,
|
getTransformForBounds,
|
||||||
getRectOfNodes,
|
getRectOfNodes,
|
||||||
graphPosToZoomedPos,
|
graphPosToZoomedPos,
|
||||||
@@ -31,6 +31,12 @@ export {
|
|||||||
getMarkerId,
|
getMarkerId,
|
||||||
} from './utils/graph'
|
} from './utils/graph'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intended for options API
|
||||||
|
* In composition API you can access apply utilities from `useVueFlow`
|
||||||
|
*/
|
||||||
|
export { applyChanges, applyEdgeChanges, applyNodeChanges } from './utils/changes'
|
||||||
|
|
||||||
export { defaultEdgeTypes, defaultNodeTypes } from './store'
|
export { defaultEdgeTypes, defaultNodeTypes } from './store'
|
||||||
export { VueFlow as VueFlowInjection, NodeId as NodeIdInjection } from './context'
|
export { VueFlow as VueFlowInjection, NodeId as NodeIdInjection } from './context'
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ import {
|
|||||||
State,
|
State,
|
||||||
} from '~/types'
|
} from '~/types'
|
||||||
import {
|
import {
|
||||||
applyChanges,
|
applyNodeChanges as applyNodes,
|
||||||
|
applyEdgeChanges as applyEdges,
|
||||||
connectionExists,
|
connectionExists,
|
||||||
createPositionChange,
|
createPositionChange,
|
||||||
createSelectionChange,
|
createSelectionChange,
|
||||||
@@ -83,11 +84,6 @@ const updateEdgeAction = (edge: GraphEdge, newConnection: Connection, edges: Gra
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
const applyEdgeChangesAction = (changes: EdgeChange[], edges: GraphEdge[], getNode: Getters['getNode']) =>
|
|
||||||
applyChanges(changes, edges, getNode)
|
|
||||||
const applyNodeChangesAction = (changes: NodeChange[], nodes: GraphNode[], getNode: Getters['getNode']) =>
|
|
||||||
applyChanges(changes, nodes, getNode)
|
|
||||||
|
|
||||||
const createGraphNodes = (nodes: Node[], getNode: Getters['getNode'], currGraphNodes: GraphNode[], extent: CoordinateExtent) => {
|
const createGraphNodes = (nodes: Node[], getNode: Getters['getNode'], currGraphNodes: GraphNode[], extent: CoordinateExtent) => {
|
||||||
const parentNodes: Record<string, true> = {}
|
const parentNodes: Record<string, true> = {}
|
||||||
|
|
||||||
@@ -127,17 +123,18 @@ export default (state: State, getters: ComputedGetters): Actions => {
|
|||||||
state.nodes.forEach((node) => {
|
state.nodes.forEach((node) => {
|
||||||
if (node.selected) {
|
if (node.selected) {
|
||||||
if (!node.parentNode) {
|
if (!node.parentNode) {
|
||||||
changes.push(createPositionChange({ node, diff, nodeExtent: state.nodeExtent, dragging }, getters.getNode.value))
|
changes.push(createPositionChange({ node, diff, nodeExtent: state.nodeExtent, dragging }, state.nodes))
|
||||||
} else if (!isParentSelected(node, getters.getNode.value)) {
|
} else if (!isParentSelected(node, getters.getNode.value)) {
|
||||||
changes.push(createPositionChange({ node, diff, nodeExtent: state.nodeExtent, dragging }, getters.getNode.value))
|
changes.push(createPositionChange({ node, diff, nodeExtent: state.nodeExtent, dragging }, state.nodes))
|
||||||
}
|
}
|
||||||
} else if (node.id === id) {
|
} else if (node.id === id) {
|
||||||
changes.push(createPositionChange({ node, diff, nodeExtent: state.nodeExtent, dragging }, getters.getNode.value))
|
changes.push(createPositionChange({ node, diff, nodeExtent: state.nodeExtent, dragging }, state.nodes))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (changes.length) state.hooks.nodesChange.trigger(changes)
|
if (changes.length) state.hooks.nodesChange.trigger(changes)
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateNodeDimensions: Actions['updateNodeDimensions'] = (updates) => {
|
const updateNodeDimensions: Actions['updateNodeDimensions'] = (updates) => {
|
||||||
const changes: NodeDimensionChange[] = updates.reduce<NodeDimensionChange[]>((res, update) => {
|
const changes: NodeDimensionChange[] = updates.reduce<NodeDimensionChange[]>((res, update) => {
|
||||||
const node = getters.getNode.value(update.id)
|
const node = getters.getNode.value(update.id)
|
||||||
@@ -167,6 +164,7 @@ export default (state: State, getters: ComputedGetters): Actions => {
|
|||||||
|
|
||||||
if (changes.length) state.hooks.nodesChange.trigger(changes)
|
if (changes.length) state.hooks.nodesChange.trigger(changes)
|
||||||
}
|
}
|
||||||
|
|
||||||
const addSelectedNodes: Actions['addSelectedNodes'] = (nodes) => {
|
const addSelectedNodes: Actions['addSelectedNodes'] = (nodes) => {
|
||||||
const selectedNodesIds = nodes.map((n) => n.id)
|
const selectedNodesIds = nodes.map((n) => n.id)
|
||||||
|
|
||||||
@@ -176,6 +174,7 @@ export default (state: State, getters: ComputedGetters): Actions => {
|
|||||||
|
|
||||||
if (changedNodes.length) state.hooks.nodesChange.trigger(changedNodes)
|
if (changedNodes.length) state.hooks.nodesChange.trigger(changedNodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
const addSelectedEdges: Actions['addSelectedEdges'] = (edges) => {
|
const addSelectedEdges: Actions['addSelectedEdges'] = (edges) => {
|
||||||
const selectedEdgesIds = edges.map((e) => e.id)
|
const selectedEdgesIds = edges.map((e) => e.id)
|
||||||
|
|
||||||
@@ -185,26 +184,32 @@ export default (state: State, getters: ComputedGetters): Actions => {
|
|||||||
|
|
||||||
if (changedEdges.length) state.hooks.edgesChange.trigger(changedEdges)
|
if (changedEdges.length) state.hooks.edgesChange.trigger(changedEdges)
|
||||||
}
|
}
|
||||||
|
|
||||||
const addSelectedElements: Actions['addSelectedElements'] = (elements) => {
|
const addSelectedElements: Actions['addSelectedElements'] = (elements) => {
|
||||||
addSelectedNodes(elements.filter(isGraphNode))
|
addSelectedNodes(elements.filter(isGraphNode))
|
||||||
addSelectedEdges(elements.filter(isGraphEdge))
|
addSelectedEdges(elements.filter(isGraphEdge))
|
||||||
}
|
}
|
||||||
|
|
||||||
const setMinZoom: Actions['setMinZoom'] = (minZoom: any) => {
|
const setMinZoom: Actions['setMinZoom'] = (minZoom: any) => {
|
||||||
state.d3Zoom?.scaleExtent([minZoom, state.maxZoom])
|
state.d3Zoom?.scaleExtent([minZoom, state.maxZoom])
|
||||||
state.minZoom = minZoom
|
state.minZoom = minZoom
|
||||||
}
|
}
|
||||||
|
|
||||||
const setMaxZoom: Actions['setMaxZoom'] = (maxZoom: any) => {
|
const setMaxZoom: Actions['setMaxZoom'] = (maxZoom: any) => {
|
||||||
state.d3Zoom?.scaleExtent([state.minZoom, maxZoom])
|
state.d3Zoom?.scaleExtent([state.minZoom, maxZoom])
|
||||||
state.maxZoom = maxZoom
|
state.maxZoom = maxZoom
|
||||||
}
|
}
|
||||||
|
|
||||||
const setTranslateExtent: Actions['setTranslateExtent'] = (translateExtent: any) => {
|
const setTranslateExtent: Actions['setTranslateExtent'] = (translateExtent: any) => {
|
||||||
state.d3Zoom?.translateExtent(translateExtent)
|
state.d3Zoom?.translateExtent(translateExtent)
|
||||||
state.translateExtent = translateExtent
|
state.translateExtent = translateExtent
|
||||||
}
|
}
|
||||||
|
|
||||||
const resetSelectedElements: Actions['resetSelectedElements'] = () => {
|
const resetSelectedElements: Actions['resetSelectedElements'] = () => {
|
||||||
addSelectedNodes([])
|
addSelectedNodes([])
|
||||||
addSelectedEdges([])
|
addSelectedEdges([])
|
||||||
}
|
}
|
||||||
|
|
||||||
const setInteractive: Actions['setInteractive'] = (isInteractive) => {
|
const setInteractive: Actions['setInteractive'] = (isInteractive) => {
|
||||||
state.nodesDraggable = isInteractive
|
state.nodesDraggable = isInteractive
|
||||||
state.nodesConnectable = isInteractive
|
state.nodesConnectable = isInteractive
|
||||||
@@ -215,6 +220,7 @@ export default (state: State, getters: ComputedGetters): Actions => {
|
|||||||
if (!state.initialized && !nodes.length) return
|
if (!state.initialized && !nodes.length) return
|
||||||
state.nodes = createGraphNodes(nodes, getters.getNode.value, state.nodes, extent ?? state.nodeExtent)
|
state.nodes = createGraphNodes(nodes, getters.getNode.value, state.nodes, extent ?? state.nodeExtent)
|
||||||
}
|
}
|
||||||
|
|
||||||
const setEdges: Actions['setEdges'] = (edges) => {
|
const setEdges: Actions['setEdges'] = (edges) => {
|
||||||
if (!state.initialized && !edges.length) return
|
if (!state.initialized && !edges.length) return
|
||||||
state.edges = edges.map((edge) => {
|
state.edges = edges.map((edge) => {
|
||||||
@@ -269,10 +275,10 @@ export default (state: State, getters: ComputedGetters): Actions => {
|
|||||||
|
|
||||||
const updateEdge: Actions['updateEdge'] = (oldEdge, newConnection) =>
|
const updateEdge: Actions['updateEdge'] = (oldEdge, newConnection) =>
|
||||||
updateEdgeAction(oldEdge, newConnection, state.edges, addEdges)
|
updateEdgeAction(oldEdge, newConnection, state.edges, addEdges)
|
||||||
const applyNodeChanges: Actions['applyNodeChanges'] = (changes) =>
|
|
||||||
applyNodeChangesAction(changes, state.nodes, getters.getNode.value)
|
const applyNodeChanges: Actions['applyNodeChanges'] = (changes) => applyNodes(changes, state.nodes)
|
||||||
const applyEdgeChanges: Actions['applyEdgeChanges'] = (changes) =>
|
|
||||||
applyEdgeChangesAction(changes, state.edges, getters.getNode.value)
|
const applyEdgeChanges: Actions['applyEdgeChanges'] = (changes) => applyEdges(changes, state.edges)
|
||||||
|
|
||||||
const setState: Actions['setState'] = (opts) => {
|
const setState: Actions['setState'] = (opts) => {
|
||||||
const skip = ['modelValue', 'nodes', 'edges', 'maxZoom', 'minZoom', 'translateExtent']
|
const skip = ['modelValue', 'nodes', 'edges', 'maxZoom', 'minZoom', 'translateExtent']
|
||||||
@@ -298,6 +304,7 @@ export default (state: State, getters: ComputedGetters): Actions => {
|
|||||||
}
|
}
|
||||||
if (!state.initialized) state.initialized = true
|
if (!state.initialized) state.initialized = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
updateNodePosition,
|
updateNodePosition,
|
||||||
updateNodeDimensions,
|
updateNodeDimensions,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
Getters,
|
Getters,
|
||||||
CoordinateExtent,
|
CoordinateExtent,
|
||||||
XYPosition,
|
XYPosition,
|
||||||
|
GraphEdge,
|
||||||
} from '~/types'
|
} from '~/types'
|
||||||
|
|
||||||
type CreatePositionChangeParams = {
|
type CreatePositionChangeParams = {
|
||||||
@@ -21,8 +22,8 @@ type CreatePositionChangeParams = {
|
|||||||
dragging?: boolean
|
dragging?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleParentExpand(updateItem: GraphNode, getNode: Getters['getNode']) {
|
function handleParentExpand(updateItem: GraphNode, curr: GraphNode[]) {
|
||||||
const parent = updateItem.parentNode ? getNode(updateItem.parentNode) : undefined
|
const parent = updateItem.parentNode ? curr.find((el) => el.id === updateItem.parentNode) : undefined
|
||||||
if (parent) {
|
if (parent) {
|
||||||
const extendWidth = updateItem.position.x + updateItem.dimensions.width - parent.dimensions.width
|
const extendWidth = updateItem.position.x + updateItem.dimensions.width - parent.dimensions.width
|
||||||
const extendHeight = updateItem.position.y + updateItem.dimensions.height - parent.dimensions.height
|
const extendHeight = updateItem.position.y + updateItem.dimensions.height - parent.dimensions.height
|
||||||
@@ -94,7 +95,6 @@ export const applyChanges = <
|
|||||||
>(
|
>(
|
||||||
changes: C[],
|
changes: C[],
|
||||||
elements: T[],
|
elements: T[],
|
||||||
getNode: Getters['getNode'],
|
|
||||||
): T[] => {
|
): T[] => {
|
||||||
let elementIds = elements.map((el) => el.id)
|
let elementIds = elements.map((el) => el.id)
|
||||||
changes.forEach((change) => {
|
changes.forEach((change) => {
|
||||||
@@ -109,13 +109,13 @@ export const applyChanges = <
|
|||||||
if (isGraphNode(el)) {
|
if (isGraphNode(el)) {
|
||||||
if (typeof change.position !== 'undefined') el.position = change.position
|
if (typeof change.position !== 'undefined') el.position = change.position
|
||||||
if (typeof change.dragging !== 'undefined') el.dragging = change.dragging
|
if (typeof change.dragging !== 'undefined') el.dragging = change.dragging
|
||||||
if (el.expandParent && el.parentNode) handleParentExpand(el, getNode)
|
if (el.expandParent && el.parentNode) handleParentExpand(el, elements as GraphNode[])
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'dimensions':
|
case 'dimensions':
|
||||||
if (isGraphNode(el)) {
|
if (isGraphNode(el)) {
|
||||||
if (typeof change.dimensions !== 'undefined') el.dimensions = change.dimensions
|
if (typeof change.dimensions !== 'undefined') el.dimensions = change.dimensions
|
||||||
if (el.expandParent && el.parentNode) handleParentExpand(el, getNode)
|
if (el.expandParent && el.parentNode) handleParentExpand(el, elements as GraphNode[])
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
case 'remove':
|
case 'remove':
|
||||||
@@ -128,6 +128,9 @@ export const applyChanges = <
|
|||||||
return elements
|
return elements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const applyEdgeChanges = (changes: EdgeChange[], edges: GraphEdge[]) => applyChanges(changes, edges)
|
||||||
|
export const applyNodeChanges = (changes: NodeChange[], nodes: GraphNode[]) => applyChanges(changes, nodes)
|
||||||
|
|
||||||
export const createSelectionChange = (id: string, selected: boolean): NodeSelectionChange | EdgeSelectionChange => ({
|
export const createSelectionChange = (id: string, selected: boolean): NodeSelectionChange | EdgeSelectionChange => ({
|
||||||
id,
|
id,
|
||||||
type: 'select',
|
type: 'select',
|
||||||
@@ -136,9 +139,9 @@ export const createSelectionChange = (id: string, selected: boolean): NodeSelect
|
|||||||
|
|
||||||
export const createPositionChange = (
|
export const createPositionChange = (
|
||||||
{ node, diff, dragging, nodeExtent }: CreatePositionChangeParams,
|
{ node, diff, dragging, nodeExtent }: CreatePositionChangeParams,
|
||||||
getNode: Getters['getNode'],
|
curr: GraphNode[],
|
||||||
): NodePositionChange => {
|
): NodePositionChange => {
|
||||||
const parent = node.parentNode ? getNode(node.parentNode) : undefined
|
const parent = node.parentNode ? curr.find((el) => el.id === node.parentNode) : undefined
|
||||||
const change: NodePositionChange = {
|
const change: NodePositionChange = {
|
||||||
id: node.id,
|
id: node.id,
|
||||||
type: 'position',
|
type: 'position',
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import {
|
|||||||
XYPosition,
|
XYPosition,
|
||||||
XYZPosition,
|
XYZPosition,
|
||||||
Getters,
|
Getters,
|
||||||
|
DefaultEdgeOptions,
|
||||||
} from '~/types'
|
} from '~/types'
|
||||||
import { useWindow } from '~/composables'
|
import { useWindow } from '~/composables'
|
||||||
|
|
||||||
@@ -139,7 +140,11 @@ export const connectionExists = (edge: Edge, elements: Elements) =>
|
|||||||
(el.targetHandle === edge.targetHandle || (!el.targetHandle && !edge.targetHandle)),
|
(el.targetHandle === edge.targetHandle || (!el.targetHandle && !edge.targetHandle)),
|
||||||
)
|
)
|
||||||
|
|
||||||
export const addEdge = (edgeParams: Edge | Connection, elements: Elements) => {
|
/**
|
||||||
|
* Intended for options API
|
||||||
|
* In composition API you can access utilities from `useVueFlow`
|
||||||
|
*/
|
||||||
|
export const addEdge = (edgeParams: Edge | Connection, elements: Elements, defaults?: DefaultEdgeOptions) => {
|
||||||
if (!edgeParams.source || !edgeParams.target) {
|
if (!edgeParams.source || !edgeParams.target) {
|
||||||
console.warn("Can't create edge. An edge needs a source and a target.")
|
console.warn("Can't create edge. An edge needs a source and a target.")
|
||||||
return elements
|
return elements
|
||||||
@@ -154,12 +159,16 @@ export const addEdge = (edgeParams: Edge | Connection, elements: Elements) => {
|
|||||||
id: getEdgeId(edgeParams),
|
id: getEdgeId(edgeParams),
|
||||||
} as Edge
|
} as Edge
|
||||||
}
|
}
|
||||||
edge = parseEdge(edge)
|
edge = parseEdge(edge, defaults)
|
||||||
if (connectionExists(edge, elements)) return elements
|
if (connectionExists(edge, elements)) return elements
|
||||||
elements.push(edge)
|
elements.push(edge)
|
||||||
return [...elements, edge]
|
return [...elements, edge]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intended for options API
|
||||||
|
* In composition API you can access utilities from `useVueFlow`
|
||||||
|
*/
|
||||||
export const updateEdge = (oldEdge: Edge, newConnection: Connection, elements: Elements) => {
|
export const updateEdge = (oldEdge: Edge, newConnection: Connection, elements: Elements) => {
|
||||||
if (!newConnection.source || !newConnection.target) {
|
if (!newConnection.source || !newConnection.target) {
|
||||||
console.warn("Can't create new edge. An edge needs a source and a target.")
|
console.warn("Can't create new edge. An edge needs a source and a target.")
|
||||||
|
|||||||
Reference in New Issue
Block a user