Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 37 additions & 10 deletions examples/feature-examples/src/pages/extensions/highlight/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Card, Divider, Tag } from 'antd'
import { Card, Divider, Radio, Tag } from 'antd'
import LogicFlow from '@logicflow/core'
import { useEffect, useRef } from 'react'
import { useEffect, useRef, useState } from 'react'
import { Highlight } from '@logicflow/extension'

import './index.less'
Expand All @@ -20,25 +20,41 @@ const config: Partial<LogicFlow.Options> = {
},
plugins: [Highlight],
snapline: true, // 是否开启辅助对齐线
pluginsOptions: {
highlight: {
mode: 'neighbour',
},
},
}

export default function HighLightExtension() {
const containerRef = useRef<HTMLDivElement | null>(null)
const [highlightMode, setHighlightMode] = useState('path')
const lfRef = useRef<LogicFlow | null>(null)

useEffect(() => {
const lf: LogicFlow = new LogicFlow({
container: containerRef.current!,
...config,
pluginsOptions: {
highlight: {
mode: highlightMode,
},
},
})
lfRef.current = lf
lfRef.current.render(data)
lfRef.current.translateCenter()
lfRef.current.on('highlight:single', ({ model }) => {
console.log('highlight:single', model)
})
lfRef.current.on('highlight:neighbours', ({ data, relateElements }) => {
console.log('highlight:neighbours', data, relateElements)
})
lfRef.current.on('highlight:path', ({ data, relateElements }) => {
console.log('highlight:path', data, relateElements)
})

lf.render(data)
lf.translateCenter()
}, [])
useEffect(() => {
;(lfRef.current?.extension.highlight as Highlight)?.setMode(
highlightMode as any,
)
}, [highlightMode])
return (
<Card title="LogicFlow Extension - Highlight" id="card">
<p>
Expand All @@ -50,6 +66,17 @@ export default function HighLightExtension() {
</p>
<p>节点:高亮这个节点前后相关的所有边和节点</p>
<p>边:高亮这个边指向的节点前后相关的所有边和节点</p>
<Radio.Group
value={highlightMode}
onChange={(e) => {
setHighlightMode(e.target.value)
}}
style={{ marginBottom: 16 }}
>
<Radio.Button value="path">全路径高亮</Radio.Button>
<Radio.Button value="single">单元素高亮</Radio.Button>
<Radio.Button value="neighbour">相邻元素高亮</Radio.Button>
</Radio.Group>
<Divider />
<div ref={containerRef} id="graph"></div>
</Card>
Expand Down
37 changes: 32 additions & 5 deletions packages/extension/src/components/highlight/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import LogicFlow, { BaseNodeModel } from '@logicflow/core'
import { concat } from 'lodash-es'
import LogicFlow, { BaseEdgeModel, BaseNodeModel } from '@logicflow/core'
import { uniqBy, concat } from 'lodash-es'

// 后续并入FlowPath
const getPath = (id: string, lf: LogicFlow) => {
Expand Down Expand Up @@ -99,7 +99,8 @@ export class Highlight {
this.enable = enable
}

setMode(mode: IMode) {
public setMode(mode: IMode) {
console.log('setMode', mode)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

干掉它

this.mode = mode
}

Expand All @@ -119,11 +120,14 @@ export class Highlight {
model.sourceNode.updateStyles(this.tempStyles[model.sourceNode.id])
model.targetNode.updateStyles(this.tempStyles[model.targetNode.id])
}
this.lf.emit('highlight:single', {
data: model,
})
}

private highlightNeighbours(id: string) {
const model = this.lf.getModelById(id)

let relateElements: (BaseNodeModel | BaseEdgeModel)[] = []
if (model?.BaseType === 'node') {
// 高亮节点
model.updateStyles(this.tempStyles[id])
Expand All @@ -135,23 +139,46 @@ export class Highlight {
concat(incomingEdges, outgoingEdges).forEach((edge) => {
edge.updateStyles(this.tempStyles[edge.id])
})
relateElements = uniqBy(
concat(
relateElements,
incomingNodes,
outgoingNodes,
incomingEdges,
outgoingEdges,
),
'id',
)
} else if (model?.BaseType === 'edge') {
// 高亮边及对应的节点
model.updateStyles(this.tempStyles[id])
model.sourceNode.updateStyles(this.tempStyles[model.sourceNode.id])
model.targetNode.updateStyles(this.tempStyles[model.targetNode.id])
relateElements = [model.sourceNode, model.targetNode]
}
this.lf.emit('highlight:neighbours', {
data: model,
relateElements,
})
}

private highlightPath(id: string) {
const path = getPath(id, this.lf)
const relateElements: any[] = []
path.forEach((_id) => {
const elementModel = this.lf.getModelById(_id)
// 高亮路径上所有的边和节点
this.lf.getModelById(_id)?.updateStyles(this.tempStyles[_id])
elementModel?.updateStyles(this.tempStyles[_id])
relateElements.push(elementModel)
})
this.lf.emit('highlight:path', {
data: this.lf.getModelById(id),
relateElements,
})
}

highlight(id: string, mode: IMode = this.mode) {
console.log('highlight', id, mode)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another one

if (!this.enable) return
if (Object.keys(this.tempStyles).length) {
this.restoreHighlight()
Expand Down
32 changes: 30 additions & 2 deletions packages/extension/src/tools/proximity-connect/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,37 @@ export class ProximityConnect {
},
)
// 节点、锚点拖拽结束事件
this.lf.graphModel.eventCenter.on('node:drop,anchor:dragend', () => {
this.lf.graphModel.eventCenter.on('node:drop', () => {
if (!this.enable) return
this.handleDrop()
})
// 锚点拖拽需要单独判断一下当前拖拽终点是否在某个锚点上,如果是,就不触发插件的连线,以免出现创建了两条连线的问题,表现见 issue 2140
this.lf.graphModel.eventCenter.on('anchor:dragend', ({ e, edgeModel }) => {
if (!this.enable) return
const {
canvasOverlayPosition: { x: eventX, y: eventY },
} = this.lf.graphModel.getPointByClient({
x: e.clientX,
y: e.clientY,
})

if (edgeModel && this.virtualEdge) {
const { id: virtualEdgeId } = this.virtualEdge as BaseEdgeModel
const { targetNodeId } = edgeModel as BaseEdgeModel
const targetNodeModel =
this.lf.graphModel.getNodeModelById(targetNodeId)
const dropPointIsAnchor = targetNodeModel?.anchors.some((anchor) => {
const { x, y } = anchor
return Math.abs(eventX - x) <= 10 && Math.abs(eventY - y) <= 10
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

确认下如果锚点大小调整了,会不会 dropPointIsAnchor 判断与实际不符

现在是判断 Math.abs(evtX - x) <= 10,相当于默认锚点大小为 10

})
if (dropPointIsAnchor) {
this.lf.deleteEdge(virtualEdgeId)
return
}
}

this.handleDrop()
})
}

// 节点拖拽动作
Expand Down Expand Up @@ -335,6 +362,7 @@ export class ProximityConnect {

// 增加实体边
addActualEdge() {
console.log('addActualEdge')
if (isNil(this.virtualEdge)) return
const {
type,
Expand All @@ -346,6 +374,7 @@ export class ProximityConnect {
endPoint,
pointsList,
} = this.virtualEdge
this.lf.deleteEdge(this.virtualEdge.id)
this.lf.addEdge({
type,
sourceNodeId,
Expand All @@ -356,7 +385,6 @@ export class ProximityConnect {
endPoint,
pointsList,
})
this.lf.deleteEdge(this.virtualEdge.id)
}

// 设置虚拟边样式
Expand Down
Loading