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:
@@ -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'
|
||||
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
@@ -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),
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user