Skip to content

Commit 6fdeb61

Browse files
fix:优化节点渲染逻辑(未完成)
1 parent 5020a88 commit 6fdeb61

File tree

4 files changed

+380
-371
lines changed

4 files changed

+380
-371
lines changed

lib/flow_chart/dashboard.dart

Lines changed: 101 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,16 @@ const double groupElementSpacing = 20;
2121
/// 节点间默认距离
2222
const int defaultNodeDistance = 50;
2323

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+
2434
class RectangleBounds {
2535
final double width;
2636
final double height;
@@ -64,6 +74,7 @@ class Dashboard extends ChangeNotifier {
6474
this.maximumZoomFactor = 1.8,
6575
this.defaultArrowStyle = ArrowStyle.rectangular,
6676
}) : elements = [],
77+
_allGroupsLayoutData = {},
6778
_dashboardPosition = Offset.zero,
6879
dashboardSize = Size.zero,
6980
gridBackgroundParams = GridBackgroundParams(
@@ -126,6 +137,9 @@ class Dashboard extends ChangeNotifier {
126137
/// The current elements in the dashboard
127138
List<FlowElement> elements;
128139

140+
Map<String, GroupLayoutData> _allGroupsLayoutData = {};
141+
Map<String, GroupLayoutData> get allGroupsLayoutData => _allGroupsLayoutData;
142+
129143
String selectedElement = '';
130144

131145
Offset _dashboardPosition;
@@ -264,11 +278,31 @@ class Dashboard extends ChangeNotifier {
264278
element.setScale(1, gridBackgroundParams.scale);
265279

266280
elements.insert(position ?? elements.length, element);
281+
updateAllGroupsLayoutData();
267282
if (notify) {
268283
notifyListeners();
269284
}
270285
}
271286

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+
272306
// TODO : 优化缩放
273307
void setFullView() {
274308
if (elements.isEmpty) {
@@ -370,8 +404,7 @@ class Dashboard extends ChangeNotifier {
370404
final orderElementBottomHandlerPos =
371405
orderElement.getHandlerPosition(Alignment.bottomCenter);
372406
final sourceEleBottomHandlerPos =
373-
sourceElement?.getHandlerPosition(Alignment.bottomCenter) ??
374-
Offset.zero;
407+
sourceElement.getHandlerPosition(Alignment.bottomCenter);
375408
final elementsDistant =
376409
orderElementBottomHandlerPos.dy - sourceEleBottomHandlerPos.dy;
377410
final orderElementIndex = elements.indexOf(orderElement);
@@ -437,7 +470,7 @@ class Dashboard extends ChangeNotifier {
437470
setSelectedElement(orderElement.id);
438471

439472
List<ConnectionParams> nextElementsConnectionParams = sourceElement.next;
440-
// orderElement.changePosition(Offset(sourceElement.position.dx, sourceElement.position.dy+));
473+
List<String> bottomOfSourceElementIds = getDestElementIds(sourceElement);
441474

442475
List<String> removedConnectDestElementIds = [];
443476
if (nextElementsConnectionParams.isNotEmpty) {
@@ -458,21 +491,14 @@ class Dashboard extends ChangeNotifier {
458491
orderElementBottomHandlerPos.dy - sourceEleBottomHandlerPos.dy;
459492

460493
/// 调整当前组当前节点所在的列后续节点的垂直位置
461-
///addHeight和elementsDistant效果一样
462494
final sourceDy = sourceElement.position.dy;
463495
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));
476502
}
477503
}
478504

@@ -487,19 +513,14 @@ class Dashboard extends ChangeNotifier {
487513
/// 预留判断:
488514
/// 判断source的所在的列最后一个元素是否是整个组内的最后一行,最后一行才需要更新组节点大小
489515
/// 找到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+
}
503524

504525
for (int i = 0; i < elements.length; i++) {
505526
if (elements[i].position.dy >= orderElement.position.dy &&
@@ -537,10 +558,25 @@ class Dashboard extends ChangeNotifier {
537558
}
538559
}
539560

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+
540576
// 判断element是否是组内的最后一行
541577
bool checkElementIsLastRow(
542578
FlowElement element, List<List<FlowElement>> groupRowLayoutData) {
543-
final lastRow = groupRowLayoutData.last;
579+
// final lastRow = groupRowLayoutData.last;
544580
// 最后一行中y坐标最大的元素
545581
FlowElement maxDyElement = groupRowLayoutData.last.reduce((current, next) =>
546582
current.position.dy > next.position.dy ? current : next);
@@ -698,50 +734,57 @@ class Dashboard extends ChangeNotifier {
698734
notifyListeners();
699735
}
700736

701-
// 获取行布局数据
737+
// 获取行布局数据
702738
List<List<FlowElement>> getGroupRowLayoutData(
703739
List<FlowElement> childElements) {
704740
List<List<FlowElement>> groupRowLayoutData = [];
705741

706742
/// 获取所有行数的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();
709747
subElementsOrderDy.sort();
748+
749+
List<List<FlowElement>> rows =
750+
List.generate(subElementsOrderDy.length, (_) => []);
710751
for (int i = 0; i < subElementsOrderDy.length; i++) {
711-
List<FlowElement> rows = [];
712752
for (int j = 0; j < childElements.length; j++) {
713753
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]);
716756
}
717757
}
718758
// 根据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]);
721761
}
722762
return groupRowLayoutData;
723763
}
724764

725-
// 获取列布局数据
765+
// 获取列布局数据
726766
List<List<FlowElement>> getGroupColumnLayoutData(
727767
List<FlowElement> childElements) {
728768
List<List<FlowElement>> groupColumnLayoutData = [];
729769

730770
/// 获取所有列数的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();
733775
subElementsOrderDx.sort();
776+
List<List<FlowElement>> columns =
777+
List.generate(subElementsOrderDx.length, (_) => []);
734778
for (int i = 0; i < subElementsOrderDx.length; i++) {
735-
List<FlowElement> columns = [];
736779
for (int j = 0; j < childElements.length; j++) {
737780
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]);
740783
}
741784
}
742785
// 根据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]);
745788
}
746789
return groupColumnLayoutData;
747790
}
@@ -784,6 +827,7 @@ class Dashboard extends ChangeNotifier {
784827
}
785828
}
786829

