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