* don't split edge prop into smaller ones Signed-off-by: Braks <78412429+bcakmakoglu@users.noreply.github.com>
124 lines
4.0 KiB
Vue
124 lines
4.0 KiB
Vue
<script lang="ts" setup>
|
|
import { CSSProperties } from 'vue'
|
|
import {
|
|
ConnectionLineType,
|
|
ConnectionMode,
|
|
Dimensions,
|
|
Edge,
|
|
EdgeComponent,
|
|
ElementId,
|
|
GraphNode,
|
|
HandleType,
|
|
Transform,
|
|
XYPosition,
|
|
} from '../../types'
|
|
import { getSourceTargetNodes } from '../../utils'
|
|
import EdgeWrapper from '../../components/Edges/EdgeWrapper.vue'
|
|
import ConnectionLine from '../../components/ConnectionLine/ConnectionLine.vue'
|
|
import MarkerDefinitions from './MarkerDefinitions.vue'
|
|
|
|
interface EdgeRendererProps {
|
|
edges: Edge[]
|
|
nodes: GraphNode[]
|
|
edgeTypes: Record<string, EdgeComponent>
|
|
transform: Transform
|
|
dimensions: Dimensions
|
|
connectionLineType?: ConnectionLineType
|
|
connectionLineStyle?: CSSProperties
|
|
arrowHeadColor?: string
|
|
markerEndId?: string
|
|
elementsSelectable?: boolean
|
|
edgeUpdaterRadius?: number
|
|
connectionNodeId?: ElementId
|
|
connectionHandleType?: HandleType
|
|
connectionHandleId?: ElementId
|
|
connectionPosition?: XYPosition
|
|
connectionMode: ConnectionMode
|
|
nodesConnectable?: boolean
|
|
}
|
|
|
|
const props = withDefaults(defineProps<EdgeRendererProps>(), {
|
|
arrowHeadColor: '#b1b1b7',
|
|
connectionLineType: ConnectionLineType.Bezier,
|
|
edgeUpdaterRadius: 10,
|
|
})
|
|
|
|
const getType = (type?: string) => {
|
|
const t = type ?? 'default'
|
|
let edgeType = props.edgeTypes[t]
|
|
if (!edgeType) {
|
|
edgeType = props.edgeTypes.default
|
|
console.warn(`Edge type "${type}" not found. Using fallback type "default".`)
|
|
}
|
|
return edgeType
|
|
}
|
|
|
|
const sourceNode = controlledComputed(
|
|
() => props.connectionNodeId,
|
|
() => {
|
|
if (props.connectionNodeId) return props.nodes[props.nodes.map((n) => n.id).indexOf(props.connectionNodeId)]
|
|
},
|
|
)
|
|
const connectionLineVisible = controlledComputed(
|
|
() => props.connectionNodeId,
|
|
() =>
|
|
!!(
|
|
sourceNode.value &&
|
|
(typeof sourceNode.value.connectable === 'undefined' ? props.nodesConnectable : sourceNode.value.connectable) &&
|
|
props.connectionNodeId &&
|
|
props.connectionHandleType
|
|
),
|
|
)
|
|
const transform = computed(() => `translate(${props.transform[0]},${props.transform[1]}) scale(${props.transform[2]})`)
|
|
|
|
const sourceTargetNodes = (edge: Edge) => {
|
|
const { sourceNode, targetNode } = getSourceTargetNodes(edge, props.nodes)
|
|
if (!sourceNode) console.warn(`couldn't create edge for source id: ${edge.source}; edge id: ${edge.id}`)
|
|
if (!targetNode) console.warn(`couldn't create edge for target id: ${edge.target}; edge id: ${edge.id}`)
|
|
return { sourceNode, targetNode }
|
|
}
|
|
</script>
|
|
<script lang="ts">
|
|
export default {
|
|
name: 'Edges',
|
|
}
|
|
</script>
|
|
<template>
|
|
<svg :width="props.dimensions.width" :height="props.dimensions.height" class="vue-flow__edges">
|
|
<MarkerDefinitions :color="props.arrowHeadColor" />
|
|
<g :transform="transform">
|
|
<EdgeWrapper
|
|
v-for="(edge, i) of props.edges"
|
|
:key="`${edge.id}-${i}`"
|
|
:edge="edge"
|
|
:source-target-nodes="sourceTargetNodes(edge)"
|
|
:component="getType(edge.type)"
|
|
:selectable="props.elementsSelectable"
|
|
:edge-updater-radius="props.edgeUpdaterRadius"
|
|
:dimensions="props.dimensions"
|
|
:transform="props.transform"
|
|
>
|
|
<template #default="edgeProps">
|
|
<slot :name="`edge-${edge.type}`" v-bind="edgeProps"></slot>
|
|
</template>
|
|
</EdgeWrapper>
|
|
<ConnectionLine
|
|
v-if="connectionLineVisible && sourceNode"
|
|
:vf="sourceNode?.__vf"
|
|
:connection-line-style="props.connectionLineStyle"
|
|
:connection-line-type="props.connectionLineType"
|
|
:connection-handle-id="props.connectionHandleId"
|
|
:connection-node-id="props.connectionNodeId"
|
|
:connection-handle-type="props.connectionHandleType"
|
|
:connection-position="props.connectionPosition"
|
|
:connection-mode="props.connectionMode"
|
|
:transform="props.transform"
|
|
>
|
|
<template #default="customConnectionLineProps">
|
|
<slot name="custom-connection-line" v-bind="customConnectionLineProps"></slot>
|
|
</template>
|
|
</ConnectionLine>
|
|
</g>
|
|
</svg>
|
|
</template>
|