update!: graphnode and node typing

* graphnode is a node containing internal Vue Flow data
* move util files to util directory
* move flow actions type into store file
* rename panel type file to zoom
* rename types file to flow
* Rename Node to NodeWrapper
* Rename Edge to EdgeWrapper

Signed-off-by: Braks <78412429+bcakmakoglu@users.noreply.github.com>
This commit is contained in:
Braks
2021-11-21 16:25:27 +01:00
parent ba24f3ca62
commit 062aee45b2
36 changed files with 280 additions and 275 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
import { CSSProperties } from 'vue'
import { ConnectionLineType } from '../../types'
import { useStore } from '../../composables'
import Edge from '../../components/Edges/Edge.vue'
import Edge from '../../components/Edges/EdgeWrapper.vue'
import ConnectionLine from '../../components/ConnectionLine/ConnectionLine.vue'
import MarkerDefinitions from './MarkerDefinitions.vue'
-124
View File
@@ -1,124 +0,0 @@
import { Edge, EdgePositions, ElementId, HandleElement, Node, Position, Transform, XYPosition } from '../../types'
import { rectToBox } from '~/utils'
export function getHandlePosition(position: Position, node: Node, handle: any | null = null): XYPosition {
const x = (handle?.x || 0) + node.__vf?.position?.x
const y = (handle?.y || 0) + node.__vf?.position?.y
const width = handle?.width || node.__vf?.width
const height = handle?.height || node.__vf?.height
switch (position) {
case Position.Top:
return {
x: x + width / 2,
y,
}
case Position.Right:
return {
x: x + width,
y: y + height / 2,
}
case Position.Bottom:
return {
x: x + width / 2,
y: y + height,
}
case Position.Left:
return {
x,
y: y + height / 2,
}
}
}
export function getHandle(bounds: HandleElement[], handleId: ElementId | null): HandleElement | undefined {
if (!bounds) return undefined
// there is no handleId when there are no multiple handles/ handles with ids
// so we just pick the first one
let handle
if (bounds.length === 1 || !handleId) {
handle = bounds[0]
} else if (handleId) {
handle = bounds.find((d) => d.id === handleId)
}
return typeof handle === 'undefined' ? undefined : handle
}
export const getEdgePositions = (
sourceNode: Node,
sourceHandle: HandleElement | unknown,
sourcePosition: Position,
targetNode: Node,
targetHandle: HandleElement | unknown,
targetPosition: Position,
): EdgePositions => {
const sourceHandlePos = getHandlePosition(sourcePosition, sourceNode, sourceHandle)
const targetHandlePos = getHandlePosition(targetPosition, targetNode, targetHandle)
return {
sourceX: sourceHandlePos.x,
sourceY: sourceHandlePos.y,
targetX: targetHandlePos.x,
targetY: targetHandlePos.y,
}
}
interface IsEdgeVisibleParams {
sourcePos: XYPosition
targetPos: XYPosition
width: number
height: number
transform: Transform
}
export function isEdgeVisible({ sourcePos, targetPos, width, height, transform }: IsEdgeVisibleParams): boolean {
const edgeBox = {
x: Math.min(sourcePos.x, targetPos.x),
y: Math.min(sourcePos.y, targetPos.y),
x2: Math.max(sourcePos.x, targetPos.x),
y2: Math.max(sourcePos.y, targetPos.y),
}
if (edgeBox.x === edgeBox.x2) {
edgeBox.x2 += 1
}
if (edgeBox.y === edgeBox.y2) {
edgeBox.y2 += 1
}
const viewBox = rectToBox({
x: (0 - transform[0]) / transform[2],
y: (0 - transform[1]) / transform[2],
width: width / transform[2],
height: height / transform[2],
})
const xOverlap = Math.max(0, Math.min(viewBox.x2, edgeBox.x2) - Math.max(viewBox.x, edgeBox.x))
const yOverlap = Math.max(0, Math.min(viewBox.y2, edgeBox.y2) - Math.max(viewBox.y, edgeBox.y))
const overlappingArea = Math.ceil(xOverlap * yOverlap)
return overlappingArea > 0
}
type SourceTargetNode = {
sourceNode: Node
targetNode: Node
}
export const getSourceTargetNodes = (edge: Edge, nodes: Node[]): SourceTargetNode => {
return nodes.reduce(
(res, node) => {
if (node.id === edge.source) {
res.sourceNode = node
}
if (node.id === edge.target) {
res.targetNode = node
}
return res
},
{ sourceNode: null, targetNode: null } as any,
)
}
+5 -2
View File
@@ -1,9 +1,12 @@
<script lang="ts" setup>
import { useStore } from '../../composables'
import Node from '../../components/Nodes/Node.vue'
import Node from '../../components/Nodes/NodeWrapper.vue'
import { SnapGrid } from '../../types'
interface NodeRendererProps {
selectNodesOnDrag?: boolean
snapToGrid?: boolean
snapGrid?: SnapGrid
}
const props = withDefaults(defineProps<NodeRendererProps>(), {
@@ -13,7 +16,7 @@ const props = withDefaults(defineProps<NodeRendererProps>(), {
const store = useStore()
const transform = computed(() => `translate(${store.transform[0]}px,${store.transform[1]}px) scale(${store.transform[2]})`)
const snapGrid = computed(() => (store.snapToGrid ? store.snapGrid : undefined))
const snapGrid = computed(() => (props.snapToGrid || store.snapToGrid ? props.snapGrid ?? store.snapGrid : undefined))
</script>
<template>
<div class="vue-flow__nodes" :style="{ transform }">
@@ -3,7 +3,7 @@ import { ElementId, FlowElement, KeyCode } from '../../types'
import { useStore, useKeyPress } from '../../composables'
import NodesSelection from '../../components/NodesSelection/NodesSelection.vue'
import UserSelection from '../../components/UserSelection/UserSelection.vue'
import { getConnectedEdges, isNode } from '../../utils'
import { getConnectedEdges, isGraphNode } from '../../utils'
interface SelectionPaneProps {
selectionKeyCode?: KeyCode
@@ -33,7 +33,7 @@ const selectionKeyPresed = ref(false)
onMounted(() => {
useKeyPress(props.deleteKeyCode, (keyPressed) => {
if (keyPressed && store.selectedElements) {
const selectedNodes = store.selectedElements.filter(isNode)
const selectedNodes = store.selectedElements.filter(isGraphNode)
const connectedEdges = getConnectedEdges(selectedNodes, store.edges)
const elementsToRemove = [...store.selectedElements, ...connectedEdges].reduce(
(res, item) => res.set(item.id, item),
-1
View File
@@ -181,7 +181,6 @@ const transitionName = computed(() => {
<Suspense>
<template #default>
<ZoomPane
v-show="store.isReady"
key="zoom-pane"
:selection-key-code="store.selectionKeyCode"
:zoom-activation-key-code="store.zoomActivationKeyCode"