init-order.js 1.0 KB

123456789101112131415161718192021222324252627282930313233343536
  1. import _ from 'lodash'
  2. /*
  3. * Assigns an initial order value for each node by performing a DFS search
  4. * starting from nodes in the first rank. Nodes are assigned an order in their
  5. * rank as they are first visited.
  6. *
  7. * This approach comes from Gansner, et al., "A Technique for Drawing Directed
  8. * Graphs."
  9. *
  10. * Returns a layering matrix with an array per layer and each layer sorted by
  11. * the order of its nodes.
  12. */
  13. function initOrder (g) {
  14. const visited = {}
  15. const simpleNodes = _.filter(g.nodes(), function (v) {
  16. return !g.children(v).length
  17. })
  18. const maxRank = _.max(_.map(simpleNodes, function (v) { return g.node(v).rank }))
  19. const layers = _.map(_.range(maxRank + 1), function () { return [] })
  20. function dfs (v) {
  21. if (_.has(visited, v)) return
  22. visited[v] = true
  23. const node = g.node(v)
  24. layers[node.rank].push(v)
  25. _.forEach(g.successors(v), dfs)
  26. }
  27. const orderedVs = _.sortBy(simpleNodes, function (v) { return g.node(v).rank })
  28. _.forEach(orderedVs, dfs)
  29. return layers
  30. }
  31. export default initOrder