@logicflow/extension 2.2.0-alpha.7 → 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.
Files changed (125) hide show
  1. package/README.md +16 -0
  2. package/package.json +10 -7
  3. package/.turbo/turbo-build.log +0 -38
  4. package/CHANGELOG.md +0 -1829
  5. package/__test__/bpmn-adapter.test.js +0 -227
  6. package/es/materials/curved-edge/__test__/curved-edge.test.d.ts +0 -1
  7. package/es/materials/curved-edge/__test__/curved-edge.test.js +0 -18
  8. package/jest.config.js +0 -198
  9. package/lib/materials/curved-edge/__test__/curved-edge.test.d.ts +0 -1
  10. package/lib/materials/curved-edge/__test__/curved-edge.test.js +0 -20
  11. package/rollup.config.js +0 -52
  12. package/src/NodeResize/BasicShape/Ellipse.tsx +0 -22
  13. package/src/NodeResize/BasicShape/Polygon.tsx +0 -24
  14. package/src/NodeResize/BasicShape/Rect.tsx +0 -44
  15. package/src/NodeResize/control/Control.tsx +0 -537
  16. package/src/NodeResize/control/ControlGroup.tsx +0 -76
  17. package/src/NodeResize/control/Util.ts +0 -206
  18. package/src/NodeResize/index.ts +0 -26
  19. package/src/NodeResize/node/DiamondResize.tsx +0 -149
  20. package/src/NodeResize/node/EllipseResize.tsx +0 -140
  21. package/src/NodeResize/node/HtmlResize.tsx +0 -125
  22. package/src/NodeResize/node/RectResize.tsx +0 -126
  23. package/src/NodeResize/node/index.ts +0 -4
  24. package/src/bpmn/constant.ts +0 -56
  25. package/src/bpmn/events/EndEvent.ts +0 -73
  26. package/src/bpmn/events/StartEvent.ts +0 -52
  27. package/src/bpmn/events/index.ts +0 -2
  28. package/src/bpmn/flow/SequenceFlow.ts +0 -25
  29. package/src/bpmn/flow/index.ts +0 -1
  30. package/src/bpmn/gateways/ExclusiveGateway.ts +0 -71
  31. package/src/bpmn/gateways/index.ts +0 -1
  32. package/src/bpmn/getBpmnId.ts +0 -31
  33. package/src/bpmn/index.ts +0 -60
  34. package/src/bpmn/tasks/ServiceTask.ts +0 -63
  35. package/src/bpmn/tasks/UserTask.ts +0 -64
  36. package/src/bpmn/tasks/index.ts +0 -2
  37. package/src/bpmn-adapter/bpmnIds.ts +0 -31
  38. package/src/bpmn-adapter/index.ts +0 -835
  39. package/src/bpmn-adapter/json2xml.ts +0 -127
  40. package/src/bpmn-adapter/xml2json.ts +0 -544
  41. package/src/bpmn-elements/README.md +0 -223
  42. package/src/bpmn-elements/__tests__/definition.test.js +0 -72
  43. package/src/bpmn-elements/index.d.ts +0 -26
  44. package/src/bpmn-elements/index.ts +0 -107
  45. package/src/bpmn-elements/presets/Event/EndEventFactory.ts +0 -114
  46. package/src/bpmn-elements/presets/Event/IntermediateCatchEvent.ts +0 -108
  47. package/src/bpmn-elements/presets/Event/IntermediateThrowEvent.ts +0 -109
  48. package/src/bpmn-elements/presets/Event/StartEventFactory.ts +0 -114
  49. package/src/bpmn-elements/presets/Event/boundaryEventFactory.ts +0 -117
  50. package/src/bpmn-elements/presets/Event/index.ts +0 -14
  51. package/src/bpmn-elements/presets/Flow/flow.d.ts +0 -6
  52. package/src/bpmn-elements/presets/Flow/index.ts +0 -8
  53. package/src/bpmn-elements/presets/Flow/manhattan.ts +0 -691
  54. package/src/bpmn-elements/presets/Flow/sequenceFlow.ts +0 -65
  55. package/src/bpmn-elements/presets/Gateway/gateway.ts +0 -107
  56. package/src/bpmn-elements/presets/Gateway/index.ts +0 -23
  57. package/src/bpmn-elements/presets/Pool/Lane.ts +0 -211
  58. package/src/bpmn-elements/presets/Pool/Pool.ts +0 -284
  59. package/src/bpmn-elements/presets/Pool/index.ts +0 -89
  60. package/src/bpmn-elements/presets/Task/index.ts +0 -122
  61. package/src/bpmn-elements/presets/Task/subProcess.ts +0 -189
  62. package/src/bpmn-elements/presets/Task/task.ts +0 -193
  63. package/src/bpmn-elements/presets/icons.ts +0 -155
  64. package/src/bpmn-elements/utils.ts +0 -52
  65. package/src/bpmn-elements-adapter/README.md +0 -293
  66. package/src/bpmn-elements-adapter/__tests__/adapter_in.test.js +0 -528
  67. package/src/bpmn-elements-adapter/__tests__/adapter_out.test.js +0 -569
  68. package/src/bpmn-elements-adapter/constant.ts +0 -76
  69. package/src/bpmn-elements-adapter/index.ts +0 -1134
  70. package/src/bpmn-elements-adapter/json2xml.ts +0 -105
  71. package/src/bpmn-elements-adapter/xml2json.ts +0 -542
  72. package/src/components/context-menu/index.ts +0 -253
  73. package/src/components/control/index.ts +0 -155
  74. package/src/components/dnd-panel/index.ts +0 -137
  75. package/src/components/highlight/index.ts +0 -227
  76. package/src/components/menu/index.ts +0 -748
  77. package/src/components/mini-map/index.ts +0 -686
  78. package/src/components/selection-select/index.ts +0 -387
  79. package/src/dynamic-group/index.ts +0 -774
  80. package/src/dynamic-group/model.ts +0 -580
  81. package/src/dynamic-group/node.ts +0 -288
  82. package/src/dynamic-group/utils.ts +0 -46
  83. package/src/index.less +0 -1
  84. package/src/index.ts +0 -47
  85. package/src/insert-node-in-polyline/edge.ts +0 -175
  86. package/src/insert-node-in-polyline/index.ts +0 -193
  87. package/src/materials/curved-edge/__test__/curved-edge.test.ts +0 -46
  88. package/src/materials/curved-edge/index.ts +0 -217
  89. package/src/materials/group/GroupNode.ts +0 -437
  90. package/src/materials/group/index.ts +0 -542
  91. package/src/materials/node-selection/index.ts +0 -380
  92. package/src/mindmap/fakerRoot.ts +0 -19
  93. package/src/mindmap/index.ts +0 -328
  94. package/src/mindmap/markContent.ts +0 -81
  95. package/src/mindmap/markContentOption.ts +0 -81
  96. package/src/mindmap/markEntity.ts +0 -82
  97. package/src/mindmap/markRoot.ts +0 -83
  98. package/src/mindmap/theme.ts +0 -11
  99. package/src/pool/LaneModel.ts +0 -226
  100. package/src/pool/LaneView.ts +0 -220
  101. package/src/pool/PoolModel.ts +0 -631
  102. package/src/pool/PoolView.ts +0 -75
  103. package/src/pool/constant.ts +0 -19
  104. package/src/pool/index.ts +0 -621
  105. package/src/pool/utils.ts +0 -46
  106. package/src/rect-label-node/RectLabelNodeView.ts +0 -33
  107. package/src/rect-label-node/index.ts +0 -15
  108. package/src/style/index.less +0 -381
  109. package/src/style/raw.ts +0 -328
  110. package/src/tools/auto-layout/index.ts +0 -282
  111. package/src/tools/flow-path/index.ts +0 -233
  112. package/src/tools/label/Label.tsx +0 -357
  113. package/src/tools/label/LabelModel.ts +0 -83
  114. package/src/tools/label/LabelOverlay.tsx +0 -162
  115. package/src/tools/label/algorithm.ts +0 -42
  116. package/src/tools/label/index.ts +0 -479
  117. package/src/tools/label/mediumEditor.ts +0 -121
  118. package/src/tools/label/utils.ts +0 -395
  119. package/src/tools/proximity-connect/index.ts +0 -435
  120. package/src/tools/snapshot/README.md +0 -145
  121. package/src/tools/snapshot/index.ts +0 -701
  122. package/src/tools/snapshot/utils.ts +0 -163
  123. package/src/turbo-adapter/index.ts +0 -212
  124. package/stats.html +0 -4842
  125. package/tsconfig.json +0 -18
