fix: inject store instance components

chore: update revue-draggable to next tag
This commit is contained in:
Braks
2021-07-20 20:01:10 +02:00
parent 8cfbc89d23
commit b4fcab4004
15 changed files with 152 additions and 140 deletions

View File

@@ -2,8 +2,9 @@ import { createApp } from 'vue';
import './index.css';
import App from './App';
import { router } from './router';
import { DraggablePlugin } from '@braks/revue-draggable';
import { createPinia } from 'pinia';
import { DraggablePlugin } from '@braks/revue-draggable';
const app = createApp(App);
app.config.performance = true;

View File

@@ -28,7 +28,7 @@
"lint": "yarn lint:js"
},
"dependencies": {
"@braks/revue-draggable": "^0.1.13",
"@braks/revue-draggable": "^0.2.1-5",
"@types/d3": "^7.0.0",
"d3": "^7.0.0",
"d3-selection": "^3.0.0",

View File

@@ -1,7 +1,6 @@
import { BackgroundVariant } from '../../types';
import { BackgroundVariant, RevueFlowStore } from '../../types';
import { createGridDotsPath, createGridLinesPath } from './utils';
import { computed, defineComponent, HTMLAttributes, PropType } from 'vue';
import store from '../../store';
import { computed, defineComponent, HTMLAttributes, inject, PropType } from 'vue';
export interface BackgroundProps extends HTMLAttributes {
variant?: BackgroundVariant;
@@ -26,7 +25,7 @@ const Background = defineComponent({
gap: {
type: Number as PropType<BackgroundProps['gap']>,
required: false,
default: 15
default: 10
},
color: {
type: String as PropType<BackgroundProps['color']>,
@@ -40,8 +39,8 @@ const Background = defineComponent({
}
},
setup(props) {
const pinia = store();
const transform = computed(() => pinia.transform);
const store = inject<RevueFlowStore>('store')!;
const transform = computed(() => store.transform);
// when there are multiple flows on a page we need to make sure that every background gets its own pattern.
const patternId = `pattern-${Math.floor(Math.random() * 100000)}`;
@@ -50,12 +49,12 @@ const Background = defineComponent({
const xOffset = computed(() => scaledGap.value && transform.value[0] % scaledGap.value);
const yOffset = computed(() => scaledGap.value && transform.value[1] % scaledGap.value);
const isLines = props.variant === BackgroundVariant.Lines;
const bgColor = props.color ? props.color : defaultColors[props.variant || BackgroundVariant.Dots];
const isLines = computed(() => props.variant === BackgroundVariant.Lines);
const bgColor = computed(() => (props.color ? props.color : defaultColors[props.variant || BackgroundVariant.Dots]));
const path = computed(() =>
isLines
? scaledGap.value && props.size && createGridLinesPath(scaledGap.value, props.size, bgColor)
: createGridDotsPath(props.size || 0.4 * transform.value[2], bgColor)
isLines.value
? scaledGap.value && props.size && createGridLinesPath(scaledGap.value, props.size, bgColor.value)
: createGridDotsPath(props.size || 0.4 * transform.value[2], bgColor.value)
);
return () => (

View File

@@ -1,7 +1,6 @@
import { defineComponent, HTMLAttributes, onMounted, PropType, ref } from 'vue';
import { defineComponent, HTMLAttributes, inject, onMounted, PropType, ref } from 'vue';
import useZoomPanHelper from '../../hooks/useZoomPanHelper';
import { FitViewParams } from '../../types';
import store from '../../store';
import { FitViewParams, RevueFlowStore } from '../../types';
import PlusIcon from '../../../assets/icons/plus.svg';
import MinusIcon from '../../../assets/icons/minus.svg';
import Fitview from '../../../assets/icons/fitview.svg';
@@ -88,7 +87,7 @@ const Controls = defineComponent({
}
},
setup(props, { slots }) {
const pinia = store();
const store = inject<RevueFlowStore>('store')!;
const isVisible = ref<boolean>(false);
const zoomHelper = ref(useZoomPanHelper());
@@ -96,7 +95,7 @@ const Controls = defineComponent({
zoomHelper.value = useZoomPanHelper();
});
const isInteractive = pinia.nodesDraggable && pinia.nodesConnectable && pinia.elementsSelectable;
const isInteractive = store.nodesDraggable && store.nodesConnectable && store.elementsSelectable;
const mapClasses = ['revue-flow__controls'];
const onZoomInHandler = () => {
@@ -115,7 +114,7 @@ const Controls = defineComponent({
};
const onInteractiveChangeHandler = () => {
pinia.setInteractive?.(!isInteractive);
store.setInteractive?.(!isInteractive);
props.onInteractiveChange?.(!isInteractive);
};

View File

@@ -1,8 +1,7 @@
import { getRectOfNodes, getBoundsofRects } from '../../utils/graph';
import { Node, Rect } from '../../types';
import { Node, Rect, RevueFlowStore } from '../../types';
import MiniMapNode from './MiniMapNode';
import { computed, defineComponent, HTMLAttributes, PropType } from 'vue';
import store from '../../store';
import { computed, defineComponent, HTMLAttributes, inject, PropType } from 'vue';
type StringFunc = (node: Node) => string;
@@ -55,8 +54,8 @@ const MiniMap = defineComponent({
}
},
setup(props, { attrs }: { attrs: Record<string, any> }) {
const pinia = store();
const transform = computed(() => pinia.transform);
const store = inject<RevueFlowStore>('store')!;
const transform = computed(() => store.transform);
const elementWidth = computed(() => (attrs.style?.width || defaultWidth)! as number);
const elementHeight = computed(() => (attrs.style?.height || defaultHeight)! as number);
const nodeColorFunc = computed(() => (props.nodeColor instanceof Function ? props.nodeColor : () => props.nodeColor) as StringFunc);
@@ -66,13 +65,13 @@ const MiniMap = defineComponent({
const nodeClassNameFunc = computed(
() => (props.nodeClassName instanceof Function ? props.nodeClassName : () => props.nodeClassName) as StringFunc
);
const hasNodes = computed(() => pinia.nodes && pinia.nodes.length);
const bb = computed(() => getRectOfNodes(pinia.nodes));
const hasNodes = computed(() => store.nodes && store.nodes.length);
const bb = computed(() => getRectOfNodes(store.nodes));
const viewBB = computed<Rect>(() => ({
x: -transform.value[0] / transform.value[2],
y: -transform.value[1] / transform.value[2],
width: pinia.width / transform.value[2],
height: pinia.height / transform.value[2]
width: store.width / transform.value[2],
height: store.height / transform.value[2]
}));
const boundingRect = computed(() => (hasNodes.value ? getBoundsofRects(bb.value, viewBB.value) : viewBB.value));
const scaledWidth = computed(() => boundingRect.value.width / elementWidth.value);
@@ -94,7 +93,7 @@ const MiniMap = defineComponent({
viewBox={`${x.value} ${y.value} ${width.value} ${height.value}`}
class="revue-flow__minimap"
>
{pinia.nodes
{store.nodes
.filter((node) => !node.isHidden)
.map((node) => (
<MiniMapNode

View File

@@ -1,11 +1,9 @@
import { Component, computed, defineComponent, PropType, ref } from 'vue';
import store from '../../store';
import { Edge, EdgeProps, Position, WrapEdgeProps } from '../../types';
import { computed, DefineComponent, defineComponent, inject, PropType, ref } from 'vue';
import { Edge, EdgeProps, Position, RevueFlowStore, WrapEdgeProps } from '../../types';
import { onMouseDown } from '../Handle/handler';
import { EdgeAnchor } from './EdgeAnchor';
export default (EdgeComponent: any): Component<EdgeProps> => {
export default (EdgeComponent: DefineComponent<EdgeProps>) => {
return defineComponent({
components: { EdgeComponent },
props: {
@@ -187,7 +185,7 @@ export default (EdgeComponent: any): Component<EdgeProps> => {
}
},
setup(props) {
const pinia = store();
const store = inject<RevueFlowStore>('store')!;
const updating = ref<boolean>(false);
const inactive = computed(() => !props.elementsSelectable && !props.onClick);
const edgeClasses = computed(() => [
@@ -221,8 +219,8 @@ export default (EdgeComponent: any): Component<EdgeProps> => {
const onEdgeClick = (event: MouseEvent) => {
if (props.elementsSelectable) {
pinia.unsetNodesSelection();
pinia.addSelectedElements(edgeElement.value as any);
store.unsetNodesSelection();
store.addSelectedElements(edgeElement.value as any);
}
if (typeof props.onClick === 'function') props.onClick(event, edgeElement.value);
@@ -262,12 +260,12 @@ export default (EdgeComponent: any): Component<EdgeProps> => {
event,
handleId,
nodeId,
pinia.setConnectionNodeId,
pinia.setConnectionPosition,
store.setConnectionNodeId,
store.setConnectionPosition,
props.onConnectEdge as any,
isTarget,
isValidConnection,
pinia.connectionMode,
store.connectionMode,
isSourceHandle ? 'target' : 'source',
_onEdgeUpdate
);

View File

@@ -1,12 +1,12 @@
import { Node, RevueFlowStore, WrapNodeProps } from '../../types';
import { computed, CSSProperties, DefineComponent, defineComponent, inject, onMounted, provide, ref } from 'vue';
import { DraggableCore, DraggableEventHandler } from '@braks/revue-draggable';
import { computed, CSSProperties, DefineComponent, defineComponent, inject, onMounted, provide, ref, watchEffect } from 'vue';
import { DraggableEventHandler, DraggableCore } from '@braks/revue-draggable';
export default (NodeComponent: DefineComponent<WrapNodeProps>) => {
return defineComponent({
props: WrapNodeProps,
setup(props) {
const store = inject<RevueFlowStore>('store');
const store = inject<RevueFlowStore>('store')!;
provide('NodeIdContext', props.id);
const nodeElement = ref<HTMLDivElement | undefined>();
@@ -134,7 +134,7 @@ export default (NodeComponent: DefineComponent<WrapNodeProps>) => {
props.onNodeDragStop?.(event as MouseEvent, node.value as Node);
};
onMounted(() => {
watchEffect(() => {
if (nodeElement.value && !props.isHidden) {
store?.updateNodeDimensions([{ id: props.id || '', nodeElement: nodeElement.value, forceUpdate: true }]);
}
@@ -164,14 +164,13 @@ export default (NodeComponent: DefineComponent<WrapNodeProps>) => {
return () => (
<DraggableCore
onStart={onDragStart}
onDrag={onDrag}
onStop={onDragStop}
scale={props.scale}
start={onDragStart}
move={onDrag}
stop={onDragStop}
scale={store.transform[2]}
disabled={!props.isDraggable}
cancel=".nodrag"
grid={grid.value}
nodeRef={nodeElement.value}
enableUserSelectHack={false}
>
<div

View File

@@ -4,8 +4,8 @@
*/
import { isNode } from '../../utils/graph';
import { Node, RevueFlowStore } from '../../types';
import { computed, defineComponent, inject, PropType, ref } from 'vue';
import Draggable, { DraggableEventHandler } from '@braks/revue-draggable';
import { computed, defineComponent, inject, PropType } from 'vue';
import { Draggable, DraggableEventHandler } from '@braks/revue-draggable';
export interface NodesSelectionProps {
onSelectionDragStart?: (event: MouseEvent, nodes: Node[]) => void;
@@ -39,7 +39,6 @@ const NodesSelection = defineComponent({
},
setup(props) {
const store = inject<RevueFlowStore>('store')!;
const nodeRef = ref<HTMLElement | undefined>();
const grid = computed(() => (store.snapToGrid ? store.snapGrid : [1, 1])! as [number, number]);
const selectedNodes = computed(() =>
@@ -67,10 +66,12 @@ const NodesSelection = defineComponent({
}));
const onStart: DraggableEventHandler = (event: MouseEvent) => {
console.log('ondragstart');
props.onSelectionDragStart?.(event, selectedNodes.value);
};
const onDrag: DraggableEventHandler = (event, data) => {
console.log('ondrag');
props.onSelectionDrag?.(event, selectedNodes.value);
store.updateNodePosDiff({
@@ -83,6 +84,7 @@ const NodesSelection = defineComponent({
};
const onStop: DraggableEventHandler = (event: MouseEvent) => {
console.log('ondragend');
store.updateNodePosDiff({
isDragging: false
});
@@ -104,16 +106,14 @@ const NodesSelection = defineComponent({
) : (
<div class="revue-flow__nodesselection" style={style.value}>
<Draggable
start={onStart}
move={onDrag}
stop={onStop}
scale={store.transform[2]}
grid={grid.value}
onStart={onStart}
onDrag={onDrag}
onStop={onStop}
nodeRef={nodeRef.value}
enableUserSelectHack={false}
nodeRef={nodeRef.value}
>
<div ref={nodeRef} class="revue-flow__nodesselection-rect" onContextmenu={onContextMenu} style={innerStyle.value} />
<div class="revue-flow__nodesselection-rect" onContextmenu={onContextMenu} style={innerStyle.value} />
</Draggable>
</div>
);

View File

@@ -1,4 +1,14 @@
import { computed, CSSProperties, defineComponent, HTMLAttributes, onBeforeUnmount, PropType, provide, watchEffect } from 'vue';
import {
computed,
CSSProperties,
defineComponent,
HTMLAttributes,
onBeforeUnmount,
onUpdated,
PropType,
provide,
watchEffect
} from 'vue';
import GraphView from '../GraphView';
import DefaultNode from '../../components/Nodes/DefaultNode';
import InputNode from '../../components/Nodes/InputNode';
@@ -547,6 +557,11 @@ const RevueFlow = defineComponent({
props.onSelectionChange?.(store.selectedElements);
});
onUpdated(() => {
store.setElements(props.elements);
props.onSelectionChange?.(store.selectedElements);
});
onBeforeUnmount(() => {
store.$reset();
store.setElements([]);

View File

@@ -2,9 +2,8 @@ import { zoom, zoomIdentity } from 'd3-zoom';
import { select, pointer } from 'd3-selection';
import { clamp } from '../../utils';
import { FlowTransform, TranslateExtent, PanOnScrollMode, KeyCode } from '../../types';
import { defineComponent, PropType, ref, watch, watchEffect } from 'vue';
import store from '../../store';
import { FlowTransform, TranslateExtent, PanOnScrollMode, KeyCode, RevueFlowStore } from '../../types';
import { defineComponent, inject, PropType, ref, watchEffect } from 'vue';
import useKeyPress from '../../hooks/useKeyPress';
import useResizeHandler from '../../hooks/useResizeHandler';
@@ -39,19 +38,19 @@ const eventToFlowTransform = (eventTransform: any): FlowTransform => ({
const ZoomPane = defineComponent({
props: {
onMove: {
type: Function() as PropType<ZoomPaneProps['onMove']>,
type: Function as unknown as PropType<ZoomPaneProps['onMove']>,
required: false,
default: undefined as any
default: () => {}
},
onMoveStart: {
type: Function() as PropType<ZoomPaneProps['onMoveStart']>,
type: Function as unknown as PropType<ZoomPaneProps['onMoveStart']>,
required: false,
default: undefined as any
default: () => {}
},
onMoveEnd: {
type: Function() as PropType<ZoomPaneProps['onMoveEnd']>,
type: Function as unknown as PropType<ZoomPaneProps['onMoveEnd']>,
required: false,
default: undefined as any
default: () => {}
},
zoomOnScroll: {
type: Boolean as PropType<ZoomPaneProps['zoomOnScroll']>,
@@ -120,30 +119,30 @@ const ZoomPane = defineComponent({
}
},
setup(props, { slots }) {
const pinia = store();
const store = inject<RevueFlowStore>('store')!;
const zoomPane = ref<HTMLDivElement | null>(null);
const prevTransform = ref<FlowTransform>({ x: 0, y: 0, zoom: 0 });
const zoomActivationKeyPressed = useKeyPress(props.zoomActivationKeyCode);
watch(zoomPane, () => {
if (zoomPane.value) useResizeHandler(zoomPane.value);
watchEffect(() => {
if (zoomPane.value) useResizeHandler(zoomPane.value, store.updateSize);
});
watchEffect(() => {
if (zoomPane.value && props.defaultPosition && props.defaultZoom) {
const currentTranslateExtent =
typeof props.translateExtent !== 'undefined' ? props.translateExtent : pinia.translateExtent;
const d3ZoomInstance = zoom().scaleExtent([pinia.minZoom, pinia.maxZoom]).translateExtent(currentTranslateExtent);
typeof props.translateExtent !== 'undefined' ? props.translateExtent : store.translateExtent;
const d3ZoomInstance = zoom().scaleExtent([store.minZoom, store.maxZoom]).translateExtent(currentTranslateExtent);
const selection = select(zoomPane.value as Element).call(d3ZoomInstance);
const clampedX = clamp(props.defaultPosition[0], currentTranslateExtent[0][0], currentTranslateExtent[1][0]);
const clampedY = clamp(props.defaultPosition[1], currentTranslateExtent[0][1], currentTranslateExtent[1][1]);
const clampedZoom = clamp(props.defaultZoom, pinia.minZoom, pinia.maxZoom);
const clampedZoom = clamp(props.defaultZoom, store.minZoom, store.maxZoom);
const updatedTransform = zoomIdentity.translate(clampedX, clampedY).scale(clampedZoom);
d3ZoomInstance.transform(selection, updatedTransform);
pinia.initD3Zoom({
store.initD3Zoom({
d3Zoom: d3ZoomInstance,
d3Selection: selection,
d3ZoomHandler: selection.on('wheel.zoom'),
@@ -154,21 +153,21 @@ const ZoomPane = defineComponent({
});
watchEffect(() => {
if (pinia.d3Selection && pinia.d3Zoom) {
if (store.d3Selection && store.d3Zoom) {
if (props.panOnScroll && zoomActivationKeyPressed) {
pinia.d3Selection
store.d3Selection
.on('wheel', (event: any) => {
event.preventDefault();
event.stopImmediatePropagation();
const currentZoom = pinia.d3Selection?.property('__zoom').k || 1;
const currentZoom = store.d3Selection?.property('__zoom').k || 1;
if (event.ctrlKey && props.zoomOnPinch) {
const point = pointer(event);
// taken from https://github.com/d3/d3-zoom/blob/master/src/zoom.js
const pinchDelta = -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * 10;
const zoom = currentZoom * Math.pow(2, pinchDelta);
if (pinia.d3Selection) pinia.d3Zoom?.scaleTo(pinia.d3Selection, zoom, point);
if (store.d3Selection) store.d3Zoom?.scaleTo(store.d3Selection, zoom, point);
return;
}
@@ -179,27 +178,27 @@ const ZoomPane = defineComponent({
const deltaX = props.panOnScrollMode === PanOnScrollMode.Vertical ? 0 : event.deltaX * deltaNormalize;
const deltaY = props.panOnScrollMode === PanOnScrollMode.Horizontal ? 0 : event.deltaY * deltaNormalize;
if (pinia.d3Selection && props.panOnScrollSpeed)
pinia.d3Zoom?.translateBy(
pinia.d3Selection,
if (store.d3Selection && props.panOnScrollSpeed)
store.d3Zoom?.translateBy(
store.d3Selection,
-(deltaX / currentZoom) * props.panOnScrollSpeed,
-(deltaY / currentZoom) * props.panOnScrollSpeed
);
})
.on('wheel.zoom', null);
} else if (typeof pinia.d3ZoomHandler !== 'undefined') {
pinia.d3Selection.on('wheel', null).on('wheel.zoom', pinia.d3ZoomHandler);
} else if (typeof store.d3ZoomHandler !== 'undefined') {
store.d3Selection.on('wheel', null).on('wheel.zoom', store.d3ZoomHandler);
}
}
});
watchEffect(() => {
if (pinia.d3Zoom) {
if (store.d3Zoom) {
if (props.selectionKeyPressed) {
pinia.d3Zoom.on('zoom', null);
store.d3Zoom.on('zoom', null);
} else {
pinia.d3Zoom.on('zoom', (event: any) => {
pinia.updateTransform([event.transform.x, event.transform.y, event.transform.k]);
store.d3Zoom.on('zoom', (event: any) => {
store.updateTransform([event.transform.x, event.transform.y, event.transform.k]);
if (props.onMove) {
const flowTransform = eventToFlowTransform(event.transform);
@@ -211,9 +210,9 @@ const ZoomPane = defineComponent({
});
watchEffect(() => {
if (pinia.d3Zoom) {
if (store.d3Zoom) {
if (props.onMoveStart) {
pinia.d3Zoom.on('start', (event: any) => {
store.d3Zoom.on('start', (event: any) => {
if (viewChanged(prevTransform.value, event.transform)) {
const flowTransform = eventToFlowTransform(event.transform);
prevTransform.value = flowTransform;
@@ -222,15 +221,15 @@ const ZoomPane = defineComponent({
}
});
} else {
pinia.d3Zoom.on('start', null);
store.d3Zoom.on('start', null);
}
}
});
watchEffect(() => {
if (pinia.d3Zoom) {
if (store.d3Zoom) {
if (props.onMoveEnd) {
pinia.d3Zoom.on('end', (event: any) => {
store.d3Zoom.on('end', (event: any) => {
if (viewChanged(prevTransform.value, event.transform)) {
const flowTransform = eventToFlowTransform(event.transform);
prevTransform.value = flowTransform;
@@ -239,14 +238,14 @@ const ZoomPane = defineComponent({
}
});
} else {
pinia.d3Zoom.on('end', null);
store.d3Zoom.on('end', null);
}
}
});
watchEffect(() => {
if (pinia.d3Zoom) {
pinia.d3Zoom.filter((event: any) => {
if (store.d3Zoom) {
store.d3Zoom.filter((event: any) => {
const zoomScroll = props.zoomOnScroll;
const pinchZoom = props.zoomOnPinch && event.ctrlKey;

View File

@@ -1,9 +1,7 @@
import { getDimensions } from '../utils';
import store from '../store';
export default (rendererNode: HTMLDivElement) => {
const pinia = store();
import { Dimensions } from '../types';
export default (rendererNode: HTMLDivElement, updateSize: (size: Dimensions) => any) => {
let resizeObserver: ResizeObserver;
const updateDimensions = () => {
@@ -17,7 +15,7 @@ export default (rendererNode: HTMLDivElement) => {
console.log('The revue Flow parent container needs a width and a height to render the graph.');
}
pinia.updateSize(size);
updateSize(size);
};
updateDimensions();
@@ -27,14 +25,4 @@ export default (rendererNode: HTMLDivElement) => {
resizeObserver = new ResizeObserver(() => updateDimensions());
resizeObserver.observe(rendererNode);
}
/*
return () => {
window.onresize = null;
if (resizeObserver && rendererNode) {
resizeObserver.unobserve(rendererNode);
}
};
*/
};

View File

@@ -1,14 +1,14 @@
import { ElementId, UpdateNodeInternals } from '../types';
import store from '../store';
import { ElementId, RevueFlowStore, UpdateNodeInternals } from '../types';
import { inject } from 'vue';
function useUpdateNodeInternals(): UpdateNodeInternals {
const pinia = store();
const store = inject<RevueFlowStore>('store')!;
return (id: ElementId) => {
const nodeElement: HTMLDivElement | null = document.querySelector(`.revue-flow__node[data-id="${id}"]`);
if (nodeElement) {
pinia.updateNodeDimensions([{ id, nodeElement, forceUpdate: true }]);
store.updateNodeDimensions([{ id, nodeElement, forceUpdate: true }]);
}
};
}

View File

@@ -1,7 +1,7 @@
import { zoomIdentity } from 'd3-zoom';
import { getRectOfNodes, pointToRendererPoint, getTransformForBounds } from '../utils/graph';
import { FitViewParams, FlowTransform, ZoomPanHelperFunctions, Rect, XYPosition } from '../types';
import store from '../store';
import { FitViewParams, FlowTransform, ZoomPanHelperFunctions, Rect, XYPosition, RevueFlowStore } from '../types';
import { inject } from 'vue';
const DEFAULT_PADDING = 0.1;
@@ -18,20 +18,20 @@ const initialZoomPanHelper: ZoomPanHelperFunctions = {
};
const useZoomPanHelper = (): ZoomPanHelperFunctions => {
const pinia = store();
const store = inject<RevueFlowStore>('store')!;
const zoomPanHelperFunctions = () => {
if (pinia.d3Selection && pinia.d3Zoom) {
if (store.d3Selection && store.d3Zoom) {
return {
zoomIn: () => pinia.d3Zoom?.scaleBy(pinia.d3Selection as any, 1.2),
zoomOut: () => pinia.d3Zoom?.scaleBy(pinia.d3Selection as any, 1 / 1.2),
zoomTo: (zoomLevel: number) => pinia.d3Zoom?.scaleTo(pinia.d3Selection as any, zoomLevel),
zoomIn: () => store.d3Zoom?.scaleBy(store.d3Selection as any, 1.2),
zoomOut: () => store.d3Zoom?.scaleBy(store.d3Selection as any, 1 / 1.2),
zoomTo: (zoomLevel: number) => store.d3Zoom?.scaleTo(store.d3Selection as any, zoomLevel),
transform: (transform: FlowTransform) => {
const nextTransform = zoomIdentity.translate(transform.x, transform.y).scale(transform.zoom);
pinia.d3Zoom?.transform(pinia.d3Selection as any, nextTransform);
store.d3Zoom?.transform(store.d3Selection as any, nextTransform);
},
fitView: (options: FitViewParams = { padding: DEFAULT_PADDING, includeHiddenNodes: false }) => {
const { nodes, width, height, minZoom, maxZoom } = pinia;
const { nodes, width, height, minZoom, maxZoom } = store;
if (!nodes.length) {
return;
@@ -48,27 +48,27 @@ const useZoomPanHelper = (): ZoomPanHelperFunctions => {
);
const transform = zoomIdentity.translate(x, y).scale(zoom);
pinia.d3Zoom?.transform(pinia.d3Selection as any, transform);
store.d3Zoom?.transform(store.d3Selection as any, transform);
},
setCenter: (x: number, y: number, zoom?: number) => {
const { width, height, maxZoom } = pinia;
const { width, height, maxZoom } = store;
const nextZoom = typeof zoom !== 'undefined' ? zoom : maxZoom;
const centerX = width / 2 - x * nextZoom;
const centerY = height / 2 - y * nextZoom;
const transform = zoomIdentity.translate(centerX, centerY).scale(nextZoom);
pinia.d3Zoom?.transform(pinia.d3Selection as any, transform);
store.d3Zoom?.transform(store.d3Selection as any, transform);
},
fitBounds: (bounds: Rect, padding = DEFAULT_PADDING) => {
const { width, height, minZoom, maxZoom } = pinia;
const { width, height, minZoom, maxZoom } = store;
const [x, y, zoom] = getTransformForBounds(bounds, width, height, minZoom, maxZoom, padding);
const transform = zoomIdentity.translate(x, y).scale(zoom);
pinia.d3Zoom?.transform(pinia.d3Selection as any, transform);
store.d3Zoom?.transform(store.d3Selection as any, transform);
},
project: (position: XYPosition) => {
const { transform, snapToGrid, snapGrid } = pinia;
const { transform, snapToGrid, snapGrid } = store;
return pointToRendererPoint(position, transform, snapToGrid, snapGrid);
},
initialized: true

View File

@@ -1,5 +1,3 @@
import configureStore from './configure-store';
import { RevueFlowState, ConnectionMode } from '../types';
export const initialState: RevueFlowState = {
@@ -55,7 +53,3 @@ export const initialState: RevueFlowState = {
revueFlowVersion: typeof __REVUE_FLOW_VERSION__ !== 'undefined' ? __REVUE_FLOW_VERSION__ : '-'
};
const store = configureStore(initialState);
export default store;

View File

@@ -262,11 +262,12 @@
"@babel/helper-validator-identifier" "^7.14.5"
to-fast-properties "^2.0.0"
"@braks/revue-draggable@^0.1.13":
version "0.1.13"
resolved "https://registry.yarnpkg.com/@braks/revue-draggable/-/revue-draggable-0.1.13.tgz#cff5a9ac21c488de5b0c3fef6cdbd3f8f828dd21"
integrity sha512-unczSXZNK3ZnHoIj5w45a4eN7iQH6s0Ot33G2s7zkdMRHcoGh8Cc0ltw5m5XlrEgk4ch0vAEIU+MQiS8/D27uw==
"@braks/revue-draggable@^0.2.1-5":
version "0.2.1-5"
resolved "https://registry.yarnpkg.com/@braks/revue-draggable/-/revue-draggable-0.2.1-5.tgz#280f9cb4dfd5c3bc88dff0f8c70ffa8966536328"
integrity sha512-+oDuUvTVd5ST6brdtfXYJMnFrmyQat9W7yUKpKBTI0od3ycfaGgMCT9w+OoQ3rlBi2cV6gFXlhZVIeLi+v55aA==
dependencies:
"@vueuse/core" "^5.1.3"
vue-demi latest
"@eslint/eslintrc@^0.4.2":
@@ -911,6 +912,21 @@
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.4.tgz#c14c461ec42ea2c1556e86f60b0354341d91adc3"
integrity sha512-6O45kZAmkLvzGLToBxEz4lR2W6kXohCtebV2UxjH9GXjd8X9AhEn68FN9eNanFtWNzvgw1hqd6HkPRVQalqf7Q==
"@vueuse/core@^5.1.3":
version "5.1.4"
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-5.1.4.tgz#c590bd1ff5cdd3d2caa033b65ed8cb42fc12a534"
integrity sha512-iuRhSaScI1GJS4N3CFPc1GajOr6F6J1Nng1I6ocNOjLx+evss6egImx9wnuX45fxqQstnh7Vfqe3FF7+0NgoWg==
dependencies:
"@vueuse/shared" "5.1.4"
vue-demi "*"
"@vueuse/shared@5.1.4":
version "5.1.4"
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-5.1.4.tgz#35e3aa8ce7e52b447191915ee8b4afa481838c43"
integrity sha512-C0xiMv8+sFI3WhXdlrcLKI4d4dFnouHe4Te51cxWgcmpW7S8eUiM8fXPaQVxUQZ4E9PCx3zEZpNpCLzQa+6Lag==
dependencies:
vue-demi "*"
acorn-jsx@^5.2.0, acorn-jsx@^5.3.1:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
@@ -5625,6 +5641,11 @@ vite@^2.3.8:
optionalDependencies:
fsevents "~2.3.2"
vue-demi@*:
version "0.11.2"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.11.2.tgz#faa06da53887c493a695b997f4fcb4784a667990"
integrity sha512-J+X8Au6BhQdcej6LY4O986634hZLu55L0ewU2j8my7WIKlu8cK0dqmdUxqVHHMd/cMrKKZ9SywB/id6aLhwCtA==
vue-demi@latest:
version "0.10.1"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.10.1.tgz#229b81395510f02f4ee255344557a12cc0120930"