| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- import _ from 'lodash'
- import util from './util'
- /*
- * Breaks any long edges in the graph into short segments that span 1 layer
- * each. This operation is undoable with the denormalize function.
- *
- * Pre-conditions:
- *
- * 1. The input graph is a DAG.
- * 2. Each node in the graph has a "rank" property.
- *
- * Post-condition:
- *
- * 1. All edges in the graph have a length of 1.
- * 2. Dummy nodes are added where edges have been split into segments.
- * 3. The graph is augmented with a "dummyChains" attribute which contains
- * the first dummy in each chain of dummy nodes produced.
- */
- function run (g) {
- g.graph().dummyChains = []
- _.forEach(g.edges(), function (edge) { normalizeEdge(g, edge) })
- }
- function normalizeEdge (g, e) {
- let v = e.v
- let vRank = g.node(v).rank
- const w = e.w
- const wRank = g.node(w).rank
- const name = e.name
- const edgeLabel = g.edge(e)
- const labelRank = edgeLabel.labelRank
- if (wRank === vRank + 1) return
- g.removeEdge(e)
- let dummy
- let attrs
- let i
- for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) {
- edgeLabel.points = []
- attrs = {
- width: 0,
- height: 0,
- edgeLabel: edgeLabel,
- edgeObj: e,
- rank: vRank
- }
- dummy = util.addDummyNode(g, 'edge', attrs, '_d')
- if (vRank === labelRank) {
- attrs.width = edgeLabel.width
- attrs.height = edgeLabel.height
- attrs.dummy = 'edge-label'
- attrs.labelpos = edgeLabel.labelpos
- }
- g.setEdge(v, dummy, { weight: edgeLabel.weight }, name)
- if (i === 0) {
- g.graph().dummyChains.push(dummy)
- }
- v = dummy
- }
- g.setEdge(v, w, { weight: edgeLabel.weight }, name)
- }
- function undo (g) {
- _.forEach(g.graph().dummyChains, function (v) {
- let node = g.node(v)
- const origLabel = node.edgeLabel
- let w = null
- g.setEdge(node.edgeObj, origLabel)
- while (node.dummy) {
- w = g.successors(v)[0]
- g.removeNode(v)
- origLabel.points.push({ x: node.x, y: node.y })
- if (node.dummy === 'edge-label') {
- origLabel.x = node.x
- origLabel.y = node.y
- origLabel.width = node.width
- origLabel.height = node.height
- }
- v = w
- node = g.node(v)
- }
- })
- }
- export default {
- run,
- undo
- }
|