|
|
@@ -1,12 +1,12 @@
|
|
|
import AlgorithmStep from "../AlgorithmStep.js";
|
|
|
import {EdgeSubdivisions, SiguiyamaContext} from "../siguiyama/SiguiyamaContext.js";
|
|
|
import EdgeRoutingStepError from "../../errors/optimizer/EdgeRoutingStepError.js";
|
|
|
+import Graph from "../../graph/Graph.js";
|
|
|
import Node from "../../graph/node/Node.js";
|
|
|
import Edge from "../../graph/edge/Edge.js";
|
|
|
+import NodeGrid from "../../graph/grid/NodeGrid.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() {
|
|
|
@@ -14,77 +14,43 @@ export default class EdgeRoutingStep extends AlgorithmStep<SiguiyamaContext> {
|
|
|
}
|
|
|
|
|
|
public run(context: SiguiyamaContext) : void {
|
|
|
- const { layering, graph, edgeSubdivisions } = context;
|
|
|
+ const { graph, grid, edgeSubdivisions } = context;
|
|
|
|
|
|
- if(!layering)
|
|
|
- throw new EdgeRoutingStepError("Layering is null or undefined");
|
|
|
if(!graph)
|
|
|
throw new EdgeRoutingStepError("Graph is null or undefined");
|
|
|
+ if(!grid)
|
|
|
+ throw new EdgeRoutingStepError("Grid is null or undefined");
|
|
|
if(!edgeSubdivisions)
|
|
|
- throw new EdgeRoutingStepError("Edge Subdivisions are null or undefined");
|
|
|
+ throw new EdgeRoutingStepError("Edge subdivisions information is null or undefined");
|
|
|
|
|
|
- this.routeEdges(graph, layering, edgeSubdivisions);
|
|
|
+ this.manhattanEdgeRouting(graph, grid, edgeSubdivisions);
|
|
|
}
|
|
|
|
|
|
- private routeEdges(graph: Graph<Node, Edge<Node>>, layering: Layering<Node, Edge<Node>>, edgeSubdivisions: EdgeSubdivisions<Node, Edge<Node>>): void {
|
|
|
+ private manhattanEdgeRouting(graph: Graph<Node, Edge<Node>>, grid: NodeGrid<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);
|
|
|
+ const from = edge.getFrom(), to = edge.getTo();
|
|
|
+ const fromPosition = grid.getPositionOf(from), toPosition = grid.getPositionOf(to);
|
|
|
|
|
|
- if(fromNodeIndex === -1 || toNodeIndex === -1 || fromNodeIndex === toNodeIndex)
|
|
|
+ if(!fromPosition || !toPosition || fromPosition.row === toPosition.row)
|
|
|
continue;
|
|
|
|
|
|
- const fromLayerIndex = layering.getNodeLayerIndex(from);
|
|
|
- if(fromLayerIndex === -1)
|
|
|
- continue;
|
|
|
+ const fromRow = fromPosition.row, fromColumn = fromPosition.column;
|
|
|
+ const toRow = toPosition.row, toColumn = toPosition.column;
|
|
|
|
|
|
- const targetRowIndex = fromNodeIndex > toNodeIndex ? fromNodeIndex - 1 : fromNodeIndex + 1;
|
|
|
- const neighborRowCenter = this.getRowCenter(layering, targetRowIndex);
|
|
|
- if(neighborRowCenter === null)
|
|
|
- continue;
|
|
|
+ const targetCellPosition: { row: number, column: number } = toRow > fromRow ? { row: toRow, column: fromColumn } : { row: fromRow, column: toColumn };
|
|
|
|
|
|
- const fromCenterY = from.getY() + from.getHeight() / 2;
|
|
|
- const routedNode = new DummyNode(
|
|
|
- from.getX() + from.getWidth() / 2,
|
|
|
- (fromCenterY + neighborRowCenter) / 2
|
|
|
- );
|
|
|
+ const cellSize = grid.getCellSize(targetCellPosition.row, targetCellPosition.column);
|
|
|
+ const dummyNode = new DummyNode(cellSize.width / 2,cellSize.height / 2);
|
|
|
+ graph.addNode(dummyNode);
|
|
|
+ grid.set(targetCellPosition.row, targetCellPosition.column, dummyNode);
|
|
|
|
|
|
- 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());
|
|
|
+ const left = new DummyEdge(from, dummyNode), right = new DummyEdge(dummyNode, to);
|
|
|
+ graph.addEdge(left).addEdge(right).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);
|
|
|
}
|
|
|
}
|