UNPKG

ngraph.hde

Version:

High dimensional embedding of a graph

64 lines (52 loc) 1.74 kB
import createGraph from 'ngraph.graph'; /** * Returns array of first `count` largest connected components * of the `graph` */ export default function findLargestComponent(graph, count) { var nodeIdToComponentId = new Map(); var connectedComponents = []; var lastComponentId = 0; graph.forEachNode(function(node) { if (nodeIdToComponentId.has(node.id)) { // we already seen this cluster. Ignore it. return; } // We found a new connected component: nodeIdToComponentId.set(node.id, lastComponentId); var currentComponent = new Set(); connectedComponents.push(currentComponent); // Let's find what other nodes belong to this component bfs(graph, node.id, otherNode => { currentComponent.add(otherNode); nodeIdToComponentId.set(otherNode, lastComponentId); }); lastComponentId += 1; }); return connectedComponents.sort((a, b) => b.size - a.size) .slice(0, count) .map(largestComponent => { let subGraph = createGraph(); // not the most efficient way, as we iterate over every single link. // This could be improved, for example by performing bfs from the component graph.forEachLink(link => { if (largestComponent.has(link.fromId)) { subGraph.addLink(link.fromId, link.toId); } }) return subGraph; }); } function bfs(graph, startFromNodeId, visitor) { let queue = [startFromNodeId]; let visited = new Set(queue); while (queue.length) { let nodeId = queue.shift(); visitor(nodeId); graph.forEachLinkedNode(nodeId, function(otherNode) { if (visited.has(otherNode.id)) return; queue.push(otherNode.id); visited.add(otherNode.id); }); } }