@@ -21,6 +21,16 @@ const double groupElementSpacing = 20;
21
21
/// 节点间默认距离
22
22
const int defaultNodeDistance = 50 ;
23
23
24
+ class GroupLayoutData {
25
+ final String id;
26
+ final List <List <FlowElement >> columnsLayoutData;
27
+ final List <List <FlowElement >> rowsLayoutData;
28
+ GroupLayoutData (
29
+ {required this .id,
30
+ required this .columnsLayoutData,
31
+ required this .rowsLayoutData});
32
+ }
33
+
24
34
class RectangleBounds {
25
35
final double width;
26
36
final double height;
@@ -64,6 +74,7 @@ class Dashboard extends ChangeNotifier {
64
74
this .maximumZoomFactor = 1.8 ,
65
75
this .defaultArrowStyle = ArrowStyle .rectangular,
66
76
}) : elements = [],
77
+ _allGroupsLayoutData = {},
67
78
_dashboardPosition = Offset .zero,
68
79
dashboardSize = Size .zero,
69
80
gridBackgroundParams = GridBackgroundParams (
@@ -126,6 +137,9 @@ class Dashboard extends ChangeNotifier {
126
137
/// The current elements in the dashboard
127
138
List <FlowElement > elements;
128
139
140
+ Map <String , GroupLayoutData > _allGroupsLayoutData = {};
141
+ Map <String , GroupLayoutData > get allGroupsLayoutData => _allGroupsLayoutData;
142
+
129
143
String selectedElement = '' ;
130
144
131
145
Offset _dashboardPosition;
@@ -264,11 +278,31 @@ class Dashboard extends ChangeNotifier {
264
278
element.setScale (1 , gridBackgroundParams.scale);
265
279
266
280
elements.insert (position ?? elements.length, element);
281
+ updateAllGroupsLayoutData ();
267
282
if (notify) {
268
283
notifyListeners ();
269
284
}
270
285
}
271
286
287
+ void updateAllGroupsLayoutData () {
288
+ Future .microtask (() {
289
+ elements
290
+ .where ((element) => element.taskType == TaskType .group)
291
+ .map ((groupElement) {
292
+ final childElements = elements
293
+ .where ((element) => element.parentId == groupElement.id)
294
+ .toList ();
295
+ final groupLayoutData = GroupLayoutData (
296
+ id: groupElement.id,
297
+ columnsLayoutData: getGroupColumnLayoutData (childElements),
298
+ rowsLayoutData: getGroupRowLayoutData (childElements),
299
+ );
300
+ _allGroupsLayoutData[groupElement.id] = groupLayoutData;
301
+ }).toList ();
302
+ notifyListeners ();
303
+ });
304
+ }
305
+
272
306
// TODO : 优化缩放
273
307
void setFullView () {
274
308
if (elements.isEmpty) {
@@ -370,8 +404,7 @@ class Dashboard extends ChangeNotifier {
370
404
final orderElementBottomHandlerPos =
371
405
orderElement.getHandlerPosition (Alignment .bottomCenter);
372
406
final sourceEleBottomHandlerPos =
373
- sourceElement? .getHandlerPosition (Alignment .bottomCenter) ??
374
- Offset .zero;
407
+ sourceElement.getHandlerPosition (Alignment .bottomCenter);
375
408
final elementsDistant =
376
409
orderElementBottomHandlerPos.dy - sourceEleBottomHandlerPos.dy;
377
410
final orderElementIndex = elements.indexOf (orderElement);
@@ -437,7 +470,7 @@ class Dashboard extends ChangeNotifier {
437
470
setSelectedElement (orderElement.id);
438
471
439
472
List <ConnectionParams > nextElementsConnectionParams = sourceElement.next;
440
- // orderElement.changePosition(Offset( sourceElement.position.dx, sourceElement.position.dy+) );
473
+ List < String > bottomOfSourceElementIds = getDestElementIds ( sourceElement);
441
474
442
475
List <String > removedConnectDestElementIds = [];
443
476
if (nextElementsConnectionParams.isNotEmpty) {
@@ -458,21 +491,14 @@ class Dashboard extends ChangeNotifier {
458
491
orderElementBottomHandlerPos.dy - sourceEleBottomHandlerPos.dy;
459
492
460
493
/// 调整当前组当前节点所在的列后续节点的垂直位置
461
- ///addHeight和elementsDistant效果一样
462
494
final sourceDy = sourceElement.position.dy;
463
495
final childElements =
464
- elements.where ((el) => el.parentId == groupElement.id);
465
- final groupColumnLayoutData =
466
- getGroupColumnLayoutData (childElements.toList ());
467
- for (int i = 0 ; i < elements.length; i++ ) {
468
- final isSameColumn = checkElementIsInColumn (elements[i].position.dx,
469
- orderElement.position.dx, groupColumnLayoutData);
470
- if (elements[i].position.dy > sourceDy.toDouble () &&
471
- sourceElement.parentId == elements[i].parentId &&
472
- elements[i].id != orderElement.id &&
473
- isSameColumn) {
474
- elements[i].changePosition (Offset (
475
- elements[i].position.dx, elements[i].position.dy + addHeight));
496
+ elements.where ((el) => el.parentId == groupElement.id).toList ();
497
+ for (int i = 0 ; i < bottomOfSourceElementIds.length; i++ ) {
498
+ final destElement = findElementById (bottomOfSourceElementIds[i])! ;
499
+ if ((destElement.position.dy > sourceDy.toDouble ())) {
500
+ destElement.changePosition (Offset (
501
+ destElement.position.dx, destElement.position.dy + addHeight));
476
502
}
477
503
}
478
504
@@ -487,19 +513,14 @@ class Dashboard extends ChangeNotifier {
487
513
/// 预留判断:
488
514
/// 判断source的所在的列最后一个元素是否是整个组内的最后一行,最后一行才需要更新组节点大小
489
515
/// 找到source所在列的最后一个元素
490
- // FlowElement? sourceColumnLastElement;
491
- // for (List<FlowElement> columnElements in groupColumnLayoutData) {
492
- // if (columnElements.first.position.dx == sourceElement.position.dx) {
493
- // sourceColumnLastElement = columnElements.last;
494
- // break;
495
- // }
496
- // }
497
- // bool isAddFromLastRow = sourceColumnLastElement == null
498
- // ? false
499
- // : checkElementIsLastRow(sourceColumnLastElement, groupRowLayoutData);
500
- // if (isAddFromLastRow) {
501
- groupElement.size = newGroupElementSize;
502
- // }
516
+ FlowElement ? sourceColumnLastElement =
517
+ findElementById (bottomOfSourceElementIds.last);
518
+ bool elementIsLastRow = sourceColumnLastElement == null
519
+ ? false
520
+ : checkElementIsLastRow (sourceColumnLastElement, groupRowLayoutData);
521
+ if (elementIsLastRow) {
522
+ groupElement.size = newGroupElementSize;
523
+ }
503
524
504
525
for (int i = 0 ; i < elements.length; i++ ) {
505
526
if (elements[i].position.dy >= orderElement.position.dy &&
@@ -537,10 +558,25 @@ class Dashboard extends ChangeNotifier {
537
558
}
538
559
}
539
560
561
+ // 获取sourceElement连线下面的所有节点Id
562
+ List <String > getDestElementIds (FlowElement sourceElement) {
563
+ List <String > destElementIds = [];
564
+ for (int i = 0 ; i < sourceElement.next.length; i++ ) {
565
+ final destElementId = sourceElement.next[i].destElementId;
566
+ destElementIds.add (destElementId);
567
+ final destElement = findElementById (destElementId);
568
+ if (destElement != null ) {
569
+ final nextDestElementIds = getDestElementIds (destElement);
570
+ destElementIds.addAll (nextDestElementIds);
571
+ }
572
+ }
573
+ return destElementIds;
574
+ }
575
+
540
576
// 判断element是否是组内的最后一行
541
577
bool checkElementIsLastRow (
542
578
FlowElement element, List <List <FlowElement >> groupRowLayoutData) {
543
- final lastRow = groupRowLayoutData.last;
579
+ // final lastRow = groupRowLayoutData.last;
544
580
// 最后一行中y坐标最大的元素
545
581
FlowElement maxDyElement = groupRowLayoutData.last.reduce ((current, next) =>
546
582
current.position.dy > next.position.dy ? current : next);
@@ -698,50 +734,57 @@ class Dashboard extends ChangeNotifier {
698
734
notifyListeners ();
699
735
}
700
736
701
- // 获取行布局数据
737
+ // 获取行布局数据
702
738
List <List <FlowElement >> getGroupRowLayoutData (
703
739
List <FlowElement > childElements) {
704
740
List <List <FlowElement >> groupRowLayoutData = [];
705
741
706
742
/// 获取所有行数的Dy
707
- final subElementsOrderDy =
708
- childElements.map ((childEle) => childEle.position.dy).toSet ().toList ();
743
+ final subElementsOrderDy = childElements
744
+ .map ((childEle) => childEle.position.dy.toStringAsFixed (4 ))
745
+ .toSet ()
746
+ .toList ();
709
747
subElementsOrderDy.sort ();
748
+
749
+ List <List <FlowElement >> rows =
750
+ List .generate (subElementsOrderDy.length, (_) => []);
710
751
for (int i = 0 ; i < subElementsOrderDy.length; i++ ) {
711
- List <FlowElement > rows = [];
712
752
for (int j = 0 ; j < childElements.length; j++ ) {
713
753
if (childElements[j].position.dy.toStringAsFixed (4 ) ==
714
- subElementsOrderDy[i]. toDouble (). toStringAsFixed ( 4 ) ) {
715
- rows.add (childElements[j]);
754
+ subElementsOrderDy[i]) {
755
+ rows[i] .add (childElements[j]);
716
756
}
717
757
}
718
758
// 根据dx的值从小到大排序
719
- rows.sort ((a, b) => a.position.dx.compareTo (b.position.dx));
720
- groupRowLayoutData.add (rows);
759
+ rows[i] .sort ((a, b) => a.position.dx.compareTo (b.position.dx));
760
+ groupRowLayoutData.add (rows[i] );
721
761
}
722
762
return groupRowLayoutData;
723
763
}
724
764
725
- // 获取列布局数据
765
+ // 获取列布局数据
726
766
List <List <FlowElement >> getGroupColumnLayoutData (
727
767
List <FlowElement > childElements) {
728
768
List <List <FlowElement >> groupColumnLayoutData = [];
729
769
730
770
/// 获取所有列数的Dx
731
- final subElementsOrderDx =
732
- childElements.map ((childEle) => childEle.position.dx).toSet ().toList ();
771
+ final subElementsOrderDx = childElements
772
+ .map ((childEle) => childEle.position.dx.toStringAsFixed (4 ))
773
+ .toSet ()
774
+ .toList ();
733
775
subElementsOrderDx.sort ();
776
+ List <List <FlowElement >> columns =
777
+ List .generate (subElementsOrderDx.length, (_) => []);
734
778
for (int i = 0 ; i < subElementsOrderDx.length; i++ ) {
735
- List <FlowElement > columns = [];
736
779
for (int j = 0 ; j < childElements.length; j++ ) {
737
780
if (childElements[j].position.dx.toStringAsFixed (4 ) ==
738
- subElementsOrderDx[i]. toDouble (). toStringAsFixed ( 4 ) ) {
739
- columns.add (childElements[j]);
781
+ subElementsOrderDx[i]) {
782
+ columns[i] .add (childElements[j]);
740
783
}
741
784
}
742
785
// 根据dx的值从小到大排序
743
- columns.sort ((a, b) => a.position.dy.compareTo (b.position.dy));
744
- groupColumnLayoutData.add (columns);
786
+ columns[i] .sort ((a, b) => a.position.dy.compareTo (b.position.dy));
787
+ groupColumnLayoutData.add (columns[i] );
745
788
}
746
789
return groupColumnLayoutData;
747
790
}
@@ -784,6 +827,7 @@ class Dashboard extends ChangeNotifier {
784
827
}
785
828
}
786
829
830
+ //更新被删除节点所在列后面的所有节点视图
787
831
void updateLayOutAfterDelElementInGroup (
788
832
FlowElement deletedElement,
789
833
FlowElement ? sourceElement,
@@ -981,6 +1025,7 @@ class Dashboard extends ChangeNotifier {
981
1025
/// 移除所有节点
982
1026
void removeAllElements ({bool notify = true }) {
983
1027
elements.clear ();
1028
+ updateAllGroupsLayoutData ();
984
1029
if (notify) notifyListeners ();
985
1030
}
986
1031
@@ -1036,6 +1081,7 @@ class Dashboard extends ChangeNotifier {
1036
1081
loadDashboardData (mapData);
1037
1082
// 通知监听器更新
1038
1083
// notifyListeners();
1084
+ updateAllGroupsLayoutData ();
1039
1085
}
1040
1086
1041
1087
/// 解除一个元素连接
@@ -1160,7 +1206,7 @@ class Dashboard extends ChangeNotifier {
1160
1206
// 更新布局
1161
1207
updateLayOutAfterDelElement (removedElement, sourceElement);
1162
1208
}
1163
-
1209
+ updateAllGroupsLayoutData ();
1164
1210
if (notify) notifyListeners ();
1165
1211
}
1166
1212
@@ -1190,7 +1236,6 @@ class Dashboard extends ChangeNotifier {
1190
1236
removedNextEleBottomHandlerPos.dy - removedEleBottomHandlerPos.dy;
1191
1237
} else {
1192
1238
//删除的节点下面没有其他节点,删除后组直接少一列
1193
- print ("lastChildElements.length===>${lastChildElements .length }" );
1194
1239
if (lastChildElements.length > 1 ) {
1195
1240
final currentGroupElementSpacing = groupElementSpacing * zoomFactor;
1196
1241
decreaseWidth =
@@ -1210,6 +1255,7 @@ class Dashboard extends ChangeNotifier {
1210
1255
return false ;
1211
1256
}
1212
1257
});
1258
+
1213
1259
// 移除当前节点所有的连接
1214
1260
for (final e in elements) {
1215
1261
e.next.removeWhere ((handlerParams) {
@@ -1226,22 +1272,19 @@ class Dashboard extends ChangeNotifier {
1226
1272
break ;
1227
1273
}
1228
1274
}
1229
- print ("bottomOfRemovedElements===>${bottomOfRemovedElements }" );
1230
-
1231
1275
updateLayOutAfterDelElementInGroup (
1232
1276
removedElement, sourceElement, bottomOfRemovedElements, decreaseHeight);
1233
1277
1234
1278
List <FlowElement > childElements = elements
1235
1279
.where ((ele) => ele.parentId == removedElement.parentId)
1236
1280
.toList ();
1237
1281
final groupRowLayoutData = getGroupRowLayoutData (childElements.toList ());
1238
- final groupColumnLayoutData =
1239
- getGroupColumnLayoutData (childElements.toList ());
1282
+ // final groupColumnLayoutData =
1283
+ // getGroupColumnLayoutData(childElements.toList());
1240
1284
final diffElementRows =
1241
1285
groupRowLayoutData.length - lastGroupRowLayoutData.length;
1242
- print ("diffElementRows=====>${diffElementRows }" );
1243
- final diffElementColumn =
1244
- groupColumnLayoutData.length - lastGroupColumnLayoutData.length;
1286
+ // final diffElementColumn =
1287
+ // groupColumnLayoutData.length - lastGroupColumnLayoutData.length;
1245
1288
if (sourceElement != null ) {
1246
1289
final sourceElementBottomHandlerPos =
1247
1290
sourceElement.getHandlerPosition (Alignment .bottomCenter);
@@ -1287,6 +1330,7 @@ class Dashboard extends ChangeNotifier {
1287
1330
}
1288
1331
}
1289
1332
}
1333
+ updateAllGroupsLayoutData ();
1290
1334
if (notify) notifyListeners ();
1291
1335
}
1292
1336
@@ -1353,6 +1397,7 @@ class Dashboard extends ChangeNotifier {
1353
1397
(handlerParams) => handlerParams.destElementId == elementId,
1354
1398
);
1355
1399
}
1400
+ updateAllGroupsLayoutData ();
1356
1401
if (notify) notifyListeners ();
1357
1402
return found;
1358
1403
}
@@ -1371,7 +1416,6 @@ class Dashboard extends ChangeNotifier {
1371
1416
if (factor < minimumZoomFactor) {
1372
1417
factor = minimumZoomFactor;
1373
1418
}
1374
- print ("=setZoomFactor=======>factor:${factor }" );
1375
1419
if (factor > maximumZoomFactor) {
1376
1420
factor = maximumZoomFactor;
1377
1421
}
@@ -1547,7 +1591,7 @@ class Dashboard extends ChangeNotifier {
1547
1591
elements
1548
1592
..clear ()
1549
1593
..addAll (loadedElements);
1550
-
1594
+ updateAllGroupsLayoutData ();
1551
1595
setFullView ();
1552
1596
}
1553
1597
}
0 commit comments