| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- /**
- * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
- * SPDX-License-Identifier: MIT
- */
- 'use strict';
- import { util } from './util';
- export const normalize = {
- run,
- undo,
- };
- export default normalize;
- /*
- * 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 = [];
- g.edges().forEach((edge) => normalizeEdge(g, edge));
- }
- function normalizeEdge(g, e) {
- let v = e.v;
- let vRank = g.node(v).rank;
- let w = e.w;
- let wRank = g.node(w).rank;
- let name = e.name;
- let edgeLabel = g.edge(e);
- let labelRank = edgeLabel.labelRank;
- if (wRank === vRank + 1) return;
- g.removeEdge(e);
- let dummy, attrs, 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) {
- g.graph().dummyChains.forEach((v) => {
- let node = g.node(v);
- let origLabel = node.edgeLabel;
- let w;
- 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);
- }
- });
- }
|