feat(edges): add connectionLineOptions prop
# What's changed? * allow defining markers on connection lines * deprecate `connectionLineType` * deprecate `connectionLineStyle`
This commit is contained in:
@@ -4,6 +4,7 @@ import type { GraphNode, HandleElement, HandleType } from '../../types'
|
|||||||
import { ConnectionLineType, Position } from '../../types'
|
import { ConnectionLineType, Position } from '../../types'
|
||||||
import { useVueFlow } from '../../composables'
|
import { useVueFlow } from '../../composables'
|
||||||
import { Slots } from '../../context'
|
import { Slots } from '../../context'
|
||||||
|
import { getMarkerId } from '../../utils'
|
||||||
|
|
||||||
const { sourceNode } = defineProps<{
|
const { sourceNode } = defineProps<{
|
||||||
sourceNode: GraphNode
|
sourceNode: GraphNode
|
||||||
@@ -17,6 +18,7 @@ const {
|
|||||||
connectionLineType,
|
connectionLineType,
|
||||||
connectionLineStyle,
|
connectionLineStyle,
|
||||||
connectionNodeId,
|
connectionNodeId,
|
||||||
|
connectionLineOptions,
|
||||||
viewport,
|
viewport,
|
||||||
} = $(useVueFlow())
|
} = $(useVueFlow())
|
||||||
|
|
||||||
@@ -44,7 +46,7 @@ const targetY = $computed(() => (connectionPosition.y - viewport.y) / viewport.z
|
|||||||
|
|
||||||
const dAttr = computed(() => {
|
const dAttr = computed(() => {
|
||||||
let path = `M${sourceX},${sourceY} ${targetX},${targetY}`
|
let path = `M${sourceX},${sourceY} ${targetX},${targetY}`
|
||||||
switch (connectionLineType) {
|
switch (connectionLineType || connectionLineOptions.type) {
|
||||||
case ConnectionLineType.Bezier:
|
case ConnectionLineType.Bezier:
|
||||||
path = getBezierPath({
|
path = getBezierPath({
|
||||||
sourceX,
|
sourceX,
|
||||||
@@ -99,13 +101,21 @@ export default {
|
|||||||
targetX,
|
targetX,
|
||||||
targetY,
|
targetY,
|
||||||
targetPosition,
|
targetPosition,
|
||||||
connectionLineType,
|
|
||||||
connectionLineStyle,
|
|
||||||
nodes: getNodes,
|
nodes: getNodes,
|
||||||
sourceNode,
|
sourceNode,
|
||||||
sourceHandle,
|
sourceHandle,
|
||||||
|
markerEnd: `url(#${getMarkerId(connectionLineOptions.markerEnd)})`,
|
||||||
|
markerStart: `url(#${getMarkerId(connectionLineOptions.markerStart)})`,
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<path v-else :d="dAttr" class="vue-flow__connection-path" :style="connectionLineStyle || {}" />
|
<path
|
||||||
|
v-else
|
||||||
|
:d="dAttr"
|
||||||
|
class="vue-flow__connection-path"
|
||||||
|
:class="connectionLineOptions.class"
|
||||||
|
:style="connectionLineStyle || connectionLineOptions.style || {}"
|
||||||
|
:marker-end="`url(#${getMarkerId(connectionLineOptions.markerEnd)})`"
|
||||||
|
:marker-start="`url(#${getMarkerId(connectionLineOptions.markerStart)})`"
|
||||||
|
/>
|
||||||
</g>
|
</g>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ const {
|
|||||||
connectionNodeId,
|
connectionNodeId,
|
||||||
nodesConnectable,
|
nodesConnectable,
|
||||||
connectionHandleType,
|
connectionHandleType,
|
||||||
defaultMarkerColor,
|
|
||||||
edgesUpdatable,
|
edgesUpdatable,
|
||||||
elementsSelectable,
|
elementsSelectable,
|
||||||
getSelectedNodes,
|
getSelectedNodes,
|
||||||
@@ -181,7 +180,7 @@ export default {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<svg v-for="group of groups" :key="group.level" class="vue-flow__edges vue-flow__container" :style="`z-index: ${group.level}`">
|
<svg v-for="group of groups" :key="group.level" class="vue-flow__edges vue-flow__container" :style="`z-index: ${group.level}`">
|
||||||
<MarkerDefinitions v-if="group.isMaxLevel" :default-color="defaultMarkerColor" />
|
<MarkerDefinitions v-if="group.isMaxLevel" />
|
||||||
<g>
|
<g>
|
||||||
<EdgeWrapper
|
<EdgeWrapper
|
||||||
v-for="edge of group.edges"
|
v-for="edge of group.edges"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const {
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
export default {
|
export default {
|
||||||
name: 'Marker',
|
name: 'MarkerType',
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,34 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useVueFlow } from '../../composables'
|
import { useVueFlow } from '../../composables'
|
||||||
import type { MarkerProps, MarkerType } from '../../types/edge'
|
import type { EdgeMarkerType, MarkerProps, MarkerType } from '../../types/edge'
|
||||||
import { getMarkerId } from '../../utils'
|
import { getMarkerId } from '../../utils'
|
||||||
import Marker from './Marker.vue'
|
import Marker from './Marker.vue'
|
||||||
|
|
||||||
const { defaultColor = '' } = defineProps<{
|
const { edges, connectionLineOptions, defaultMarkerColor: defaultColor } = $(useVueFlow())
|
||||||
defaultColor: string
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const { edges } = $(useVueFlow())
|
|
||||||
|
|
||||||
const markers = computed(() => {
|
const markers = computed(() => {
|
||||||
const ids: string[] = []
|
const ids: string[] = []
|
||||||
|
const markers: MarkerProps[] = []
|
||||||
|
|
||||||
return edges.reduce<MarkerProps[]>((markers, edge) => {
|
const createMarkers = (marker?: EdgeMarkerType) => {
|
||||||
;[edge.markerStart, edge.markerEnd].forEach((marker) => {
|
if (marker) {
|
||||||
if (marker) {
|
const markerId = getMarkerId(marker)
|
||||||
const markerId = getMarkerId(marker)
|
if (!ids.includes(markerId)) {
|
||||||
if (!ids.includes(markerId)) {
|
if (typeof marker === 'object') markers.push({ ...marker, id: markerId, color: marker.color || defaultColor })
|
||||||
if (typeof marker === 'object') markers.push({ ...marker, id: markerId, color: marker.color || defaultColor })
|
else markers.push({ id: markerId, color: defaultColor, type: marker as MarkerType })
|
||||||
else markers.push({ id: markerId, color: defaultColor, type: marker as MarkerType })
|
ids.push(markerId)
|
||||||
ids.push(markerId)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
;[connectionLineOptions.markerEnd, connectionLineOptions.markerStart].forEach(createMarkers)
|
||||||
|
|
||||||
|
edges.reduce<MarkerProps[]>((markers, edge) => {
|
||||||
|
;[edge.markerStart, edge.markerEnd].forEach(createMarkers)
|
||||||
return markers.sort((a, b) => a.id.localeCompare(b.id))
|
return markers.sort((a, b) => a.id.localeCompare(b.id))
|
||||||
}, [])
|
}, markers)
|
||||||
|
|
||||||
|
return markers
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ const defaultState = (): State => ({
|
|||||||
defaultMarkerColor: '#b1b1b7',
|
defaultMarkerColor: '#b1b1b7',
|
||||||
connectionLineStyle: {},
|
connectionLineStyle: {},
|
||||||
connectionLineType: ConnectionLineType.Bezier,
|
connectionLineType: ConnectionLineType.Bezier,
|
||||||
|
connectionLineOptions: {
|
||||||
|
type: ConnectionLineType.Bezier,
|
||||||
|
style: {},
|
||||||
|
},
|
||||||
connectionNodeId: null,
|
connectionNodeId: null,
|
||||||
connectionHandleId: null,
|
connectionHandleId: null,
|
||||||
connectionHandleType: null,
|
connectionHandleType: null,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import type { CSSProperties } from 'vue'
|
|||||||
import type { Position } from './flow'
|
import type { Position } from './flow'
|
||||||
import type { GraphNode } from './node'
|
import type { GraphNode } from './node'
|
||||||
import type { HandleElement, HandleType } from './handle'
|
import type { HandleElement, HandleType } from './handle'
|
||||||
import type { Edge } from './edge'
|
import type { Edge, EdgeMarkerType } from './edge'
|
||||||
|
|
||||||
/** Connection line types (same as default edge types */
|
/** Connection line types (same as default edge types */
|
||||||
export enum ConnectionLineType {
|
export enum ConnectionLineType {
|
||||||
@@ -12,6 +12,14 @@ export enum ConnectionLineType {
|
|||||||
SmoothStep = 'smoothstep',
|
SmoothStep = 'smoothstep',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ConnectionLineOptions {
|
||||||
|
type?: ConnectionLineType
|
||||||
|
style?: CSSProperties
|
||||||
|
class?: string
|
||||||
|
markerEnd?: EdgeMarkerType
|
||||||
|
markerStart?: EdgeMarkerType
|
||||||
|
}
|
||||||
|
|
||||||
/** Connection params that are passed when onConnect is called */
|
/** Connection params that are passed when onConnect is called */
|
||||||
export interface Connection {
|
export interface Connection {
|
||||||
/** Source node id */
|
/** Source node id */
|
||||||
@@ -67,4 +75,8 @@ export interface ConnectionLineProps {
|
|||||||
sourceNode: GraphNode
|
sourceNode: GraphNode
|
||||||
/** The source handle element of the connection line */
|
/** The source handle element of the connection line */
|
||||||
sourceHandle: HandleElement
|
sourceHandle: HandleElement
|
||||||
|
/** marker url */
|
||||||
|
markerStart: string
|
||||||
|
/** marker url */
|
||||||
|
markerEnd: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { CSSProperties } from 'vue'
|
import type { CSSProperties } from 'vue'
|
||||||
import type { DefaultEdgeOptions, Edge, GraphEdge } from './edge'
|
import type { DefaultEdgeOptions, Edge, GraphEdge } from './edge'
|
||||||
import type { CoordinateExtent, GraphNode, Node } from './node'
|
import type { CoordinateExtent, GraphNode, Node } from './node'
|
||||||
import type { ConnectionLineType, ConnectionMode, Connector } from './connection'
|
import type { ConnectionLineOptions, ConnectionLineType, ConnectionMode, Connector } from './connection'
|
||||||
import type { KeyCode, PanOnScrollMode } from './zoom'
|
import type { KeyCode, PanOnScrollMode } from './zoom'
|
||||||
import type { DefaultEdgeTypes, DefaultNodeTypes, EdgeComponent, NodeComponent } from './components'
|
import type { DefaultEdgeTypes, DefaultNodeTypes, EdgeComponent, NodeComponent } from './components'
|
||||||
|
|
||||||
@@ -85,8 +85,11 @@ export interface FlowProps {
|
|||||||
/** either use the nodeTypes prop to define your node-types or use slots (<template #node-mySpecialType="props">) */
|
/** either use the nodeTypes prop to define your node-types or use slots (<template #node-mySpecialType="props">) */
|
||||||
nodeTypes?: { [key in keyof DefaultNodeTypes]?: NodeComponent } & Record<string, NodeComponent>
|
nodeTypes?: { [key in keyof DefaultNodeTypes]?: NodeComponent } & Record<string, NodeComponent>
|
||||||
connectionMode?: ConnectionMode
|
connectionMode?: ConnectionMode
|
||||||
|
/** @deprecated use {@link ConnectionLineOptions.type} */
|
||||||
connectionLineType?: ConnectionLineType
|
connectionLineType?: ConnectionLineType
|
||||||
|
/** @deprecated use {@link ConnectionLineOptions.style} */
|
||||||
connectionLineStyle?: CSSProperties | null
|
connectionLineStyle?: CSSProperties | null
|
||||||
|
connectionLineOptions?: ConnectionLineOptions
|
||||||
deleteKeyCode?: KeyCode
|
deleteKeyCode?: KeyCode
|
||||||
selectionKeyCode?: KeyCode
|
selectionKeyCode?: KeyCode
|
||||||
multiSelectionKeyCode?: KeyCode
|
multiSelectionKeyCode?: KeyCode
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { CSSProperties, ComputedRef, ToRefs } from 'vue'
|
import type { CSSProperties, ComputedRef, ToRefs } from 'vue'
|
||||||
import type { Dimensions, ElementData, Elements, FlowElements, FlowExportObject, FlowOptions, SnapGrid, XYPosition } from './flow'
|
import type { Dimensions, ElementData, Elements, FlowElements, FlowExportObject, FlowOptions, SnapGrid, XYPosition } from './flow'
|
||||||
import type { DefaultEdgeTypes, DefaultNodeTypes, EdgeComponent, NodeComponent } from './components'
|
import type { DefaultEdgeTypes, DefaultNodeTypes, EdgeComponent, NodeComponent } from './components'
|
||||||
import type { Connection, ConnectionLineType, ConnectionMode, Connector } from './connection'
|
import type { Connection, ConnectionLineOptions, ConnectionLineType, ConnectionMode, Connector } from './connection'
|
||||||
import type { DefaultEdgeOptions, Edge, GraphEdge } from './edge'
|
import type { DefaultEdgeOptions, Edge, GraphEdge } from './edge'
|
||||||
import type { CoordinateExtent, GraphNode, Node } from './node'
|
import type { CoordinateExtent, GraphNode, Node } from './node'
|
||||||
import type { D3Selection, D3Zoom, D3ZoomHandler, KeyCode, PanOnScrollMode, Viewport, ViewportFunctions } from './zoom'
|
import type { D3Selection, D3Zoom, D3ZoomHandler, KeyCode, PanOnScrollMode, Viewport, ViewportFunctions } from './zoom'
|
||||||
@@ -59,7 +59,10 @@ export interface State extends Omit<FlowOptions, 'id' | 'modelValue'> {
|
|||||||
connectionHandleType: HandleType | null
|
connectionHandleType: HandleType | null
|
||||||
connectionPosition: XYPosition
|
connectionPosition: XYPosition
|
||||||
connectionMode: ConnectionMode
|
connectionMode: ConnectionMode
|
||||||
|
connectionLineOptions: ConnectionLineOptions
|
||||||
|
/** @deprecated use {@link ConnectionLineOptions.type} */
|
||||||
connectionLineType: ConnectionLineType
|
connectionLineType: ConnectionLineType
|
||||||
|
/** @deprecated use {@link ConnectionLineOptions.style} */
|
||||||
connectionLineStyle: CSSProperties | null
|
connectionLineStyle: CSSProperties | null
|
||||||
connectionStartHandle: StartHandle | null
|
connectionStartHandle: StartHandle | null
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user