diff --git a/src/store/stateStore.ts b/src/store/stateStore.ts index 78ab295e..8e5d8d9a 100644 --- a/src/store/stateStore.ts +++ b/src/store/stateStore.ts @@ -1,9 +1,8 @@ import microDiff from 'microdiff' import { setActivePinia, createPinia, defineStore, StoreDefinition, acceptHMRUpdate } from 'pinia' -import { FlowState, Node, FlowActions, Elements, FlowGetters, GraphNode, NextElements, GraphEdge } from '~/types' +import { FlowState, FlowActions, Elements, FlowGetters, GraphNode, NextElements, GraphEdge, FlowElements } from '~/types' import { clampPosition, - getDimensions, getConnectedEdges, getNodesInside, getRectOfNodes, @@ -11,9 +10,9 @@ import { defaultNodeTypes, defaultEdgeTypes, deepUnref, - getHandleBounds, isGraphNode, getSourceTargetNodes, + isEdge, } from '~/utils' import parseElementsWorker from '~/workers/parseElements' @@ -42,11 +41,12 @@ export default (id: string, preloadedState: FlowState) => { this.nodeTypes?.forEach((n) => (nodeTypes[n] = n)) return nodeTypes }, - getNodes(): Node[] { + getNodes(): GraphNode[] { + const nodes = this.elements.filter(isGraphNode) const n = this.onlyRenderVisibleElements - ? this.nodes && + ? nodes && getNodesInside( - this.nodes, + nodes, { x: 0, y: 0, @@ -56,12 +56,13 @@ export default (id: string, preloadedState: FlowState) => { this.transform, true, ) - : this.nodes + : nodes return n.filter((node) => !node.isHidden) }, getEdges(): GraphEdge[] { - return this.edges + const edges = this.elements.filter(isEdge) + return edges .filter((edge) => !edge.isHidden) .map((edge) => { const { sourceNode, targetNode } = getSourceTargetNodes(edge, this.getNodes) @@ -78,6 +79,9 @@ export default (id: string, preloadedState: FlowState) => { }) .filter(({ sourceTargetNodes: { sourceNode, targetNode } }) => !!(sourceNode && targetNode)) }, + getSelectedNodes(): GraphNode[] { + return this.selectedElements?.filter(isGraphNode) ?? [] + }, }, actions: { async setElements(elements) { @@ -106,86 +110,6 @@ export default (id: string, preloadedState: FlowState) => { next = await parseElements(elements, this.nodes, this.edges, this.nodeExtent) } this.elements = [...next.nextNodes, ...next.nextEdges] - this.nodes = next.nextNodes ?? [] - this.edges = next.nextEdges ?? [] - }, - updateNodeDimensions({ id, nodeElement, forceUpdate }) { - const i = this.nodes.map((x) => x.id).indexOf(id) - const node = this.nodes[i] - const dimensions = getDimensions(nodeElement) - - const doUpdate = - dimensions.width && - dimensions.height && - (node.__vf?.width !== dimensions.width || node.__vf?.height !== dimensions.height || forceUpdate) - - if (doUpdate) { - const handleBounds = getHandleBounds(nodeElement, this.transform[2]) - - this.nodes.splice(i, 1, { - ...node, - __vf: { - ...node.__vf, - ...dimensions, - handleBounds, - }, - }) - } - }, - updateNodePos({ id, pos }) { - const i = this.nodes.map((x) => x.id).indexOf(id) - const node = this.nodes[i] - - if (this.snapToGrid) { - const [gridSizeX, gridSizeY] = this.snapGrid - pos = { - x: gridSizeX * Math.round(pos.x / gridSizeX), - y: gridSizeY * Math.round(pos.y / gridSizeY), - } - } - - this.nodes.splice(i, 1, { - ...node, - __vf: { - ...node.__vf, - position: pos, - }, - }) - }, - updateNodePosDiff({ id, diff, isDragging }) { - const update = (node: GraphNode, i: number) => { - const updatedNode: GraphNode = { - ...node, - __vf: { - ...node.__vf, - isDragging, - }, - } - - if (diff && node.__vf) { - updatedNode.__vf!.position = { - x: node.__vf.position.x + diff.x, - y: node.__vf.position.y + diff.y, - } - } - - this.nodes.splice(i, 1, { - ...node, - ...updatedNode, - }) - } - - if (!id) { - const selectedNodes = this.nodes.filter((x) => this.selectedElements?.find((sNode) => sNode?.id === x.id)) - selectedNodes.forEach((node) => { - const i = this.nodes.map((x) => x.id).indexOf(node.id) - update(node, i) - }) - } else { - const i = this.nodes.map((x) => x.id).indexOf(id) - const node = this.nodes[i] - update(node, i) - } }, setUserSelection(mousePos) { this.selectionActive = true @@ -210,25 +134,22 @@ export default (id: string, preloadedState: FlowState) => { width: Math.abs(mousePos.x - startX), height: Math.abs(mousePos.y - startY), } - - const selectedNodes = getNodesInside(this.nodes, nextUserSelectRect, this.transform) - const selectedEdges = getConnectedEdges(selectedNodes, this.edges) + const selectedNodes = getNodesInside(this.getNodes, this.userSelectionRect, this.transform) + const selectedEdges = getConnectedEdges(selectedNodes, this.getEdges) const nextSelectedElements = [...selectedNodes, ...selectedEdges] this.userSelectionRect = nextUserSelectRect this.selectedElements = nextSelectedElements }, unsetUserSelection() { - const selectedNodes = this.selectedElements?.filter((node) => node && isGraphNode(node) && node.__vf) as GraphNode[] - this.selectionActive = false this.userSelectionRect.draw = false - if (!selectedNodes || selectedNodes.length === 0) { + if (!this.getSelectedNodes || this.getSelectedNodes.length === 0) { this.selectedElements = undefined this.nodesSelectionActive = false } else { - this.selectedNodesBbox = getRectOfNodes(selectedNodes) + this.selectedNodesBbox = getRectOfNodes(this.getSelectedNodes) this.nodesSelectionActive = true } }, @@ -259,10 +180,7 @@ export default (id: string, preloadedState: FlowState) => { this.nodes = this.nodes.map((node) => { return { ...node, - __vf: { - ...node.__vf, - position: node.__vf?.position ? clampPosition(node.__vf.position, nodeExtent) : { x: 0, y: 0 }, - }, + position: node.position ? clampPosition(node.position, nodeExtent) : { x: 0, y: 0 }, } }) }, diff --git a/src/types/node.ts b/src/types/node.ts index 0c257ef3..ec03c99c 100644 --- a/src/types/node.ts +++ b/src/types/node.ts @@ -57,17 +57,6 @@ export type SourceTargetNode = { targetNode: GraphNode } -export type NodePosUpdate = { - id: ElementId - pos: XYPosition -} - -export type NodeDiffUpdate = { - id?: ElementId - diff?: XYPosition - isDragging?: boolean -} - export type TranslateExtent = [[number, number], [number, number]] export type NodeExtent = TranslateExtent diff --git a/src/types/store.ts b/src/types/store.ts index 4a5788f7..4de4d55f 100644 --- a/src/types/store.ts +++ b/src/types/store.ts @@ -22,16 +22,17 @@ import { SetConnectionId, } from './connection' import { Edge, EdgeComponent, GraphEdge } from './edge' -import { NodeComponent, NodeDiffUpdate, NodeDimensionUpdate, NodeExtent, GraphNode, NodePosUpdate, TranslateExtent } from './node' +import { NodeComponent, NodeExtent, GraphNode, TranslateExtent } from './node' import { D3Selection, D3Zoom, D3ZoomHandler, InitD3ZoomPayload } from './zoom' import { FlowHooks } from './hooks' export interface FlowState extends FlowOptions { + hooks: FlowHooks + instance?: FlowInstance + elements: FlowElements nodes: GraphNode[] edges: Edge[] - selectedElements?: FlowElements - selectedNodesBbox: Rect d3Zoom?: D3Zoom d3Selection?: D3Selection @@ -43,6 +44,8 @@ export interface FlowState extends FlowOptions { dimensions: Dimensions transform: Transform + selectedElements?: FlowElements + selectedNodesBbox?: Rect nodesSelectionActive: boolean selectionActive: boolean userSelectionRect: SelectionRect @@ -67,17 +70,12 @@ export interface FlowState extends FlowOptions { onConnectEnd?: OnConnectEndFunc isReady: boolean - hooks: FlowHooks - instance?: FlowInstance vueFlowVersion: string } export interface FlowActions { setElements: (elements: Elements) => Promise - updateNodeDimensions: (update: NodeDimensionUpdate) => void - updateNodePos: (payload: NodePosUpdate) => void - updateNodePosDiff: (payload: NodeDiffUpdate) => void setUserSelection: (mousePos: XYPosition) => void updateUserSelection: (mousePos: XYPosition) => void unsetUserSelection: () => void @@ -100,6 +98,7 @@ export interface FlowGetters { getNodeTypes: () => Record getNodes: () => GraphNode[] getEdges: () => GraphEdge[] + getSelectedNodes: () => GraphNode[] } export type FlowStore = Store diff --git a/src/utils/store.ts b/src/utils/store.ts index 68fcad54..d5d44486 100644 --- a/src/utils/store.ts +++ b/src/utils/store.ts @@ -7,8 +7,7 @@ import { NodeExtent, GraphNode, PanOnScrollMode, - Node, - Edge, + GraphEdge, DefaultNodeTypes, DefaultEdgeTypes, } from '~/types'