doLayout method
void
doLayout(
- Context context,
- Graph graph,
- num width,
- num height,
)
override
Implementation
@override
void doLayout(Context context, Graph graph, num width, num height) {
List<GraphNode> nodes = graph.nodes;
int n = graph.nodes.length;
if (n == 0) {
onLayoutEnd();
return;
}
List<num> center = [this.center[0].convert(width), this.center[1].convert(height)];
if (n == 1) {
nodes[0].x = center[0].toDouble();
nodes[0].y = center[1].toDouble();
onLayoutEnd();
return;
}
List<GraphNode> layoutNodes = graph.nodes;
Map<GraphNode, num> sortMap = _innerSortNode(graph, layoutNodes);
///数据分层
var maxValueNode = layoutNodes[0];
var maxValue = sortMap[maxValueNode] ?? 0;
var maxLevelDiff = this.maxLevelDiff ?? maxValue / 4;
Map<int, List<GraphNode>> levelMap = {};
for (var ele in layoutNodes) {
if (ele == maxValueNode) {
continue;
}
var levelIndex = (maxValue - (sortMap[ele] ?? 0)) ~/ maxLevelDiff;
levelIndex + 1;
List<GraphNode> levelList = levelMap[levelIndex] ?? [];
levelMap[levelIndex] = levelList;
levelList.add(ele);
}
///没有存储最大点的值
List<List<GraphNode>> levelList = [];
List<num> keyList = List.from(levelMap.keys);
keyList.sort();
for (var index in keyList) {
levelList.add(levelMap[index]!);
}
///计算每个分层的半径和大小
Map<int, _LevelInfo> infoMap = {};
for (int i = 0; i < levelList.length; i++) {
var level = levelList[i];
_LevelInfo info = infoMap[i] ?? _LevelInfo();
infoMap[i] = info;
var maxSizeNode = findMaxSizeNode(level);
if (i == 0) {
info.r = getNodeSize(maxSizeNode) + getNodeSize(maxValueNode);
info.angleSpace = computeLevelAngleSpace(level, info.r);
} else {
_LevelInfo lastLevel = infoMap[i - 1]!;
info.r = getNodeSize(maxSizeNode) + lastLevel.r + getNodeSize(findMaxSizeNode(levelList[i - 1]));
info.angleSpace = computeLevelAngleSpace(level, info.r);
}
}
///等距
if (equidistant) {
_LevelInfo info = infoMap.values.first;
infoMap.forEach((key, value) {
if (value.r > info.r) {
info = value;
}
});
infoMap.forEach((key, value) {
value.r = info.r;
value.angleSpace = computeLevelAngleSpace(levelList[key], value.r);
});
}
///布局
for (int i = 0; i < levelList.length; i++) {
var level = levelList[i];
var levelInfo = infoMap[i]!;
num rr = levelInfo.r;
num ap = levelInfo.angleSpace;
num startAngle = this.startAngle;
for (int j = 0; j < level.length; j++) {
var node = level[j];
node.x = center[0] + rr * cos(startAngle * Constants.angleUnit);
node.y = center[1] + rr * sin(startAngle * Constants.angleUnit);
num nodeAngle = computeNodeAngle(node, rr);
startAngle += (clockwise ? 1 : -1) * (ap + nodeAngle);
}
}
///最大节点
maxValueNode.x = center[0].toDouble();
maxValueNode.y = center[1].toDouble();
onLayoutEnd();
}