Reputation: 1007
I have a GoJS canvas in which the user creates as per his wish, and the application needs to process the nodes in sequence.
So by GoJS documentation, there's gojsNodeObject.findTreeLevel()
, which returns the level of the node in the diagram.
So far it worked just fine, but recently it caused an issue.
Please take a look at my diagram below on fiddle http://jsfiddle.net/2pqretgu/1/
according to the logic it is returning me the sequence as
["s1", "s2", "s3", "s4", "i1", "i2", "i3", "j1", "j2", "j3", "i4", "j4"]
but I would like the sequence to be
i1 should be before j1
j1 should be before i2 and i3
i2 and i3 should be before j2 and j3
j4 should be last
In short, I am executing the nodes as per the layers created by the layered layout, but I cannot depend on the layout to find its position, as a user can change the layout.
Any help or pointers would be appreciated
Upvotes: 3
Views: 352
Reputation: 570
In my opinion, if the implementation of the library is not suitable for you, it would be better to implement the logic yourself.
This is exactly what I did, take a look at this fiddle: https://jsfiddle.net/Ba2siK/8megtv0k/
I mapped the nodes into a graph, and then traversed the graph in recursion to calculate depth of each node.
The output is: ["s1", "s2", "i1", "j1", "s3", "s4", "i2", "i3", "j2", "j3", "i4", "j4"]
// Create an object that maps each node to its children
const graph = {};
myDiagram.nodes.each(node => {
graph[node.data.key] = flattenIterator(node.findNodesOutOf());
});
const nodesLevels = getNodesLevels(myDiagram);
const sortedLevelsInfo = Object.keys(nodesLevels).sort((a, b) => nodesLevels[a] - nodesLevels[b]);
console.log(nodesLevels);
console.log(sortedLevelsInfo);
// Output: ["s1", "s2", "i1", "j1", "s3", "s4", "i2", "i3", "j2", "j3", "i4", "j4"]
// Convert an iterator to an array, to make the code more readable
function flattenIterator(collection) {
const items = [];
var it = collection.iterator;
while (it.next()) {
items.push(it.value);
}
return items;
}
function getNodesLevels(diagram) {
const treeLevels = {};
var nodeIterator = diagram.nodes.iterator;
while (nodeIterator.next()) {
findNodeLevel(graph, nodeIterator.value, treeLevels);
}
const maxLevel = Math.max(...Object.values(treeLevels));
// Reversing the order of node depths, since deepest node starts from 0
Object.keys(treeLevels).map((key, index) => {
treeLevels[key] = maxLevel - treeLevels[key];
});
return treeLevels;
}
function findNodeLevel(graph, node, levels) {
const key = node.data.key;
if (!Object.keys(levels).includes(key)) {
const child = graph[key];
if (!child) {
levels[key] = 0
} else {
if (child.length) {
const childrenLevels = child.map(child => findNodeLevel(graph, child, levels) + 1);
levels[key] = Math.max(...childrenLevels);
} else {
levels[key] = 0;
}
}
}
return levels[key];
}
Upvotes: 0