iterate method

bool iterate()

Implementation

bool iterate() {
  // Initially assume this layout is stable.
  var isStable = true;

  // The displacement of each node.
  final nodeDisplacement = Map.fromEntries(
      graph.adjacencyList.keys.map((node) => MapEntry(node, Vector2.zero())));

  // Calculate repulsive forces.
  for (final node in graph.adjacencyList.keys) {
    // Iterate over every _other_ node in the graph.
    for (final otherNode
        in graph.adjacencyList.keys.where((other) => other != node)) {
      final delta = nodeLayout[node]! - nodeLayout[otherNode]!;
      nodeDisplacement[node]!.add(delta.normalized() * _f_r(delta.length));
    }
  }

  // Calculate attractive forces.
  for (final edge in graph.edgeList) {
    final delta = nodeLayout[edge.left]! - nodeLayout[edge.right]!;
    nodeDisplacement[edge.left]!.sub(delta.normalized() * _f_a(delta.length));
    nodeDisplacement[edge.right]!
        .add(delta.normalized() * _f_a(delta.length));
  }

  for (final node in graph.adjacencyList.keys) {
    nodeLayout.update(node, (position) {
      final positionChange = nodeDisplacement[node]!.normalized() *
          min(nodeDisplacement[node]!.length, t);
      final newPosition = position + positionChange;

      clampNodeVector(newPosition);

      // If the position of this node changes too much, the layout is unstable.
      isStable = isStable && positionChange.length < stableThreshold;

      return newPosition;
    });
  }

  t *= tDecay;

  return isStable;
}