sprotty
Version:
A next-gen framework for graphical views
499 lines • 28.9 kB
JavaScript
"use strict";
/********************************************************************************
* Copyright (c) 2019-2020 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ManhattanEdgeRouter = void 0;
const geometry_1 = require("sprotty-protocol/lib/utils/geometry");
const smodel_utils_1 = require("../../base/model/smodel-utils");
const abstract_edge_router_1 = require("./abstract-edge-router");
const model_1 = require("./model");
class ManhattanEdgeRouter extends abstract_edge_router_1.AbstractEdgeRouter {
get kind() {
return ManhattanEdgeRouter.KIND;
}
getOptions(edge) {
return {
standardDistance: 20,
minimalPointDistance: 3,
selfEdgeOffset: 0.25
};
}
route(edge) {
if (!edge.source || !edge.target)
return [];
const routedCorners = this.createRoutedCorners(edge);
const sourceRefPoint = routedCorners[0]
|| (0, smodel_utils_1.translatePoint)(geometry_1.Bounds.center(edge.target.bounds), edge.target.parent, edge.parent);
const sourceAnchor = this.getTranslatedAnchor(edge.source, sourceRefPoint, edge.parent, edge, edge.sourceAnchorCorrection);
const targetRefPoint = routedCorners[routedCorners.length - 1]
|| (0, smodel_utils_1.translatePoint)(geometry_1.Bounds.center(edge.source.bounds), edge.source.parent, edge.parent);
const targetAnchor = this.getTranslatedAnchor(edge.target, targetRefPoint, edge.parent, edge, edge.targetAnchorCorrection);
if (!sourceAnchor || !targetAnchor)
return [];
const routedPoints = [];
routedPoints.push(Object.assign({ kind: 'source' }, sourceAnchor));
routedCorners.forEach(corner => routedPoints.push(corner));
routedPoints.push(Object.assign({ kind: 'target' }, targetAnchor));
return routedPoints;
}
createRoutedCorners(edge) {
const sourceAnchors = new abstract_edge_router_1.DefaultAnchors(edge.source, edge.parent, 'source');
const targetAnchors = new abstract_edge_router_1.DefaultAnchors(edge.target, edge.parent, 'target');
if (edge.routingPoints.length > 0) {
const routingPointsCopy = edge.routingPoints.slice();
this.cleanupRoutingPoints(edge, routingPointsCopy, false, true);
if (routingPointsCopy.length > 0)
return routingPointsCopy.map((routingPoint, index) => {
return Object.assign({ kind: 'linear', pointIndex: index }, routingPoint);
});
}
const options = this.getOptions(edge);
const corners = this.calculateDefaultCorners(edge, sourceAnchors, targetAnchors, options);
return corners.map(corner => {
return Object.assign({ kind: 'linear' }, corner);
});
}
createRoutingHandles(edge) {
const routedPoints = this.route(edge);
this.commitRoute(edge, routedPoints);
if (routedPoints.length > 0) {
this.addHandle(edge, 'source', 'routing-point', -2);
for (let i = 0; i < routedPoints.length - 1; ++i)
this.addHandle(edge, 'manhattan-50%', 'volatile-routing-point', i - 1);
this.addHandle(edge, 'target', 'routing-point', routedPoints.length - 2);
}
}
getInnerHandlePosition(edge, route, handle) {
const fraction = this.getFraction(handle.kind);
if (fraction !== undefined) {
const { start, end } = this.findRouteSegment(edge, route, handle.pointIndex);
if (start !== undefined && end !== undefined)
return geometry_1.Point.linear(start, end, fraction);
}
return undefined;
}
getFraction(kind) {
switch (kind) {
case 'manhattan-50%': return 0.5;
default: return undefined;
}
}
applyInnerHandleMoves(edge, moves) {
const route = this.route(edge);
const routingPoints = edge.routingPoints;
const minimalPointDistance = this.getOptions(edge).minimalPointDistance;
moves.forEach(move => {
const handle = move.handle;
const index = handle.pointIndex;
const correctedX = this.correctX(routingPoints, index, move.toPosition.x, minimalPointDistance);
const correctedY = this.correctY(routingPoints, index, move.toPosition.y, minimalPointDistance);
switch (handle.kind) {
case 'manhattan-50%':
if (index < 0) {
if (routingPoints.length === 0) {
routingPoints.push({ x: correctedX, y: correctedY });
handle.pointIndex = 0;
}
else if ((0, geometry_1.almostEquals)(route[0].x, route[1].x)) {
this.alignX(routingPoints, 0, correctedX);
}
else {
this.alignY(routingPoints, 0, correctedY);
}
}
else if (index < routingPoints.length - 1) {
if ((0, geometry_1.almostEquals)(routingPoints[index].x, routingPoints[index + 1].x)) {
this.alignX(routingPoints, index, correctedX);
this.alignX(routingPoints, index + 1, correctedX);
}
else {
this.alignY(routingPoints, index, correctedY);
this.alignY(routingPoints, index + 1, correctedY);
}
}
else {
if ((0, geometry_1.almostEquals)(route[route.length - 2].x, route[route.length - 1].x)) {
this.alignX(routingPoints, routingPoints.length - 1, correctedX);
}
else {
this.alignY(routingPoints, routingPoints.length - 1, correctedY);
}
}
break;
}
});
}
correctX(routingPoints, index, x, minimalPointDistance) {
if (index > 0 && Math.abs(x - routingPoints[index - 1].x) < minimalPointDistance)
return routingPoints[index - 1].x;
else if (index < routingPoints.length - 2 && Math.abs(x - routingPoints[index + 2].x) < minimalPointDistance)
return routingPoints[index + 2].x;
else
return x;
}
alignX(routingPoints, index, x) {
if (index >= 0 && index < routingPoints.length)
routingPoints[index] = {
x,
y: routingPoints[index].y
};
}
correctY(routingPoints, index, y, minimalPointDistance) {
if (index > 0 && Math.abs(y - routingPoints[index - 1].y) < minimalPointDistance)
return routingPoints[index - 1].y;
else if (index < routingPoints.length - 2 && Math.abs(y - routingPoints[index + 2].y) < minimalPointDistance)
return routingPoints[index + 2].y;
else
return y;
}
alignY(routingPoints, index, y) {
if (index >= 0 && index < routingPoints.length)
routingPoints[index] = {
x: routingPoints[index].x,
y
};
}
cleanupRoutingPoints(edge, routingPoints, updateHandles, addRoutingPoints) {
const sourceAnchors = new abstract_edge_router_1.DefaultAnchors(edge.source, edge.parent, "source");
const targetAnchors = new abstract_edge_router_1.DefaultAnchors(edge.target, edge.parent, "target");
if (this.resetRoutingPointsOnReconnect(edge, routingPoints, updateHandles, sourceAnchors, targetAnchors))
return;
// delete leading RPs inside the bounds of the source
for (let i = 0; i < routingPoints.length; ++i)
if (geometry_1.Bounds.includes(sourceAnchors.bounds, routingPoints[i])) {
routingPoints.splice(0, 1);
if (updateHandles) {
this.removeHandle(edge, -1);
}
}
else {
break;
}
// delete trailing RPs inside the bounds of the target
for (let i = routingPoints.length - 1; i >= 0; --i)
if (geometry_1.Bounds.includes(targetAnchors.bounds, routingPoints[i])) {
routingPoints.splice(i, 1);
if (updateHandles) {
this.removeHandle(edge, i);
}
}
else {
break;
}
if (routingPoints.length >= 2) {
const options = this.getOptions(edge);
for (let i = routingPoints.length - 2; i >= 0; --i) {
if (geometry_1.Point.manhattanDistance(routingPoints[i], routingPoints[i + 1]) < options.minimalPointDistance) {
routingPoints.splice(i, 2);
--i;
if (updateHandles) {
this.removeHandle(edge, i - 1);
this.removeHandle(edge, i);
}
}
}
}
if (addRoutingPoints) {
this.addAdditionalCorner(edge, routingPoints, sourceAnchors, targetAnchors, updateHandles);
this.addAdditionalCorner(edge, routingPoints, targetAnchors, sourceAnchors, updateHandles);
this.manhattanify(edge, routingPoints);
}
}
removeHandle(edge, pointIndex) {
const toBeRemoved = [];
edge.children.forEach(child => {
if (child instanceof model_1.SRoutingHandleImpl) {
if (child.pointIndex > pointIndex)
--child.pointIndex;
else if (child.pointIndex === pointIndex)
toBeRemoved.push(child);
}
});
toBeRemoved.forEach(child => edge.remove(child));
}
addAdditionalCorner(edge, routingPoints, currentAnchors, otherAnchors, updateHandles) {
if (routingPoints.length === 0)
return;
const refPoint = currentAnchors.kind === 'source' ? routingPoints[0] : routingPoints[routingPoints.length - 1];
const index = currentAnchors.kind === 'source' ? 0 : routingPoints.length;
const shiftIndex = index - (currentAnchors.kind === 'source' ? 1 : 0);
let isHorizontal;
if (routingPoints.length > 1) {
isHorizontal = index === 0
? (0, geometry_1.almostEquals)(routingPoints[0].x, routingPoints[1].x)
: (0, geometry_1.almostEquals)(routingPoints[routingPoints.length - 1].x, routingPoints[routingPoints.length - 2].x);
}
else {
const nearestSide = otherAnchors.getNearestSide(refPoint);
isHorizontal = nearestSide === abstract_edge_router_1.Side.TOP || nearestSide === abstract_edge_router_1.Side.BOTTOM;
}
if (isHorizontal) {
if (refPoint.y < currentAnchors.get(abstract_edge_router_1.Side.TOP).y || refPoint.y > currentAnchors.get(abstract_edge_router_1.Side.BOTTOM).y) {
const newPoint = { x: currentAnchors.get(abstract_edge_router_1.Side.TOP).x, y: refPoint.y };
routingPoints.splice(index, 0, newPoint);
if (updateHandles) {
edge.children.forEach(child => {
if (child instanceof model_1.SRoutingHandleImpl && child.pointIndex >= shiftIndex)
++child.pointIndex;
});
this.addHandle(edge, 'manhattan-50%', 'volatile-routing-point', shiftIndex);
}
}
}
else {
if (refPoint.x < currentAnchors.get(abstract_edge_router_1.Side.LEFT).x || refPoint.x > currentAnchors.get(abstract_edge_router_1.Side.RIGHT).x) {
const newPoint = { x: refPoint.x, y: currentAnchors.get(abstract_edge_router_1.Side.LEFT).y };
routingPoints.splice(index, 0, newPoint);
if (updateHandles) {
edge.children.forEach(child => {
if (child instanceof model_1.SRoutingHandleImpl && child.pointIndex >= shiftIndex)
++child.pointIndex;
});
this.addHandle(edge, 'manhattan-50%', 'volatile-routing-point', shiftIndex);
}
}
}
}
/**
* Add artificial routing points to keep all angles rectilinear.
*
* This makes edge morphing look a lot smoother, where RP positions are interpolated
* linearly probably resulting in non-rectilinear angles. We don't add handles for
* these additional RPs.
*/
manhattanify(edge, routingPoints) {
for (let i = 1; i < routingPoints.length; ++i) {
const isVertical = Math.abs(routingPoints[i - 1].x - routingPoints[i].x) < 1;
const isHorizontal = Math.abs(routingPoints[i - 1].y - routingPoints[i].y) < 1;
if (!isVertical && !isHorizontal) {
routingPoints.splice(i, 0, {
x: routingPoints[i - 1].x,
y: routingPoints[i].y
});
++i;
}
}
}
calculateDefaultCorners(edge, sourceAnchors, targetAnchors, options) {
const selfEdge = super.calculateDefaultCorners(edge, sourceAnchors, targetAnchors, options);
if (selfEdge.length > 0)
return selfEdge;
const bestAnchors = this.getBestConnectionAnchors(edge, sourceAnchors, targetAnchors, options);
const sourceSide = bestAnchors.source;
const targetSide = bestAnchors.target;
const corners = [];
const startPoint = sourceAnchors.get(sourceSide);
let endPoint = targetAnchors.get(targetSide);
switch (sourceSide) {
case abstract_edge_router_1.Side.RIGHT:
switch (targetSide) {
case abstract_edge_router_1.Side.BOTTOM:
corners.push({ x: endPoint.x, y: startPoint.y });
break;
case abstract_edge_router_1.Side.TOP:
corners.push({ x: endPoint.x, y: startPoint.y });
break;
case abstract_edge_router_1.Side.RIGHT:
corners.push({ x: Math.max(startPoint.x, endPoint.x) + 1.5 * options.standardDistance, y: startPoint.y });
corners.push({ x: Math.max(startPoint.x, endPoint.x) + 1.5 * options.standardDistance, y: endPoint.y });
break;
case abstract_edge_router_1.Side.LEFT:
if (endPoint.y !== startPoint.y) {
corners.push({ x: (startPoint.x + endPoint.x) / 2, y: startPoint.y });
corners.push({ x: (startPoint.x + endPoint.x) / 2, y: endPoint.y });
}
break;
}
break;
case abstract_edge_router_1.Side.LEFT:
switch (targetSide) {
case abstract_edge_router_1.Side.BOTTOM:
corners.push({ x: endPoint.x, y: startPoint.y });
break;
case abstract_edge_router_1.Side.TOP:
corners.push({ x: endPoint.x, y: startPoint.y });
break;
default:
endPoint = targetAnchors.get(abstract_edge_router_1.Side.RIGHT);
if (endPoint.y !== startPoint.y) {
corners.push({ x: (startPoint.x + endPoint.x) / 2, y: startPoint.y });
corners.push({ x: (startPoint.x + endPoint.x) / 2, y: endPoint.y });
}
break;
}
break;
case abstract_edge_router_1.Side.TOP:
switch (targetSide) {
case abstract_edge_router_1.Side.RIGHT:
if ((endPoint.x - startPoint.x) > 0) {
corners.push({ x: startPoint.x, y: startPoint.y - options.standardDistance });
corners.push({ x: endPoint.x + 1.5 * options.standardDistance, y: startPoint.y - options.standardDistance });
corners.push({ x: endPoint.x + 1.5 * options.standardDistance, y: endPoint.y });
}
else {
corners.push({ x: startPoint.x, y: endPoint.y });
}
break;
case abstract_edge_router_1.Side.LEFT:
if ((endPoint.x - startPoint.x) < 0) {
corners.push({ x: startPoint.x, y: startPoint.y - options.standardDistance });
corners.push({ x: endPoint.x - 1.5 * options.standardDistance, y: startPoint.y - options.standardDistance });
corners.push({ x: endPoint.x - 1.5 * options.standardDistance, y: endPoint.y });
}
else {
corners.push({ x: startPoint.x, y: endPoint.y });
}
break;
case abstract_edge_router_1.Side.TOP:
corners.push({ x: startPoint.x, y: Math.min(startPoint.y, endPoint.y) - 1.5 * options.standardDistance });
corners.push({ x: endPoint.x, y: Math.min(startPoint.y, endPoint.y) - 1.5 * options.standardDistance });
break;
case abstract_edge_router_1.Side.BOTTOM:
if (endPoint.x !== startPoint.x) {
corners.push({ x: startPoint.x, y: (startPoint.y + endPoint.y) / 2 });
corners.push({ x: endPoint.x, y: (startPoint.y + endPoint.y) / 2 });
}
break;
}
break;
case abstract_edge_router_1.Side.BOTTOM:
switch (targetSide) {
case abstract_edge_router_1.Side.RIGHT:
if ((endPoint.x - startPoint.x) > 0) {
corners.push({ x: startPoint.x, y: startPoint.y + options.standardDistance });
corners.push({ x: endPoint.x + 1.5 * options.standardDistance, y: startPoint.y + options.standardDistance });
corners.push({ x: endPoint.x + 1.5 * options.standardDistance, y: endPoint.y });
}
else {
corners.push({ x: startPoint.x, y: endPoint.y });
}
break;
case abstract_edge_router_1.Side.LEFT:
if ((endPoint.x - startPoint.x) < 0) {
corners.push({ x: startPoint.x, y: startPoint.y + options.standardDistance });
corners.push({ x: endPoint.x - 1.5 * options.standardDistance, y: startPoint.y + options.standardDistance });
corners.push({ x: endPoint.x - 1.5 * options.standardDistance, y: endPoint.y });
}
else {
corners.push({ x: startPoint.x, y: endPoint.y });
}
break;
default:
endPoint = targetAnchors.get(abstract_edge_router_1.Side.TOP);
if (endPoint.x !== startPoint.x) {
corners.push({ x: startPoint.x, y: (startPoint.y + endPoint.y) / 2 });
corners.push({ x: endPoint.x, y: (startPoint.y + endPoint.y) / 2 });
}
break;
}
break;
}
return corners;
}
getBestConnectionAnchors(edge, sourceAnchors, targetAnchors, options) {
// distance is enough
let sourcePoint = sourceAnchors.get(abstract_edge_router_1.Side.RIGHT);
let targetPoint = targetAnchors.get(abstract_edge_router_1.Side.LEFT);
if ((targetPoint.x - sourcePoint.x) > options.standardDistance)
return { source: abstract_edge_router_1.Side.RIGHT, target: abstract_edge_router_1.Side.LEFT };
sourcePoint = sourceAnchors.get(abstract_edge_router_1.Side.LEFT);
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.RIGHT);
if ((sourcePoint.x - targetPoint.x) > options.standardDistance)
return { source: abstract_edge_router_1.Side.LEFT, target: abstract_edge_router_1.Side.RIGHT };
sourcePoint = sourceAnchors.get(abstract_edge_router_1.Side.TOP);
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.BOTTOM);
if ((sourcePoint.y - targetPoint.y) > options.standardDistance)
return { source: abstract_edge_router_1.Side.TOP, target: abstract_edge_router_1.Side.BOTTOM };
sourcePoint = sourceAnchors.get(abstract_edge_router_1.Side.BOTTOM);
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.TOP);
if ((targetPoint.y - sourcePoint.y) > options.standardDistance)
return { source: abstract_edge_router_1.Side.BOTTOM, target: abstract_edge_router_1.Side.TOP };
// One additional point
sourcePoint = sourceAnchors.get(abstract_edge_router_1.Side.RIGHT);
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.TOP);
if (((targetPoint.x - sourcePoint.x) > 0.5 * options.standardDistance) && ((targetPoint.y - sourcePoint.y) > options.standardDistance))
return { source: abstract_edge_router_1.Side.RIGHT, target: abstract_edge_router_1.Side.TOP };
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.BOTTOM);
if (((targetPoint.x - sourcePoint.x) > 0.5 * options.standardDistance) && ((sourcePoint.y - targetPoint.y) > options.standardDistance))
return { source: abstract_edge_router_1.Side.RIGHT, target: abstract_edge_router_1.Side.BOTTOM };
sourcePoint = sourceAnchors.get(abstract_edge_router_1.Side.LEFT);
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.BOTTOM);
if (((sourcePoint.x - targetPoint.x) > 0.5 * options.standardDistance) && ((sourcePoint.y - targetPoint.y) > options.standardDistance))
return { source: abstract_edge_router_1.Side.LEFT, target: abstract_edge_router_1.Side.BOTTOM };
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.TOP);
if (((sourcePoint.x - targetPoint.x) > 0.5 * options.standardDistance) && ((targetPoint.y - sourcePoint.y) > options.standardDistance))
return { source: abstract_edge_router_1.Side.LEFT, target: abstract_edge_router_1.Side.TOP };
sourcePoint = sourceAnchors.get(abstract_edge_router_1.Side.TOP);
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.RIGHT);
if (((sourcePoint.y - targetPoint.y) > 0.5 * options.standardDistance) && ((sourcePoint.x - targetPoint.x) > options.standardDistance))
return { source: abstract_edge_router_1.Side.TOP, target: abstract_edge_router_1.Side.RIGHT };
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.LEFT);
if (((sourcePoint.y - targetPoint.y) > 0.5 * options.standardDistance) && ((targetPoint.x - sourcePoint.x) > options.standardDistance))
return { source: abstract_edge_router_1.Side.TOP, target: abstract_edge_router_1.Side.LEFT };
sourcePoint = sourceAnchors.get(abstract_edge_router_1.Side.BOTTOM);
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.RIGHT);
if (((targetPoint.y - sourcePoint.y) > 0.5 * options.standardDistance) && ((sourcePoint.x - targetPoint.x) > options.standardDistance))
return { source: abstract_edge_router_1.Side.BOTTOM, target: abstract_edge_router_1.Side.RIGHT };
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.LEFT);
if (((targetPoint.y - sourcePoint.y) > 0.5 * options.standardDistance) && ((targetPoint.x - sourcePoint.x) > options.standardDistance))
return { source: abstract_edge_router_1.Side.BOTTOM, target: abstract_edge_router_1.Side.LEFT };
// Two points
// priority NN >> EE >> NE >> NW >> SE >> SW
sourcePoint = sourceAnchors.get(abstract_edge_router_1.Side.TOP);
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.TOP);
if (!geometry_1.Bounds.includes(targetAnchors.bounds, sourcePoint) && !geometry_1.Bounds.includes(sourceAnchors.bounds, targetPoint)) {
if ((sourcePoint.y - targetPoint.y) < 0) {
if (Math.abs(sourcePoint.x - targetPoint.x) > ((sourceAnchors.bounds.width + options.standardDistance) / 2))
return { source: abstract_edge_router_1.Side.TOP, target: abstract_edge_router_1.Side.TOP };
}
else {
if (Math.abs(sourcePoint.x - targetPoint.x) > (targetAnchors.bounds.width / 2))
return { source: abstract_edge_router_1.Side.TOP, target: abstract_edge_router_1.Side.TOP };
}
}
sourcePoint = sourceAnchors.get(abstract_edge_router_1.Side.RIGHT);
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.RIGHT);
if (!geometry_1.Bounds.includes(targetAnchors.bounds, sourcePoint) && !geometry_1.Bounds.includes(sourceAnchors.bounds, targetPoint)) {
if ((sourcePoint.x - targetPoint.x) > 0) {
if (Math.abs(sourcePoint.y - targetPoint.y) > ((sourceAnchors.bounds.height + options.standardDistance) / 2))
return { source: abstract_edge_router_1.Side.RIGHT, target: abstract_edge_router_1.Side.RIGHT };
}
else if (Math.abs(sourcePoint.y - targetPoint.y) > (targetAnchors.bounds.height / 2))
return { source: abstract_edge_router_1.Side.RIGHT, target: abstract_edge_router_1.Side.RIGHT };
}
// Secondly, judge NE NW is available
sourcePoint = sourceAnchors.get(abstract_edge_router_1.Side.TOP);
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.RIGHT);
if (!geometry_1.Bounds.includes(targetAnchors.bounds, sourcePoint) && !geometry_1.Bounds.includes(sourceAnchors.bounds, targetPoint))
return { source: abstract_edge_router_1.Side.TOP, target: abstract_edge_router_1.Side.RIGHT };
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.LEFT);
if (!geometry_1.Bounds.includes(targetAnchors.bounds, sourcePoint) && !geometry_1.Bounds.includes(sourceAnchors.bounds, targetPoint))
return { source: abstract_edge_router_1.Side.TOP, target: abstract_edge_router_1.Side.LEFT };
// Finally, judge SE SW is available
sourcePoint = sourceAnchors.get(abstract_edge_router_1.Side.BOTTOM);
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.RIGHT);
if (!geometry_1.Bounds.includes(targetAnchors.bounds, sourcePoint) && !geometry_1.Bounds.includes(sourceAnchors.bounds, targetPoint))
return { source: abstract_edge_router_1.Side.BOTTOM, target: abstract_edge_router_1.Side.RIGHT };
targetPoint = targetAnchors.get(abstract_edge_router_1.Side.LEFT);
if (!geometry_1.Bounds.includes(targetAnchors.bounds, sourcePoint) && !geometry_1.Bounds.includes(sourceAnchors.bounds, targetPoint))
return { source: abstract_edge_router_1.Side.BOTTOM, target: abstract_edge_router_1.Side.LEFT };
// Only to return to the
return { source: abstract_edge_router_1.Side.RIGHT, target: abstract_edge_router_1.Side.BOTTOM };
}
}
exports.ManhattanEdgeRouter = ManhattanEdgeRouter;
ManhattanEdgeRouter.KIND = 'manhattan';
//# sourceMappingURL=manhattan-edge-router.js.map