@logicflow/extension 2.2.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/dist/index.css +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/es/NodeResize/node/RectResize.d.ts +0 -6
- package/es/NodeResize/node/RectResize.js +2 -11
- package/es/bpmn-elements-adapter/json2xml.d.ts +2 -1
- package/es/bpmn-elements-adapter/json2xml.js +18 -4
- package/es/bpmn-elements-adapter/xml2json.js +2 -7
- package/es/components/control/index.d.ts +1 -0
- package/es/components/control/index.js +24 -11
- package/es/components/mini-map/index.js +1 -1
- package/es/dynamic-group/model.d.ts +2 -1
- package/es/dynamic-group/model.js +28 -11
- package/es/dynamic-group/node.js +1 -0
- package/es/index.css +1 -1
- package/es/index.d.ts +1 -0
- package/es/index.js +2 -0
- package/es/insert-node-in-polyline/index.js +11 -35
- package/es/materials/curved-edge/index.js +49 -21
- package/es/materials/group/GroupNode.d.ts +0 -6
- package/es/materials/group/GroupNode.js +1 -6
- package/es/pool/LaneModel.d.ts +90 -0
- package/es/pool/LaneModel.js +252 -0
- package/es/pool/LaneView.d.ts +40 -0
- package/es/pool/LaneView.js +202 -0
- package/es/pool/PoolModel.d.ts +120 -0
- package/es/pool/PoolModel.js +586 -0
- package/es/pool/PoolView.d.ts +17 -0
- package/es/pool/PoolView.js +76 -0
- package/es/pool/constant.d.ts +15 -0
- package/es/pool/constant.js +17 -0
- package/es/pool/index.d.ts +89 -0
- package/es/pool/index.js +524 -0
- package/es/pool/utils.d.ts +19 -0
- package/es/pool/utils.js +33 -0
- package/es/style/index.css +1 -1
- package/es/style/raw.d.ts +1 -1
- package/es/style/raw.js +1 -1
- package/es/tools/label/LabelOverlay.js +3 -3
- package/es/tools/label/mediumEditor.d.ts +1 -1
- package/es/tools/label/mediumEditor.js +89 -52
- package/es/tools/snapshot/index.d.ts +7 -3
- package/es/tools/snapshot/index.js +72 -77
- package/lib/NodeResize/node/RectResize.d.ts +0 -6
- package/lib/NodeResize/node/RectResize.js +1 -10
- package/lib/bpmn-elements-adapter/json2xml.d.ts +2 -1
- package/lib/bpmn-elements-adapter/json2xml.js +19 -4
- package/lib/bpmn-elements-adapter/xml2json.js +2 -7
- package/lib/components/control/index.d.ts +1 -0
- package/lib/components/control/index.js +24 -11
- package/lib/components/mini-map/index.js +1 -1
- package/lib/dynamic-group/model.d.ts +2 -1
- package/lib/dynamic-group/model.js +28 -11
- package/lib/dynamic-group/node.js +1 -0
- package/lib/index.css +1 -1
- package/lib/index.d.ts +1 -0
- package/lib/index.js +2 -0
- package/lib/insert-node-in-polyline/index.js +10 -34
- package/lib/materials/curved-edge/index.js +49 -21
- package/lib/materials/group/GroupNode.d.ts +0 -6
- package/lib/materials/group/GroupNode.js +1 -6
- package/lib/pool/LaneModel.d.ts +90 -0
- package/lib/pool/LaneModel.js +255 -0
- package/lib/pool/LaneView.d.ts +40 -0
- package/lib/pool/LaneView.js +205 -0
- package/lib/pool/PoolModel.d.ts +120 -0
- package/lib/pool/PoolModel.js +589 -0
- package/lib/pool/PoolView.d.ts +17 -0
- package/lib/pool/PoolView.js +79 -0
- package/lib/pool/constant.d.ts +15 -0
- package/lib/pool/constant.js +20 -0
- package/lib/pool/index.d.ts +89 -0
- package/lib/pool/index.js +527 -0
- package/lib/pool/utils.d.ts +19 -0
- package/lib/pool/utils.js +38 -0
- package/lib/style/index.css +1 -1
- package/lib/style/raw.d.ts +1 -1
- package/lib/style/raw.js +1 -1
- package/lib/tools/label/LabelOverlay.js +2 -2
- package/lib/tools/label/mediumEditor.d.ts +1 -1
- package/lib/tools/label/mediumEditor.js +91 -53
- package/lib/tools/snapshot/index.d.ts +7 -3
- package/lib/tools/snapshot/index.js +72 -77
- package/package.json +10 -7
- package/.turbo/turbo-build.log +0 -38
- package/CHANGELOG.md +0 -1766
- package/__test__/bpmn-adapter.test.js +0 -227
- package/es/materials/curved-edge/__test__/curved-edge.test.d.ts +0 -1
- package/es/materials/curved-edge/__test__/curved-edge.test.js +0 -18
- package/jest.config.js +0 -198
- package/lib/materials/curved-edge/__test__/curved-edge.test.d.ts +0 -1
- package/lib/materials/curved-edge/__test__/curved-edge.test.js +0 -20
- package/rollup.config.js +0 -52
- package/src/NodeResize/BasicShape/Ellipse.tsx +0 -22
- package/src/NodeResize/BasicShape/Polygon.tsx +0 -24
- package/src/NodeResize/BasicShape/Rect.tsx +0 -44
- package/src/NodeResize/control/Control.tsx +0 -537
- package/src/NodeResize/control/ControlGroup.tsx +0 -76
- package/src/NodeResize/control/Util.ts +0 -206
- package/src/NodeResize/index.ts +0 -26
- package/src/NodeResize/node/DiamondResize.tsx +0 -149
- package/src/NodeResize/node/EllipseResize.tsx +0 -140
- package/src/NodeResize/node/HtmlResize.tsx +0 -125
- package/src/NodeResize/node/RectResize.tsx +0 -146
- package/src/NodeResize/node/index.ts +0 -4
- package/src/bpmn/constant.ts +0 -56
- package/src/bpmn/events/EndEvent.ts +0 -73
- package/src/bpmn/events/StartEvent.ts +0 -52
- package/src/bpmn/events/index.ts +0 -2
- package/src/bpmn/flow/SequenceFlow.ts +0 -25
- package/src/bpmn/flow/index.ts +0 -1
- package/src/bpmn/gateways/ExclusiveGateway.ts +0 -71
- package/src/bpmn/gateways/index.ts +0 -1
- package/src/bpmn/getBpmnId.ts +0 -31
- package/src/bpmn/index.ts +0 -60
- package/src/bpmn/tasks/ServiceTask.ts +0 -63
- package/src/bpmn/tasks/UserTask.ts +0 -64
- package/src/bpmn/tasks/index.ts +0 -2
- package/src/bpmn-adapter/bpmnIds.ts +0 -31
- package/src/bpmn-adapter/index.ts +0 -835
- package/src/bpmn-adapter/json2xml.ts +0 -127
- package/src/bpmn-adapter/xml2json.ts +0 -544
- package/src/bpmn-elements/README.md +0 -223
- package/src/bpmn-elements/__tests__/definition.test.js +0 -72
- package/src/bpmn-elements/index.d.ts +0 -26
- package/src/bpmn-elements/index.ts +0 -107
- package/src/bpmn-elements/presets/Event/EndEventFactory.ts +0 -114
- package/src/bpmn-elements/presets/Event/IntermediateCatchEvent.ts +0 -108
- package/src/bpmn-elements/presets/Event/IntermediateThrowEvent.ts +0 -109
- package/src/bpmn-elements/presets/Event/StartEventFactory.ts +0 -114
- package/src/bpmn-elements/presets/Event/boundaryEventFactory.ts +0 -117
- package/src/bpmn-elements/presets/Event/index.ts +0 -14
- package/src/bpmn-elements/presets/Flow/flow.d.ts +0 -6
- package/src/bpmn-elements/presets/Flow/index.ts +0 -8
- package/src/bpmn-elements/presets/Flow/manhattan.ts +0 -691
- package/src/bpmn-elements/presets/Flow/sequenceFlow.ts +0 -65
- package/src/bpmn-elements/presets/Gateway/gateway.ts +0 -107
- package/src/bpmn-elements/presets/Gateway/index.ts +0 -23
- package/src/bpmn-elements/presets/Pool/Lane.ts +0 -211
- package/src/bpmn-elements/presets/Pool/Pool.ts +0 -284
- package/src/bpmn-elements/presets/Pool/index.ts +0 -89
- package/src/bpmn-elements/presets/Task/index.ts +0 -122
- package/src/bpmn-elements/presets/Task/subProcess.ts +0 -189
- package/src/bpmn-elements/presets/Task/task.ts +0 -193
- package/src/bpmn-elements/presets/icons.ts +0 -155
- package/src/bpmn-elements/utils.ts +0 -52
- package/src/bpmn-elements-adapter/README.md +0 -293
- package/src/bpmn-elements-adapter/__tests__/adapter_in.test.js +0 -528
- package/src/bpmn-elements-adapter/__tests__/adapter_out.test.js +0 -569
- package/src/bpmn-elements-adapter/constant.ts +0 -76
- package/src/bpmn-elements-adapter/index.ts +0 -1134
- package/src/bpmn-elements-adapter/json2xml.ts +0 -91
- package/src/bpmn-elements-adapter/xml2json.ts +0 -548
- package/src/components/context-menu/index.ts +0 -253
- package/src/components/control/index.ts +0 -141
- package/src/components/dnd-panel/index.ts +0 -137
- package/src/components/highlight/index.ts +0 -227
- package/src/components/menu/index.ts +0 -748
- package/src/components/mini-map/index.ts +0 -686
- package/src/components/selection-select/index.ts +0 -387
- package/src/dynamic-group/index.ts +0 -775
- package/src/dynamic-group/model.ts +0 -562
- package/src/dynamic-group/node.ts +0 -288
- package/src/dynamic-group/utils.ts +0 -46
- package/src/index.less +0 -1
- package/src/index.ts +0 -45
- package/src/insert-node-in-polyline/edge.ts +0 -175
- package/src/insert-node-in-polyline/index.ts +0 -187
- package/src/materials/curved-edge/__test__/curved-edge.test.ts +0 -46
- package/src/materials/curved-edge/index.ts +0 -185
- package/src/materials/group/GroupNode.ts +0 -442
- package/src/materials/group/index.ts +0 -542
- package/src/materials/node-selection/index.ts +0 -380
- package/src/mindmap/fakerRoot.ts +0 -19
- package/src/mindmap/index.ts +0 -328
- package/src/mindmap/markContent.ts +0 -81
- package/src/mindmap/markContentOption.ts +0 -81
- package/src/mindmap/markEntity.ts +0 -82
- package/src/mindmap/markRoot.ts +0 -83
- package/src/mindmap/theme.ts +0 -11
- package/src/rect-label-node/RectLabelNodeView.ts +0 -33
- package/src/rect-label-node/index.ts +0 -15
- package/src/style/index.less +0 -342
- package/src/style/raw.ts +0 -295
- package/src/tools/auto-layout/index.ts +0 -282
- package/src/tools/flow-path/index.ts +0 -233
- package/src/tools/label/Label.tsx +0 -357
- package/src/tools/label/LabelModel.ts +0 -83
- package/src/tools/label/LabelOverlay.tsx +0 -158
- package/src/tools/label/algorithm.ts +0 -42
- package/src/tools/label/index.ts +0 -479
- package/src/tools/label/mediumEditor.ts +0 -94
- package/src/tools/label/utils.ts +0 -395
- package/src/tools/proximity-connect/index.ts +0 -435
- package/src/tools/snapshot/README.md +0 -145
- package/src/tools/snapshot/index.ts +0 -718
- package/src/tools/snapshot/utils.ts +0 -163
- package/src/turbo-adapter/index.ts +0 -212
- package/stats.html +0 -4842
- package/tsconfig.json +0 -18
|
@@ -1,435 +0,0 @@
|
|
|
1
|
-
import LogicFlow, {
|
|
2
|
-
Model,
|
|
3
|
-
twoPointDistance,
|
|
4
|
-
BaseNodeModel,
|
|
5
|
-
BaseEdgeModel,
|
|
6
|
-
isInNode,
|
|
7
|
-
} from '@logicflow/core'
|
|
8
|
-
import { assign, isEmpty, isEqual, isNil, isFinite, reduce } from 'lodash-es'
|
|
9
|
-
|
|
10
|
-
import AnchorConfig = Model.AnchorConfig
|
|
11
|
-
import Point = LogicFlow.Point
|
|
12
|
-
|
|
13
|
-
export type ProximityConnectProps = {
|
|
14
|
-
enable: boolean
|
|
15
|
-
distance: number
|
|
16
|
-
reverseDirection: boolean
|
|
17
|
-
virtualEdgeStyle: Record<string, unknown>
|
|
18
|
-
/**
|
|
19
|
-
* proximityConnect 类型:
|
|
20
|
-
* - 'node': 节点-节点连接
|
|
21
|
-
* - 'anchor': 锚点-锚点连接
|
|
22
|
-
* - 'default': 节点-锚点连接
|
|
23
|
-
*/
|
|
24
|
-
type: 'node' | 'anchor' | 'default'
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export class ProximityConnect {
|
|
28
|
-
static pluginName = 'proximityConnect'
|
|
29
|
-
enable: boolean = true
|
|
30
|
-
type: 'node' | 'anchor' | 'default' = 'default'
|
|
31
|
-
lf: LogicFlow // lf实例
|
|
32
|
-
closestNode?: BaseNodeModel // 当前距离最近的节点
|
|
33
|
-
currentDistance: number = Infinity // 当前间距
|
|
34
|
-
thresholdDistance: number = 100 // 节点-节点连接距离阈值
|
|
35
|
-
|
|
36
|
-
currentNode?: BaseNodeModel // 当前操作节点
|
|
37
|
-
reverseDirection: boolean = false // 节点-节点连线方向,默认是拖拽节点连向最近节点
|
|
38
|
-
|
|
39
|
-
currentAnchor?: AnchorConfig // 当前连线锚点
|
|
40
|
-
closestAnchor?: AnchorConfig // 当前距离最近锚点
|
|
41
|
-
virtualEdge?: BaseEdgeModel // 虚拟边
|
|
42
|
-
virtualEdgeStyle: Record<string, unknown> = {
|
|
43
|
-
strokeDasharray: '10,10',
|
|
44
|
-
stroke: '#acacac',
|
|
45
|
-
} // 虚拟边样式
|
|
46
|
-
|
|
47
|
-
constructor({
|
|
48
|
-
lf,
|
|
49
|
-
options,
|
|
50
|
-
}: LogicFlow.IExtensionProps & { options: ProximityConnectProps }) {
|
|
51
|
-
this.lf = lf
|
|
52
|
-
assign(this, options)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
render() {
|
|
56
|
-
this.addEventListeners()
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// 增加节点拖拽和锚点拖拽的事件监听
|
|
60
|
-
addEventListeners() {
|
|
61
|
-
// 节点开始拖拽事件
|
|
62
|
-
this.lf.graphModel.eventCenter.on('node:dragstart', ({ data }) => {
|
|
63
|
-
if (this.type === 'anchor') return
|
|
64
|
-
if (!this.enable) return
|
|
65
|
-
const { graphModel } = this.lf
|
|
66
|
-
const { id } = data
|
|
67
|
-
this.currentNode = graphModel.getNodeModelById(id)
|
|
68
|
-
})
|
|
69
|
-
// 节点拖拽事件
|
|
70
|
-
this.lf.graphModel.eventCenter.on('node:drag', () => {
|
|
71
|
-
if (this.type === 'anchor') return
|
|
72
|
-
this.handleNodeDrag()
|
|
73
|
-
})
|
|
74
|
-
// 锚点开始拖拽事件
|
|
75
|
-
this.lf.graphModel.eventCenter.on(
|
|
76
|
-
'anchor:dragstart',
|
|
77
|
-
({ data, nodeModel }) => {
|
|
78
|
-
if (!this.enable || this.type === 'node') return
|
|
79
|
-
this.currentNode = nodeModel
|
|
80
|
-
this.currentAnchor = data
|
|
81
|
-
},
|
|
82
|
-
)
|
|
83
|
-
// 锚点拖拽事件
|
|
84
|
-
this.lf.graphModel.eventCenter.on(
|
|
85
|
-
'anchor:drag',
|
|
86
|
-
({ e: { clientX, clientY } }) => {
|
|
87
|
-
if (!this.enable || this.type === 'node') return
|
|
88
|
-
this.handleAnchorDrag(clientX, clientY)
|
|
89
|
-
},
|
|
90
|
-
)
|
|
91
|
-
// 节点、锚点拖拽结束事件
|
|
92
|
-
this.lf.graphModel.eventCenter.on('node:drop', () => {
|
|
93
|
-
if (!this.enable || this.type === 'anchor') return
|
|
94
|
-
this.handleDrop()
|
|
95
|
-
})
|
|
96
|
-
// 锚点拖拽需要单独判断一下当前拖拽终点是否在某个锚点上,如果是,就不触发插件的连线,以免出现创建了两条连线的问题,表现见 issue 2140
|
|
97
|
-
this.lf.graphModel.eventCenter.on('anchor:dragend', ({ e, edgeModel }) => {
|
|
98
|
-
if (!this.enable || this.type === 'node') return
|
|
99
|
-
const {
|
|
100
|
-
canvasOverlayPosition: { x: eventX, y: eventY },
|
|
101
|
-
} = this.lf.graphModel.getPointByClient({
|
|
102
|
-
x: e.clientX,
|
|
103
|
-
y: e.clientY,
|
|
104
|
-
})
|
|
105
|
-
if (edgeModel && this.virtualEdge) {
|
|
106
|
-
const { id: virtualEdgeId } = this.virtualEdge as BaseEdgeModel
|
|
107
|
-
const { targetNodeId } = edgeModel as BaseEdgeModel
|
|
108
|
-
const targetNodeModel =
|
|
109
|
-
this.lf.graphModel.getNodeModelById(targetNodeId)
|
|
110
|
-
if (
|
|
111
|
-
targetNodeModel &&
|
|
112
|
-
isInNode({ x: eventX, y: eventY }, targetNodeModel, 10)
|
|
113
|
-
) {
|
|
114
|
-
// 如果当前拖拽点在锚点上,就不触发插件的连线
|
|
115
|
-
this.lf.deleteEdge(virtualEdgeId)
|
|
116
|
-
return
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
this.handleDrop()
|
|
121
|
-
})
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// 节点拖拽动作
|
|
125
|
-
handleNodeDrag() {
|
|
126
|
-
/**
|
|
127
|
-
* 主要做几件事情
|
|
128
|
-
* 判断当前是否有虚拟连线,有的话判断两点距离是否超过阈值,超过的话删除连线
|
|
129
|
-
* 遍历画布上的所有节点,找到距离最近的节点,获取其所有锚点数据
|
|
130
|
-
* 判断每个锚点与当前选中节点的所有锚点之间的距离,找到路路径最短的两个点时,把当前节点、当前锚点当前最短记录记录下来,作为当前最近数据
|
|
131
|
-
* 判断当前最短距离是否小于阈值
|
|
132
|
-
* 如果是 就创建虚拟边
|
|
133
|
-
*/
|
|
134
|
-
const { nodes } = this.lf.graphModel
|
|
135
|
-
|
|
136
|
-
if (!isNil(this.virtualEdge)) {
|
|
137
|
-
const { startPoint, endPoint, id } = this.virtualEdge
|
|
138
|
-
const curDistance = twoPointDistance(startPoint, endPoint)
|
|
139
|
-
if (curDistance > this.thresholdDistance) {
|
|
140
|
-
this.lf.deleteEdge(id)
|
|
141
|
-
this.virtualEdge = undefined
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
if (this.currentNode) {
|
|
145
|
-
this.findClosestAnchorOfNode(this.currentNode, nodes)
|
|
146
|
-
}
|
|
147
|
-
if (this.currentDistance < this.thresholdDistance) {
|
|
148
|
-
this.addVirtualEdge()
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// 节点放下
|
|
153
|
-
handleDrop() {
|
|
154
|
-
this.addActualEdge()
|
|
155
|
-
this.resetData()
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// 锚点拖拽动作
|
|
159
|
-
handleAnchorDrag(clientX: number, clientY: number) {
|
|
160
|
-
// 获取当前点在画布上的位置
|
|
161
|
-
const { graphModel } = this.lf
|
|
162
|
-
const {
|
|
163
|
-
canvasOverlayPosition: { x, y },
|
|
164
|
-
} = graphModel.getPointByClient({
|
|
165
|
-
x: clientX,
|
|
166
|
-
y: clientY,
|
|
167
|
-
})
|
|
168
|
-
if (isNil(x) || isNil(y)) return
|
|
169
|
-
const currentPoint: Point = { x, y }
|
|
170
|
-
const { nodes } = graphModel
|
|
171
|
-
// 判断当前是否有虚拟连线,有的话判断两点距离是否超过阈值,超过的话删除连线
|
|
172
|
-
if (!isNil(this.virtualEdge)) {
|
|
173
|
-
const { endPoint, id } = this.virtualEdge
|
|
174
|
-
const curDistance = twoPointDistance(currentPoint, endPoint)
|
|
175
|
-
if (curDistance > this.thresholdDistance) {
|
|
176
|
-
this.lf.deleteEdge(id)
|
|
177
|
-
this.virtualEdge = undefined
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
// 记录最近点的信息
|
|
181
|
-
this.findClosestAnchorOfAnchor(currentPoint, nodes)
|
|
182
|
-
if (this.currentDistance < this.thresholdDistance) {
|
|
183
|
-
this.addVirtualEdge()
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// 节点→节点 找最近的节点和锚点
|
|
188
|
-
findClosestAnchorOfNode(
|
|
189
|
-
draggingNode: BaseNodeModel,
|
|
190
|
-
allNodes: BaseNodeModel[],
|
|
191
|
-
) {
|
|
192
|
-
if (isNil(draggingNode) || isEmpty(draggingNode)) return
|
|
193
|
-
const { anchors: draggingAnchors = [], id } = draggingNode
|
|
194
|
-
let distance
|
|
195
|
-
let preConnectAnchor
|
|
196
|
-
let closestAnchor
|
|
197
|
-
let closestNode
|
|
198
|
-
allNodes.forEach((node) => {
|
|
199
|
-
if (isEqual(node.id, id)) return
|
|
200
|
-
const { anchors = [] } = node
|
|
201
|
-
// 遍历所有节点,找离当前拖拽节点最近的可连接节点和锚点
|
|
202
|
-
anchors.forEach((anchor) => {
|
|
203
|
-
// 找距离最近的两个锚点
|
|
204
|
-
draggingAnchors.forEach((draggingAnchor) => {
|
|
205
|
-
// 判断拖拽点锚点和当前锚点是否可连线
|
|
206
|
-
const anchorAllowConnect = this.anchorAllowConnect(
|
|
207
|
-
node,
|
|
208
|
-
anchor,
|
|
209
|
-
draggingAnchor,
|
|
210
|
-
)
|
|
211
|
-
if (!anchorAllowConnect) return
|
|
212
|
-
// 获取两个锚点之间的距离
|
|
213
|
-
const curDistance = twoPointDistance(draggingAnchor, anchor)
|
|
214
|
-
if (!distance || curDistance < distance) {
|
|
215
|
-
// 如果是第一条数据,或者当前这对锚点距离更短,就替换数据
|
|
216
|
-
distance = curDistance
|
|
217
|
-
preConnectAnchor = draggingAnchor
|
|
218
|
-
closestAnchor = anchor
|
|
219
|
-
closestNode = node
|
|
220
|
-
}
|
|
221
|
-
})
|
|
222
|
-
})
|
|
223
|
-
})
|
|
224
|
-
this.currentDistance = distance
|
|
225
|
-
this.currentAnchor = preConnectAnchor
|
|
226
|
-
this.closestAnchor = closestAnchor
|
|
227
|
-
this.closestNode = closestNode
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// 锚点→节点 找最近的锚点
|
|
231
|
-
findClosestAnchorOfAnchor(draggingPoint: Point, allNodes: BaseNodeModel[]) {
|
|
232
|
-
if (isNil(draggingPoint)) return
|
|
233
|
-
let distance
|
|
234
|
-
let closestAnchor
|
|
235
|
-
let closestNode
|
|
236
|
-
const { currentNode, currentAnchor } = this
|
|
237
|
-
allNodes.forEach((node) => {
|
|
238
|
-
if (!currentNode) return
|
|
239
|
-
const { anchors = [] } = node
|
|
240
|
-
// 遍历所有节点,找离当前拖拽节点最近的可连接节点和锚点
|
|
241
|
-
anchors.forEach((anchor) => {
|
|
242
|
-
if (isEqual(this.currentAnchor?.id, anchor.id)) return
|
|
243
|
-
// 判断拖拽点锚点和当前锚点是否可连线
|
|
244
|
-
const anchorAllowConnect = this.anchorAllowConnect(
|
|
245
|
-
node,
|
|
246
|
-
anchor,
|
|
247
|
-
currentAnchor,
|
|
248
|
-
)
|
|
249
|
-
if (!anchorAllowConnect) return
|
|
250
|
-
// 获取两个锚点之间的距离
|
|
251
|
-
const curDistance = twoPointDistance(draggingPoint, anchor)
|
|
252
|
-
if (!distance || curDistance < distance) {
|
|
253
|
-
// 如果是第一条数据,或者当前这对锚点距离更短,就替换数据
|
|
254
|
-
distance = curDistance
|
|
255
|
-
closestAnchor = anchor
|
|
256
|
-
closestNode = node
|
|
257
|
-
}
|
|
258
|
-
})
|
|
259
|
-
})
|
|
260
|
-
this.currentDistance = distance
|
|
261
|
-
this.closestAnchor = closestAnchor
|
|
262
|
-
this.closestNode = closestNode
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// 判断锚点是否允许连线
|
|
266
|
-
anchorAllowConnect(
|
|
267
|
-
node: BaseNodeModel,
|
|
268
|
-
anchor: AnchorConfig,
|
|
269
|
-
draggingAnchor: AnchorConfig | undefined,
|
|
270
|
-
) {
|
|
271
|
-
const { currentNode } = this
|
|
272
|
-
if (!currentNode) return
|
|
273
|
-
// 判断起点是否可连接
|
|
274
|
-
const { isAllPass: sourceValidResult } = this.reverseDirection
|
|
275
|
-
? node.isAllowConnectedAsSource(currentNode, anchor, draggingAnchor)
|
|
276
|
-
: currentNode.isAllowConnectedAsSource(node, draggingAnchor, anchor)
|
|
277
|
-
// 判断终点是否可连接
|
|
278
|
-
const { isAllPass: targetValidResult } = this.reverseDirection
|
|
279
|
-
? currentNode.isAllowConnectedAsTarget(node, anchor, draggingAnchor)
|
|
280
|
-
: node.isAllowConnectedAsTarget(currentNode, draggingAnchor, anchor)
|
|
281
|
-
return sourceValidResult && targetValidResult
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// 判断是否应该删除虚拟边
|
|
285
|
-
sameEdgeIsExist(edge: BaseEdgeModel) {
|
|
286
|
-
if (
|
|
287
|
-
isNil(this.closestNode) ||
|
|
288
|
-
isNil(this.currentNode) ||
|
|
289
|
-
isNil(this.closestAnchor) ||
|
|
290
|
-
isNil(this.currentAnchor)
|
|
291
|
-
)
|
|
292
|
-
return false
|
|
293
|
-
if (isNil(edge)) return false
|
|
294
|
-
const {
|
|
295
|
-
closestNode: { id: closestNodeId },
|
|
296
|
-
currentNode: { id: currentNodeId },
|
|
297
|
-
closestAnchor: { id: closestAnchorId },
|
|
298
|
-
currentAnchor: { id: currentAnchorId },
|
|
299
|
-
reverseDirection,
|
|
300
|
-
} = this
|
|
301
|
-
const { sourceNodeId, targetNodeId, sourceAnchorId, targetAnchorId } = edge
|
|
302
|
-
const isExist = reverseDirection
|
|
303
|
-
? isEqual(closestNodeId, sourceNodeId) &&
|
|
304
|
-
isEqual(currentNodeId, targetNodeId) &&
|
|
305
|
-
isEqual(closestAnchorId, sourceAnchorId) &&
|
|
306
|
-
isEqual(currentAnchorId, targetAnchorId)
|
|
307
|
-
: isEqual(currentNodeId, sourceNodeId) &&
|
|
308
|
-
isEqual(closestNodeId, targetNodeId) &&
|
|
309
|
-
isEqual(currentAnchorId, sourceAnchorId) &&
|
|
310
|
-
isEqual(closestAnchorId, targetAnchorId)
|
|
311
|
-
return isExist
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// 增加虚拟边
|
|
315
|
-
addVirtualEdge() {
|
|
316
|
-
const { edges } = this.lf.graphModel
|
|
317
|
-
// 判断当前是否已存在一条同样配置的真实边
|
|
318
|
-
const actualEdgeIsExist = reduce(
|
|
319
|
-
edges,
|
|
320
|
-
(result, edge) => {
|
|
321
|
-
if (edge.virtual) return result
|
|
322
|
-
return result || this.sameEdgeIsExist(edge)
|
|
323
|
-
},
|
|
324
|
-
false,
|
|
325
|
-
)
|
|
326
|
-
// 如果有真实边就不重复创建边了
|
|
327
|
-
if (actualEdgeIsExist) return
|
|
328
|
-
|
|
329
|
-
// 判断当前是否有虚拟边
|
|
330
|
-
// 如果当前已有虚拟边,判断当前的节点和锚点信息与虚拟边的信息是否一致
|
|
331
|
-
if (!isNil(this.virtualEdge)) {
|
|
332
|
-
const {
|
|
333
|
-
virtualEdge: { id: edgeId },
|
|
334
|
-
} = this
|
|
335
|
-
// 信息一致不做处理
|
|
336
|
-
if (this.sameEdgeIsExist(this.virtualEdge)) return
|
|
337
|
-
// 不一致就删除老边
|
|
338
|
-
this.lf.deleteEdge(edgeId)
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// 开始创建虚拟边
|
|
342
|
-
const {
|
|
343
|
-
reverseDirection,
|
|
344
|
-
currentNode,
|
|
345
|
-
closestNode,
|
|
346
|
-
currentAnchor,
|
|
347
|
-
closestAnchor,
|
|
348
|
-
} = this
|
|
349
|
-
if (isEmpty(currentNode) || isEmpty(closestNode)) return
|
|
350
|
-
const properties = {
|
|
351
|
-
style: this.virtualEdgeStyle,
|
|
352
|
-
}
|
|
353
|
-
this.virtualEdge = this.lf.addEdge(
|
|
354
|
-
reverseDirection
|
|
355
|
-
? {
|
|
356
|
-
sourceNodeId: closestNode?.id,
|
|
357
|
-
targetNodeId: currentNode?.id,
|
|
358
|
-
sourceAnchorId: closestAnchor?.id,
|
|
359
|
-
targetAnchorId: currentAnchor?.id,
|
|
360
|
-
properties,
|
|
361
|
-
}
|
|
362
|
-
: {
|
|
363
|
-
sourceNodeId: currentNode?.id,
|
|
364
|
-
targetNodeId: closestNode?.id,
|
|
365
|
-
sourceAnchorId: currentAnchor?.id,
|
|
366
|
-
targetAnchorId: closestAnchor?.id,
|
|
367
|
-
properties,
|
|
368
|
-
},
|
|
369
|
-
)
|
|
370
|
-
this.virtualEdge.virtual = true
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
// 增加实体边
|
|
374
|
-
addActualEdge() {
|
|
375
|
-
if (isNil(this.virtualEdge)) return
|
|
376
|
-
const {
|
|
377
|
-
type,
|
|
378
|
-
sourceNodeId,
|
|
379
|
-
targetNodeId,
|
|
380
|
-
sourceAnchorId,
|
|
381
|
-
targetAnchorId,
|
|
382
|
-
startPoint,
|
|
383
|
-
endPoint,
|
|
384
|
-
pointsList,
|
|
385
|
-
} = this.virtualEdge
|
|
386
|
-
this.lf.deleteEdge(this.virtualEdge.id)
|
|
387
|
-
this.lf.addEdge({
|
|
388
|
-
type,
|
|
389
|
-
sourceNodeId,
|
|
390
|
-
targetNodeId,
|
|
391
|
-
sourceAnchorId,
|
|
392
|
-
targetAnchorId,
|
|
393
|
-
startPoint,
|
|
394
|
-
endPoint,
|
|
395
|
-
pointsList,
|
|
396
|
-
})
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
// 设置虚拟边样式
|
|
400
|
-
public setVirtualEdgeStyle(value: Record<string, unknown>) {
|
|
401
|
-
this.virtualEdgeStyle = {
|
|
402
|
-
...this.virtualEdgeStyle,
|
|
403
|
-
...value,
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// 设置连线阈值
|
|
408
|
-
public setThresholdDistance(distance: number) {
|
|
409
|
-
if (!isFinite(distance)) return
|
|
410
|
-
this.thresholdDistance = distance
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// 设置连线方向
|
|
414
|
-
public setReverseDirection(value: boolean) {
|
|
415
|
-
this.reverseDirection = value
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// 设置插件开关状态
|
|
419
|
-
public setEnable(enable: boolean) {
|
|
420
|
-
this.enable = enable
|
|
421
|
-
if (!enable) {
|
|
422
|
-
this.resetData()
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
// 重置数据
|
|
427
|
-
resetData() {
|
|
428
|
-
this.closestNode = undefined
|
|
429
|
-
this.currentDistance = Infinity
|
|
430
|
-
this.currentNode = undefined
|
|
431
|
-
this.currentAnchor = undefined
|
|
432
|
-
this.closestAnchor = undefined
|
|
433
|
-
this.virtualEdge = undefined
|
|
434
|
-
}
|
|
435
|
-
}
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
# 导出 Snapshot
|
|
2
|
-
|
|
3
|
-
我们经常需要将画布内容通过图片的形式导出来,我们提供了一个独立的插件包 `Snapshot` 来使用这个功能。
|
|
4
|
-
|
|
5
|
-
## 使用
|
|
6
|
-
|
|
7
|
-
### 1. 注册
|
|
8
|
-
|
|
9
|
-
两种注册方式,全局注册和局部注册,区别是全局注册每一个`lf`实例都可以使用。
|
|
10
|
-
|
|
11
|
-
```tsx | pure
|
|
12
|
-
import LogicFlow from "@logicflow/core";
|
|
13
|
-
import { Snapshot } from "@logicflow/extension";
|
|
14
|
-
|
|
15
|
-
// 全局注册
|
|
16
|
-
LogicFlow.use(Snapshot);
|
|
17
|
-
|
|
18
|
-
// 局部注册
|
|
19
|
-
const lf = new LogicFlow({
|
|
20
|
-
...config,
|
|
21
|
-
plugins: [Snapshot]
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
### 2. 使用
|
|
27
|
-
|
|
28
|
-
注册后,`lf`实例身上将被挂载`getSnapshot()`方法,通过`lf.getSnapshot()`方法调用。
|
|
29
|
-
|
|
30
|
-
```tsx | pure
|
|
31
|
-
|
|
32
|
-
// 可以使用任意方式触发,然后将绘制的图形下载到本地磁盘上
|
|
33
|
-
document.getElementById("button").addEventListener("click", () => {
|
|
34
|
-
lf.getSnapshot();
|
|
35
|
-
|
|
36
|
-
// 或者 1.1.13版本
|
|
37
|
-
// lf.extension.snapshot.getSnapshot()
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
值得一提的是:通过此插件截取下载的图片不会因为偏移、缩放受到影响。
|
|
43
|
-
|
|
44
|
-
## 自定义设置 css
|
|
45
|
-
|
|
46
|
-
当自定义元素在导出图片时需要额外添加 css 样式时,可以用如下方式实现:
|
|
47
|
-
|
|
48
|
-
为了保持流程图生成的图片与画布上效果一致,`snapshot`插件默认会将当前页面所有的 `css` 规则都加载到导出图片中,
|
|
49
|
-
但是可能会因为 css 文件跨域引起报错,参考 issue575。可以修改useGlobalRules来禁止加载所有 css
|
|
50
|
-
规则,然后通过`customCssRules`属性来自定义增加css样式。
|
|
51
|
-
|
|
52
|
-
```tsx
|
|
53
|
-
|
|
54
|
-
// 默认开启css样式
|
|
55
|
-
lf.extension.snapshot.useGlobalRules = true
|
|
56
|
-
// 不会覆盖css样式,会叠加,customCssRules优先级高
|
|
57
|
-
lf.extension.snapshot.customCssRules = `
|
|
58
|
-
.uml-wrapper {
|
|
59
|
-
line-height: 1.2;
|
|
60
|
-
text-align: center;
|
|
61
|
-
color: blue;
|
|
62
|
-
}
|
|
63
|
-
`
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
## API
|
|
68
|
-
|
|
69
|
-
### lf.getSnapshot(...)
|
|
70
|
-
|
|
71
|
-
导出图片。
|
|
72
|
-
|
|
73
|
-
```ts
|
|
74
|
-
|
|
75
|
-
const getSnapshot = (fileName?: string, toImageOptions?: ToImageOptions): Promise<void> => {}
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
`fileName` 为文件名称,不填为默认为`logic-flow.当前时间戳`,`ToImageOptions` 描述如下:
|
|
80
|
-
|
|
81
|
-
| 属性名 | 类型 | 默认值 | 必填 | 描述 |
|
|
82
|
-
|-----------------|---------|-----|----|----------------------------------------------------------------------------------------|
|
|
83
|
-
| fileType | string | png | | 图片类型: 默认不填是png 还可以设置有webp、gif、jpeg、svg |
|
|
84
|
-
| width | number | - | | 自定义导出图片的宽度,不设置即可,设置可能会拉伸图形 |
|
|
85
|
-
| height | number | - | | 自定义导出图片的宽度,不设置即可,设置可能会拉伸图形 |
|
|
86
|
-
| backgroundColor | string | - | | 图片背景,不设置背景默认透明 |
|
|
87
|
-
| quality | number | - | | 图片质量,在指定图片格式为 jpeg 或 webp 的情况下,可以从 0 到 1 的区间内选择图片的质量。如果超出取值范围,将会使用默认值 0.92。其他不合法参数会被忽略 |
|
|
88
|
-
| padding | number | 40 | | 图片内边距: 元素内容所在区之外空白空间,不设置默认有40的内边距 |
|
|
89
|
-
| partial | boolean | - | | 导出时是否开启局部渲染,false:将导出画布上所有的元素,true:只导出画面区域内的可见元素,不设置默认为lf实例身上partial值 |
|
|
90
|
-
|
|
91
|
-
注意:
|
|
92
|
-
|
|
93
|
-
- `svg`目前暂不支持`width`,`height`, `backgroundColor`, `padding` 属性。
|
|
94
|
-
- 自定义宽高后,可能会拉伸图形,这时候`padding`也会被拉伸导致不准确。
|
|
95
|
-
|
|
96
|
-
### lf.getSnapshotBlob(...)
|
|
97
|
-
|
|
98
|
-
`snapshot`
|
|
99
|
-
除了支持图片类型导出,还支持下载<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Blob" target="_blank">
|
|
100
|
-
Blob文件对象 </a>
|
|
101
|
-
和 <a href="https://developer.mozilla.org/zh-CN/docs/Glossary/Base64" target="_blank">
|
|
102
|
-
Base64文本编码 </a>
|
|
103
|
-
|
|
104
|
-
获取`Blob`对象。
|
|
105
|
-
|
|
106
|
-
```ts
|
|
107
|
-
|
|
108
|
-
const getSnapshotBlob = async (
|
|
109
|
-
backgroundColor?: string,
|
|
110
|
-
fileType?: string
|
|
111
|
-
): Promise<SnapshotResponse> => {}
|
|
112
|
-
|
|
113
|
-
// example
|
|
114
|
-
const { data: blob } = await lf.getSnapshotBlob()
|
|
115
|
-
console.log(blob)
|
|
116
|
-
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
`backgroundColor`: 背景,不填默认为透明。
|
|
120
|
-
|
|
121
|
-
`fileType`: 文件类型,不填默认为png。
|
|
122
|
-
|
|
123
|
-
`SnapshotResponse`: 返回对象。
|
|
124
|
-
|
|
125
|
-
```tsx | pure
|
|
126
|
-
|
|
127
|
-
export type SnapshotResponse = {
|
|
128
|
-
data: Blob | string // Blob对象 或 Base64文本编码文本
|
|
129
|
-
width: number // 图片宽度
|
|
130
|
-
height: number // 图片高度
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### lf.getSnapshotBase64(...)
|
|
136
|
-
|
|
137
|
-
获取`Base64文本编码`文本。
|
|
138
|
-
|
|
139
|
-
```ts
|
|
140
|
-
|
|
141
|
-
async getSnapshotBase64(backgroundColor?: string, fileType?: string) : Promise<SnapshotResponse>
|
|
142
|
-
|
|
143
|
-
// example
|
|
144
|
-
const { data : base64 } = await lf.getSnapshotBlob()
|
|
145
|
-
console.log(base64)
|