Skip to content

Instantly share code, notes, and snippets.

@AlphaGit
Last active August 29, 2015 14:00
Show Gist options
  • Save AlphaGit/11074056 to your computer and use it in GitHub Desktop.
Save AlphaGit/11074056 to your computer and use it in GitHub Desktop.
Arrange nodes of an acyclic graph in layers of dependencies
// example as described in http://blog.alphasmanifesto.com/2014/04/12/what-now-graficando-dependencias/
function arrangeInLayers(graph) {
var nodesToVisit = graph.slice(0);
var visitedNodes = [];
var layers = [];
var currentLayer = [];
while (nodesToVisit.length) {
for (var i = nodesToVisit.length - 1; i >= 0; i--) {
var currentNode = nodesToVisit[i];
if (containsAll(visitedNodes, currentNode.previousNodes)) {
currentLayer.push(currentNode);
nodesToVisit.splice(i, 1);
}
}
layers.push(currentLayer);
visitedNodes = visitedNodes.concat(currentLayer);
currentLayer = [];
}
return layers;
}
function containsAll(nodeList, nodesToCheck) {
var containsAll = true;
for (var i = nodesToCheck.length - 1; i >= 0 && containsAll; i--) {
containsAll = containsAll && nodeList.indexOf(nodesToCheck[i]) > -1;
}
return containsAll;
}
// example from sugiyamaService in what-now
sugiyamaService.areAllPresent = function (listOfNodes, nodesToCheck) {
var areAllPresent = true;
var evaluatingIndex = nodesToCheck.length - 1;
while (areAllPresent && evaluatingIndex >= 0) {
areAllPresent = listOfNodes.indexOf(nodesToCheck[evaluatingIndex--]) > -1;
}
return areAllPresent;
};
var extractIndependent = function(availableDependencies, availableNodes) {
var nodeIndex = availableNodes.length - 1;
var layer = [];
while (nodeIndex >= 0) {
var currentNode = availableNodes[nodeIndex];
if (sugiyamaService.areAllPresent(availableDependencies, currentNode.previousNodes)) {
layer.push(currentNode);
availableNodes.splice(nodeIndex, 1);
}
nodeIndex--;
}
return layer;
};
sugiyamaService.arrangeInLayers = function (nodeArray) {
var layers = [];
nodeArray = nodeArray || [];
var nodesToVisit = nodeArray.slice(0);
var visitedNodes = [];
while (nodesToVisit.length) {
var layer = extractIndependent(visitedNodes, nodesToVisit);
layers.push(layer);
visitedNodes = visitedNodes.concat(layer);
}
return layers;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment