function limitNodes()

in packages-ext/recoil-devtools/src/utils/sankey/SankeyGraphLayout.js [89:132]


function limitNodes<N, L>(
  graph: Graph<N, L>,
  nodeLimit: ?number,
  rootNodes: Array<Node<N, L>> = graph.nodes.filter(
    node => node.sourceLinks.length === 0,
  ),
): ?Graph<N, L> {
  if (nodeLimit == null || nodeLimit >= graph.nodes.length) {
    return graph;
  }
  let nodesToAdd = nodeLimit;

  const nodesSet: Set<Node<N, L>> = new Set();
  let nextLinks = rootNodes.flatMap(node =>
    node.targetLinks.concat(node.sourceLinks),
  );
  // $FlowFixMe[incompatible-type-arg] Uncovered while typing recoil-devtools
  const consideredLinks: Set<Link<mixed, mixed>> = new Set(nextLinks);

  function addNode(node) {
    if (!nodesToAdd) {
      return;
    }
    nodesSet.add(node);
    const newLinks = node.targetLinks
      .concat(node.sourceLinks)
      .filter(link => !consideredLinks.has(link));
    newLinks.forEach(link => consideredLinks.add(link));
    nextLinks = nextLinks.concat(newLinks);
    nodesToAdd--;
  }

  while (nodesToAdd && nextLinks.length) {
    sortDesc(nextLinks, link => link.value);
    const link = nextLinks.shift();
    for (const node of [link.target, link.source]) {
      if (node && !nodesSet.has(node)) {
        addNode(node);
      }
    }
  }

  updateVisibility(graph, nodesSet);
}