@projectstorm/react-diagrams-routing
Version:
This package adds dagre integration for laying out nodes and links
86 lines • 3.51 kB
JavaScript
import * as PF from 'pathfinding';
/*
it can be very expensive to calculate routes when every single pixel on the canvas
is individually represented. Using the factor below, we combine values in order
to achieve the best trade-off between accuracy and performance.
*/
const pathFinderInstance = new PF.JumpPointFinder({
heuristic: PF.Heuristic.manhattan,
diagonalMovement: PF.DiagonalMovement.Never
});
export class PathFinding {
constructor(factory) {
this.instance = pathFinderInstance;
this.factory = factory;
}
/**
* Taking as argument a fully unblocked walking matrix, this method
* finds a direct path from point A to B.
*/
calculateDirectPath(from, to) {
const matrix = this.factory.getCanvasMatrix();
const grid = new PF.Grid(matrix);
return pathFinderInstance.findPath(this.factory.translateRoutingX(Math.floor(from.getX() / this.factory.ROUTING_SCALING_FACTOR)), this.factory.translateRoutingY(Math.floor(from.getY() / this.factory.ROUTING_SCALING_FACTOR)), this.factory.translateRoutingX(Math.floor(to.getX() / this.factory.ROUTING_SCALING_FACTOR)), this.factory.translateRoutingY(Math.floor(to.getY() / this.factory.ROUTING_SCALING_FACTOR)), grid);
}
/**
* Using @link{#calculateDirectPath}'s result as input, we here
* determine the first walkable point found in the matrix that includes
* blocked paths.
*/
calculateLinkStartEndCoords(matrix, path) {
const startIndex = path.findIndex((point) => {
if (matrix[point[1]])
return matrix[point[1]][point[0]] === 0;
else
return false;
});
const endIndex = path.length -
1 -
path
.slice()
.reverse()
.findIndex((point) => {
if (matrix[point[1]])
return matrix[point[1]][point[0]] === 0;
else
return false;
});
// are we trying to create a path exclusively through blocked areas?
// if so, let's fallback to the linear routing
if (startIndex === -1 || endIndex === -1) {
return undefined;
}
const pathToStart = path.slice(0, startIndex);
const pathToEnd = path.slice(endIndex);
return {
start: {
x: path[startIndex][0],
y: path[startIndex][1]
},
end: {
x: path[endIndex][0],
y: path[endIndex][1]
},
pathToStart,
pathToEnd
};
}
/**
* Puts everything together: merges the paths from/to the centre of the ports,
* with the path calculated around other elements.
*/
calculateDynamicPath(routingMatrix, start, end, pathToStart, pathToEnd) {
// generate the path based on the matrix with obstacles
const grid = new PF.Grid(routingMatrix);
const dynamicPath = pathFinderInstance.findPath(start.x, start.y, end.x, end.y, grid);
// aggregate everything to have the calculated path ready for rendering
const pathCoords = pathToStart
.concat(dynamicPath, pathToEnd)
.map((coords) => [
this.factory.translateRoutingX(coords[0], true),
this.factory.translateRoutingY(coords[1], true)
]);
return PF.Util.compressPath(pathCoords);
}
}
//# sourceMappingURL=PathFinding.js.map