From 0450ba2eae24b9f8b0c834525328c8d44f0084ad Mon Sep 17 00:00:00 2001 From: Braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Sat, 11 Dec 2021 14:11:44 +0100 Subject: [PATCH] feat(store): flatten child map of nodes Signed-off-by: Braks <78412429+bcakmakoglu@users.noreply.github.com> --- examples/Basic/Basic.vue | 6 ++++-- examples/Nesting/Nesting.vue | 22 +++++++++++----------- src/store/actions.ts | 36 ++++++++++++++++++++++++++---------- src/types/flow.ts | 3 ++- src/utils/graph.ts | 7 +++---- 5 files changed, 46 insertions(+), 28 deletions(-) diff --git a/examples/Basic/Basic.vue b/examples/Basic/Basic.vue index 86ea3444..3c20d8f7 100644 --- a/examples/Basic/Basic.vue +++ b/examples/Basic/Basic.vue @@ -9,7 +9,6 @@ import { Elements, FlowInstance, addEdge, - isNode, removeElements, } from '~/index' @@ -21,7 +20,10 @@ const nodes = ref([ { id: '3', label: 'Node 3', position: { x: 400, y: 100 } }, { id: '4', label: 'Node 4', position: { x: 400, y: 200 } }, ]) -const edges = ref([]) +const edges = ref([ + { id: 'e1-2', source: '1', target: '2', animated: true }, + { id: 'e1-3', source: '1', target: '3' }, +]) const vfInstance = ref() const onLoad = (flowInstance: FlowInstance) => { flowInstance.fitView({ padding: 0.1 }) diff --git a/examples/Nesting/Nesting.vue b/examples/Nesting/Nesting.vue index 4d756a5e..005d81ef 100644 --- a/examples/Nesting/Nesting.vue +++ b/examples/Nesting/Nesting.vue @@ -3,27 +3,27 @@ import GroupNode from './GroupNode.vue' import { VueFlow, Elements, Node, Edge, Connection, addEdge } from '~/index' const elements = ref>([ - { - id: 'node-1', - data: { label: 'node-1', group: undefined }, - position: { x: 250, y: 5 }, - parentNode: 'group-a', - extent: 'parent', - }, - { id: 'node-2', data: { label: 'node-2', group: undefined }, position: { x: 50, y: 5 } }, + { id: 'node-2', label: 'node-2', position: { x: 50, y: 5 } }, { id: 'group-a', style: { zIndex: 2, width: '300px', height: '300px' }, selectable: false, - data: { label: 'A' }, + label: 'A', position: { x: 50, y: 100 }, + children: [ + { + id: 'node-1', + label: 'node-1', + position: { x: 250, y: 5 }, + extent: 'parent', + }, + ], }, { id: 'group-b', - type: 'group-b', style: { zIndex: 2 }, selectable: false, - data: { label: 'B' }, + label: 'B', position: { x: 500, y: 100 }, }, ]) diff --git a/src/store/actions.ts b/src/store/actions.ts index d3f49209..d2af74bf 100644 --- a/src/store/actions.ts +++ b/src/store/actions.ts @@ -95,22 +95,37 @@ export default (state: FlowState, getters: FlowGetters): FlowActions => { state.nodesConnectable = isInteractive state.elementsSelectable = isInteractive } + + function getParent(root: Node[], id: string): GraphNode | undefined { + let node + + root.some((n) => { + if (n.id === id) { + return (node = n) + } + if (n.children) { + return (node = getParent(n.children, id)) + } + return false + }) + return node + } + const setNodes: FlowActions['setNodes'] = (nodes, extent: CoordinateExtent) => { - const parseChildren = (n: Node, arr: GraphNode[] = []) => { - arr.concat(parseNode(n, extent)) + const parseChildren = (n: Node, p?: GraphNode, arr: GraphNode[] = []) => { + const parent = typeof p === 'undefined' || typeof p !== 'object' ? getParent(arr, n.id) : p + const parsed = parseNode(n, extent, { + parentNode: parent, + }) + arr.push(parsed) if (n.children && n.children.length) { - n.children.forEach((c) => parseChildren(c)) - } else { - return arr + n.children.forEach((c) => parseChildren(c, parsed, arr)) } } nodes = nodes.flatMap((node) => { - const parsed = parseNode(node, extent) const children: GraphNode[] = [] - if (node.children && node.children.length) { - node.children.forEach((c) => parseChildren(c, children)) - } - return [parsed, ...children] + parseChildren(node, undefined, children) + return children }) state.nodes = nodes } @@ -136,6 +151,7 @@ export default (state: FlowState, getters: FlowGetters): FlowActions => { } const setState: FlowActions['setState'] = (opts) => { + if (typeof opts.modelValue !== 'undefined') setElements(opts.modelValue, opts.nodeExtent ?? state.nodeExtent) if (typeof opts.elements !== 'undefined') setElements(opts.elements, opts.nodeExtent ?? state.nodeExtent) if (typeof opts.nodes !== 'undefined') setNodes(opts.nodes, opts.nodeExtent ?? state.nodeExtent) if (typeof opts.edges !== 'undefined') setEdges(opts.edges) diff --git a/src/types/flow.ts b/src/types/flow.ts index 71a451a3..dbf37501 100644 --- a/src/types/flow.ts +++ b/src/types/flow.ts @@ -113,7 +113,8 @@ export type FlowInstance = { } export interface FlowProps { - nodes: Node[] + modelValue?: any + nodes?: Node[] edges?: Edge[] elements?: Elements id?: string diff --git a/src/utils/graph.ts b/src/utils/graph.ts index b35ffbc5..0aa27385 100644 --- a/src/utils/graph.ts +++ b/src/utils/graph.ts @@ -163,7 +163,8 @@ export const pointToRendererPoint = ( export const onLoadProject = (currentStore: FlowStore) => (position: XYPosition) => pointToRendererPoint(position, currentStore.transform, currentStore.snapToGrid, currentStore.snapGrid) -export const parseNode = (node: Node, nodeExtent: CoordinateExtent): GraphNode => ({ +export const parseNode = (node: Node, nodeExtent: CoordinateExtent, defaults?: Partial): GraphNode => ({ + ...defaults, ...node, id: node.id.toString(), type: node.type ?? 'default', @@ -322,9 +323,7 @@ export function calculateXYZPosition(node: GraphNode, result: XYZPosition): XYZP x: result.x + node.parentNode.position.x, y: result.y + node.parentNode.position.y, z: - node.parentNode.computedPosition.z > node.computedPosition.z - ? node.parentNode.computedPosition.z + 1 - : node.computedPosition.z, + node.parentNode.computedPosition.z > node.computedPosition.z ? node.parentNode.computedPosition.z : node.computedPosition.z, }) }