You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

98 lines
3.0 KiB

import { addDummyNode } 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.
*/
const DUMMY_NODE_EDGE = 'edge';
const DUMMY_NODE_EDGE_LABEL = 'edge-label';
const run = (g, dummyChains) => {
g.getAllEdges().forEach((edge) => normalizeEdge(g, edge, dummyChains));
};
const normalizeEdge = (g, e, dummyChains) => {
let v = e.source;
let vRank = g.getNode(v).data.rank;
const w = e.target;
const wRank = g.getNode(w).data.rank;
const labelRank = e.data.labelRank;
if (wRank === vRank + 1)
return;
g.removeEdge(e.id);
let dummy;
let nodeData;
let i;
for (i = 0, ++vRank; vRank < wRank; ++i, ++vRank) {
e.data.points = [];
nodeData = {
originalEdge: e,
width: 0,
height: 0,
rank: vRank,
};
dummy = addDummyNode(g, DUMMY_NODE_EDGE, nodeData, '_d');
if (vRank === labelRank) {
nodeData.width = e.data.width;
nodeData.height = e.data.height;
nodeData.dummy = DUMMY_NODE_EDGE_LABEL;
nodeData.labelpos = e.data.labelpos;
}
g.addEdge({
id: `e${Math.random()}`,
source: v,
target: dummy,
data: { weight: e.data.weight },
});
if (i === 0) {
dummyChains.push(dummy);
}
v = dummy;
}
g.addEdge({
id: `e${Math.random()}`,
source: v,
target: w,
data: { weight: e.data.weight },
});
};
const undo = (g, dummyChains) => {
dummyChains.forEach((v) => {
let node = g.getNode(v);
const { data } = node;
const originalEdge = data.originalEdge;
let w;
// Restore original edge.
if (originalEdge) {
g.addEdge(originalEdge);
}
let currentV = v;
while (node.data.dummy) {
w = g.getSuccessors(currentV)[0];
g.removeNode(currentV);
originalEdge.data.points.push({
x: node.data.x,
y: node.data.y,
});
if (node.data.dummy === DUMMY_NODE_EDGE_LABEL) {
originalEdge.data.x = node.data.x;
originalEdge.data.y = node.data.y;
originalEdge.data.width = node.data.width;
originalEdge.data.height = node.data.height;
}
currentV = w.id;
node = g.getNode(currentV);
}
});
};
export { run, undo };
//# sourceMappingURL=normalize.js.map