From e8a6dc37af76a10cfdf059a188cffd1a09c9622f Mon Sep 17 00:00:00 2001 From: braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Tue, 30 Aug 2022 14:08:00 +0200 Subject: [PATCH] fix(nodes): apply global node extent when changed --- .../vue-flow/src/container/VueFlow/watch.ts | 31 +++++++++++- packages/vue-flow/src/store/actions.ts | 47 +++++++++++++------ packages/vue-flow/src/types/store.ts | 2 + 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/packages/vue-flow/src/container/VueFlow/watch.ts b/packages/vue-flow/src/container/VueFlow/watch.ts index 18667c42..6bbc1aab 100644 --- a/packages/vue-flow/src/container/VueFlow/watch.ts +++ b/packages/vue-flow/src/container/VueFlow/watch.ts @@ -159,6 +159,20 @@ export default (models: ToRefs }) } + const watchNodeExtent = () => { + scope.run(() => { + watch( + () => props.nodeExtent, + () => { + if (props.nodeExtent && isDef(props.nodeExtent)) { + store.setNodeExtent(props.nodeExtent) + } + }, + { immediate: isDef(props.nodeExtent) }, + ) + }) + } + const watchApplyDefault = () => { scope.run(() => { watch( @@ -235,9 +249,21 @@ export default (models: ToRefs } const watchRest = () => { - const skip = ['id', 'modelValue', 'translateExtent', 'edges', 'nodes', 'maxZoom', 'minZoom', 'applyDefault', 'autoConnect'] + const skip: (keyof typeof props)[] = [ + 'id', + 'modelValue', + 'translateExtent', + 'nodeExtent', + 'edges', + 'nodes', + 'maxZoom', + 'minZoom', + 'applyDefault', + 'autoConnect', + ] + Object.keys(props).forEach((prop) => { - if (!skip.includes(prop)) { + if (!skip.includes(prop as keyof typeof props)) { const model = toRef(props, prop as keyof typeof props) const storedValue = store[prop as keyof typeof store] as typeof model @@ -263,6 +289,7 @@ export default (models: ToRefs watchMinZoom, watchMaxZoom, watchTranslateExtent, + watchNodeExtent, watchApplyDefault, watchAutoConnect, watchRest, diff --git a/packages/vue-flow/src/store/actions.ts b/packages/vue-flow/src/store/actions.ts index 86193f6d..c727050f 100644 --- a/packages/vue-flow/src/store/actions.ts +++ b/packages/vue-flow/src/store/actions.ts @@ -37,6 +37,10 @@ import { import { useZoomPanHelper } from '~/composables' export default (state: State, getters: ComputedGetters): Actions => { + const updateNodeInternals: Actions['updateNodeInternals'] = (ids) => { + state.hooks.updateNodeInternals.trigger(ids) + } + const updateNodePositions: Actions['updateNodePositions'] = (dragItems, changed, dragging) => { const changes: NodePositionChange[] = [] @@ -166,11 +170,17 @@ export default (state: State, getters: ComputedGetters): Actions => { state.maxZoom = maxZoom } - const setTranslateExtent: Actions['setTranslateExtent'] = (translateExtent: any) => { + const setTranslateExtent: Actions['setTranslateExtent'] = (translateExtent) => { state.d3Zoom?.translateExtent(translateExtent) state.translateExtent = translateExtent } + const setNodeExtent: Actions['setNodeExtent'] = (nodeExtent) => { + state.nodeExtent = nodeExtent + const nodeIds = getters.getNodes.value.map((n) => n.id) + updateNodeInternals(nodeIds) + } + const setInteractive: Actions['setInteractive'] = (isInteractive) => { state.nodesDraggable = isInteractive state.nodesConnectable = isInteractive @@ -321,29 +331,39 @@ export default (state: State, getters: ComputedGetters): Actions => { const applyEdgeChanges: Actions['applyEdgeChanges'] = (changes) => applyChanges(changes, state.edges) const setState: Actions['setState'] = (options) => { - const skip = ['modelValue', 'nodes', 'edges', 'maxZoom', 'minZoom', 'translateExtent', 'hooks'] const opts = options instanceof Function ? options(state) : options + const skip: (keyof typeof opts)[] = [ + 'modelValue', + 'nodes', + 'edges', + 'maxZoom', + 'minZoom', + 'translateExtent', + 'nodeExtent', + 'hooks', + ] if (typeof opts.modelValue !== 'undefined') setElements(opts.modelValue, opts.nodeExtent ?? state.nodeExtent) if (typeof opts.nodes !== 'undefined') setNodes(opts.nodes, opts.nodeExtent ?? state.nodeExtent) if (typeof opts.edges !== 'undefined') setEdges(opts.edges) + const setSkippedOptions = () => { + if (typeof opts.maxZoom !== 'undefined') setMaxZoom(opts.maxZoom) + if (typeof opts.minZoom !== 'undefined') setMinZoom(opts.minZoom) + if (typeof opts.translateExtent !== 'undefined') setTranslateExtent(opts.translateExtent) + if (typeof opts.nodeExtent !== 'undefined') setNodeExtent(opts.nodeExtent) + } + Object.keys(opts).forEach((o) => { const option = opts[o as keyof typeof opts] - if (!skip.includes(o) && isDef(option)) (state)[o] = option + if (!skip.includes(o as keyof typeof opts) && isDef(option)) (state)[o] = option }) if (!state.d3Zoom) until(() => state.d3Zoom) .not.toBeUndefined() - .then(() => { - if (typeof opts.maxZoom !== 'undefined') setMaxZoom(opts.maxZoom) - if (typeof opts.minZoom !== 'undefined') setMinZoom(opts.minZoom) - if (typeof opts.translateExtent !== 'undefined') setTranslateExtent(opts.translateExtent) - }) + .then(setSkippedOptions) else { - if (typeof opts.maxZoom !== 'undefined') setMaxZoom(opts.maxZoom) - if (typeof opts.minZoom !== 'undefined') setMinZoom(opts.minZoom) - if (typeof opts.translateExtent !== 'undefined') setTranslateExtent(opts.translateExtent) + setSkippedOptions() } if (!state.initialized) state.initialized = true } @@ -360,10 +380,6 @@ export default (state: State, getters: ComputedGetters): Actions => { ) } - const updateNodeInternals: Actions['updateNodeInternals'] = (ids) => { - state.hooks.updateNodeInternals.trigger(ids) - } - let zoomPanHelper: ReturnType state.hooks.paneReady.on(({ id }) => { @@ -403,6 +419,7 @@ export default (state: State, getters: ComputedGetters): Actions => { setMinZoom, setMaxZoom, setTranslateExtent, + setNodeExtent, removeSelectedElements, removeSelectedNodes, removeSelectedEdges, diff --git a/packages/vue-flow/src/types/store.ts b/packages/vue-flow/src/types/store.ts index 3c7de27f..59c96a62 100644 --- a/packages/vue-flow/src/types/store.ts +++ b/packages/vue-flow/src/types/store.ts @@ -174,6 +174,8 @@ export interface Actions extends ViewportFunctions { setMaxZoom: (zoom: number) => void /** apply translate extent to d3 */ setTranslateExtent: (translateExtent: CoordinateExtent) => void + /** apply extent to nodes */ + setNodeExtent: (nodeExtent: CoordinateExtent) => void /** enable/disable node interaction (dragging, selecting etc) */ setInteractive: (isInteractive: boolean) => void /** set new state */