update: fix names
This commit is contained in:
@@ -28,9 +28,9 @@ const rfInstance = ref<OnLoadParams | null>(null)
|
|||||||
const onElementsRemove = (elementsToRemove: Elements) =>
|
const onElementsRemove = (elementsToRemove: Elements) =>
|
||||||
(elements.value = removeElements(elementsToRemove, elements.value as Elements))
|
(elements.value = removeElements(elementsToRemove, elements.value as Elements))
|
||||||
const onConnect = (params: Edge | Connection) => (elements.value = addEdge(params, elements.value as Elements))
|
const onConnect = (params: Edge | Connection) => (elements.value = addEdge(params, elements.value as Elements))
|
||||||
const onLoad = (revueFlowInstance: OnLoadParams) => {
|
const onLoad = (flowInstance: OnLoadParams) => {
|
||||||
revueFlowInstance.fitView({ padding: 0.1 })
|
flowInstance.fitView({ padding: 0.1 })
|
||||||
rfInstance.value = revueFlowInstance
|
rfInstance.value = flowInstance
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatePos = () => {
|
const updatePos = () => {
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ const nodeTypes = {
|
|||||||
selectorNode: ColorSelectorNode,
|
selectorNode: ColorSelectorNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
const onLoad = (revueFlowInstance: OnLoadParams) => {
|
const onLoad = (flowInstance: OnLoadParams) => {
|
||||||
revueFlowInstance.fitView()
|
flowInstance.fitView()
|
||||||
console.log('flow loaded:', revueFlowInstance)
|
console.log('flow loaded:', flowInstance)
|
||||||
}
|
}
|
||||||
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node)
|
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node)
|
||||||
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element)
|
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import Sidebar from './Sidebar.vue'
|
|||||||
import Flow, { addEdge, removeElements, Controls, OnLoadParams, Elements, Connection, Edge, ElementId, Node } from '~/index'
|
import Flow, { addEdge, removeElements, Controls, OnLoadParams, Elements, Connection, Edge, ElementId, Node } from '~/index'
|
||||||
import './dnd.css'
|
import './dnd.css'
|
||||||
|
|
||||||
const revueFlowInstance = ref<OnLoadParams>()
|
const flowInstance = ref<OnLoadParams>()
|
||||||
const elements = ref<Elements>([
|
const elements = ref<Elements>([
|
||||||
{
|
{
|
||||||
id: '1',
|
id: '1',
|
||||||
@@ -26,15 +26,15 @@ const onDragOver = (event: DragEvent) => {
|
|||||||
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value as Elements))
|
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value as Elements))
|
||||||
const onElementsRemove = (elementsToRemove: Elements) =>
|
const onElementsRemove = (elementsToRemove: Elements) =>
|
||||||
(elements.value = removeElements(elementsToRemove, elements.value as Elements))
|
(elements.value = removeElements(elementsToRemove, elements.value as Elements))
|
||||||
const onLoad = (instance: OnLoadParams) => (revueFlowInstance.value = instance)
|
const onLoad = (instance: OnLoadParams) => (flowInstance.value = instance)
|
||||||
|
|
||||||
const onDrop = (event: DragEvent) => {
|
const onDrop = (event: DragEvent) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
if (revueFlowInstance.value) {
|
if (flowInstance.value) {
|
||||||
console.log(event.dataTransfer?.getData('application/revueflow'))
|
console.log(event.dataTransfer?.getData('application/vueflow'))
|
||||||
const type = event.dataTransfer?.getData('application/revueflow')
|
const type = event.dataTransfer?.getData('application/vueflow')
|
||||||
const position = revueFlowInstance.value.project({ x: event.clientX, y: event.clientY - 40 })
|
const position = flowInstance.value.project({ x: event.clientX, y: event.clientY - 40 })
|
||||||
const newNode = {
|
const newNode = {
|
||||||
id: getId(),
|
id: getId(),
|
||||||
type,
|
type,
|
||||||
@@ -48,7 +48,7 @@ const onDrop = (event: DragEvent) => {
|
|||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="dndflow">
|
<div class="dndflow">
|
||||||
<div class="revueflow-wrapper" @drop="onDrop">
|
<div class="vueflow-wrapper" @drop="onDrop">
|
||||||
<Flow :elements="elements" @elements-remove="onElementsRemove" @load="onLoad" @connect="onConnect" @dragover="onDragOver">
|
<Flow :elements="elements" @elements-remove="onElementsRemove" @load="onLoad" @connect="onConnect" @dragover="onDragOver">
|
||||||
<Controls />
|
<Controls />
|
||||||
</Flow>
|
</Flow>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
const onDragStart = (event: DragEvent, nodeType: string) => {
|
const onDragStart = (event: DragEvent, nodeType: string) => {
|
||||||
if (event.dataTransfer) {
|
if (event.dataTransfer) {
|
||||||
event.dataTransfer.setData('application/revueflow', nodeType)
|
event.dataTransfer.setData('application/vueflow', nodeType)
|
||||||
event.dataTransfer.effectAllowed = 'move'
|
event.dataTransfer.effectAllowed = 'move'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dndflow .revueflow-wrapper {
|
.dndflow .vue-flow-wrapper {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
import { getElements } from './utils'
|
import { getElements } from './utils'
|
||||||
import Flow, { removeElements, addEdge, MiniMap, Controls, Background, OnLoadParams, Connection, Edge, Elements } from '~/index'
|
import Flow, { removeElements, addEdge, MiniMap, Controls, Background, OnLoadParams, Connection, Edge, Elements } from '~/index'
|
||||||
|
|
||||||
const onLoad = (reactFlowInstance: OnLoadParams) => {
|
const onLoad = (flowInstance: OnLoadParams) => {
|
||||||
reactFlowInstance.fitView()
|
flowInstance.fitView()
|
||||||
console.log(reactFlowInstance.getElements())
|
console.log(flowInstance.getElements())
|
||||||
}
|
}
|
||||||
|
|
||||||
const elements = ref<Elements>(getElements())
|
const elements = ref<Elements>(getElements())
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const elements = ref<Elements>([
|
|||||||
},
|
},
|
||||||
] as Elements)
|
] as Elements)
|
||||||
|
|
||||||
const onLoad = (reactFlowInstance: OnLoadParams) => reactFlowInstance.fitView()
|
const onLoad = (flowInstance: OnLoadParams) => flowInstance.fitView()
|
||||||
const onElementsRemove = (elementsToRemove: Elements) =>
|
const onElementsRemove = (elementsToRemove: Elements) =>
|
||||||
(elements.value = removeElements(elementsToRemove, elements.value as Elements))
|
(elements.value = removeElements(elementsToRemove, elements.value as Elements))
|
||||||
const onConnect = (params: Connection | Edge) =>
|
const onConnect = (params: Connection | Edge) =>
|
||||||
|
|||||||
@@ -81,9 +81,9 @@ const edgeTypes: Record<string, any> = {
|
|||||||
|
|
||||||
const elements = ref<Elements>(initialElements as Elements)
|
const elements = ref<Elements>(initialElements as Elements)
|
||||||
|
|
||||||
const onLoad = (reactFlowInstance: OnLoadParams) => reactFlowInstance.fitView()
|
const onLoad = (flowInstance: OnLoadParams) => flowInstance.fitView()
|
||||||
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node)
|
const onNodeDragStop = (node: Node) => console.log('drag stop', node)
|
||||||
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element)
|
const onElementClick = (element: FlowElement) => console.log('click', element)
|
||||||
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
|
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
|
||||||
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
|
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ const elements = ref<Elements>([])
|
|||||||
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
|
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
|
||||||
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
|
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
|
||||||
|
|
||||||
const onLoad = (reactFlowInstance: OnLoadParams) => console.log('flow loaded:', reactFlowInstance)
|
const onLoad = (flowInstance: OnLoadParams) => console.log('flow loaded:', flowInstance)
|
||||||
const onElementClick = (_: MouseEvent, element: FlowElement) => console.log('click', element)
|
const onElementClick = (element: FlowElement) => console.log('click', element)
|
||||||
const onNodeDragStop = (_: MouseEvent, node: Node) => console.log('drag stop', node)
|
const onNodeDragStop = (node: Node) => console.log('drag stop', node)
|
||||||
|
|
||||||
const buttonStyle: CSSProperties = { position: 'absolute', left: '10px', top: '10px', zIndex: 4 }
|
const buttonStyle: CSSProperties = { position: 'absolute', left: '10px', top: '10px', zIndex: 4 }
|
||||||
const addRandomNode = () => {
|
const addRandomNode = () => {
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ const nodeExtent: NodeExtent = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const elements = ref<Elements>(initialElements)
|
const elements = ref<Elements>(initialElements)
|
||||||
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
|
const onConnect = (params: Connection | Edge) => (elements.value = addEdge({ ...params, animated: true }, elements.value))
|
||||||
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
|
const onElementsRemove = (elementsToRemove: Elements) => (elements.value = removeElements(elementsToRemove, elements.value))
|
||||||
|
|
||||||
|
// todo changing elements not properly updating flowchart...
|
||||||
const onLayout = (direction: string) => {
|
const onLayout = (direction: string) => {
|
||||||
const isHorizontal = direction === 'LR'
|
const isHorizontal = direction === 'LR'
|
||||||
dagreGraph.setGraph({ rankdir: direction })
|
dagreGraph.setGraph({ rankdir: direction })
|
||||||
@@ -50,7 +51,7 @@ const onLayout = (direction: string) => {
|
|||||||
:node-extent="nodeExtent"
|
:node-extent="nodeExtent"
|
||||||
@connect="onConnect"
|
@connect="onConnect"
|
||||||
@clements-remove="onElementsRemove"
|
@clements-remove="onElementsRemove"
|
||||||
@load="() => onLayout('TB')"
|
@load="() => onLayout('LR')"
|
||||||
>
|
>
|
||||||
<Controls />
|
<Controls />
|
||||||
</Flow>
|
</Flow>
|
||||||
|
|||||||
@@ -56,16 +56,16 @@ const elements: Elements = [
|
|||||||
position,
|
position,
|
||||||
},
|
},
|
||||||
{ id: '7', type: 'output', data: { label: 'output' }, position: { x: 400, y: 450 } },
|
{ id: '7', type: 'output', data: { label: 'output' }, position: { x: 400, y: 450 } },
|
||||||
{ id: 'e12', source: '1', target: '2', type: 'smoothstep' },
|
{ id: 'e12', source: '1', target: '2', type: 'smoothstep', animated: true },
|
||||||
{ id: 'e13', source: '1', target: '3', type: 'smoothstep' },
|
{ id: 'e13', source: '1', target: '3', type: 'smoothstep', animated: true },
|
||||||
{ id: 'e22a', source: '2', target: '2a', type: 'smoothstep' },
|
{ id: 'e22a', source: '2', target: '2a', type: 'smoothstep', animated: true },
|
||||||
{ id: 'e22b', source: '2', target: '2b', type: 'smoothstep' },
|
{ id: 'e22b', source: '2', target: '2b', type: 'smoothstep', animated: true },
|
||||||
{ id: 'e22c', source: '2', target: '2c', type: 'smoothstep' },
|
{ id: 'e22c', source: '2', target: '2c', type: 'smoothstep', animated: true },
|
||||||
{ id: 'e2c2d', source: '2c', target: '2d', type: 'smoothstep' },
|
{ id: 'e2c2d', source: '2c', target: '2d', type: 'smoothstep', animated: true },
|
||||||
|
|
||||||
{ id: 'e45', source: '4', target: '5', type: 'smoothstep' },
|
{ id: 'e45', source: '4', target: '5', type: 'smoothstep', animated: true },
|
||||||
{ id: 'e56', source: '5', target: '6', type: 'smoothstep' },
|
{ id: 'e56', source: '5', target: '6', type: 'smoothstep', animated: true },
|
||||||
{ id: 'e57', source: '5', target: '7', type: 'smoothstep' },
|
{ id: 'e57', source: '5', target: '7', type: 'smoothstep', animated: true },
|
||||||
] as Elements
|
] as Elements
|
||||||
|
|
||||||
export default elements
|
export default elements
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ const elements = ref<Elements>(initialElements)
|
|||||||
|
|
||||||
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
|
const onConnect = (params: Connection | Edge) => (elements.value = addEdge(params, elements.value))
|
||||||
|
|
||||||
const onLoad = (reactFlowInstance: OnLoadParams) => reactFlowInstance.fitView()
|
const onLoad = (flowInstance: OnLoadParams) => flowInstance.fitView()
|
||||||
|
|
||||||
const changeType = () => {
|
const changeType = () => {
|
||||||
elements.value = elements.value.map((el) => {
|
elements.value = elements.value.map((el) => {
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ const onSelectionContextMenu = (event: MouseEvent, nodes: Node[]) => {
|
|||||||
const onElementClick = (_: MouseEvent, element: FlowElement) =>
|
const onElementClick = (_: MouseEvent, element: FlowElement) =>
|
||||||
console.log(`${isNode(element) ? 'node' : 'edge'} click:`, element)
|
console.log(`${isNode(element) ? 'node' : 'edge'} click:`, element)
|
||||||
const onSelectionChange = (elements: Elements | null) => console.log('selection change', elements)
|
const onSelectionChange = (elements: Elements | null) => console.log('selection change', elements)
|
||||||
const onLoad = (reactFlowInstance: OnLoadParams) => {
|
const onLoad = (flowInstance: OnLoadParams) => {
|
||||||
console.log('flow loaded:', reactFlowInstance)
|
console.log('flow loaded:', flowInstance)
|
||||||
reactFlowInstance.fitView()
|
flowInstance.fitView()
|
||||||
}
|
}
|
||||||
|
|
||||||
const onMoveEnd = (transform?: FlowTransform) => console.log('zoom/move end', transform)
|
const onMoveEnd = (transform?: FlowTransform) => console.log('zoom/move end', transform)
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ for (const { external, iife } of activePackages) {
|
|||||||
'@vueuse/core': 'VueUse',
|
'@vueuse/core': 'VueUse',
|
||||||
}
|
}
|
||||||
|
|
||||||
const iifeName = 'RevueFlow'
|
const iifeName = 'VueFlow'
|
||||||
const functionNames = ['vue-flow']
|
const functionNames = ['vue-flow']
|
||||||
|
|
||||||
for (const fn of functionNames) {
|
for (const fn of functionNames) {
|
||||||
@@ -89,7 +89,7 @@ for (const { external, iife } of activePackages) {
|
|||||||
}),
|
}),
|
||||||
commonjs({ include: 'node_modules/**' }),
|
commonjs({ include: 'node_modules/**' }),
|
||||||
replace({
|
replace({
|
||||||
__REACT_FLOW_VERSION__: JSON.stringify(pkg.version),
|
__VUE_FLOW_VERSION__: JSON.stringify(pkg.version),
|
||||||
preventAssignment: true,
|
preventAssignment: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import { XYPosition } from '~/types'
|
import { XYPosition } from '~/types'
|
||||||
|
|
||||||
export function getMousePosition(event: MouseEvent): XYPosition | void {
|
export function getMousePosition(event: MouseEvent): XYPosition | void {
|
||||||
const revueFlowNode = (event.target as Element).closest('.vue-flow')
|
const flowNode = (event.target as Element).closest('.vue-flow')
|
||||||
if (!revueFlowNode) {
|
if (!flowNode) return
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const containerBounds = revueFlowNode.getBoundingClientRect()
|
const containerBounds = flowNode.getBoundingClientRect()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
x: event.clientX - containerBounds.left,
|
x: event.clientX - containerBounds.left,
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export default () => {
|
|||||||
},
|
},
|
||||||
elementEdgeUpdaterType?: HandleType,
|
elementEdgeUpdaterType?: HandleType,
|
||||||
) => {
|
) => {
|
||||||
const revueFlowNode = (event.target as Element).closest('.vue-flow')
|
const flowNode = (event.target as Element).closest('.vue-flow')
|
||||||
// when vue-flow is used inside a shadow root we can't use document
|
// when vue-flow is used inside a shadow root we can't use document
|
||||||
const doc = getHostForElement(event.target as HTMLElement)
|
const doc = getHostForElement(event.target as HTMLElement)
|
||||||
|
|
||||||
@@ -92,10 +92,10 @@ export default () => {
|
|||||||
const elementBelowIsTarget = elementBelow?.classList.contains('target')
|
const elementBelowIsTarget = elementBelow?.classList.contains('target')
|
||||||
const elementBelowIsSource = elementBelow?.classList.contains('source')
|
const elementBelowIsSource = elementBelow?.classList.contains('source')
|
||||||
|
|
||||||
if (!revueFlowNode || (!elementBelowIsTarget && !elementBelowIsSource && !elementEdgeUpdaterType)) return
|
if (!flowNode || (!elementBelowIsTarget && !elementBelowIsSource && !elementEdgeUpdaterType)) return
|
||||||
|
|
||||||
const handleType = elementEdgeUpdaterType || (elementBelowIsTarget ? 'target' : 'source')
|
const handleType = elementEdgeUpdaterType || (elementBelowIsTarget ? 'target' : 'source')
|
||||||
const containerBounds = revueFlowNode.getBoundingClientRect()
|
const containerBounds = flowNode.getBoundingClientRect()
|
||||||
let recentHoveredHandle: Element
|
let recentHoveredHandle: Element
|
||||||
|
|
||||||
store.connectionPosition.x = event.clientX - containerBounds.left
|
store.connectionPosition.x = event.clientX - containerBounds.left
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ const init = (opts: typeof props) => {
|
|||||||
onBeforeUnmount(() => store?.$dispose())
|
onBeforeUnmount(() => store?.$dispose())
|
||||||
|
|
||||||
watch(props, (val) => init(val))
|
watch(props, (val) => init(val))
|
||||||
init(props)
|
onMounted(() => init(props))
|
||||||
|
|
||||||
const nodeTypes = createNodeTypes({ ...defaultNodeTypes, ...props.nodeTypes })
|
const nodeTypes = createNodeTypes({ ...defaultNodeTypes, ...props.nodeTypes })
|
||||||
const edgeTypes = createEdgeTypes({ ...defaultEdgeTypes, ...props.edgeTypes })
|
const edgeTypes = createEdgeTypes({ ...defaultEdgeTypes, ...props.edgeTypes })
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted } from 'vue'
|
import { onMounted } from 'vue'
|
||||||
import { KeyCode, PanOnScrollMode } from '~/types'
|
import { D3ZoomEvent, zoom, zoomIdentity, ZoomTransform } from 'd3-zoom'
|
||||||
import { useHooks, useStore, useZoom, useZoomPanHelper } from '~/composables'
|
import { get } from '@vueuse/core'
|
||||||
import { onLoadGetElements, onLoadProject, onLoadToObject } from '~/utils/graph'
|
import { pointer, select } from 'd3-selection'
|
||||||
|
import { FlowTransform, KeyCode, PanOnScrollMode } from '~/types'
|
||||||
|
import { useHooks, useKeyPress, useStore, useZoomPanHelper } from '~/composables'
|
||||||
|
import { clamp, onLoadGetElements, onLoadProject, onLoadToObject } from '~/utils/graph'
|
||||||
|
|
||||||
interface ZoomPaneProps {
|
interface ZoomPaneProps {
|
||||||
selectionKeyCode?: KeyCode
|
selectionKeyCode?: KeyCode
|
||||||
@@ -36,13 +39,157 @@ const hooks = useHooks()
|
|||||||
|
|
||||||
const zoomPaneEl = templateRef<HTMLDivElement>('zoom-pane', null)
|
const zoomPaneEl = templateRef<HTMLDivElement>('zoom-pane', null)
|
||||||
|
|
||||||
|
const viewChanged = (prevTransform: FlowTransform, eventTransform: ZoomTransform): boolean =>
|
||||||
|
prevTransform.x !== eventTransform.x || prevTransform.y !== eventTransform.y || prevTransform.zoom !== eventTransform.k
|
||||||
|
|
||||||
|
const eventToFlowTransform = (eventTransform: ZoomTransform): FlowTransform => ({
|
||||||
|
x: eventTransform.x,
|
||||||
|
y: eventTransform.y,
|
||||||
|
zoom: eventTransform.k,
|
||||||
|
})
|
||||||
|
|
||||||
|
const clampedX = clamp(props.defaultPosition[0], store.translateExtent[0][0], store.translateExtent[1][0])
|
||||||
|
const clampedY = clamp(props.defaultPosition[1], store.translateExtent[0][1], store.translateExtent[1][1])
|
||||||
|
const clampedZoom = clamp(props.defaultZoom, store.minZoom, store.maxZoom)
|
||||||
|
const transform = ref({ x: clampedX, y: clampedY, zoom: clampedZoom })
|
||||||
|
|
||||||
|
const d3Zoom = ref(zoom<HTMLDivElement, any>().scaleExtent([store.minZoom, store.maxZoom]).translateExtent(store.translateExtent))
|
||||||
|
const d3Selection = ref()
|
||||||
|
|
||||||
|
until(zoomPaneEl)
|
||||||
|
.toBeTruthy()
|
||||||
|
.then(() => {
|
||||||
|
const d3z = get(d3Zoom)!
|
||||||
|
d3Selection.value = select(zoomPaneEl.value).call(d3z)
|
||||||
|
const d3s = get(d3Selection)!
|
||||||
|
const d3ZoomHandler = d3s.on('wheel.zoom')
|
||||||
|
|
||||||
|
const updatedTransform = zoomIdentity.translate(clampedX, clampedY).scale(clampedZoom)
|
||||||
|
d3z.transform(d3s, updatedTransform)
|
||||||
|
store.initD3Zoom({ d3Zoom: d3z, d3Selection: d3s, d3ZoomHandler })
|
||||||
|
store.transform = [updatedTransform.x, updatedTransform.y, updatedTransform.k]
|
||||||
|
|
||||||
|
const applyZoomHandlers = () => {
|
||||||
|
d3z.on('start', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||||
|
if (viewChanged(transform.value, event.transform)) {
|
||||||
|
const flowTransform = eventToFlowTransform(event.transform)
|
||||||
|
transform.value = flowTransform
|
||||||
|
|
||||||
|
hooks.moveStart.trigger(flowTransform)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
d3z.on('end', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||||
|
if (viewChanged(transform.value, event.transform)) {
|
||||||
|
const flowTransform = eventToFlowTransform(event.transform)
|
||||||
|
transform.value = flowTransform
|
||||||
|
|
||||||
|
hooks.moveEnd.trigger(flowTransform)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
useKeyPress(props.selectionKeyCode, (keyPress) => {
|
||||||
|
if (keyPress) {
|
||||||
|
d3z.on('zoom', null)
|
||||||
|
} else {
|
||||||
|
d3z.on('zoom', (event: D3ZoomEvent<HTMLDivElement, any>) => {
|
||||||
|
const flowTransform = eventToFlowTransform(event.transform)
|
||||||
|
transform.value = flowTransform
|
||||||
|
|
||||||
|
hooks.move.trigger(flowTransform)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
useKeyPress(props.zoomActivationKeyCode, (keyPress) => {
|
||||||
|
if (props.panOnScroll && keyPress) {
|
||||||
|
d3s
|
||||||
|
?.on('wheel', (event: WheelEvent) => {
|
||||||
|
event.preventDefault()
|
||||||
|
event.stopImmediatePropagation()
|
||||||
|
|
||||||
|
const currentZoom = d3s?.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 (d3s) d3z.scaleTo(d3s, zoom, point)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// increase scroll speed in firefox
|
||||||
|
// firefox: deltaMode === 1; chrome: deltaMode === 0
|
||||||
|
const deltaNormalize = event.deltaMode === 1 ? 20 : 1
|
||||||
|
const deltaX = props.panOnScrollMode === PanOnScrollMode.Vertical ? 0 : event.deltaX * deltaNormalize
|
||||||
|
const deltaY = props.panOnScrollMode === PanOnScrollMode.Horizontal ? 0 : event.deltaY * deltaNormalize
|
||||||
|
|
||||||
|
if (d3s && props.panOnScrollSpeed)
|
||||||
|
d3z?.translateBy(
|
||||||
|
d3s,
|
||||||
|
-(deltaX / currentZoom) * props.panOnScrollSpeed,
|
||||||
|
-(deltaY / currentZoom) * props.panOnScrollSpeed,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.on('wheel.zoom', null)
|
||||||
|
} else if (typeof d3ZoomHandler !== 'undefined') {
|
||||||
|
d3s?.on('wheel', null).on('wheel.zoom', d3ZoomHandler)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const applyZoomFilter = () => {
|
||||||
|
const keyPress = useKeyPress(props.selectionKeyCode)
|
||||||
|
d3z.filter((event: MouseEvent) => {
|
||||||
|
const zoomScroll = props.zoomOnScroll
|
||||||
|
const pinchZoom = props.zoomOnPinch && event.ctrlKey
|
||||||
|
|
||||||
|
// if all interactions are disabled, we prevent all zoom events
|
||||||
|
if (!props.paneMoveable && !zoomScroll && !props.panOnScroll && !props.zoomOnDoubleClick && !props.zoomOnPinch)
|
||||||
|
return false
|
||||||
|
|
||||||
|
// during a selection we prevent all other interactions
|
||||||
|
if (keyPress.value) return false
|
||||||
|
|
||||||
|
// if zoom on double click is disabled, we prevent the double click event
|
||||||
|
if (!props.zoomOnDoubleClick && event.type === 'dblclick') return false
|
||||||
|
|
||||||
|
if ((event.target as Element).closest('.nowheel') && event.type === 'wheel') return false
|
||||||
|
|
||||||
|
// when the target element is a node, we still allow zooming
|
||||||
|
if (
|
||||||
|
((event.target as Element).closest('.vue-flow__node') || (event.target as Element).closest('.vue-flow__edge')) &&
|
||||||
|
event.type !== 'wheel'
|
||||||
|
)
|
||||||
|
return false
|
||||||
|
|
||||||
|
// when the target element is a node selection, we still allow zooming
|
||||||
|
if ((event.target as Element).closest('.vue-flow__nodesselection') && event.type !== 'wheel') return false
|
||||||
|
|
||||||
|
if (!props.zoomOnPinch && event.ctrlKey && event.type === 'wheel') return false
|
||||||
|
|
||||||
|
// when there is no scroll handling enabled, we prevent all wheel events
|
||||||
|
if (!zoomScroll && !props.panOnScroll && !pinchZoom && event.type === 'wheel') return false
|
||||||
|
|
||||||
|
// if the pane is not movable, we prevent dragging it with mousestart or touchstart
|
||||||
|
if (!props.paneMoveable && (event.type === 'mousedown' || event.type === 'touchstart')) return false
|
||||||
|
|
||||||
|
// default filter for d3-zoom
|
||||||
|
return (!event.ctrlKey || event.type === 'wheel') && !event.button
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
applyZoomHandlers()
|
||||||
|
applyZoomFilter()
|
||||||
|
})
|
||||||
|
|
||||||
const { width, height } = useElementBounding(zoomPaneEl)
|
const { width, height } = useElementBounding(zoomPaneEl)
|
||||||
store.dimensions = {
|
store.dimensions = {
|
||||||
width: width.value,
|
width: width.value,
|
||||||
height: height.value,
|
height: height.value,
|
||||||
}
|
}
|
||||||
|
|
||||||
const { transform } = useZoom(zoomPaneEl, props)
|
|
||||||
store.transform = [transform.value.x, transform.value.y, transform.value.zoom]
|
store.transform = [transform.value.x, transform.value.y, transform.value.zoom]
|
||||||
|
|
||||||
watch(width, (val) => (store.dimensions.width = val))
|
watch(width, (val) => (store.dimensions.width = val))
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@ export const initialState = (): FlowState => ({
|
|||||||
|
|
||||||
multiSelectionActive: false,
|
multiSelectionActive: false,
|
||||||
|
|
||||||
revueFlowVersion: typeof __VUE_FLOW_VERSION__ !== 'undefined' ? __VUE_FLOW_VERSION__ : '-',
|
vueFlowVersion: typeof __VUE_FLOW_VERSION__ !== 'undefined' ? __VUE_FLOW_VERSION__ : '-',
|
||||||
})
|
})
|
||||||
|
|
||||||
export { default as useFlowStore } from './useFlowStore'
|
export { default as useFlowStore } from './useFlowStore'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { setActivePinia, createPinia, defineStore, StoreDefinition } from 'pinia'
|
import { setActivePinia, createPinia, defineStore, StoreDefinition } from 'pinia'
|
||||||
import isEqual from 'fast-deep-equal'
|
import isEqual from 'fast-deep-equal'
|
||||||
import { Edge, FlowState, Node, RevueFlowActions } from '~/types'
|
import { Edge, FlowState, Node, FlowActions } from '~/types'
|
||||||
import { clampPosition, getDimensions } from '~/utils'
|
import { clampPosition, getDimensions } from '~/utils'
|
||||||
import { getConnectedEdges, getNodesInside, getRectOfNodes, isEdge, isNode, parseEdge, parseNode } from '~/utils/graph'
|
import { getConnectedEdges, getNodesInside, getRectOfNodes, isEdge, isNode, parseEdge, parseNode } from '~/utils/graph'
|
||||||
import { getHandleBounds } from '~/components/Nodes/utils'
|
import { getHandleBounds } from '~/components/Nodes/utils'
|
||||||
@@ -11,7 +11,7 @@ type NextElements = {
|
|||||||
}
|
}
|
||||||
const pinia = createPinia()
|
const pinia = createPinia()
|
||||||
|
|
||||||
export default function useFlowStore(preloadedState: FlowState): StoreDefinition<string, FlowState, any, RevueFlowActions> {
|
export default function useFlowStore(preloadedState: FlowState): StoreDefinition<string, FlowState, any, FlowActions> {
|
||||||
setActivePinia(pinia)
|
setActivePinia(pinia)
|
||||||
|
|
||||||
return defineStore({
|
return defineStore({
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { NodeDiffUpdate, NodeDimensionUpdate, NodeExtent, NodePosUpdate, Transla
|
|||||||
import { InitD3ZoomPayload } from './panel'
|
import { InitD3ZoomPayload } from './panel'
|
||||||
import { SetConnectionId } from './connection'
|
import { SetConnectionId } from './connection'
|
||||||
|
|
||||||
export interface RevueFlowActions {
|
export interface FlowActions {
|
||||||
setElements: (elements: Elements) => void
|
setElements: (elements: Elements) => void
|
||||||
updateNodeDimensions: (update: NodeDimensionUpdate) => void
|
updateNodeDimensions: (update: NodeDimensionUpdate) => void
|
||||||
updateNodePos: (payload: NodePosUpdate) => void
|
updateNodePos: (payload: NodePosUpdate) => void
|
||||||
|
|||||||
+3
-3
@@ -4,7 +4,7 @@ import { HandleType } from './handle'
|
|||||||
import { ConnectionMode, OnConnectEndFunc, OnConnectFunc, OnConnectStartFunc, OnConnectStopFunc } from './connection'
|
import { ConnectionMode, OnConnectEndFunc, OnConnectFunc, OnConnectStartFunc, OnConnectStopFunc } from './connection'
|
||||||
import { Edge } from './edge'
|
import { Edge } from './edge'
|
||||||
import { Node, NodeExtent, TranslateExtent } from './node'
|
import { Node, NodeExtent, TranslateExtent } from './node'
|
||||||
import { RevueFlowActions } from './actions'
|
import { FlowActions } from './actions'
|
||||||
import { D3Selection, D3Zoom, D3ZoomHandler } from '~/types/panel'
|
import { D3Selection, D3Zoom, D3ZoomHandler } from '~/types/panel'
|
||||||
|
|
||||||
export interface FlowState {
|
export interface FlowState {
|
||||||
@@ -44,7 +44,7 @@ export interface FlowState {
|
|||||||
|
|
||||||
multiSelectionActive: boolean
|
multiSelectionActive: boolean
|
||||||
|
|
||||||
revueFlowVersion: string
|
vueFlowVersion: string
|
||||||
|
|
||||||
onConnect?: OnConnectFunc
|
onConnect?: OnConnectFunc
|
||||||
onConnectStart?: OnConnectStartFunc
|
onConnectStart?: OnConnectStartFunc
|
||||||
@@ -52,4 +52,4 @@ export interface FlowState {
|
|||||||
onConnectEnd?: OnConnectEndFunc
|
onConnectEnd?: OnConnectEndFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FlowStore = Store<string, FlowState, any, RevueFlowActions>
|
export type FlowStore = Store<string, FlowState, any, FlowActions>
|
||||||
|
|||||||
+1
-1
@@ -75,7 +75,7 @@ export const removeElements = (elementsToRemove: Elements, elements: Elements):
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getEdgeId = ({ source, sourceHandle, target, targetHandle }: Connection): ElementId =>
|
const getEdgeId = ({ source, sourceHandle, target, targetHandle }: Connection): ElementId =>
|
||||||
`revueflow__edge-${source}${sourceHandle}-${target}${targetHandle}`
|
`vueflow__edge-${source}${sourceHandle}-${target}${targetHandle}`
|
||||||
|
|
||||||
const connectionExists = (edge: Edge, elements: Elements) => {
|
const connectionExists = (edge: Edge, elements: Elements) => {
|
||||||
return elements.some(
|
return elements.some(
|
||||||
|
|||||||
Reference in New Issue
Block a user