@logicflow/extension 2.0.8 → 2.0.10

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.
@@ -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 transformWidthContainer: boolean = true
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
@@ -195,8 +204,15 @@ export class DynamicGroupNodeModel extends RectNodeModel<IGroupNodeProperties> {
195
204
  isCollapsed,
196
205
  } = this
197
206
  if (isCollapsed) {
207
+ // 如果当前是折叠模式
208
+ // 存入history的时候,将坐标恢复到未折叠前的坐标数据
209
+ // 因为拿出history数据的时候,会触发collapse()进行坐标的折叠计算
198
210
  data.x = x + expandWidth / 2 - collapsedWidth / 2
199
211
  data.y = y + expandHeight / 2 - collapsedHeight / 2
212
+ if (data.text) {
213
+ data.text.x = data.text.x + expandWidth / 2 - collapsedWidth / 2
214
+ data.text.y = data.text.y + expandHeight / 2 - collapsedHeight / 2
215
+ }
200
216
  }
201
217
  return data
202
218
  }
@@ -1,7 +1,11 @@
1
- import LogicFlow, { GraphModel, h, RectNode } from '@logicflow/core'
1
+ import LogicFlow, {
2
+ GraphModel,
3
+ h,
4
+ RectNode,
5
+ handleResize,
6
+ } from '@logicflow/core'
2
7
  import { forEach } from 'lodash-es'
3
8
  import { DynamicGroupNodeModel } from './model'
4
- import { handleResize } from '@logicflow/core/es/util/resize'
5
9
 
6
10
  import Position = LogicFlow.Position
7
11
  import { rotatePointAroundCenter } from '../tools/label/utils'
@@ -24,6 +28,16 @@ export class DynamicGroupNode<
24
28
 
25
29
  // 在 group 旋转时,对组内的所有子节点也进行对应的旋转计算
26
30
  eventCenter.on('node:rotate', ({ model }) => {
31
+ const { transformWithContainer, isRestrict } = this.props.model
32
+ if (!transformWithContainer || isRestrict) {
33
+ // isRestrict限制模式下,当前model resize时不能小于占地面积
34
+ // 由于parent:resize=>child:resize计算复杂,需要根据child:resize的判定结果来递归判断parent能否resize
35
+ // 不符合目前 parent:resize成功后emit事件 -> 触发child:resize 的代码交互模式
36
+ // 因此isRestrict限制模式下不支持联动(parent:resize=>child:resize)
37
+ // 由于transformWidthContainer是控制rotate+resize,为保持transformWidthContainer本来的含义
38
+ // parent:resize=>child:resize不支持,那么parent:rotate=>child:rotate也不支持
39
+ return
40
+ }
27
41
  // DONE: 目前操作是对分组内节点以节点中心旋转节点本身,而按照正常逻辑,应该是以分组中心,旋转节点(跟 Label 旋转操作逻辑一致)
28
42
  if (model.id === curGroup.id) {
29
43
  const center = { x: curGroup.x, y: curGroup.y }
@@ -53,27 +67,81 @@ export class DynamicGroupNode<
53
67
  })
54
68
 
55
69
  // 在 group 缩放时,对组内的所有子节点也进行对应的缩放计算
56
- eventCenter.on('node:resize', ({ deltaX, deltaY, index, model }) => {
57
- // TODO: 目前 Resize 的比例值有问题,导致缩放时,节点会变形,需要修复
58
- if (model.id === curGroup.id) {
59
- forEach(Array.from(curGroup.children), (childId) => {
60
- const child = graphModel.getNodeModelById(childId)
61
- if (child) {
62
- // child.rotate = model.rotate
63
- handleResize({
64
- deltaX,
65
- deltaY,
66
- index,
67
- nodeModel: child,
68
- graphModel,
69
- cancelCallback: () => {},
70
- })
71
- }
72
- })
70
+ eventCenter.on(
71
+ 'node:resize',
72
+ ({ deltaX, deltaY, index, model, preData }) => {
73
+ const { transformWithContainer, isRestrict } = this.props.model
74
+ if (!transformWithContainer || isRestrict) {
75
+ // isRestrict限制模式下,当前model resize时不能小于占地面积
76
+ // 由于parent:resize=>child:resize计算复杂,需要根据child:resize的判定结果来递归判断parent能否resize
77
+ // 不符合目前 parent:resize成功后emit事件 -> 触发child:resize 的代码交互模式
78
+ // 因此isRestrict限制模式下不支持联动(parent:resize=>child:resize)
79
+ return
80
+ }
81
+ if (model.id === curGroup.id) {
82
+ // node:resize是group已经改变width和height后的回调
83
+ // 因此这里一定得用preData(没resize改变width之前的值),而不是data/model
84
+ const { properties } = preData
85
+ const { width: groupWidth, height: groupHeight } = properties || {}
86
+ forEach(Array.from(curGroup.children), (childId) => {
87
+ const child = graphModel.getNodeModelById(childId)
88
+ if (child) {
89
+ // 根据比例去控制缩放dx和dy
90
+ const childDx = (child.width / groupWidth!) * deltaX
91
+ const childDy = (child.height / groupHeight!) * deltaY
92
+
93
+ // child.rotate = model.rotate
94
+ handleResize({
95
+ deltaX: childDx,
96
+ deltaY: childDy,
97
+ index,
98
+ nodeModel: child,
99
+ graphModel,
100
+ cancelCallback: () => {},
101
+ })
102
+ }
103
+ })
104
+ }
105
+ },
106
+ )
107
+
108
+ // 在 group 移动时,对组内的所有子节点也进行对应的移动计算
109
+ eventCenter.on('node:mousemove', ({ deltaX, deltaY, data }) => {
110
+ if (data.id === curGroup.id) {
111
+ const { model: curGroup, graphModel } = this.props
112
+ const nodeIds = this.getNodesInGroup(curGroup, graphModel)
113
+ graphModel.moveNodes(nodeIds, deltaX, deltaY, true)
73
114
  }
74
115
  })
75
116
  }
76
117
 
118
+ /**
119
+ * 获取分组内的节点
120
+ * @param groupModel
121
+ */
122
+ getNodesInGroup(
123
+ groupModel: DynamicGroupNodeModel,
124
+ graphModel: GraphModel,
125
+ ): string[] {
126
+ let nodeIds: string[] = []
127
+ if (groupModel.isGroup) {
128
+ forEach(Array.from(groupModel.children), (nodeId: string) => {
129
+ nodeIds.push(nodeId)
130
+
131
+ const nodeModel = graphModel.getNodeModelById(nodeId)
132
+ if (nodeModel?.isGroup) {
133
+ nodeIds = nodeIds.concat(
134
+ this.getNodesInGroup(
135
+ nodeModel as DynamicGroupNodeModel,
136
+ graphModel,
137
+ ),
138
+ )
139
+ }
140
+ })
141
+ }
142
+ return nodeIds
143
+ }
144
+
77
145
  getResizeControl(): h.JSX.Element | null {
78
146
  const { resizable, isCollapsed } = this.props.model
79
147
  const showResizeControl = resizable && !isCollapsed