@logicflow/core 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.
Files changed (236) hide show
  1. package/dist/index.css +3 -2
  2. package/dist/index.min.js +1 -1
  3. package/dist/index.min.js.map +1 -1
  4. package/es/LogicFlow.d.ts +9 -0
  5. package/es/LogicFlow.js +0 -1
  6. package/es/constant/index.d.ts +1 -1
  7. package/es/constant/index.js +1 -1
  8. package/es/constant/theme.d.ts +136 -0
  9. package/es/constant/theme.js +680 -0
  10. package/es/index.css +3 -2
  11. package/es/model/GraphModel.d.ts +10 -2
  12. package/es/model/GraphModel.js +48 -14
  13. package/es/model/TransformModel.js +9 -9
  14. package/es/model/edge/BaseEdgeModel.js +7 -2
  15. package/es/model/edge/PolylineEdgeModel.d.ts +7 -0
  16. package/es/model/edge/PolylineEdgeModel.js +136 -7
  17. package/es/model/node/BaseNodeModel.d.ts +12 -1
  18. package/es/model/node/BaseNodeModel.js +9 -2
  19. package/es/model/node/HtmlNodeModel.d.ts +12 -0
  20. package/es/model/node/HtmlNodeModel.js +19 -0
  21. package/es/model/node/PolygonNodeModel.js +3 -3
  22. package/es/options.d.ts +4 -2
  23. package/es/style/index.css +3 -2
  24. package/es/style/index.less +3 -2
  25. package/es/style/raw.d.ts +1 -1
  26. package/es/style/raw.js +1 -1
  27. package/es/tool/MultipleSelectTool.js +10 -5
  28. package/es/util/drag.js +0 -1
  29. package/es/util/edge.d.ts +40 -1
  30. package/es/util/edge.js +43 -9
  31. package/es/util/geometry.d.ts +8 -0
  32. package/es/util/geometry.js +79 -0
  33. package/es/util/theme.d.ts +2 -65
  34. package/es/util/theme.js +4 -281
  35. package/es/view/Anchor.d.ts +1 -0
  36. package/es/view/Anchor.js +24 -21
  37. package/es/view/Control.d.ts +5 -0
  38. package/es/view/Control.js +44 -57
  39. package/es/view/edge/BaseEdge.js +9 -0
  40. package/es/view/edge/PolylineEdge.js +13 -2
  41. package/es/view/node/BaseNode.d.ts +1 -0
  42. package/es/view/node/BaseNode.js +23 -11
  43. package/es/view/node/HtmlNode.js +2 -4
  44. package/es/view/overlay/CanvasOverlay.js +5 -2
  45. package/es/view/overlay/Grid.d.ts +12 -1
  46. package/es/view/overlay/Grid.js +85 -23
  47. package/es/view/overlay/OutlineOverlay.d.ts +1 -0
  48. package/es/view/overlay/OutlineOverlay.js +18 -17
  49. package/es/view/overlay/gridConfig.d.ts +46 -0
  50. package/es/view/overlay/gridConfig.js +99 -0
  51. package/es/view/shape/Polygon.d.ts +0 -7
  52. package/es/view/shape/Polygon.js +12 -43
  53. package/lib/LogicFlow.d.ts +9 -0
  54. package/lib/LogicFlow.js +0 -1
  55. package/lib/constant/index.d.ts +1 -1
  56. package/lib/constant/index.js +16 -2
  57. package/lib/constant/theme.d.ts +136 -0
  58. package/lib/constant/theme.js +683 -0
  59. package/lib/index.css +3 -2
  60. package/lib/model/GraphModel.d.ts +10 -2
  61. package/lib/model/GraphModel.js +49 -15
  62. package/lib/model/TransformModel.js +9 -9
  63. package/lib/model/edge/BaseEdgeModel.js +7 -2
  64. package/lib/model/edge/PolylineEdgeModel.d.ts +7 -0
  65. package/lib/model/edge/PolylineEdgeModel.js +136 -7
  66. package/lib/model/node/BaseNodeModel.d.ts +12 -1
  67. package/lib/model/node/BaseNodeModel.js +9 -2
  68. package/lib/model/node/HtmlNodeModel.d.ts +12 -0
  69. package/lib/model/node/HtmlNodeModel.js +19 -0
  70. package/lib/model/node/PolygonNodeModel.js +3 -3
  71. package/lib/options.d.ts +4 -2
  72. package/lib/style/index.css +3 -2
  73. package/lib/style/index.less +3 -2
  74. package/lib/style/raw.d.ts +1 -1
  75. package/lib/style/raw.js +1 -1
  76. package/lib/tool/MultipleSelectTool.js +10 -5
  77. package/lib/util/drag.js +0 -1
  78. package/lib/util/edge.d.ts +40 -1
  79. package/lib/util/edge.js +43 -9
  80. package/lib/util/geometry.d.ts +8 -0
  81. package/lib/util/geometry.js +81 -1
  82. package/lib/util/theme.d.ts +2 -65
  83. package/lib/util/theme.js +15 -292
  84. package/lib/view/Anchor.d.ts +1 -0
  85. package/lib/view/Anchor.js +24 -21
  86. package/lib/view/Control.d.ts +5 -0
  87. package/lib/view/Control.js +44 -57
  88. package/lib/view/edge/BaseEdge.js +9 -0
  89. package/lib/view/edge/PolylineEdge.js +13 -2
  90. package/lib/view/node/BaseNode.d.ts +1 -0
  91. package/lib/view/node/BaseNode.js +22 -10
  92. package/lib/view/node/HtmlNode.js +1 -3
  93. package/lib/view/overlay/CanvasOverlay.js +5 -2
  94. package/lib/view/overlay/Grid.d.ts +12 -1
  95. package/lib/view/overlay/Grid.js +83 -21
  96. package/lib/view/overlay/OutlineOverlay.d.ts +1 -0
  97. package/lib/view/overlay/OutlineOverlay.js +18 -17
  98. package/lib/view/overlay/gridConfig.d.ts +46 -0
  99. package/lib/view/overlay/gridConfig.js +104 -0
  100. package/lib/view/shape/Polygon.d.ts +0 -7
  101. package/lib/view/shape/Polygon.js +13 -45
  102. package/package.json +6 -1
  103. package/.turbo/turbo-build$colon$dev.log +0 -10
  104. package/.turbo/turbo-build.log +0 -33
  105. package/CHANGELOG.md +0 -1849
  106. package/__tests__/algorithm/egde.test.ts +0 -131
  107. package/__tests__/algorithm/index.test.ts +0 -74
  108. package/__tests__/algorithm/outline.test.ts +0 -43
  109. package/__tests__/bugs/1545-spec.test.ts +0 -42
  110. package/__tests__/event/event.test.ts +0 -22
  111. package/__tests__/history/history.test.ts +0 -28
  112. package/__tests__/logicflow.test.ts +0 -575
  113. package/__tests__/model/graphmodel.test.ts +0 -87
  114. package/__tests__/util/compatible.test.ts +0 -48
  115. package/__tests__/util/edge.test.ts +0 -224
  116. package/__tests__/util/geometry.test.ts +0 -14
  117. package/__tests__/util/graph.test.ts +0 -16
  118. package/__tests__/util/matrix.test.ts +0 -41
  119. package/__tests__/util/node.test.ts +0 -68
  120. package/__tests__/util/sampling.test.ts +0 -12
  121. package/__tests__/util/vector.test.ts +0 -50
  122. package/__tests__/util/zIndex.test.ts +0 -10
  123. package/src/LogicFlow.tsx +0 -2008
  124. package/src/algorithm/edge.ts +0 -67
  125. package/src/algorithm/index.ts +0 -70
  126. package/src/algorithm/outline.ts +0 -77
  127. package/src/algorithm/rotate.ts +0 -55
  128. package/src/common/drag.ts +0 -219
  129. package/src/common/history.ts +0 -108
  130. package/src/common/index.ts +0 -6
  131. package/src/common/keyboard.ts +0 -108
  132. package/src/common/matrix.ts +0 -122
  133. package/src/common/vector.ts +0 -93
  134. package/src/constant/index.ts +0 -179
  135. package/src/event/event.md +0 -66
  136. package/src/event/eventArgs.ts +0 -643
  137. package/src/event/eventEmitter.ts +0 -156
  138. package/src/history/index.ts +0 -119
  139. package/src/index.less +0 -1
  140. package/src/index.ts +0 -26
  141. package/src/keyboard/index.ts +0 -112
  142. package/src/keyboard/shortcut.ts +0 -200
  143. package/src/model/BaseModel.ts +0 -250
  144. package/src/model/EditConfigModel.ts +0 -334
  145. package/src/model/GraphModel.ts +0 -1788
  146. package/src/model/NestedTransformModel.ts +0 -121
  147. package/src/model/SnaplineModel.ts +0 -256
  148. package/src/model/TransformModel.ts +0 -258
  149. package/src/model/edge/BaseEdgeModel.ts +0 -777
  150. package/src/model/edge/BezierEdgeModel.ts +0 -197
  151. package/src/model/edge/LineEdgeModel.ts +0 -36
  152. package/src/model/edge/PolylineEdgeModel.ts +0 -672
  153. package/src/model/edge/index.ts +0 -4
  154. package/src/model/index.ts +0 -9
  155. package/src/model/node/BaseNodeModel.ts +0 -949
  156. package/src/model/node/CircleNodeModel.ts +0 -91
  157. package/src/model/node/DiamondNodeModel.ts +0 -132
  158. package/src/model/node/EllipseNodeModel.ts +0 -98
  159. package/src/model/node/HtmlNodeModel.ts +0 -50
  160. package/src/model/node/PolygonNodeModel.ts +0 -150
  161. package/src/model/node/RectNodeModel.ts +0 -69
  162. package/src/model/node/TextNodeModel.ts +0 -54
  163. package/src/model/node/index.ts +0 -8
  164. package/src/options.ts +0 -145
  165. package/src/style/index.less +0 -261
  166. package/src/style/raw.ts +0 -220
  167. package/src/tool/MultipleSelectTool.tsx +0 -132
  168. package/src/tool/TextEditTool.tsx +0 -193
  169. package/src/tool/index.ts +0 -101
  170. package/src/typings.d.ts +0 -5
  171. package/src/util/animation.ts +0 -29
  172. package/src/util/browser.ts +0 -4
  173. package/src/util/compatible.ts +0 -15
  174. package/src/util/drag.ts +0 -220
  175. package/src/util/edge.ts +0 -1060
  176. package/src/util/geometry.ts +0 -55
  177. package/src/util/graph.ts +0 -46
  178. package/src/util/index.ts +0 -17
  179. package/src/util/matrix.ts +0 -129
  180. package/src/util/mobx.ts +0 -23
  181. package/src/util/node.ts +0 -543
  182. package/src/util/raf.ts +0 -28
  183. package/src/util/resize.ts +0 -606
  184. package/src/util/sampling.ts +0 -85
  185. package/src/util/theme.ts +0 -375
  186. package/src/util/uuid.ts +0 -26
  187. package/src/util/vector.ts +0 -93
  188. package/src/util/zIndex.ts +0 -6
  189. package/src/view/Anchor.tsx +0 -445
  190. package/src/view/Control.tsx +0 -512
  191. package/src/view/Graph.tsx +0 -141
  192. package/src/view/Rotate.tsx +0 -113
  193. package/src/view/behavior/dnd.ts +0 -162
  194. package/src/view/behavior/index.ts +0 -2
  195. package/src/view/behavior/snapline.ts +0 -16
  196. package/src/view/edge/AdjustPoint.tsx +0 -425
  197. package/src/view/edge/Arrow.tsx +0 -54
  198. package/src/view/edge/BaseEdge.tsx +0 -650
  199. package/src/view/edge/BezierEdge.tsx +0 -101
  200. package/src/view/edge/LineEdge.tsx +0 -81
  201. package/src/view/edge/PolylineEdge.tsx +0 -299
  202. package/src/view/edge/index.ts +0 -6
  203. package/src/view/index.ts +0 -8
  204. package/src/view/node/BaseNode.tsx +0 -571
  205. package/src/view/node/CircleNode.tsx +0 -21
  206. package/src/view/node/DiamondNode.tsx +0 -24
  207. package/src/view/node/EllipseNode.tsx +0 -22
  208. package/src/view/node/HtmlNode.tsx +0 -95
  209. package/src/view/node/PolygonNode.tsx +0 -28
  210. package/src/view/node/RectNode.tsx +0 -30
  211. package/src/view/node/TextNode.tsx +0 -39
  212. package/src/view/node/index.ts +0 -8
  213. package/src/view/overlay/BackgroundOverlay.tsx +0 -34
  214. package/src/view/overlay/BezierAdjustOverlay.tsx +0 -150
  215. package/src/view/overlay/CanvasOverlay.tsx +0 -288
  216. package/src/view/overlay/Grid.tsx +0 -162
  217. package/src/view/overlay/ModificationOverlay.tsx +0 -31
  218. package/src/view/overlay/OutlineOverlay.tsx +0 -170
  219. package/src/view/overlay/SnaplineOverlay.tsx +0 -44
  220. package/src/view/overlay/ToolOverlay.tsx +0 -65
  221. package/src/view/overlay/getTransformHoc.tsx +0 -50
  222. package/src/view/overlay/index.ts +0 -8
  223. package/src/view/shape/Circle.tsx +0 -41
  224. package/src/view/shape/Ellipse.tsx +0 -42
  225. package/src/view/shape/Line.tsx +0 -39
  226. package/src/view/shape/Path.tsx +0 -22
  227. package/src/view/shape/Polygon.tsx +0 -91
  228. package/src/view/shape/Polyline.tsx +0 -31
  229. package/src/view/shape/Rect.tsx +0 -44
  230. package/src/view/shape/Text.tsx +0 -169
  231. package/src/view/shape/index.ts +0 -8
  232. package/src/view/text/BaseText.tsx +0 -134
  233. package/src/view/text/LineText.tsx +0 -168
  234. package/src/view/text/index.ts +0 -2
  235. package/stats.html +0 -4842
  236. package/tsconfig.json +0 -18
