| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- import AlgorithmStep from "../AlgorithmStep.js";
- import {EdgeSubdivisions, SiguiyamaContext} from "../siguiyama/SiguiyamaContext.js";
- import EdgeRoutingStepError from "../../errors/optimizer/EdgeRoutingStepError.js";
- import Node from "../../graph/node/Node.js";
- import Edge from "../../graph/edge/Edge.js";
- import DummyNode from "../../graph/node/DummyNode.js";
- import DummyEdge from "../../graph/edge/DummyEdge.js";
- import Graph from "../../graph/Graph.js";
- import Layering from "../../graph/layering/Layering.js";
- export default class EdgeRoutingStep extends AlgorithmStep<SiguiyamaContext> {
- public constructor() {
- super(EdgeRoutingStep.name);
- }
- public run(context: SiguiyamaContext) : void {
- const { layering, graph, edgeSubdivisions } = context;
- if(!layering)
- throw new EdgeRoutingStepError("Layering is null or undefined");
- if(!graph)
- throw new EdgeRoutingStepError("Graph is null or undefined");
- if(!edgeSubdivisions)
- throw new EdgeRoutingStepError("Edge Subdivisions are null or undefined");
- this.routeEdges(graph, layering, edgeSubdivisions);
- }
- private routeEdges(graph: Graph<Node, Edge<Node>>, layering: Layering<Node, Edge<Node>>, edgeSubdivisions: EdgeSubdivisions<Node, Edge<Node>>): void {
- const edges = graph.getEdges();
- for(const edge of edges) {
- const from = edge.getFrom();
- const to = edge.getTo();
- const fromNodeIndex = this.getNodeIndex(layering, from);
- const toNodeIndex = this.getNodeIndex(layering, to);
- if(fromNodeIndex === -1 || toNodeIndex === -1 || fromNodeIndex === toNodeIndex)
- continue;
- const fromLayerIndex = layering.getNodeLayerIndex(from);
- if(fromLayerIndex === -1)
- continue;
- const targetRowIndex = fromNodeIndex > toNodeIndex ? fromNodeIndex - 1 : fromNodeIndex + 1;
- const neighborRowCenter = this.getRowCenter(layering, targetRowIndex);
- if(neighborRowCenter === null)
- continue;
- const fromCenterY = from.getY() + from.getHeight() / 2;
- const routedNode = new DummyNode(
- from.getX() + from.getWidth() / 2,
- (fromCenterY + neighborRowCenter) / 2
- );
- layering.addToLayer(fromLayerIndex, routedNode);
- graph.addNode(routedNode);
- const left = new DummyEdge(from, routedNode);
- const right = new DummyEdge(routedNode, to);
- graph.addEdge(left);
- graph.addEdge(right);
- graph.removeEdge(edge.getId());
- edgeSubdivisions.set(edge, { left, right });
- }
- }
- private getRowCenter(layering: Layering<Node, Edge<Node>>, rowIndex: number): number | null {
- if(rowIndex < 0)
- return null;
- for(const layer of layering.getLayers()) {
- const node = layer.getNodes().at(rowIndex);
- if(node)
- return node.getY() + node.getHeight() / 2;
- }
- return null;
- }
- private getNodeIndex(layering: Layering<Node, Edge<Node>>, node: Node) : number {
- const layerIndex = layering.getNodeLayerIndex(node);
- if(layerIndex === -1)
- return -1;
- return layering.getLayers()[layerIndex]!.getNodes().indexOf(node);
- }
- }
|