fix: edges and edge anchors not re-calculating correctly

This commit is contained in:
Braks
2021-10-20 22:39:54 +02:00
parent 7ecbcba7eb
commit 61dc9dea33
7 changed files with 60 additions and 49 deletions
+2
View File
@@ -13,6 +13,7 @@ import Flow, {
Position,
SnapGrid,
Connection,
ConnectionMode,
Edge,
} from '~/index'
@@ -114,6 +115,7 @@ const onConnect = (params: Connection | Edge) =>
:elements="elements"
:style="`background: ${bgColor}`"
:node-types="nodeTypes"
:connection-mode="ConnectionMode.Loose"
:connection-line-style="connectionLineStyle"
:snap-to-grid="true"
:snap-grid="snapGrid"
+34 -21
View File
@@ -2,14 +2,13 @@
import EdgeAnchor from './EdgeAnchor.vue'
import { getEdgePositions, getHandle, getSourceTargetNodes, isEdgeVisible } from '~/container/EdgeRenderer/utils'
import { isEdge } from '~/utils/graph'
import { ConnectionMode, Edge, EdgeType, Position } from '~/types'
import { ConnectionMode, Edge, EdgeType, HandleElement, Position, EdgePositions } from '~/types'
import { Hooks, Store } from '~/context'
import { useHandle } from '~/composables'
interface EdgeProps {
type: EdgeType
edge: Edge
nodes: ReturnType<typeof getSourceTargetNodes>
markerEndId?: string
edgeUpdaterRadius?: number
}
@@ -23,27 +22,19 @@ hooks.connect.on((connection) => {
hooks.edgeUpdate.trigger({ edge: props.edge, connection })
})
if (!props.nodes.sourceNode) {
console.warn(`couldn't create edge for source id: ${props.edge.source}; edge id: ${props.edge.id}`)
}
const nodes = computed(() => {
const n = getSourceTargetNodes(props.edge, store.nodes)
if (!props.nodes.targetNode) {
console.warn(`couldn't create edge for target id: ${props.edge.target}; edge id: ${props.edge.id}`)
}
if (!n.sourceNode) {
console.warn(`couldn't create edge for source id: ${props.edge.source}; edge id: ${props.edge.id}`)
}
// when connection type is loose we can define all handles as sources
const targetNodeHandles =
store.connectionMode === ConnectionMode.Strict
? props.nodes.targetNode?.__rf.handleBounds.target
: props.nodes.targetNode?.__rf.handleBounds.target || props.nodes.targetNode?.__rf.handleBounds.source
if (!n.targetNode) {
console.warn(`couldn't create edge for target id: ${props.edge.target}; edge id: ${props.edge.id}`)
}
const sourceHandle =
props.nodes.sourceNode && getHandle(props.nodes.sourceNode.__rf.handleBounds.source, props.edge.sourceHandle || null)
const targetHandle = getHandle(targetNodeHandles, props.edge.targetHandle || null)
const sourcePosition = sourceHandle ? sourceHandle.position : Position.Bottom
const targetPosition = targetHandle ? targetHandle.position : Position.Top
const isSelected = store.selectedElements?.some((elm) => isEdge(elm) && elm.id === props.edge.id) || false
return n
})
const onEdgeClick = (event: MouseEvent) => {
if (store.elementsSelectable) {
@@ -102,8 +93,30 @@ const isVisible = ({ sourceX, sourceY, targetX, targetY }: ReturnType<typeof get
: true
}
// when connection type is loose we can define all handles as sources
const targetNodeHandles = computed(() =>
store.connectionMode === ConnectionMode.Strict
? nodes.value.targetNode?.__rf.handleBounds.target
: nodes.value.targetNode?.__rf.handleBounds.target || nodes.value.targetNode?.__rf.handleBounds.source,
)
const sourceHandle = computed(
() => nodes.value.sourceNode && getHandle(nodes.value.sourceNode.__rf.handleBounds.source, props.edge.sourceHandle || null),
)
const targetHandle = computed(() => getHandle(targetNodeHandles.value, props.edge.targetHandle || null))
const sourcePosition = computed(() => (sourceHandle.value ? sourceHandle.value.position : Position.Bottom))
const targetPosition = computed(() => (targetHandle.value ? targetHandle.value.position : Position.Top))
const isSelected = computed(() => store.selectedElements?.some((elm) => isEdge(elm) && elm.id === props.edge.id) || false)
const edgePos = computed(() =>
getEdgePositions(props.nodes.sourceNode, sourceHandle, sourcePosition, props.nodes.targetNode, targetHandle, targetPosition),
getEdgePositions(
nodes.value.sourceNode,
sourceHandle.value,
sourcePosition.value,
nodes.value.targetNode,
targetHandle.value,
targetPosition.value,
),
)
</script>
<template>
+1 -13
View File
@@ -3,10 +3,9 @@ import { pointer, select } from 'd3-selection'
import { Ref } from 'vue'
import { get } from '@vueuse/core'
import { FlowTransform, PanOnScrollMode, Transform, UseZoom, UseZoomOptions } from '~/types'
import { clamp, onLoadGetElements, onLoadProject, onLoadToObject } from '~/utils'
import { clamp } from '~/utils'
import useKeyPress from '~/composables/useKeyPress'
import { Hooks, Store } from '~/context'
import { useZoomPanHelper } from '~/composables/index'
const viewChanged = (prevTransform: FlowTransform, eventTransform: ZoomTransform): boolean =>
prevTransform.x !== eventTransform.x || prevTransform.y !== eventTransform.y || prevTransform.zoom !== eventTransform.k
@@ -60,17 +59,6 @@ export default function (el: Ref<HTMLDivElement>, options: UseZoomOptions): UseZ
const updatedTransform = zoomIdentity.translate(clampedX, clampedY).scale(clampedZoom)
d3z.transform(d3s, updatedTransform)
store.initD3Zoom({ d3Zoom: d3z, d3Selection: d3s, d3ZoomHandler })
const { zoomIn, zoomOut, zoomTo, transform: setTransform, fitView } = useZoomPanHelper(store)
hooks.load.trigger({
fitView: (params = { padding: 0.1 }) => fitView(params),
zoomIn,
zoomOut,
zoomTo,
setTransform,
project: onLoadProject(store),
getElements: onLoadGetElements(store),
toObject: onLoadToObject(store),
})
const applyZoomHandlers = () => {
d3z.on('start', (event: D3ZoomEvent<HTMLDivElement, any>) => {
@@ -39,7 +39,6 @@ const connectionLineVisible = computed(
<Edge
v-if="!edge.isHidden"
:edge="edge"
:nodes="getSourceTargetNodes(edge, store.nodes)"
:type="props.edgeTypes[edge.type || 'default']"
:marker-end-id="props.markerEndId"
:edge-updater-radius="props.edgeUpdaterRadius"
+5 -14
View File
@@ -1,6 +1,6 @@
import { BezierEdge, SmoothStepEdge, StepEdge, StraightEdge } from '~/components/Edges'
import { rectToBox } from '~/utils/graph'
import { Edge, EdgeType, ElementId, HandleElement, Node, Position, Transform, XYPosition } from '~/types'
import { Edge, EdgePositions, EdgeType, ElementId, HandleElement, Node, Position, Transform, XYPosition } from '~/types'
export function createEdgeTypes(edgeTypes: Record<string, EdgeType>): Record<string, EdgeType> {
const standardTypes: Record<string, EdgeType> = {
@@ -55,28 +55,19 @@ export function getHandlePosition(position: Position, node: Node, handle: any |
}
}
export function getHandle(bounds: HandleElement[], handleId: ElementId | null): HandleElement | null {
if (!bounds) {
return null
}
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 = null
let handle
if (bounds.length === 1 || !handleId) {
handle = bounds[0]
} else if (handleId) {
handle = bounds.find((d) => d.id === handleId)
}
return typeof handle === 'undefined' ? null : handle
}
interface EdgePositions {
sourceX: number
sourceY: number
targetX: number
targetY: number
return typeof handle === 'undefined' ? undefined : handle
}
export const getEdgePositions = (
+11
View File
@@ -46,6 +46,17 @@ store.dimensions = {
width: width.value,
height: height.value,
}
const { zoomIn, zoomOut, zoomTo, transform: setTransform, fitView } = useZoomPanHelper()
hooks.load.trigger({
fitView: (params = { padding: 0.1 }) => fitView(params),
zoomIn,
zoomOut,
zoomTo,
setTransform,
project: onLoadProject(store),
getElements: onLoadGetElements(store),
toObject: onLoadToObject(store),
})
</script>
<template>
<div ref="zoom-pane" class="revue-flow__renderer revue-flow__zoompane">
+7
View File
@@ -56,3 +56,10 @@ export interface EdgeSmoothStepProps<T = any> extends EdgeProps<T> {
export type EdgeType = DefineComponent<EdgeSmoothStepProps>
export type OnEdgeUpdateFunc<T = any> = (oldEdge: Edge<T>, newConnection: Connection) => void
export interface EdgePositions {
sourceX: number
sourceY: number
targetX: number
targetY: number
}