830+
//更新被删除节点所在列后面的所有节点视图
787831
void updateLayOutAfterDelElementInGroup(
788832
FlowElement deletedElement,
789833
FlowElement? sourceElement,
@@ -981,6 +1025,7 @@ class Dashboard extends ChangeNotifier {
9811025
/// 移除所有节点
9821026
void removeAllElements({bool notify = true}) {
9831027
elements.clear();
1028+
updateAllGroupsLayoutData();
9841029
if (notify) notifyListeners();
9851030
}
9861031

@@ -1036,6 +1081,7 @@ class Dashboard extends ChangeNotifier {
10361081
loadDashboardData(mapData);
10371082
// 通知监听器更新
10381083
// notifyListeners();
1084+
updateAllGroupsLayoutData();
10391085
}
10401086

10411087
/// 解除一个元素连接
@@ -1160,7 +1206,7 @@ class Dashboard extends ChangeNotifier {
11601206
// 更新布局
11611207
updateLayOutAfterDelElement(removedElement, sourceElement);
11621208
}
1163-
1209+
updateAllGroupsLayoutData();
11641210
if (notify) notifyListeners();
11651211
}
11661212

@@ -1190,7 +1236,6 @@ class Dashboard extends ChangeNotifier {
11901236
removedNextEleBottomHandlerPos.dy - removedEleBottomHandlerPos.dy;
11911237
} else {
11921238
//删除的节点下面没有其他节点,删除后组直接少一列
1193-
print("lastChildElements.length===>${lastChildElements.length}");
11941239
if (lastChildElements.length > 1) {
11951240
final currentGroupElementSpacing = groupElementSpacing * zoomFactor;
11961241
decreaseWidth =
@@ -1210,6 +1255,7 @@ class Dashboard extends ChangeNotifier {
12101255
return false;
12111256
}
12121257
});
1258+
12131259
// 移除当前节点所有的连接
12141260
for (final e in elements) {
12151261
e.next.removeWhere((handlerParams) {
@@ -1226,22 +1272,19 @@ class Dashboard extends ChangeNotifier {
12261272
break;
12271273
}
12281274
}
1229-
print("bottomOfRemovedElements===>${bottomOfRemovedElements}");
1230-
12311275
updateLayOutAfterDelElementInGroup(
12321276
removedElement, sourceElement, bottomOfRemovedElements, decreaseHeight);
12331277

12341278
List<FlowElement> childElements = elements
12351279
.where((ele) => ele.parentId == removedElement.parentId)
12361280
.toList();
12371281
final groupRowLayoutData = getGroupRowLayoutData(childElements.toList());
1238-
final groupColumnLayoutData =
1239-
getGroupColumnLayoutData(childElements.toList());
1282+
// final groupColumnLayoutData =
1283+
// getGroupColumnLayoutData(childElements.toList());
12401284
final diffElementRows =
12411285
groupRowLayoutData.length - lastGroupRowLayoutData.length;
1242-
print("diffElementRows=====>${diffElementRows}");
1243-
final diffElementColumn =
1244-
groupColumnLayoutData.length - lastGroupColumnLayoutData.length;
1286+
// final diffElementColumn =
1287+
// groupColumnLayoutData.length - lastGroupColumnLayoutData.length;
12451288
if (sourceElement != null) {
12461289
final sourceElementBottomHandlerPos =
12471290
sourceElement.getHandlerPosition(Alignment.bottomCenter);
@@ -1287,6 +1330,7 @@ class Dashboard extends ChangeNotifier {
12871330
}
12881331
}
12891332
}
1333+
updateAllGroupsLayoutData();
12901334
if (notify) notifyListeners();
12911335
}
12921336

@@ -1353,6 +1397,7 @@ class Dashboard extends ChangeNotifier {
13531397
(handlerParams) => handlerParams.destElementId == elementId,
13541398
);
13551399
}
1400+
updateAllGroupsLayoutData();
13561401
if (notify) notifyListeners();
13571402
return found;
13581403
}
@@ -1371,7 +1416,6 @@ class Dashboard extends ChangeNotifier {
13711416
if (factor < minimumZoomFactor) {
13721417
factor = minimumZoomFactor;
13731418
}
1374-
print("=setZoomFactor=======>factor:${factor}");
13751419
if (factor > maximumZoomFactor) {
13761420
factor = maximumZoomFactor;
13771421
}
@@ -1547,7 +1591,7 @@ class Dashboard extends ChangeNotifier {
15471591
elements
15481592
..clear()
15491593
..addAll(loadedElements);
1550-
1594+
updateAllGroupsLayoutData();
15511595
setFullView();
15521596
}
15531597
}

0 commit comments

Comments
 (0)