@@ -1,571 +0,0 @@
1
- import { createElement as h, Component } from 'preact/compat'
2
- import { reaction, IReactionDisposer } from 'mobx'
3
- import { map } from 'lodash-es'
4
- import Anchor from '../Anchor'
5
- import { BaseText } from '../text'
6
- import LogicFlow from '../../LogicFlow'
7
- import { GraphModel, BaseNodeModel, Model } from '../../model'
8
- import { ElementState, EventType, TextMode } from '../../constant'
9
- import {
10
- StepDrag,
11
- snapToGrid,
12
- isIe,
13
- isMultipleSelect,
14
- cancelRaf,
15
- createRaf,
16
- IDragParams,
17
- // RotateMatrix,
18
- } from '../../util'
19
- import RotateControlPoint from '../Rotate'
20
- import ResizeControlGroup from '../Control'
21
-
22
- type IProps = {
23
- model: BaseNodeModel
24
- graphModel: GraphModel
25
- }
26
-
27
- type IState = {
28
- isDragging?: boolean
29
- }
30
-
31
- export abstract class BaseNode<P extends IProps = IProps> extends Component<
32
- P,
33
- IState
34
- > {
35
- static isObserved: boolean = false
36
- static extendsKey?: string
37
-
38
- t: any
39
- moveOffset?: LogicFlow.OffsetData
40
-
41
- stepDrag: StepDrag
42
- mouseUpDrag?: boolean
43
- startTime?: number
44
- modelDisposer: IReactionDisposer
45
- longPressTimer?: number
46
-
47
- constructor(props: IProps) {
48
- super()
49
- const {
50
- graphModel: { gridSize, eventCenter },
51
- model,
52
- } = props
53
- // 不在构造函数中判断,因为editConfig可能会被动态改变
54
- this.stepDrag = new StepDrag({
55
- onDragStart: this.onDragStart,
56
- onDragging: this.onDragging,
57
- onDragEnd: this.onDragEnd,
58
- step: gridSize,
59
- eventType: 'NODE',
60
- isStopPropagation: false,
61
- eventCenter,
62
- model,
63
- })
64
- // https://github.com/didi/LogicFlow/issues/1370
65
- // 当使用撤销功能:LogicFlow.undo()时,会重新初始化所有model数据,即LogicFlow.undo()时会新构建一个model对象
66
- // 但是this.stepDrag并不会重新创建
67
- // 导致this.stepDrag持有的model并没有重新赋值,因为之前的做法是构造函数中传入一个model对象
68
- // 使用mobx的reaction监听能力,如果this.props.model发生变化,则进行this.stepDrag.setModel()操作
69
- this.modelDisposer = reaction(
70
- () => this.props,
71
- (newProps) => {
72
- if (newProps && newProps.model) {
73
- this.stepDrag.setModel(newProps.model)
74
- }
75
- },
76
- )
77
- }
78
-
79
- componentWillUnmount() {
80
- if (this.modelDisposer) {
81
- this.modelDisposer()
82
- }
83
-
84
- // 以下是 mobx-preact 中 componentWillUnmount 的回调逻辑,但是不知道出于什么考虑,mobx-preact 没有混入这一段逻辑
85
- // @ts-ignore
86
- if (this.render.$mobx) {
87
- // @ts-ignore
88
- this.render.$mobx.dispose()
89
- }
90
- }
91
-
92
- componentDidMount() {}
93
-
94
- componentDidUpdate() {}
95
-
96
- abstract getShape(): h.JSX.Element | null
97
-
98
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
99
- getAnchorShape(_anchorData?: Model.AnchorConfig): h.JSX.Element | null {
100
- return null
101
- }
102
-
103
- getAnchors() {
104
- const { model, graphModel } = this.props
105
- const { isSelected, isHitable, isDragging, isShowAnchor } = model
106
- if (isHitable && (isSelected || isShowAnchor) && !isDragging) {
107
- return map(model.anchors, (anchor, index) => {
108
- const edgeStyle = model.getAnchorLineStyle(anchor)
109
- const style = model.getAnchorStyle(anchor)
110
- return (
111
- <Anchor
112
- anchorData={anchor}
113
- node={this}
114
- style={style}
115
- edgeStyle={edgeStyle}
116
- anchorIndex={index}
117
- nodeModel={model}
118
- graphModel={graphModel}
119
- setHoverOff={this.setHoverOff}
120
- />
121
- )
122
- })
123
- }
124
- return []
125
- }
126
-
127
- getRotateControl() {
128
- const { model, graphModel } = this.props
129
- const {
130
- editConfigModel: { isSilentMode, allowRotate },
131
- } = graphModel
132
- const { isSelected, isHitable, rotatable, isHovered } = model
133
-
134
- // 合并全局 allResize 和节点自身的 resizable 配置,以节点配置高于全局配置
135
- const canRotate = allowRotate && rotatable // 全局开关 > 节点配置
136
-
137
- const style = model.getRotateControlStyle()
138
- if (!isSilentMode && isHitable && (isSelected || isHovered) && canRotate) {
139
- return (
140
- <RotateControlPoint
141
- graphModel={graphModel}
142
- nodeModel={model}
143
- eventCenter={graphModel.eventCenter}
144
- style={style}
145
- />
146
- )
147
- }
148
- }
149
-
150
- getResizeControl(): h.JSX.Element | null {
151
- const { model, graphModel } = this.props
152
- const {
153
- editConfigModel: { isSilentMode, allowResize },
154
- } = graphModel
155
- const { isSelected, isHitable, resizable, isHovered } = model
156
-
157
- // 合并全局 allResize 和节点自身的 resizable 配置,以节点配置高于全局配置
158
- const canResize = allowResize && resizable // 全局开关 > 节点配置
159
- const style = model.getResizeControlStyle()
160
- if (!isSilentMode && isHitable && (isSelected || isHovered) && canResize) {
161
- return (
162
- <ResizeControlGroup
163
- style={style}
164
- model={model}
165
- graphModel={graphModel}
166
- />
167
- )
168
- }
169
- return null
170
- }
171
-
172
- getText(): h.JSX.Element | null {
173
- const { model, graphModel } = this.props
174
- const { editConfigModel } = graphModel
175
-
176
- // 当 节点文本模式非 TEXT 时,不显示文本
177
- if (editConfigModel.nodeTextMode !== TextMode.TEXT) return null
178
- // 文本被编辑的时候,显示编辑框,不显示文本。
179
- if (model.state === ElementState.TEXT_EDIT) return null
180
-
181
- if (model.text) {
182
- let draggable = false
183
- if (editConfigModel.nodeTextDraggable && model.text.draggable) {
184
- draggable = true
185
- }
186
- return (
187
- <BaseText
188
- editable={
189
- editConfigModel.nodeTextEdit && (model.text.editable ?? true)
190
- }
191
- model={model}
192
- graphModel={graphModel}
193
- draggable={draggable}
194
- />
195
- )
196
- }
197
- return null
198
- }
199
-
200
- getStateClassName() {
201
- const {
202
- model: { state, isDragging, isSelected },
203
- } = this.props
204
- let className = 'lf-node'
205
- switch (state) {
206
- case ElementState.ALLOW_CONNECT:
207
- className += ' lf-node-allow'
208
- break
209
- case ElementState.NOT_ALLOW_CONNECT:
210
- className += ' lf-node-not-allow'
211
- break
212
- default:
213
- className += ' lf-node-default'
214
- break
215
- }
216
- if (isDragging) {
217
- className += ' lf-dragging'
218
- }
219
- if (isSelected) {
220
- className += ' lf-node-selected'
221
- }
222
- return className
223
- }
224
-
225
- onDragStart = ({ event }: Partial<IDragParams>) => {
226
- const { model, graphModel } = this.props
227
- if (event) {
228
- const {
229
- canvasOverlayPosition: { x, y },
230
- } = graphModel.getPointByClient({
231
- x: event.clientX,
232
- y: event.clientY,
233
- })
234
- this.moveOffset = {
235
- dx: model.x - x,
236
- dy: model.y - y,
237
- }
238
- }
239
- }
240
-
241
- onDragging = ({ event }: IDragParams) => {
242
- const { model, graphModel } = this.props
243
- const {
244
- editConfigModel: { stopMoveGraph, autoExpand, snapGrid },
245
- transformModel,
246
- selectNodes,
247
- width,
248
- height,
249
- gridSize,
250
- } = graphModel
251
- model.isDragging = true
252
- const { clientX, clientY } = event!
253
- let {
254
- canvasOverlayPosition: { x, y },
255
- } = graphModel.getPointByClient({
256
- x: clientX,
257
- y: clientY,
258
- })
259
- const [x1, y1] = transformModel.CanvasPointToHtmlPoint([x, y])
260
- // 1. 考虑画布被缩放
261
- // 2. 考虑鼠标位置不再节点中心
262
- x = x + (this.moveOffset?.dx ?? 0)
263
- y = y + (this.moveOffset?.dy ?? 0)
264
- // 校准坐标
265
- x = snapToGrid(x, gridSize, snapGrid)
266
- y = snapToGrid(y, gridSize, snapGrid)
267
- if (!width || !height) {
268
- graphModel.moveNode2Coordinate(model.id, x, y)
269
- return
270
- }
271
- const isOutCanvas = x1 < 0 || y1 < 0 || x1 > width || y1 > height
272
- if (autoExpand && !stopMoveGraph && isOutCanvas) {
273
- // 鼠标超出画布后的拖动,不处理,而是让上一次setInterval持续滚动画布
274
- return
275
- }
276
- // 取节点左上角和右下角,计算节点移动是否超出范围
277
- const [leftTopX, leftTopY] = transformModel.CanvasPointToHtmlPoint([
278
- x - model.width / 2,
279
- y - model.height / 2,
280
- ])
281
- const [rightBottomX, rightBottomY] = transformModel.CanvasPointToHtmlPoint([
282
- x + model.width / 2,
283
- y + model.height / 2,
284
- ])
285
- const size: number = Math.max(gridSize, 20)
286
- let nearBoundary: LogicFlow.PointTuple | [] = []
287
- if (leftTopX < 0) {
288
- nearBoundary = [size, 0]
289
- } else if (rightBottomX > graphModel.width) {
290
- nearBoundary = [-size, 0]
291
- } else if (leftTopY < 0) {
292
- nearBoundary = [0, size]
293
- } else if (rightBottomY > graphModel.height) {
294
- nearBoundary = [0, -size]
295
- }
296
- if (this.t) {
297
- cancelRaf(this.t)
298
- }
299
-
300
- let moveNodes = selectNodes.map((node) => node.id)
301
- // 未被选中的节点也可以拖动
302
- if (moveNodes.indexOf(model.id) === -1) {
303
- moveNodes = [model.id]
304
- }
305
- if (nearBoundary.length > 0 && !stopMoveGraph && autoExpand) {
306
- this.t = createRaf(() => {
307
- const [translateX, translateY] = nearBoundary
308
- transformModel.translate(translateX ?? 0, translateY ?? 0)
309
- const deltaX = -(translateX ?? 0) / transformModel.SCALE_X
310
- const deltaY = -(translateY ?? 0) / transformModel.SCALE_X
311
- graphModel.moveNodes(moveNodes, deltaX, deltaY)
312
- })
313
- } else {
314
- graphModel.moveNodes(moveNodes, x - model.x, y - model.y)
315
- }
316
- }
317
-
318
- onDragEnd = () => {
319
- if (this.t) {
320
- cancelRaf(this.t)
321
- }
322
- const { model } = this.props
323
- model.isDragging = false
324
- }
325
- onMouseOut = (ev: MouseEvent) => {
326
- if (isIe()) {
327
- this.setHoverOff(ev)
328
- }
329
- }
330
-
331
- handleMouseUp = () => {
332
- const { model } = this.props
333
- this.mouseUpDrag = model.isDragging
334
- if (this.longPressTimer) {
335
- clearTimeout(this.longPressTimer)
336
- this.longPressTimer = undefined
337
- }
338
- }
339
-
340
- handleClick = (e: MouseEvent) => {
341
- // 节点拖拽进画布之后,不触发click事件相关emit
342
- // 点拖拽进画布没有触发mousedown事件,没有startTime,用这个值做区分
343
- const isDragging = this.mouseUpDrag === false
344
- const curTime = new Date().getTime()
345
- if (!this.startTime) return
346
- const timeInterval = curTime - this.startTime
347
- const { model, graphModel } = this.props
348
- // 这里会有一种极端情况:当网格大小是1或者关闭网格吸附时,用触摸板点击节点会触发拖拽事件导致节点无法选中
349
- // 当触摸板点击节点时,为了防止误触发拖拽导致节点无法选中,允许在非拖拽状态且时间间隔小于100ms时触发点击事件
350
- if (!isDragging && timeInterval > 100) return
351
- if (!isDragging) {
352
- this.onDragEnd()
353
- this.handleMouseUp()
354
- }
355
- // 节点数据,多为事件对象数据抛出
356
- const nodeData = model.getData()
357
- const position = graphModel.getPointByClient({
358
- x: e.clientX,
359
- y: e.clientY,
360
- })
361
-
362
- // TODO: 这里加入了 isSelected 与 isMultiple,主要是为 group 插件做的加强,有种被插件夺舍的感觉
363
- const eventOptions = {
364
- data: nodeData,
365
- e,
366
- position,
367
- isSelected: false,
368
- isMultiple: false,
369
- }
370
-
371
- const isRightClick = e.button === 2
372
- // 这里 IE 11不能正确显示
373
- const isDoubleClick = e.detail === 2
374
-
375
- // 判断是否有右击,如果有右击则取消点击事件触发
376
- if (isRightClick) return
377
-
378
- const { editConfigModel } = graphModel
379
- // 在multipleSelect tool禁用的情况下,允许取消选中节点
380
- const isMultiple = isMultipleSelect(e, editConfigModel)
381
- eventOptions.isMultiple = isMultiple
382
- if (model.isSelected && !isDoubleClick && isMultiple) {
383
- eventOptions.isSelected = false
384
- model.setSelected(false)
385
- } else {
386
- graphModel.selectNodeById(model.id, isMultiple)
387
- eventOptions.isSelected = true
388
- // 静默模式下点击节点不变更节点层级
389
- if (!editConfigModel.isSilentMode) {
390
- this.toFront()
391
- }
392
- }
393
-
394
- // 不是双击的,默认都是单击
395
- if (isDoubleClick) {
396
- if (editConfigModel.nodeTextEdit) {
397
- if (model.text.editable && editConfigModel.textMode === TextMode.TEXT) {
398
- model.setSelected(false)
399
- graphModel.setElementStateById(model.id, ElementState.TEXT_EDIT)
400
- }
401
- }
402
- graphModel.eventCenter.emit(EventType.NODE_DBCLICK, eventOptions)
403
- } else {
404
- graphModel.eventCenter.emit(EventType.ELEMENT_CLICK, eventOptions)
405
- graphModel.eventCenter.emit(EventType.NODE_CLICK, eventOptions)
406
- }
407
- }
408
-
409
- handleContextMenu = (ev: MouseEvent) => {
410
- ev.preventDefault()
411
- const { model, graphModel } = this.props
412
- const { editConfigModel } = graphModel
413
- // 节点数据,多为事件对象数据抛出
414
- const nodeData = model.getData()
415
-
416
- const position = graphModel.getPointByClient({
417
- x: ev.clientX,
418
- y: ev.clientY,
419
- })
420
- graphModel.setElementStateById(
421
- model.id,
422
- ElementState.SHOW_MENU,
423
- position.domOverlayPosition,
424
- )
425
- if (!model.isSelected) {
426
- graphModel.selectNodeById(model.id)
427
- }
428
- graphModel.eventCenter.emit(EventType.NODE_CONTEXTMENU, {
429
- data: nodeData,
430
- e: ev,
431
- position,
432
- })
433
- // 静默模式下点击节点不变更节点层级
434
- if (!editConfigModel.isSilentMode) {
435
- this.toFront()
436
- }
437
- }
438
-
439
- handleMouseDown = (ev: PointerEvent) => {
440
- const { model, graphModel } = this.props
441
- this.startTime = new Date().getTime()
442
- const { editConfigModel } = graphModel
443
- if (editConfigModel.adjustNodePosition && model.draggable) {
444
- this.stepDrag && this.stepDrag.handleMouseDown(ev)
445
- }
446
- if (this.longPressTimer) {
447
- clearTimeout(this.longPressTimer)
448
- }
449
- if (ev.pointerType === 'touch') {
450
- this.longPressTimer = window.setTimeout(() => {
451
- if (!this.props.model.isDragging) {
452
- this.handleContextMenu(ev)
453
- }
454
- }, 500)
455
- }
456
- }
457
-
458
- handleFocus = () => {
459
- const { model, graphModel } = this.props
460
- graphModel.eventCenter.emit(EventType.NODE_FOCUS, {
461
- data: model.getData(),
462
- })
463
- }
464
-
465
- handleBlur = () => {
466
- // 当节点通过自定义锚点实现节点删除时,这里props会变成undefined,需兼容一下
467
- if (!this.props) return
468
- const { model, graphModel } = this.props
469
- graphModel.eventCenter.emit(EventType.NODE_BLUR, {
470
- data: model.getData(),
471
- })
472
- }
473
-
474
- // 因为自定义节点的时候,可能会基于hover状态自定义不同的样式。
475
- setHoverOn = (ev: MouseEvent) => {
476
- const { model, graphModel } = this.props
477
- if (model.isHovered) return
478
- const nodeData = model.getData()
479
- model.setHovered(true)
480
- graphModel.eventCenter.emit(EventType.NODE_MOUSEENTER, {
481
- data: nodeData,
482
- e: ev,
483
- })
484
- }
485
-
486
- setHoverOff = (ev: MouseEvent) => {
487
- const { model, graphModel } = this.props
488
- const nodeData = model.getData()
489
- // 文本focus时,关联的元素也需要高亮,所以元素失焦时还要判断下是否有文本处于focus状态
490
- if (!model.isHovered) return
491
- model.setHovered(false)
492
- graphModel.eventCenter.emit(EventType.NODE_MOUSELEAVE, {
493
- data: nodeData,
494
- e: ev,
495
- })
496
- }
497
-
498
- /**
499
- * @overridable 支持重写, 节点置顶,可以被某些不需要置顶的节点重写,如group节点。
500
- */
501
- toFront() {
502
- const { model, graphModel } = this.props
503
- if (model.autoToFront) {
504
- graphModel.toFront(model.id)
505
- }
506
- }
507
-
508
- render() {
509
- const { model, graphModel } = this.props
510
- const {
511
- editConfigModel: {
512
- hideAnchors,
513
- adjustNodePosition,
514
- allowRotate,
515
- allowResize,
516
- },
517
- gridSize,
518
- transformModel: { SCALE_X },
519
- } = graphModel
520
- const { isHitable, draggable, transform } = model
521
- const { className = '', ...restAttributes } = model.getOuterGAttributes()
522
- const nodeShapeInner = (
523
- <g className="lf-node-content">
524
- <g transform={transform}>
525
- {this.getShape()}
526
- {this.getText()}
527
- {allowRotate && this.getRotateControl()}
528
- {allowResize && this.getResizeControl()}
529
- </g>
530
- {!hideAnchors && this.getAnchors()}
531
- </g>
532
- )
533
- let nodeShape: h.JSX.Element
534
- if (!isHitable) {
535
- nodeShape = (
536
- <g
537
- className={`${this.getStateClassName()} ${className}`}
538
- {...restAttributes}
539
- >
540
- {nodeShapeInner}
541
- </g>
542
- )
543
- } else {
544
- if (adjustNodePosition && draggable) {
545
- this.stepDrag.setStep(gridSize * SCALE_X)
546
- }
547
- nodeShape = (
548
- <g
549
- className={`${this.getStateClassName()} ${className}`}
550
- onPointerDown={this.handleMouseDown}
551
- onPointerUp={this.handleMouseUp}
552
- onClick={this.handleClick}
553
- //因为移动端点击操作完成会按顺序触发enter、leave、click事件,所以会造成节点的闪烁,所以在这里没有统一状态为Pointer
554
- onMouseEnter={this.setHoverOn}
555
- onMouseOver={this.setHoverOn}
556
- onMouseLeave={this.setHoverOff}
557
- onMouseOut={this.onMouseOut}
558
- onContextMenu={this.handleContextMenu}
559
- onFocus={this.handleFocus}
560
- onBlur={this.handleBlur}
561
- {...restAttributes}
562
- >
563
- {nodeShapeInner}
564
- </g>
565
- )
566
- }
567
- return nodeShape
568
- }
569
- }
570
-
571
- export default BaseNode
@@ -1,21 +0,0 @@
1
- import Circle from '../shape/Circle'
2
- import BaseNode from './BaseNode'
3
- import { GraphModel, CircleNodeModel } from '../../model'
4
-
5
- export type ICircleNodeProps = {
6
- model: CircleNodeModel
7
- graphModel: GraphModel
8
- }
9
-
10
- export class CircleNode<
11
- P extends ICircleNodeProps = ICircleNodeProps,
12
- > extends BaseNode<P> {
13
- getShape() {
14
- const { model } = this.props
15
- const { x, y, r } = model
16
- const style = model.getNodeStyle()
17
- return <Circle {...style} x={x} y={y} r={r} />
18
- }
19
- }
20
-
21
- export default CircleNode
@@ -1,24 +0,0 @@
1
- import BaseNode from './BaseNode'
2
- import Polygon from '../shape/Polygon'
3
- import { GraphModel, DiamondNodeModel } from '../../model'
4
-
5
- export type IDiamondNodeProps = {
6
- model: DiamondNodeModel
7
- graphModel: GraphModel
8
- }
9
-
10
- export class DiamondNode<
11
- P extends IDiamondNodeProps = IDiamondNodeProps,
12
- > extends BaseNode<P> {
13
- getShape() {
14
- const { model } = this.props
15
- const style = model.getNodeStyle()
16
- return (
17
- <g>
18
- <Polygon {...style} points={model.points} x={model.x} y={model.y} />
19
- </g>
20
- )
21
- }
22
- }
23
-
24
- export default DiamondNode
@@ -1,22 +0,0 @@
1
- import BaseNode from './BaseNode'
2
- import Ellipse from '../shape/Ellipse'
3
- import { GraphModel, EllipseNodeModel } from '../../model'
4
-
5
- export type IEllipseNodeProps = {
6
- model: EllipseNodeModel
7
- graphModel: GraphModel
8
- }
9
-
10
- export class EllipseNode<
11
- P extends IEllipseNodeProps = IEllipseNodeProps,
12
- > extends BaseNode<P> {
13
- getShape() {
14
- const { model } = this.props
15
- const style = model.getNodeStyle()
16
- return (
17
- <Ellipse {...style} x={model.x} y={model.y} rx={model.rx} ry={model.ry} />
18
- )
19
- }
20
- }
21
-
22
- export default EllipseNode