@@ -1,288 +0,0 @@
1
- import LogicFlow, {
2
- GraphModel,
3
- h,
4
- RectNode,
5
- handleResize,
6
- CallbackArgs,
7
- } from '@logicflow/core'
8
- import { forEach } from 'lodash-es'
9
- import { DynamicGroupNodeModel } from './model'
10
-
11
- import Position = LogicFlow.Position
12
- import { rotatePointAroundCenter } from '../tools/label/utils'
13
-
14
- export interface IDynamicGroupNodeProps {
15
- model: DynamicGroupNodeModel
16
- graphModel: GraphModel
17
- }
18
-
19
- export class DynamicGroupNode<
20
- P extends IDynamicGroupNodeProps = IDynamicGroupNodeProps,
21
- > extends RectNode<P> {
22
- childrenPositionMap: Map<string, Position> = new Map()
23
-
24
- onNodeRotate = ({
25
- model,
26
- }: Omit<CallbackArgs<'node:rotate'>, 'e' | 'position'>) => {
27
- const { model: curGroup, graphModel } = this.props
28
- const { transformWithContainer, isRestrict } = curGroup
29
- const childrenPositionMap = this.childrenPositionMap
30
- if (!transformWithContainer || isRestrict) {
31
- // isRestrict限制模式下,当前model resize时不能小于占地面积
32
- // 由于parent:resize=>child:resize计算复杂,需要根据child:resize的判定结果来递归判断parent能否resize
33
- // 不符合目前 parent:resize成功后emit事件 -> 触发child:resize 的代码交互模式
34
- // 因此isRestrict限制模式下不支持联动(parent:resize=>child:resize)
35
- // 由于transformWidthContainer是控制rotate+resize,为保持transformWidthContainer本来的含义
36
- // parent:resize=>child:resize不支持,那么parent:rotate=>child:rotate也不支持
37
- return
38
- }
39
- // DONE: 目前操作是对分组内节点以节点中心旋转节点本身,而按照正常逻辑,应该是以分组中心,旋转节点(跟 Label 旋转操作逻辑一致)
40
- if (model.id === curGroup.id) {
41
- const center = { x: curGroup.x, y: curGroup.y }
42
- forEach(Array.from(curGroup.children), (childId) => {
43
- const child = graphModel.getNodeModelById(childId)
44
- if (child) {
45
- let point: Position = { x: child.x, y: child.y }
46
- if (childrenPositionMap.has(child.id)) {
47
- point = childrenPositionMap.get(child.id)!
48
- } else {
49
- childrenPositionMap.set(child.id, point)
50
- }
51
-
52
- // 弧度转角度
53
- let theta = model.rotate * (180 / Math.PI)
54
- if (theta < 0) theta += 360
55
- const radian = theta * (Math.PI / 180)
56
-
57
- const newPoint = rotatePointAroundCenter(point, center, radian)
58
-
59
- child.moveTo(newPoint.x, newPoint.y)
60
- child.rotate = model.rotate
61
- console.log('childInfo', child)
62
- }
63
- })
64
- }
65
- }
66
-
67
- onNodeResize = ({
68
- deltaX,
69
- deltaY,
70
- index,
71
- model,
72
- preData,
73
- }: Omit<CallbackArgs<'node:resize'>, 'e' | 'position'>) => {
74
- const { model: curGroup, graphModel } = this.props
75
- const { transformWithContainer, isRestrict } = curGroup
76
- if (!transformWithContainer || isRestrict) {
77
- // isRestrict限制模式下,当前model resize时不能小于占地面积
78
- // 由于parent:resize=>child:resize计算复杂,需要根据child:resize的判定结果来递归判断parent能否resize
79
- // 不符合目前 parent:resize成功后emit事件 -> 触发child:resize 的代码交互模式
80
- // 因此isRestrict限制模式下不支持联动(parent:resize=>child:resize)
81
- return
82
- }
83
- if (model.id === curGroup.id) {
84
- // node:resize是group已经改变width和height后的回调
85
- // 因此这里一定得用preData(没resize改变width之前的值),而不是data/model
86
- const { properties } = preData
87
- const { width: groupWidth, height: groupHeight } = properties || {}
88
- forEach(Array.from(curGroup.children), (childId) => {
89
- const child = graphModel.getNodeModelById(childId)
90
- if (child) {
91
- // 根据比例去控制缩放dx和dy
92
- const childDx = (child.width / groupWidth!) * deltaX
93
- const childDy = (child.height / groupHeight!) * deltaY
94
-
95
- // child.rotate = model.rotate
96
- handleResize({
97
- deltaX: childDx,
98
- deltaY: childDy,
99
- index,
100
- nodeModel: child,
101
- graphModel,
102
- cancelCallback: () => {},
103
- })
104
- }
105
- })
106
- }
107
- }
108
-
109
- onNodeMouseMove = () =>
110
- // {
111
- // deltaX,
112
- // deltaY,
113
- // data,
114
- // }: Omit<CallbackArgs<'node:mousemove'>, 'e' | 'position'>
115
- {
116
- // console.log(data,deltaX,deltaY,'111')
117
- // const { model: curGroup, graphModel } = this.props
118
- // const { transformModel } = graphModel
119
- // const { SCALE_X, SCALE_Y } = transformModel
120
- // if (data.id === curGroup.id) {
121
- // const nodeIds = this.getNodesInGroup(curGroup, graphModel)
122
- // // https://github.com/didi/LogicFlow/issues/1914
123
- // // 当调用lf.fitView()时,会改变整体的SCALE_X和SCALE_Y
124
- // // 由于group的mousemove是在drag.ts的this.onDragging()处理的,在onDragging()里面进行SCALE的处理
125
- // // 而"node:mousemove"emit出来跟onDragging()是同时的,也就是emit出来的数据是没有经过SCALE处理的坐标
126
- // // 因此这里需要增加SCALE的处理
127
- // graphModel.moveNodes(nodeIds, deltaX / SCALE_X, deltaY / SCALE_Y, true)
128
- // }
129
- }
130
-
131
- graphRendered = () => {
132
- const { model } = this.props
133
- // 初始化时,如果 this.isCollapsed 为 true,则主动触发一次折叠操作
134
- if (model.isCollapsed) {
135
- // https://github.com/didi/LogicFlow/issues/1918
136
- // 当lf.render({nodes:[{分组节点}, {普通节点}]})时,由于是顺序遍历
137
- // 会先触发分组Group节点的new Model => toggleCollapse()
138
- // => 此时在graphModel.elementsModelMap找不到它的children,因为还没初始化,因此无法正确折叠子元素
139
- // --------------------
140
- // 当lf.render({nodes:[{普通节点}, {分组节点}]})时,
141
- // 会先触发普通节点的new Model => graphModel.elementsModelMap.set(id, new Model())
142
- // 然后再触发分组Group节点的new Model => toggleCollapse() =>
143
- // 此时在graphModel.elementsModelMap能找到它的children了,因此可以正确折叠子元素
144
- // --------------------
145
- // 因此将整个初始化判断是否【主动触发一次折叠操作】放在"graph:rendered"全部渲染完成后再执行
146
- model.toggleCollapse(true)
147
- }
148
- }
149
-
150
- componentDidMount() {
151
- super.componentDidMount()
152
- const { eventCenter } = this.props.graphModel
153
- // 在 group 旋转时,对组内的所有子节点也进行对应的旋转计算
154
- eventCenter.on('node:rotate', this.onNodeRotate)
155
- // 在 group 缩放时,对组内的所有子节点也进行对应的缩放计算
156
- eventCenter.on('node:resize', this.onNodeResize)
157
- // 在 group 移动时,对组内的所有子节点也进行对应的移动计算
158
- eventCenter.on('node:mousemove', this.onNodeMouseMove)
159
- // 全部渲染完成后,判断是否【主动触发一次折叠操作】
160
- eventCenter.on('graph:rendered', this.graphRendered)
161
- }
162
-
163
- componentWillUnmount() {
164
- super.componentWillUnmount()
165
- const { eventCenter } = this.props.graphModel
166
- eventCenter.off('node:rotate', this.onNodeRotate)
167
- eventCenter.off('node:resize', this.onNodeResize)
168
- eventCenter.off('node:mousemove', this.onNodeMouseMove)
169
- eventCenter.off('graph:rendered', this.graphRendered)
170
- }
171
-
172
- /**
173
- * 获取分组内的节点
174
- * @param groupModel
175
- * @param graphModel
176
- */
177
- getNodesInGroup(
178
- groupModel: DynamicGroupNodeModel,
179
- graphModel: GraphModel,
180
- ): string[] {
181
- let nodeIds: string[] = []
182
- if (groupModel.isGroup) {
183
- forEach(Array.from(groupModel.children), (nodeId: string) => {
184
- nodeIds.push(nodeId)
185
-
186
- const nodeModel = graphModel.getNodeModelById(nodeId)
187
- if (nodeModel?.isGroup) {
188
- nodeIds = nodeIds.concat(
189
- this.getNodesInGroup(
190
- nodeModel as DynamicGroupNodeModel,
191
- graphModel,
192
- ),
193
- )
194
- }
195
- })
196
- }
197
- return nodeIds
198
- }
199
-
200
- getResizeControl(): h.JSX.Element | null {
201
- const { resizable, isCollapsed } = this.props.model
202
- const showResizeControl = resizable && !isCollapsed
203
- return showResizeControl ? super.getResizeControl() : null
204
- }
205
-
206
- getAppendAreaShape(): h.JSX.Element | null {
207
- // DONE: 此区域用于初始化 group container, 即元素拖拽进入感应区域
208
- const { model } = this.props
209
- const { width, height, x, y, radius, groupAddable } = model
210
- if (!groupAddable) return null
211
-
212
- const { strokeWidth = 0 } = model.getNodeStyle()
213
- const style = model.getAddableOutlineStyle()
214
-
215
- const newWidth = width + strokeWidth + 8
216
- const newHeight = height + strokeWidth + 8
217
- return h('rect', {
218
- ...style,
219
- width: newWidth,
220
- height: newHeight,
221
- x: x - newWidth / 2,
222
- y: y - newHeight / 2,
223
- rx: radius,
224
- ry: radius,
225
- })
226
- }
227
-
228
- getCollapseIcon(sx: number, sy: number): string {
229
- return `M ${sx + 3},${sy + 6} ${sx + 11},${sy + 6} M${sx + 7},${sy + 2} ${
230
- sx + 7
231
- },${sy + 10}`
232
- }
233
-
234
- getExpandIcon(sx: number, sy: number): string {
235
- return `M ${sx + 3},${sy + 6} ${sx + 11},${sy + 6} `
236
- }
237
-
238
- // 获取操作图标(收起或展开)
239
- getOperateIcon(): h.JSX.Element | null {
240
- const { model } = this.props
241
- const { x, y, width, height } = model
242
- const sx = x - width / 2 + 10
243
- const sy = y - height / 2 + 10
244
-
245
- if (!model.collapsible) return null
246
- const iconPath = model?.isCollapsed
247
- ? this.getCollapseIcon(sx, sy)
248
- : this.getExpandIcon(sx, sy)
249
-
250
- const operateIcon = h('path', {
251
- fill: 'none',
252
- stroke: '#818281',
253
- strokeWidth: 2,
254
- 'pointer-events': 'none',
255
- d: iconPath,
256
- })
257
-
258
- return h('g', {}, [
259
- h('rect', {
260
- height: 12,
261
- width: 14,
262
- rx: 2,
263
- ry: 2,
264
- strokeWidth: 1,
265
- fill: '#f4f5f6',
266
- stroke: '#cecece',
267
- cursor: 'pointer',
268
- x: sx,
269
- y: sy,
270
- onClick: () => {
271
- // DONE: 抛出折叠或展开事件 -> 在 toggleCollapse 方法中抛出
272
- model.toggleCollapse(!model.isCollapsed)
273
- },
274
- }),
275
- operateIcon,
276
- ])
277
- }
278
-
279
- getShape(): h.JSX.Element | null {
280
- return h('g', {}, [
281
- this.getAppendAreaShape(),
282
- super.getShape(),
283
- this.getOperateIcon(),
284
- ])
285
- }
286
- }
287
-
288
- export default DynamicGroupNode
@@ -1,46 +0,0 @@
1
- import { BaseNodeModel, Model } from '@logicflow/core'
2
- import BoxBoundsPoint = Model.BoxBoundsPoint
3
-
4
- /**
5
- *
6
- * @param bounds
7
- * @param group
8
- */
9
- export function isBoundsInGroup(bounds: BoxBoundsPoint, group: BaseNodeModel) {
10
- const { minX, minY, maxX, maxY } = bounds
11
- const { x, y, width, height } = group
12
- return (
13
- minX >= x - width / 2 &&
14
- maxX <= x + width / 2 &&
15
- minY >= y - height / 2 &&
16
- maxY <= y + height / 2
17
- )
18
- }
19
-
20
- /**
21
- * 判断 bounds 是否可以移动到下一个范围
22
- * @param groupBounds
23
- * @param node
24
- * @param deltaX
25
- * @param deltaY
26
- */
27
- export function isAllowMoveTo(
28
- groupBounds: BoxBoundsPoint,
29
- node: BaseNodeModel,
30
- deltaX: number,
31
- deltaY: number,
32
- ) {
33
- const { minX, minY, maxX, maxY } = groupBounds
34
- const { x, y, width, height } = node
35
-
36
- // DONE: 计算节点坐标 (x, y) 可移动的范围,并判断 x + deltaX, y + deltaY 是否在范围内
37
- const allowMoveMinX = minX + width / 2
38
- const allowMoveMinY = minY + height / 2
39
- const allowMoveMaxX = maxX - width / 2
40
- const allowMoveMaxY = maxY - height / 2
41
-
42
- return {
43
- x: x + deltaX >= allowMoveMinX && x + deltaX <= allowMoveMaxX,
44
- y: y + deltaY >= allowMoveMinY && y + deltaY <= allowMoveMaxY,
45
- }
46
- }
package/src/index.less DELETED
@@ -1 +0,0 @@
1
- @import url('./style/index.less');
package/src/index.ts DELETED
@@ -1,47 +0,0 @@
1
- // BPMN 相关
2
- export * from './bpmn'
3
- export * from './bpmn-adapter'
4
- export * from './bpmn-elements'
5
- export * from './bpmn-elements-adapter'
6
- export * from './bpmn-adapter/xml2json'
7
- export * from './bpmn-adapter/json2xml'
8
-
9
- // Adapter
10
- export * from './turbo-adapter'
11
-
12
- // 泳道相关
13
- export * from './pool'
14
- // 新版 Group
15
- export * from './dynamic-group'
16
- // 折线上动态插入节点
17
- export * from './insert-node-in-polyline'
18
-
19
- // Tools -> 流程图辅助工具
20
- export * from './tools/label'
21
- export * from './tools/snapshot'
22
- export * from './tools/flow-path'
23
- export * from './tools/auto-layout'
24
- export * from './tools/proximity-connect'
25
-
26
- // Component -> 流程图中交互组件
27
- export * from './components/control'
28
- export * from './components/menu'
29
- export * from './components/context-menu'
30
- export * from './components/dnd-panel'
31
- export * from './components/mini-map'
32
- export * from './components/selection-select'
33
- export * from './components/highlight'
34
-
35
- // materials -> 拓展物料
36
- export * from './materials/curved-edge'
37
- export * from './materials/node-selection'
38
-
39
- /**
40
- * @deprecated
41
- * 2.0 版本废弃该插件
42
- */
43
- export * from './NodeResize'
44
- export * from './materials/group'
45
-
46
- // 迷之插件
47
- export * from './rect-label-node'
@@ -1,175 +0,0 @@
1
- import LogicFlow, { PolylineEdgeModel, BaseNodeModel } from '@logicflow/core'
2
-
3
- import Point = LogicFlow.Point
4
-
5
- // 这个里面的函数有些在core中已经存在,为了解耦关系,没有引用
6
-
7
- enum SegmentDirection {
8
- HORIZONTAL = 'horizontal',
9
- VERTICAL = 'vertical',
10
- }
11
-
12
- /**
13
- * 判断一个点是否在线段中
14
- * @param point 判断的点
15
- * @param start 线段的起点
16
- * @param end 线段的终点
17
- * @param deviation 误差范围
18
- * @returns boolean
19
- */
20
- export const isInSegment = (point, start, end, deviation = 0) => {
21
- const distance = distToSegment(point, start, end)
22
- return distance <= deviation
23
- }
24
-
25
- function sqr(x) {
26
- return x * x
27
- }
28
-
29
- function dist2(v, w) {
30
- return sqr(v.x - w.x) + sqr(v.y - w.y)
31
- }
32
-
33
- export const distToSegmentSquared = (p, v, w) => {
34
- const l2 = dist2(v, w)
35
- if (l2 === 0) return dist2(p, v)
36
- let t = ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / l2
37
- t = Math.max(0, Math.min(1, t))
38
- return dist2(p, {
39
- x: v.x + t * (w.x - v.x),
40
- y: v.y + t * (w.y - v.y),
41
- })
42
- }
43
-
44
- export const distToSegment = (point: Point, start: Point, end: Point) =>
45
- Math.sqrt(distToSegmentSquared(point, start, end))
46
-
47
- /* 获取节点bbox */
48
- const getNodeBBox = (node: BaseNodeModel) => {
49
- const { x, y, width, height } = node
50
- const bBox = {
51
- minX: x - width / 2,
52
- minY: y - height / 2,
53
- maxX: x + width / 2,
54
- maxY: y + height / 2,
55
- x,
56
- y,
57
- width,
58
- height,
59
- centerX: x,
60
- centerY: y,
61
- }
62
- return bBox
63
- }
64
-
65
- /* 判断线段的方向 */
66
- const segmentDirection = (start: Point, end: Point) => {
67
- let direction
68
- if (start.x === end.x) {
69
- direction = SegmentDirection.VERTICAL
70
- } else if (start.y === end.y) {
71
- direction = SegmentDirection.HORIZONTAL
72
- }
73
- return direction
74
- }
75
-
76
- // 节点是够在线段内,求出节点与线段的交点
77
- export const crossPointInSegment = (
78
- node: BaseNodeModel,
79
- start: Point,
80
- end: Point,
81
- ) => {
82
- const bBox = getNodeBBox(node)
83
- const direction = segmentDirection(start, end)
84
- const maxX = Math.max(start.x, end.x)
85
- const minX = Math.min(start.x, end.x)
86
- const maxY = Math.max(start.y, end.y)
87
- const minY = Math.min(start.y, end.y)
88
- const { x, y, width, height } = node
89
- if (direction === SegmentDirection.HORIZONTAL) {
90
- // 同一水平线
91
- if (maxX >= bBox.maxX && minX <= bBox.minX) {
92
- return {
93
- startCrossPoint: {
94
- x: start.x > end.x ? x + width / 2 : x - width / 2,
95
- y: start.y,
96
- },
97
- endCrossPoint: {
98
- x: start.x > end.x ? x - width / 2 : x + width / 2,
99
- y: start.y,
100
- },
101
- }
102
- }
103
- } else if (direction === SegmentDirection.VERTICAL) {
104
- // 同一垂直线
105
- if (maxY >= bBox.maxY && minY <= bBox.minY) {
106
- return {
107
- startCrossPoint: {
108
- x: start.x,
109
- y: start.y > end.y ? y + height / 2 : y - height / 2,
110
- },
111
- endCrossPoint: {
112
- x: start.x,
113
- y: start.y > end.y ? y - height / 2 : y + height / 2,
114
- },
115
- }
116
- }
117
- }
118
- }
119
-
120
- interface SegmentCross {
121
- crossIndex: number
122
- crossPoints: {
123
- startCrossPoint: Point
124
- endCrossPoint: Point
125
- }
126
- }
127
-
128
- // 节点是否在线段内
129
- // eslint-disable-next-line max-len
130
- export const isNodeInSegment = (
131
- node: BaseNodeModel,
132
- polyline: PolylineEdgeModel,
133
- deviation = 0,
134
- ): SegmentCross => {
135
- const { x, y } = node
136
- const { pointsList } = polyline
137
- for (let i = 0; i < pointsList.length - 1; i++) {
138
- if (
139
- isInSegment(
140
- {
141
- x,
142
- y,
143
- },
144
- pointsList[i],
145
- pointsList[i + 1],
146
- deviation,
147
- )
148
- ) {
149
- const bBoxCross = crossPointInSegment(
150
- node,
151
- pointsList[i],
152
- pointsList[i + 1],
153
- )
154
- if (bBoxCross) {
155
- return {
156
- crossIndex: i + 1,
157
- crossPoints: bBoxCross,
158
- }
159
- }
160
- }
161
- }
162
- return {
163
- crossIndex: -1,
164
- crossPoints: {
165
- startCrossPoint: {
166
- x: 0,
167
- y: 0,
168
- },
169
- endCrossPoint: {
170
- x: 0,
171
- y: 0,
172
- },
173
- },
174
- }
175
- }