EdgeRoutingStep.ts 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import AlgorithmStep from "../AlgorithmStep.js";
  2. import {SiguiyamaContext} from "../siguiyama/SiguiyamaContext.js";
  3. import EdgeRoutingStepError from "../../errors/optimizer/EdgeRoutingStepError.js";
  4. import Node from "../../graph/node/Node.js";
  5. import Edge from "../../graph/edge/Edge.js";
  6. import DummyNode from "../../graph/node/DummyNode.js";
  7. import DummyEdge from "../../graph/edge/DummyEdge.js";
  8. export default class EdgeRoutingStep extends AlgorithmStep<SiguiyamaContext> {
  9. public constructor() {
  10. super(EdgeRoutingStep.name);
  11. }
  12. public run(context: SiguiyamaContext) : void {
  13. const { layering, graph } = context;
  14. if(!layering)
  15. throw new EdgeRoutingStepError("Layering is null or undefined");
  16. if(!graph)
  17. throw new EdgeRoutingStepError("Graph is null or undefined");
  18. this.routeEdges(graph.getEdges(), layering, graph);
  19. }
  20. private routeEdges(edges: Edge<Node>[], layering: NonNullable<SiguiyamaContext["layering"]>, graph: NonNullable<SiguiyamaContext["graph"]>): void {
  21. const layers = layering.getLayers();
  22. for(const edge of edges) {
  23. const from = edge.getFrom();
  24. const to = edge.getTo();
  25. const fromLayerIndex = layering.getNodeLayerIndex(from);
  26. const toLayerIndex = layering.getNodeLayerIndex(to);
  27. if(fromLayerIndex < 0 || toLayerIndex < 0)
  28. continue;
  29. const fromRowIndex = layers[fromLayerIndex]?.getNodes().findIndex(node => node === from) ?? -1;
  30. const toRowIndex = layers[toLayerIndex]?.getNodes().findIndex(node => node === to) ?? -1;
  31. if(fromRowIndex < 0 || toRowIndex < 0 || fromRowIndex === toRowIndex)
  32. continue;
  33. const rightLayer = layers[fromLayerIndex - 1];
  34. if(!rightLayer)
  35. continue;
  36. const rightLayerNodes = rightLayer.getNodes();
  37. if(rightLayerNodes.length === 0)
  38. continue;
  39. const anchorNode = rightLayerNodes[0]!;
  40. const routedNode = new DummyNode(
  41. anchorNode.getX() + anchorNode.getWidth() / 2,
  42. from.getY() + from.getHeight() / 2,
  43. edge.getId()
  44. );
  45. layering.addToLayer(fromLayerIndex - 1, routedNode);
  46. graph.addNode(routedNode);
  47. const firstSegment = new DummyEdge(from, routedNode, []);
  48. const secondSegment = new DummyEdge(routedNode, to, []);
  49. graph.addEdge(firstSegment);
  50. graph.addEdge(secondSegment);
  51. graph.removeEdge(edge.getId());
  52. }
  53. }
  54. }