@logicflow/extension 2.0.9 → 2.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +34 -61
- package/CHANGELOG.md +33 -0
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/es/bpmn-elements/presets/Pool/index.js +7 -7
- package/es/bpmn-elements/presets/Task/subProcess.js +2 -2
- package/es/dynamic-group/index.d.ts +11 -5
- package/es/dynamic-group/index.js +125 -23
- package/es/dynamic-group/model.d.ts +6 -1
- package/es/dynamic-group/model.js +14 -8
- package/es/dynamic-group/node.d.ts +13 -1
- package/es/dynamic-group/node.js +135 -19
- package/es/tools/label/index.js +2 -2
- package/lib/bpmn-elements/presets/Pool/index.js +7 -7
- package/lib/bpmn-elements/presets/Task/subProcess.js +2 -2
- package/lib/dynamic-group/index.d.ts +11 -5
- package/lib/dynamic-group/index.js +125 -23
- package/lib/dynamic-group/model.d.ts +6 -1
- package/lib/dynamic-group/model.js +14 -8
- package/lib/dynamic-group/node.d.ts +13 -1
- package/lib/dynamic-group/node.js +135 -19
- package/lib/tools/label/index.js +2 -2
- package/package.json +3 -3
- package/src/dynamic-group/index.ts +146 -3
- package/src/dynamic-group/model.ts +18 -7
- package/src/dynamic-group/node.ts +137 -68
- package/stats.html +1 -1
|
@@ -339,6 +339,72 @@ export class DynamicGroup {
|
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
+
onNodeMove = ({
|
|
343
|
+
deltaX,
|
|
344
|
+
deltaY,
|
|
345
|
+
data,
|
|
346
|
+
}: Omit<CallbackArgs<'node:mousemove'>, 'e' | 'position'>) => {
|
|
347
|
+
const { id, x, y, properties } = data
|
|
348
|
+
if (!properties) {
|
|
349
|
+
return
|
|
350
|
+
}
|
|
351
|
+
const { width, height } = properties
|
|
352
|
+
const groupId = this.nodeGroupMap.get(id)
|
|
353
|
+
if (!groupId) {
|
|
354
|
+
return
|
|
355
|
+
}
|
|
356
|
+
const groupModel = this.lf.getNodeModelById(
|
|
357
|
+
groupId,
|
|
358
|
+
) as DynamicGroupNodeModel
|
|
359
|
+
|
|
360
|
+
if (!groupModel || !groupModel.isRestrict || !groupModel.autoResize) {
|
|
361
|
+
return
|
|
362
|
+
}
|
|
363
|
+
// 当父节点isRestrict=true & autoResize=true
|
|
364
|
+
// 子节点在父节点中移动时,父节点会自动调整大小
|
|
365
|
+
|
|
366
|
+
// step1: 计算出当前child的bounds
|
|
367
|
+
const newX = x + deltaX / 2
|
|
368
|
+
const newY = y + deltaY / 2
|
|
369
|
+
const minX = newX - width! / 2
|
|
370
|
+
const minY = newY - height! / 2
|
|
371
|
+
const maxX = newX + width! / 2
|
|
372
|
+
const maxY = newY + height! / 2
|
|
373
|
+
// step2:比较当前child.bounds与parent.bounds的差异,比如child.minX<parent.minX,那么parent.minX=child.minX
|
|
374
|
+
let hasChange = false
|
|
375
|
+
const groupBounds = groupModel.getBounds()
|
|
376
|
+
const newGroupBounds = Object.assign({}, groupBounds)
|
|
377
|
+
if (minX < newGroupBounds.minX) {
|
|
378
|
+
newGroupBounds.minX = minX
|
|
379
|
+
hasChange = true
|
|
380
|
+
}
|
|
381
|
+
if (minY < newGroupBounds.minY) {
|
|
382
|
+
newGroupBounds.minY = minY
|
|
383
|
+
hasChange = true
|
|
384
|
+
}
|
|
385
|
+
if (maxX > newGroupBounds.maxX) {
|
|
386
|
+
newGroupBounds.maxX = maxX
|
|
387
|
+
hasChange = true
|
|
388
|
+
}
|
|
389
|
+
if (maxY > newGroupBounds.maxY) {
|
|
390
|
+
newGroupBounds.maxY = maxY
|
|
391
|
+
hasChange = true
|
|
392
|
+
}
|
|
393
|
+
if (!hasChange) {
|
|
394
|
+
return
|
|
395
|
+
}
|
|
396
|
+
// step3: 根据当前parent.bounds去计算出最新的x、y、width、height
|
|
397
|
+
const newGroupX =
|
|
398
|
+
newGroupBounds.minX + (newGroupBounds.maxX - newGroupBounds.minX) / 2
|
|
399
|
+
const newGroupY =
|
|
400
|
+
newGroupBounds.minY + (newGroupBounds.maxY - newGroupBounds.minY) / 2
|
|
401
|
+
const newGroupWidth = newGroupBounds.maxX - newGroupBounds.minX
|
|
402
|
+
const newGroupHeight = newGroupBounds.maxY - newGroupBounds.minY
|
|
403
|
+
groupModel.moveTo(newGroupX, newGroupY)
|
|
404
|
+
groupModel.width = newGroupWidth
|
|
405
|
+
groupModel.height = newGroupHeight
|
|
406
|
+
}
|
|
407
|
+
|
|
342
408
|
onGraphRendered = ({ data }: CallbackArgs<'graph:rendered'>) => {
|
|
343
409
|
console.log('data', data)
|
|
344
410
|
forEach(data.nodes, (node) => {
|
|
@@ -451,6 +517,56 @@ export class DynamicGroup {
|
|
|
451
517
|
})
|
|
452
518
|
}
|
|
453
519
|
|
|
520
|
+
/**
|
|
521
|
+
* 检测group:resize后的bounds是否会小于children的bounds
|
|
522
|
+
* 限制group进行resize时不能小于内部的占地面积
|
|
523
|
+
* @param groupModel
|
|
524
|
+
* @param deltaX
|
|
525
|
+
* @param deltaY
|
|
526
|
+
* @param newWidth
|
|
527
|
+
* @param newHeight
|
|
528
|
+
*/
|
|
529
|
+
checkGroupBoundsWithChildren(
|
|
530
|
+
groupModel: DynamicGroupNodeModel,
|
|
531
|
+
deltaX: number,
|
|
532
|
+
deltaY: number,
|
|
533
|
+
newWidth: number,
|
|
534
|
+
newHeight: number,
|
|
535
|
+
) {
|
|
536
|
+
if (groupModel.children) {
|
|
537
|
+
const { children, x, y } = groupModel
|
|
538
|
+
// 根据deltaX和deltaY计算出当前model的bounds
|
|
539
|
+
const newX = x + deltaX / 2
|
|
540
|
+
const newY = y + deltaY / 2
|
|
541
|
+
const groupMinX = newX - newWidth / 2
|
|
542
|
+
const groupMinY = newY - newHeight / 2
|
|
543
|
+
const groupMaxX = newX + newWidth / 2
|
|
544
|
+
const groupMaxY = newY + newHeight / 2
|
|
545
|
+
|
|
546
|
+
const childrenArray = Array.from(children)
|
|
547
|
+
for (let i = 0; i < childrenArray.length; i++) {
|
|
548
|
+
const childId = childrenArray[i]
|
|
549
|
+
const child = this.lf.getNodeModelById(childId)
|
|
550
|
+
if (!child) {
|
|
551
|
+
continue
|
|
552
|
+
}
|
|
553
|
+
const childBounds = child.getBounds()
|
|
554
|
+
const { minX, minY, maxX, maxY } = childBounds
|
|
555
|
+
// parent:resize后的bounds不能小于child:bounds,否则阻止其resize
|
|
556
|
+
const canResize =
|
|
557
|
+
groupMinX <= minX &&
|
|
558
|
+
groupMinY <= minY &&
|
|
559
|
+
groupMaxX >= maxX &&
|
|
560
|
+
groupMaxY >= maxY
|
|
561
|
+
if (!canResize) {
|
|
562
|
+
return false
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
return true
|
|
568
|
+
}
|
|
569
|
+
|
|
454
570
|
/**
|
|
455
571
|
* Group 插件的初始化方法
|
|
456
572
|
* TODO:1. 待讨论,可能之前插件分类是有意义的 components, material, tools
|
|
@@ -487,19 +603,45 @@ export class DynamicGroup {
|
|
|
487
603
|
) as DynamicGroupNodeModel
|
|
488
604
|
|
|
489
605
|
if (groupModel && groupModel.isRestrict) {
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
606
|
+
if (groupModel.autoResize) {
|
|
607
|
+
// 子节点在父节点中移动时,父节点会自动调整大小
|
|
608
|
+
// 在node:mousemove中进行父节点的调整
|
|
609
|
+
return true
|
|
610
|
+
} else {
|
|
611
|
+
// 如果移动的节点存在于某个分组中,且这个分组禁止子节点移出去
|
|
612
|
+
const groupBounds = groupModel.getBounds()
|
|
613
|
+
return isAllowMoveTo(groupBounds, model, deltaX, deltaY)
|
|
614
|
+
}
|
|
493
615
|
}
|
|
494
616
|
|
|
495
617
|
return true
|
|
496
618
|
})
|
|
619
|
+
|
|
620
|
+
// https://github.com/didi/LogicFlow/issues/1442
|
|
621
|
+
// https://github.com/didi/LogicFlow/issues/937
|
|
622
|
+
// 添加分组节点resize规则
|
|
623
|
+
// isRestrict限制模式下,当前model resize时不能小于children的占地面积
|
|
624
|
+
// 并且在isRestrict限制模式下,transformWidthContainer即使设置为true,也无效
|
|
625
|
+
graphModel.addNodeResizeRules((model, deltaX, deltaY, width, height) => {
|
|
626
|
+
if (model.isGroup && model.isRestrict) {
|
|
627
|
+
return this.checkGroupBoundsWithChildren(
|
|
628
|
+
model as DynamicGroupNodeModel,
|
|
629
|
+
deltaX,
|
|
630
|
+
deltaY,
|
|
631
|
+
width,
|
|
632
|
+
height,
|
|
633
|
+
)
|
|
634
|
+
}
|
|
635
|
+
return true
|
|
636
|
+
})
|
|
637
|
+
|
|
497
638
|
graphModel.dynamicGroup = this
|
|
498
639
|
|
|
499
640
|
lf.on('node:add,node:drop,node:dnd-add', this.addNodeToGroup)
|
|
500
641
|
lf.on('node:delete', this.removeNodeFromGroup)
|
|
501
642
|
lf.on('node:drag,node:dnd-drag', this.setActiveGroup)
|
|
502
643
|
lf.on('node:click', this.onNodeSelect)
|
|
644
|
+
lf.on('node:mousemove', this.onNodeMove)
|
|
503
645
|
lf.on('graph:rendered', this.onGraphRendered)
|
|
504
646
|
|
|
505
647
|
lf.on('graph:updated', ({ data }) => console.log('data', data))
|
|
@@ -568,6 +710,7 @@ export class DynamicGroup {
|
|
|
568
710
|
this.lf.off('node:delete', this.removeNodeFromGroup)
|
|
569
711
|
this.lf.off('node:drag,node:dnd-drag', this.setActiveGroup)
|
|
570
712
|
this.lf.off('node:click', this.onNodeSelect)
|
|
713
|
+
this.lf.off('node:mousemove', this.onNodeMove)
|
|
571
714
|
this.lf.off('graph:rendered', this.onGraphRendered)
|
|
572
715
|
|
|
573
716
|
// 还原 lf.addElements 方法?
|
|
@@ -49,6 +49,11 @@ export type IGroupNodeProperties = {
|
|
|
49
49
|
// expandWidth?: number
|
|
50
50
|
// expandHeight?: number
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* 缩放或旋转容器时,是否缩放或旋转组内节点
|
|
54
|
+
*/
|
|
55
|
+
transformWithContainer?: boolean
|
|
56
|
+
|
|
52
57
|
/**
|
|
53
58
|
* 当前分组元素的 zIndex
|
|
54
59
|
*/
|
|
@@ -79,6 +84,8 @@ export class DynamicGroupNodeModel extends RectNodeModel<IGroupNodeProperties> {
|
|
|
79
84
|
children!: Set<string>
|
|
80
85
|
// 是否限制组内节点的移动范围。默认不限制 TODO: 完善该功能
|
|
81
86
|
isRestrict: boolean = false
|
|
87
|
+
// isRestrict 模式启用时,如果同时设置 autoResize 为 true,那么子节点在父节点中移动时,父节点会自动调整大小
|
|
88
|
+
autoResize: boolean = false
|
|
82
89
|
// 分组节点是否可以折叠
|
|
83
90
|
collapsible: boolean = true
|
|
84
91
|
|
|
@@ -94,7 +101,7 @@ export class DynamicGroupNodeModel extends RectNodeModel<IGroupNodeProperties> {
|
|
|
94
101
|
// 当前分组是否在可添加状态 - 实时状态
|
|
95
102
|
@observable groupAddable: boolean = false
|
|
96
103
|
// 缩放或旋转容器时,是否缩放或旋转组内节点
|
|
97
|
-
@observable
|
|
104
|
+
@observable transformWithContainer: boolean = false
|
|
98
105
|
childrenLastCollapseStateDict: Map<string, boolean> = new Map()
|
|
99
106
|
|
|
100
107
|
constructor(data: NodeConfig<IGroupNodeProperties>, graphModel: GraphModel) {
|
|
@@ -121,6 +128,7 @@ export class DynamicGroupNodeModel extends RectNodeModel<IGroupNodeProperties> {
|
|
|
121
128
|
isRestrict,
|
|
122
129
|
autoResize,
|
|
123
130
|
autoToFront,
|
|
131
|
+
transformWithContainer,
|
|
124
132
|
} = data.properties ?? {}
|
|
125
133
|
|
|
126
134
|
this.children = children ? new Set(children) : new Set()
|
|
@@ -139,6 +147,7 @@ export class DynamicGroupNodeModel extends RectNodeModel<IGroupNodeProperties> {
|
|
|
139
147
|
this.collapsedHeight = collapsedHeight ?? DEFAULT_GROUP_COLLAPSE_HEIGHT
|
|
140
148
|
|
|
141
149
|
this.isRestrict = isRestrict ?? false
|
|
150
|
+
this.transformWithContainer = transformWithContainer ?? false
|
|
142
151
|
this.autoResize = autoResize ?? false
|
|
143
152
|
this.collapsible = collapsible ?? true
|
|
144
153
|
this.autoToFront = autoToFront ?? false
|
|
@@ -150,11 +159,6 @@ export class DynamicGroupNodeModel extends RectNodeModel<IGroupNodeProperties> {
|
|
|
150
159
|
|
|
151
160
|
setAttributes() {
|
|
152
161
|
super.setAttributes()
|
|
153
|
-
|
|
154
|
-
// 初始化时,如果 this.isCollapsed 为 true,则主动触发一次折叠操作
|
|
155
|
-
if (this.isCollapsed) {
|
|
156
|
-
this.toggleCollapse(true)
|
|
157
|
-
}
|
|
158
162
|
}
|
|
159
163
|
|
|
160
164
|
getData(): NodeData {
|
|
@@ -195,8 +199,15 @@ export class DynamicGroupNodeModel extends RectNodeModel<IGroupNodeProperties> {
|
|
|
195
199
|
isCollapsed,
|
|
196
200
|
} = this
|
|
197
201
|
if (isCollapsed) {
|
|
202
|
+
// 如果当前是折叠模式
|
|
203
|
+
// 存入history的时候,将坐标恢复到未折叠前的坐标数据
|
|
204
|
+
// 因为拿出history数据的时候,会触发collapse()进行坐标的折叠计算
|
|
198
205
|
data.x = x + expandWidth / 2 - collapsedWidth / 2
|
|
199
206
|
data.y = y + expandHeight / 2 - collapsedHeight / 2
|
|
207
|
+
if (data.text) {
|
|
208
|
+
data.text.x = data.text.x + expandWidth / 2 - collapsedWidth / 2
|
|
209
|
+
data.text.y = data.text.y + expandHeight / 2 - collapsedHeight / 2
|
|
210
|
+
}
|
|
200
211
|
}
|
|
201
212
|
return data
|
|
202
213
|
}
|
|
@@ -429,8 +440,8 @@ export class DynamicGroupNodeModel extends RectNodeModel<IGroupNodeProperties> {
|
|
|
429
440
|
* TODO: 如何重写该方法呢?
|
|
430
441
|
* @param _nodeData
|
|
431
442
|
*/
|
|
443
|
+
// eslint-disable-next-line
|
|
432
444
|
isAllowAppendIn(_nodeData: NodeData) {
|
|
433
|
-
console.info('_nodeData', _nodeData)
|
|
434
445
|
// TODO: 此处使用 this.properties.groupAddable 还是 this.groupAddable
|
|
435
446
|
// this.groupAddable 是否存在更新不及时的问题
|
|
436
447
|
return true
|
|
@@ -3,6 +3,7 @@ import LogicFlow, {
|
|
|
3
3
|
h,
|
|
4
4
|
RectNode,
|
|
5
5
|
handleResize,
|
|
6
|
+
CallbackArgs,
|
|
6
7
|
} from '@logicflow/core'
|
|
7
8
|
import { forEach } from 'lodash-es'
|
|
8
9
|
import { DynamicGroupNodeModel } from './model'
|
|
@@ -18,83 +19,151 @@ export interface IDynamicGroupNodeProps {
|
|
|
18
19
|
export class DynamicGroupNode<
|
|
19
20
|
P extends IDynamicGroupNodeProps = IDynamicGroupNodeProps,
|
|
20
21
|
> extends RectNode<P> {
|
|
21
|
-
|
|
22
|
-
super.componentDidMount()
|
|
22
|
+
childrenPositionMap: Map<string, Position> = new Map()
|
|
23
23
|
|
|
24
|
+
onNodeRotate = ({
|
|
25
|
+
model,
|
|
26
|
+
}: Omit<CallbackArgs<'node:rotate'>, 'e' | 'position'>) => {
|
|
24
27
|
const { model: curGroup, graphModel } = this.props
|
|
25
|
-
const {
|
|
26
|
-
|
|
27
|
-
|
|
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)
|
|
28
44
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const child = graphModel.getNodeModelById(childId)
|
|
36
|
-
|
|
37
|
-
if (child) {
|
|
38
|
-
let point: Position = { x: child.x, y: child.y }
|
|
39
|
-
if (childrenPositionMap.has(child.id)) {
|
|
40
|
-
point = childrenPositionMap.get(child.id)!
|
|
41
|
-
} else {
|
|
42
|
-
childrenPositionMap.set(child.id, point)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// 弧度转角度
|
|
46
|
-
let theta = model.rotate * (180 / Math.PI)
|
|
47
|
-
if (theta < 0) theta += 360
|
|
48
|
-
const radian = theta * (Math.PI / 180)
|
|
49
|
-
|
|
50
|
-
const newPoint = rotatePointAroundCenter(point, center, radian)
|
|
51
|
-
|
|
52
|
-
child.moveTo(newPoint.x, newPoint.y)
|
|
53
|
-
child.rotate = model.rotate
|
|
45
|
+
if (child) {
|
|
46
|
+
let point: Position = { x: child.x, y: child.y }
|
|
47
|
+
if (childrenPositionMap.has(child.id)) {
|
|
48
|
+
point = childrenPositionMap.get(child.id)!
|
|
49
|
+
} else {
|
|
50
|
+
childrenPositionMap.set(child.id, point)
|
|
54
51
|
}
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
|
-
})
|
|
58
52
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
53
|
+
// 弧度转角度
|
|
54
|
+
let theta = model.rotate * (180 / Math.PI)
|
|
55
|
+
if (theta < 0) theta += 360
|
|
56
|
+
const radian = theta * (Math.PI / 180)
|
|
57
|
+
|
|
58
|
+
const newPoint = rotatePointAroundCenter(point, center, radian)
|
|
59
|
+
|
|
60
|
+
child.moveTo(newPoint.x, newPoint.y)
|
|
61
|
+
child.rotate = model.rotate
|
|
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: () => {},
|
|
85
103
|
})
|
|
86
104
|
}
|
|
87
|
-
}
|
|
88
|
-
|
|
105
|
+
})
|
|
106
|
+
}
|
|
107
|
+
}
|
|
89
108
|
|
|
109
|
+
onNodeMouseMove = ({
|
|
110
|
+
deltaX,
|
|
111
|
+
deltaY,
|
|
112
|
+
data,
|
|
113
|
+
}: Omit<CallbackArgs<'node:mousemove'>, 'e' | 'position'>) => {
|
|
114
|
+
const { model: curGroup, graphModel } = this.props
|
|
115
|
+
const { transformModel } = graphModel
|
|
116
|
+
const { SCALE_X, SCALE_Y } = transformModel
|
|
117
|
+
if (data.id === curGroup.id) {
|
|
118
|
+
const nodeIds = this.getNodesInGroup(curGroup, graphModel)
|
|
119
|
+
// https://github.com/didi/LogicFlow/issues/1914
|
|
120
|
+
// 当调用lf.fitView()时,会改变整体的SCALE_X和SCALE_Y
|
|
121
|
+
// 由于group的mousemove是在drag.ts的this.onDragging()处理的,在onDragging()里面进行SCALE的处理
|
|
122
|
+
// 而"node:mousemove"emit出来跟onDragging()是同时的,也就是emit出来的数据是没有经过SCALE处理的坐标
|
|
123
|
+
// 因此这里需要增加SCALE的处理
|
|
124
|
+
graphModel.moveNodes(nodeIds, deltaX / SCALE_X, deltaY / SCALE_Y, true)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
graphRendered = () => {
|
|
129
|
+
const { model } = this.props
|
|
130
|
+
// 初始化时,如果 this.isCollapsed 为 true,则主动触发一次折叠操作
|
|
131
|
+
if (model.isCollapsed) {
|
|
132
|
+
// https://github.com/didi/LogicFlow/issues/1918
|
|
133
|
+
// 当lf.render({nodes:[{分组节点}, {普通节点}]})时,由于是顺序遍历
|
|
134
|
+
// 会先触发分组Group节点的new Model => toggleCollapse()
|
|
135
|
+
// => 此时在graphModel.elementsModelMap找不到它的children,因为还没初始化,因此无法正确折叠子元素
|
|
136
|
+
// --------------------
|
|
137
|
+
// 当lf.render({nodes:[{普通节点}, {分组节点}]})时,
|
|
138
|
+
// 会先触发普通节点的new Model => graphModel.elementsModelMap.set(id, new Model())
|
|
139
|
+
// 然后再触发分组Group节点的new Model => toggleCollapse() =>
|
|
140
|
+
// 此时在graphModel.elementsModelMap能找到它的children了,因此可以正确折叠子元素
|
|
141
|
+
// --------------------
|
|
142
|
+
// 因此将整个初始化判断是否【主动触发一次折叠操作】放在"graph:rendered"全部渲染完成后再执行
|
|
143
|
+
model.toggleCollapse(true)
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
componentDidMount() {
|
|
148
|
+
super.componentDidMount()
|
|
149
|
+
const { eventCenter } = this.props.graphModel
|
|
150
|
+
// 在 group 旋转时,对组内的所有子节点也进行对应的旋转计算
|
|
151
|
+
eventCenter.on('node:rotate', this.onNodeRotate)
|
|
152
|
+
// 在 group 缩放时,对组内的所有子节点也进行对应的缩放计算
|
|
153
|
+
eventCenter.on('node:resize', this.onNodeResize)
|
|
90
154
|
// 在 group 移动时,对组内的所有子节点也进行对应的移动计算
|
|
91
|
-
eventCenter.on('node:mousemove',
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
155
|
+
eventCenter.on('node:mousemove', this.onNodeMouseMove)
|
|
156
|
+
// 全部渲染完成后,判断是否【主动触发一次折叠操作】
|
|
157
|
+
eventCenter.on('graph:rendered', this.graphRendered)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
componentWillUnmount() {
|
|
161
|
+
super.componentWillUnmount()
|
|
162
|
+
const { eventCenter } = this.props.graphModel
|
|
163
|
+
eventCenter.off('node:rotate', this.onNodeRotate)
|
|
164
|
+
eventCenter.off('node:resize', this.onNodeResize)
|
|
165
|
+
eventCenter.off('node:mousemove', this.onNodeMouseMove)
|
|
166
|
+
eventCenter.off('graph:rendered', this.graphRendered)
|
|
98
167
|
}
|
|
99
168
|
|
|
100
169
|
/**
|