in src/sankeyDiagram.ts [740:781]
public static dfs(nodes: SankeyDiagramNode[], currNode: SankeyDiagramNode, nodesStatuses: SankeyDiagramNodeStatus[], simpleCycles: SankeyDiagramCycleDictionary): void {
nodesStatuses[currNode.label.name].status = SankeyDiagramNodeStatus.Processing;
currNode.links.forEach((link: SankeyDiagramLink) => {
// consider only output links
if (link.source !== currNode) {
return;
}
// get node by output link
let nextNode: SankeyDiagramNode = link.destination;
// move to next not visited node
if (nodesStatuses[nextNode.label.name].status === SankeyDiagramNodeStatus.NotVisited) {
SankeyDiagram.dfs(nodes, nextNode, nodesStatuses, simpleCycles);
}
// if cycle was found
if (nodesStatuses[nextNode.label.name].status === SankeyDiagramNodeStatus.Processing) {
// add item to dictionary
let cycleName: string = nextNode.label.name;
let nameIndex: number = 0;
// get new name if name already used
if (simpleCycles[cycleName]) {
while (simpleCycles[cycleName]) {
cycleName = cycleName + nameIndex++;
}
}
simpleCycles[cycleName] = <SankeyDiagramNode[]>[];
// collect all nodes which were processed in current step
nodes.forEach((node: SankeyDiagramNode) => {
if (nodesStatuses[node.label.name].status === SankeyDiagramNodeStatus.Processing &&
node.links.length > 0 && currNode !== node) { // push current node always as the last
simpleCycles[cycleName].push(node);
}
});
// push current node always as the last
simpleCycles[cycleName].push(currNode);
}
});
nodesStatuses[currNode.label.name].status = SankeyDiagramNodeStatus.Visited;
}