@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,193 +0,0 @@
1
- import LogicFlow, {
2
- BaseNodeModel,
3
- PolylineEdgeModel,
4
- EventType,
5
- formatAnchorConnectValidateData,
6
- getClosestAnchor,
7
- } from '@logicflow/core'
8
- import { cloneDeep } from 'lodash-es'
9
- import { isNodeInSegment } from './edge'
10
-
11
- import NodeData = LogicFlow.NodeData
12
-
13
- export class InsertNodeInPolyline {
14
- static pluginName = 'insertNodeInPolyline'
15
- _lf: LogicFlow
16
- dndAdd: boolean // dnd 添加节点到折线上的开关
17
- dropAdd: boolean // 移动节点到折线上的开关
18
- deviation: number // 节点中心距离直接距离小于该值时,认为节点在折线上
19
- constructor({ lf }) {
20
- this._lf = lf
21
- // fix https://github.com/didi/LogicFlow/issues/754
22
- this.deviation = 20
23
- this.dndAdd = true
24
- this.dropAdd = true
25
- this.eventHandler()
26
- }
27
-
28
- eventHandler() {
29
- // 监听事件
30
- if (this.dndAdd) {
31
- this._lf.on('node:dnd-add', ({ data }: { data: NodeData }) => {
32
- this.insetNode(data)
33
- })
34
- }
35
- if (this.dropAdd) {
36
- this._lf.on('node:drop', ({ data }: { data: NodeData }) => {
37
- const { edges } = this._lf.graphModel
38
- const { id } = data
39
- // 只有游离节点才能插入到连线上
40
- let pureNode = true
41
- for (let i = 0; i < edges.length; i++) {
42
- if (edges[i].sourceNodeId === id || edges[i].targetNodeId === id) {
43
- pureNode = false
44
- break
45
- }
46
- }
47
- if (pureNode) {
48
- this.insetNode(data)
49
- }
50
- })
51
- }
52
- }
53
-
54
- /**
55
- * 插入节点前校验规则
56
- * @param sourceNodeId
57
- * @param targetNodeId
58
- * @param sourceAnchorId
59
- * @param targetAnchorId
60
- * @param nodeData
61
- */
62
- // fix: https://github.com/didi/LogicFlow/issues/1078
63
- checkRuleBeforeInsetNode(
64
- sourceNodeId: string,
65
- targetNodeId: string,
66
- sourceAnchorId: string,
67
- targetAnchorId: string,
68
- nodeData: NodeData,
69
- ) {
70
- const sourceNodeModel = this._lf.getNodeModelById(sourceNodeId)!
71
- const targetNodeModel = this._lf.getNodeModelById(targetNodeId)!
72
-
73
- const sourceAnchorInfo = sourceNodeModel.getAnchorInfo(sourceAnchorId)!
74
- const targetAnchorInfo = targetNodeModel.getAnchorInfo(targetAnchorId)!
75
-
76
- // TODO: nodeData 与 isAllowConnectedAsSource 方法需要的类型 BaseNodeModel 不一致,少了 target 属性等,需要验证是否可用。
77
- const sourceRuleResultData = sourceNodeModel.isAllowConnectedAsSource(
78
- nodeData as BaseNodeModel,
79
- sourceAnchorInfo,
80
- targetAnchorInfo,
81
- )
82
- const targetRuleResultData = targetNodeModel.isAllowConnectedAsTarget(
83
- nodeData as BaseNodeModel,
84
- sourceAnchorInfo,
85
- targetAnchorInfo,
86
- )
87
-
88
- const { isAllPass: isSourcePass, msg: sourceMsg } =
89
- formatAnchorConnectValidateData(sourceRuleResultData)
90
- const { isAllPass: isTargetPass, msg: targetMsg } =
91
- formatAnchorConnectValidateData(targetRuleResultData)
92
-
93
- return {
94
- isPass: isSourcePass && isTargetPass,
95
- sourceMsg,
96
- targetMsg,
97
- }
98
- }
99
-
100
- insetNode(nodeData: NodeData): void {
101
- const { edges } = this._lf.graphModel
102
- const nodeModel = this._lf.getNodeModelById(nodeData.id)
103
-
104
- // fix: https://github.com/didi/LogicFlow/issues/1077
105
- // 参照https://github.com/didi/LogicFlow/issues/454=>当getDefaultAnchor(){return []}表示:不显示锚点,也不允许其他节点连接到此节点
106
- // 当getDefaultAnchor=[],直接阻止下面进行edges的截断插入node相关逻辑
107
- const anchorArray = nodeModel?.getDefaultAnchor()
108
- const isNotAllowConnect = !anchorArray || anchorArray.length === 0
109
- if (isNotAllowConnect) {
110
- this._lf.graphModel.eventCenter.emit(EventType.CONNECTION_NOT_ALLOWED, {
111
- data: nodeData,
112
- msg: '自定义类型节点不显示锚点,也不允许其他节点连接到此节点',
113
- })
114
- return
115
- }
116
-
117
- if (!nodeModel) return
118
- for (let i = 0; i < edges.length; i++) {
119
- const { crossIndex, crossPoints } = isNodeInSegment(
120
- nodeModel,
121
- edges[i] as PolylineEdgeModel,
122
- this.deviation,
123
- )
124
- if (crossIndex >= 0) {
125
- const {
126
- sourceNodeId,
127
- targetNodeId,
128
- id,
129
- type,
130
- pointsList,
131
- sourceAnchorId,
132
- targetAnchorId,
133
- } = edges[i]
134
- // fix https://github.com/didi/LogicFlow/issues/996
135
- const startPoint = cloneDeep(pointsList[0])
136
- this._lf.deleteEdge(id)
137
- const checkResult = this.checkRuleBeforeInsetNode(
138
- sourceNodeId,
139
- targetNodeId,
140
- sourceAnchorId!,
141
- targetAnchorId!,
142
- nodeData,
143
- )
144
- // 基于插入节点的进入交点计算出最近的“进入锚点”,用于重连原边的前半段
145
- const entryAnchorInfo = getClosestAnchor(
146
- crossPoints.startCrossPoint,
147
- nodeModel,
148
- )
149
- const entryAnchor = entryAnchorInfo.anchor
150
- // 构造第一条边:原 source → 插入节点(终点为进入锚点)
151
- this._lf.addEdge({
152
- type,
153
- sourceNodeId,
154
- targetNodeId: nodeData.id,
155
- startPoint,
156
- endPoint: entryAnchor,
157
- })
158
- // 基于插入节点的离开交点计算出最近的“离开锚点”,用于重连原边的后半段
159
- const exitAnchorInfo = getClosestAnchor(
160
- crossPoints.endCrossPoint,
161
- nodeModel,
162
- )
163
- const exitAnchor = exitAnchorInfo.anchor
164
- // 构造第二条边:插入节点 → 原 target(起点为离开锚点)
165
- this._lf.addEdge({
166
- type,
167
- sourceNodeId: nodeData.id,
168
- targetNodeId,
169
- startPoint: cloneDeep(exitAnchor),
170
- endPoint: cloneDeep(pointsList[pointsList.length - 1]),
171
- })
172
- if (!checkResult.isPass) {
173
- this._lf.graphModel.eventCenter.emit(
174
- EventType.CONNECTION_NOT_ALLOWED,
175
- {
176
- data: nodeData,
177
- msg: checkResult.targetMsg || checkResult.sourceMsg,
178
- },
179
- )
180
- // FIXME:在关闭了历史记录的情况下,撤销操作会不生效。
181
- setTimeout(() => {
182
- this._lf.undo()
183
- }, 200)
184
- break
185
- } else {
186
- break
187
- }
188
- }
189
- }
190
- }
191
- }
192
-
193
- export default InsertNodeInPolyline
@@ -1,46 +0,0 @@
1
- import { getCurvedEdgePath } from '../index'
2
-
3
- describe('test curved edge ', () => {
4
- test('path calculation', () => {
5
- const radius = 5
6
-
7
- const points1 = '460,150 670,150'
8
- const path1 = 'M460 150 L 670 150'
9
- expect(
10
- getCurvedEdgePath(
11
- points1.split(' ').map((p) => p.split(',').map((a) => +a)),
12
- radius,
13
- ),
14
- ).toBe(path1)
15
-
16
- const points2 = '510,250 540,250 540,175 490,175 490,100 520,100'
17
- const path2 =
18
- 'M510 250L 510 250L 535 250 Q 540 250 540 245L 540 245L 540 180 Q 540 175 535 175L 535 175L 495 175 Q 490 175 490 170L 490 170L 490 105 Q 490 100 495 100L 520 100'
19
- expect(
20
- getCurvedEdgePath(
21
- points2.split(' ').map((p) => p.split(',').map((a) => +a)),
22
- radius,
23
- ),
24
- ).toBe(path2)
25
-
26
- const points3 = '690,120 720,120 720,50 560,50 560,260 690,260'
27
- const path3 =
28
- 'M690 120L 690 120L 715 120 Q 720 120 720 115L 720 115L 720 55 Q 720 50 715 50L 715 50L 565 50 Q 560 50 560 55L 560 55L 560 255 Q 560 260 565 260L 690 260'
29
- expect(
30
- getCurvedEdgePath(
31
- points3.split(' ').map((p) => p.split(',').map((a) => +a)),
32
- radius,
33
- ),
34
- ).toBe(path3)
35
-
36
- const point4 = '690,180 690,210 660,210 660,190 630,190 630,220'
37
- const path4 =
38
- 'M690 180L 690 180L 690 205 Q 690 210 685 210L 685 210L 665 210 Q 660 210 660 205L 660 205L 660 195 Q 660 190 655 190L 655 190L 635 190 Q 630 190 630 195L 630 220'
39
- expect(
40
- getCurvedEdgePath(
41
- point4.split(' ').map((p) => p.split(',').map((a) => +a)),
42
- radius,
43
- ),
44
- ).toBe(path4)
45
- })
46
- })
@@ -1,217 +0,0 @@
1
- import { PolylineEdge, PolylineEdgeModel, h, LogicFlow } from '@logicflow/core'
2
- import PointTuple = LogicFlow.PointTuple
3
-
4
- // 方向类型:t=上(top), b=下(bottom), l=左(left), r=右(right),'' 表示未确定
5
- type DirectionType = 't' | 'b' | 'l' | 'r' | ''
6
- // 圆弧所在象限:tl=左上,tr=右上,bl=左下,br=右下,'-' 表示不需要圆弧
7
- type ArcQuadrantType = 'tl' | 'tr' | 'bl' | 'br' | '-'
8
-
9
- // 方向组合到圆弧象限的映射。
10
- // key 由进入方向(dir1)和离开方向(dir2)拼接,例如 'tr' 表示从上(t)到右(r)的拐角。
11
- // 通过该映射确定在拐点处应该绘制的圆弧象限,用于计算中间控制点。
12
- const directionMap: {
13
- [key: string]: ArcQuadrantType
14
- } = {
15
- tr: 'tl',
16
- lb: 'tl',
17
- tl: 'tr',
18
- rb: 'tr',
19
- br: 'bl',
20
- lt: 'bl',
21
- bl: 'br',
22
- rt: 'br',
23
- }
24
-
25
- // 过滤折线中的共线中间点,减少不必要的顶点
26
- function pointFilter(points: number[][]) {
27
- // 原地修改传入的数组
28
- const all = points
29
- // 从第二个点开始,检查三点是否共线
30
- let i = 1
31
- while (i < all.length - 1) {
32
- const [x, y] = all[i - 1]
33
- const [x1, y1] = all[i]
34
- const [x2, y2] = all[i + 1]
35
- // 如果三点在同一条水平或垂直直线上,删除中间点
36
- if ((x === x1 && x1 === x2) || (y === y1 && y1 === y2)) {
37
- all.splice(i, 1)
38
- } else {
39
- i++
40
- }
41
- }
42
- // 返回精简后的点集
43
- return all
44
- }
45
-
46
- function getMidPoints(
47
- cur: PointTuple,
48
- key: string,
49
- orientation: ArcQuadrantType,
50
- radius: number,
51
- ) {
52
- const mid1 = [cur[0], cur[1]]
53
- const mid2 = [cur[0], cur[1]]
54
- switch (orientation) {
55
- case 'tl': {
56
- if (key === 'tr') {
57
- mid1[1] += radius
58
- mid2[0] += radius
59
- } else if (key === 'lb') {
60
- mid1[0] += radius
61
- mid2[1] += radius
62
- }
63
- return [mid1, mid2]
64
- }
65
- case 'tr': {
66
- if (key === 'tl') {
67
- mid1[1] += radius
68
- mid2[0] -= radius
69
- } else if (key === 'rb') {
70
- mid1[0] -= radius
71
- mid2[1] += radius
72
- }
73
- return [mid1, mid2]
74
- }
75
- case 'bl': {
76
- if (key === 'br') {
77
- mid1[1] -= radius
78
- mid2[0] += radius
79
- } else if (key === 'lt') {
80
- mid1[0] += radius
81
- mid2[1] -= radius
82
- }
83
- return [mid1, mid2]
84
- }
85
- case 'br': {
86
- if (key === 'bl') {
87
- mid1[1] -= radius
88
- mid2[0] -= radius
89
- } else if (key === 'rt') {
90
- mid1[0] -= radius
91
- mid2[1] -= radius
92
- }
93
- return [mid1, mid2]
94
- }
95
- default:
96
- return []
97
- }
98
- }
99
-
100
- /**
101
- * 生成局部路径片段(包含圆角)
102
- * - 输入为上一个顶点、当前拐点、下一个顶点,计算方向组合并选择圆弧象限
103
- * - 将圆角半径限制在相邻两段长度的一半以内,避免过度弯曲
104
- * @param prevPoint 上一个顶点
105
- * @param cornerPoint 当前拐点(圆角所在拐点)
106
- * @param nextPoint 下一个顶点
107
- * @param cornerRadius 圆角半径上限
108
- * @returns 局部 path 字符串(包含 L/Q 操作)
109
- */
110
- function getPartialPath(
111
- prevPoint: PointTuple,
112
- cornerPoint: PointTuple,
113
- nextPoint: PointTuple,
114
- cornerRadius: number,
115
- ): string {
116
- // 轴对齐容差(像素),用于消除微小误差
117
- const epsilon = 1
118
-
119
- const resolveDir = (a: PointTuple, b: PointTuple): DirectionType => {
120
- const dx = b[0] - a[0]
121
- const dy = b[1] - a[1]
122
- const adx = Math.abs(dx)
123
- const ady = Math.abs(dy)
124
- if (ady <= epsilon && adx > epsilon) {
125
- return dx < 0 ? 'l' : 'r'
126
- }
127
- if (adx <= epsilon && ady > epsilon) {
128
- return dy < 0 ? 't' : 'b'
129
- }
130
- if (adx <= epsilon && ady <= epsilon) {
131
- return ''
132
- }
133
- // 非严格对齐时,选择更接近的轴
134
- return adx < ady ? (dx < 0 ? 'l' : 'r') : dy < 0 ? 't' : 'b'
135
- }
136
-
137
- const dir1: DirectionType = resolveDir(prevPoint, cornerPoint)
138
- const dir2: DirectionType = resolveDir(cornerPoint, nextPoint)
139
-
140
- const r =
141
- Math.min(
142
- Math.hypot(cornerPoint[0] - prevPoint[0], cornerPoint[1] - prevPoint[1]) /
143
- 2,
144
- Math.hypot(nextPoint[0] - cornerPoint[0], nextPoint[1] - cornerPoint[1]) /
145
- 2,
146
- cornerRadius,
147
- ) || (1 / 5) * cornerRadius
148
-
149
- const key = `${dir1}${dir2}`
150
- const orientation: ArcQuadrantType = directionMap[key] || '-'
151
- let path = ''
152
-
153
- if (orientation === '-') {
154
- // 仅移动到当前拐点,由下一次迭代决定如何从拐点继续(直线或圆角)
155
- path += `L ${cornerPoint[0]} ${cornerPoint[1]}`
156
- } else {
157
- const [mid1, mid2] = getMidPoints(cornerPoint, key, orientation, r)
158
- if (mid1 && mid2) {
159
- path += `L ${mid1[0]} ${mid1[1]} Q ${cornerPoint[0]} ${cornerPoint[1]} ${mid2[0]} ${mid2[1]}`
160
- ;[cornerPoint[0], cornerPoint[1]] = mid2
161
- }
162
- }
163
- return path
164
- }
165
-
166
- function getCurvedEdgePath(points: number[][], radius: number): string {
167
- let i = 0
168
- let d = ''
169
- if (points.length === 2) {
170
- d += `M${points[i][0]} ${points[i++][1]} L ${points[i][0]} ${points[i][1]}`
171
- } else {
172
- d += `M${points[i][0]} ${points[i++][1]}`
173
- for (; i + 1 < points.length; ) {
174
- const prev = points[i - 1] as PointTuple
175
- const cur = points[i] as PointTuple
176
- const next = points[i++ + 1] as PointTuple
177
- d += getPartialPath(prev, cur, next, radius as number)
178
- }
179
- d += `L ${points[i][0]} ${points[i][1]}`
180
- }
181
- return d
182
- }
183
-
184
- class CurvedEdge extends PolylineEdge {
185
- getEdge(): h.JSX.Element {
186
- const { model } = this.props
187
- const { points: pointsStr, isAnimation, arrowConfig, radius = 5 } = model
188
- const style = model.getEdgeStyle()
189
- const animationStyle = model.getEdgeAnimationStyle()
190
- const points = pointFilter(
191
- pointsStr.split(' ').map((p) => p.split(',').map((a) => +a)),
192
- )
193
- const d = getCurvedEdgePath(points, radius as number)
194
- const attrs = {
195
- style: isAnimation ? animationStyle : {},
196
- ...style,
197
- ...arrowConfig,
198
- fill: 'none',
199
- }
200
- return h('path', {
201
- d,
202
- ...attrs,
203
- })
204
- }
205
- }
206
-
207
- class CurvedEdgeModel extends PolylineEdgeModel {}
208
-
209
- const defaultCurvedEdge = {
210
- type: 'curved-edge',
211
- view: CurvedEdge,
212
- model: CurvedEdgeModel,
213
- }
214
-
215
- export default defaultCurvedEdge
216
-
217
- export { CurvedEdge, CurvedEdgeModel, getCurvedEdgePath }