doLayout method

  1. @override
void doLayout(
  1. Context context,
  2. Graph graph,
  3. num width,
  4. num height,
)
override

Implementation

@override
void doLayout(Context context, Graph graph, num width, num height) {
  var nodes = graph.nodes;
  int nodeCount = nodes.length;
  if (nodeCount == 0) {
    onLayoutEnd();
    return;
  }
  _begin = [begin[0].convert(width), begin[1].convert(height)];
  if (nodeCount == 1) {
    nodes[0].x = _begin[0];
    nodes[0].y = _begin[1];
    onLayoutEnd();
    return;
  }

  List<GraphNode> layoutNodes = [...nodes];
  Map<String, int> nodeIdxMap = {};
  for (int i = 0; i < layoutNodes.length; i++) {
    nodeIdxMap[layoutNodes[i].id] = i;
  }
  sortNode(graph, layoutNodes);

  ///计算 row col
  _computeRowAndCol(nodeCount, width, height);

  ///修正 row col
  if (cols! * rows! > _cells) {
    int sm = _small(null)!;
    int lg = _large(null)!;
    if ((sm - 1) * lg >= _cells) {
      _small(sm - 1);
    } else if ((lg - 1) * sm >= _cells) {
      _large(lg - 1);
    }
  } else {
    while (cols! * rows! < _cells) {
      int sm = _small(null)!;
      int lg = _large(null)!;
      if ((lg + 1) * sm >= _cells) {
        _large(lg + 1);
      } else {
        _small(sm + 1);
      }
    }
  }

  ///计算单元格大小
  _cellWidth = width / cols!;
  _cellHeight = height / rows!;
  if (condense) {
    _cellWidth = 0;
    _cellHeight = 0;
  }

  // 防重叠处理
  if (preventOverlap || nodeSpaceFun != null) {
    Fun1<GraphNode, num> spaceFun = nodeSpaceFun ?? (a) => 10;
    Fun1<GraphNode, Size> nodeSizeFun = sizeFun ?? (a) => const Size.square(15);
    for (var node in layoutNodes) {
      Size res = jsOr(nodeSizeFun.call(node), const Size.square(15));
      num nodeW;
      num nodeH;
      nodeW = res.width;
      nodeH = res.height;
      num p = spaceFun.call(node);
      var w = nodeW + p;
      var h = nodeH + p;
      _cellWidth = m.max(_cellWidth, w);
      _cellHeight = m.max(_cellHeight, h);
    }
  }

  _row = 0;
  _col = 0;
  _id2manPos = {};

  for (int i = 0; i < layoutNodes.length; i++) {
    var node = layoutNodes[i];
    m.Point<int>? rcPos;

    ///固定位置处理
    if (positionFun != null) {
      rcPos = positionFun!.call(node, rows!, cols!);
    }
    if (rcPos != null) {
      _InnerPos pos = _InnerPos(rcPos.x, rcPos.y);
      _id2manPos[node.id] = pos;
      _setUsed(pos.row, pos.col);
    }
    _computePosition(node);
  }
  onLayoutEnd();
}