UNPKG

gpml2pvjson

Version:
335 lines 25.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calculateAllPoints = void 0; var fp_1 = require("lodash/fp"); var geom_utils_1 = require("../geom-utils"); var edge_1 = require("./edge"); var orientation_1 = require("./orientation"); /* import { Point, PvjsonEdge, AttachablePoint, , SegmentPoint } from "../gpml2pvjson"; //*/ var INDEX_TO_DIMENSION = ["x", "y"]; function getActiveOrientationIndexAndDimension(orientation) { var activeOrientationIndex = fp_1.findIndex(function (orientationScalar) { return orientationScalar !== 0; }, orientation); var activeOrientationDimension = INDEX_TO_DIMENSION[activeOrientationIndex]; var otherOrientationDimension = activeOrientationDimension === "x" ? "y" : "x"; return { activeOrientationIndex: activeOrientationIndex, activeOrientationDimension: activeOrientationDimension, otherOrientationDimension: otherOrientationDimension }; } /** * calculateAllPoints for edges of type Elbow and Curved * * PathVisio-Java does not always specify all the points needed to draw edges * of type Elbow and Curved. Unless the user drags one or more of the * waypoints, PathVisio-Java will only specify the first and last points, * leaving implicit one or more additional points that are required to draw * the edge. * * Kaavio requires that a PvjsonEdge specifies ALL the points required for * drawing the edge, so this function calculates any implicit points required * to unambiguously specify an edge and returns the full set of points * (implicit points are made explicit). * * @param explicitPoints {Array} * @param [sourceEntity] {Object} entity from which the EDGE emanates * (never an Anchor) * @param [targetEntity] {Object} entity into which the EDGE terminates * (never an Anchor) * @return {Array} Full set of points required to render the edge */ function calculateAllPoints(explicitPoints, sourceEntity, targetEntity) { var firstPoint = explicitPoints[0]; var lastPoint = explicitPoints[explicitPoints.length - 1]; // NOTE: we need at least one of the first point or the last point to have a // valid orientation. If that's not the case already, we try setting it here, // based on other information available to us. if (!orientation_1.validateOrientation(firstPoint.orientation)) { if (firstPoint.hasOwnProperty("isAttachedTo")) { // It is correct to specify <PvjsonEdge> as the type for // sourceEntity/targetEntity when calculating the orientation of a point // attached to another edge below, because we get into there if neither // the first nor last point have a valid orientation. If a point is // attached to a SingleFreeNode, a Group or a GPML State, it would already // have a valid orientation calculated by this point, so the point must // be either attached to nothing or else attached to an edge. firstPoint.orientation = orientation_1.getOrientationOfHyperedgeStartPoint(sourceEntity, firstPoint, lastPoint); } else { firstPoint.orientation = [-1, 0]; } } if (!orientation_1.validateOrientation(lastPoint.orientation)) { if (lastPoint.hasOwnProperty("isAttachedTo")) { // It is correct to specify <PvjsonEdge> as the type for // sourceEntity/targetEntity when calculating the orientation of a point // attached to another edge below, because we get into there if neither // the first nor last point have a valid orientation. If a point is // attached to a SingleFreeNode, a Group or a GPML State, it would already // have a valid orientation calculated by this point, so the point must // be either attached to nothing or else attached to an edge. lastPoint.orientation = orientation_1.getOrientationOfHyperedgeEndPoint(targetEntity, lastPoint, firstPoint); } else { var x0 = firstPoint.x, y0 = firstPoint.y; var x1 = lastPoint.x, y1 = lastPoint.y; var firstSide = geom_utils_1.getStartSideByOrientation(firstPoint.orientation); if (firstSide === "left") { if (x0 >= x1 && x0 < x1 + edge_1.DEFAULT_STUB_LENGTH) { lastPoint.orientation = [1, 0]; } else { lastPoint.orientation = [-1, 0]; } } else if (firstSide === "right") { if (x0 + edge_1.DEFAULT_STUB_LENGTH <= x1) { lastPoint.orientation = [1, 0]; } else { lastPoint.orientation = [-1, 0]; } } else { lastPoint.orientation = [-1, 0]; } } } if (explicitPoints.length > 2) { return explicitPoints; } var startPoint; var endPoint; var endEntity; var pointOrderReversed; if (orientation_1.validateOrientation(firstPoint.orientation)) { pointOrderReversed = false; startPoint = firstPoint; endPoint = lastPoint; endEntity = targetEntity; } else if (orientation_1.validateOrientation(lastPoint.orientation)) { pointOrderReversed = true; startPoint = lastPoint; endPoint = firstPoint; endEntity = sourceEntity; } else { throw new Error("Either first or last point (or both) should have a valid\n\t\t\torientation by now in\n\t\t\tcalculateAllPoints(\n\t\t\t\t" + JSON.stringify(explicitPoints) + ",\n\t\t\t\t" + JSON.stringify(sourceEntity) + ",\n\t\t\t\t" + JSON.stringify(targetEntity) + "\n\t\t\t)"); } var startOrientation = startPoint.orientation; var endOrientation = endPoint.orientation; var vectorSumOrientation = [ Math.sign(endPoint.x - startPoint.x), Math.sign(endPoint.y - startPoint.y) ]; var _a = getActiveOrientationIndexAndDimension(startOrientation), activeStartOrientationIndex = _a.activeOrientationIndex, activeStartOrientationDimension = _a.activeOrientationDimension, otherStartOrientationDimension = _a.otherOrientationDimension; var _b = getActiveOrientationIndexAndDimension(endOrientation), activeEndOrientationIndex = _b.activeOrientationIndex, activeEndOrientationDimension = _b.activeOrientationDimension, otherEndOrientationDimension = _b.otherOrientationDimension; var pvjsonPoints = []; pvjsonPoints.push(startPoint); // Calculate intermediate data points, which are implicit. // Remember that this refers to the minimum number of points required to // define the path, so 3 points could mean this: // // -------------------*------------------- // | | // | | // * * // // or this: // * // | // | // -------------------*------------------- // | // | // * // // or several other possible configurations // NOTE: when an edge is connected to a SingleFreeNode or a Group (how about a State?), // PathVisio-Java will route the edge around the side from which the edge // emanates, if needed. // But when an edge is connected to another edge, PathVisio-Java // does not do any special re-routing for that connection. if (activeStartOrientationIndex === activeEndOrientationIndex) { // Start and end orientations are parallel, e.g., // starts at right and ends on either right or left side, or // starts on top and ends on either top or bottom side. var activeOrientationIndex = activeStartOrientationIndex; var activeOrientationDimension = activeStartOrientationDimension; var otherOrientationDimension = otherStartOrientationDimension; var otherOrientationDimensionDisplacement = endPoint[otherOrientationDimension] - startPoint[otherOrientationDimension]; if (startOrientation[activeOrientationIndex] === vectorSumOrientation[activeOrientationIndex]) { // we don't have to avoid the start side pvjsonPoints[1] = {}; pvjsonPoints[1][otherOrientationDimension] = startPoint[otherOrientationDimension] + otherOrientationDimensionDisplacement / 2; if (startOrientation[activeOrientationIndex] === endOrientation[activeOrientationIndex]) { // *--- // | // | // * // | // | // ---------------------* pvjsonPoints[1][activeOrientationDimension] = startPoint[activeOrientationDimension] + startOrientation[activeOrientationIndex] * edge_1.DEFAULT_STUB_LENGTH; } else { // *------------------------- // | // | // * // | // | // *--- pvjsonPoints[1][activeOrientationDimension] = endPoint[activeOrientationDimension] - endOrientation[activeOrientationIndex] * edge_1.DEFAULT_STUB_LENGTH; } } else { // must initially route around start side if (startOrientation[activeOrientationIndex] === endOrientation[activeOrientationIndex]) { // *--- // | // | // * // | // | // -----------*----------- // | // | // * // | // | // ---* pvjsonPoints[1] = {}; pvjsonPoints[1][activeOrientationDimension] = startPoint[activeOrientationDimension] + startOrientation[activeOrientationIndex] * edge_1.DEFAULT_STUB_LENGTH; pvjsonPoints[1][otherOrientationDimension] = startPoint[otherOrientationDimension] + otherOrientationDimensionDisplacement / 4; pvjsonPoints[2] = {}; pvjsonPoints[2][activeOrientationDimension] = (startPoint[activeOrientationDimension] + endPoint[activeOrientationDimension]) / 2; pvjsonPoints[2][otherOrientationDimension] = startPoint[otherOrientationDimension] + otherOrientationDimensionDisplacement / 2; pvjsonPoints[3] = {}; pvjsonPoints[3][activeOrientationDimension] = endPoint[activeOrientationDimension] - endOrientation[activeOrientationIndex] * edge_1.DEFAULT_STUB_LENGTH; pvjsonPoints[3][otherOrientationDimension] = startPoint[otherOrientationDimension] + (3 * otherOrientationDimensionDisplacement) / 4; } else { // *--- // | // | // * // | // | // *--------------------- pvjsonPoints[1] = {}; pvjsonPoints[1][activeOrientationDimension] = startPoint[activeOrientationDimension] + startOrientation[activeOrientationIndex] * edge_1.DEFAULT_STUB_LENGTH; pvjsonPoints[1][otherOrientationDimension] = startPoint[otherOrientationDimension] + otherOrientationDimensionDisplacement / 2; } } } else { // Start and end orientations are perpendicular if (startOrientation[activeStartOrientationIndex] === vectorSumOrientation[activeStartOrientationIndex] && endOrientation[activeEndOrientationIndex] === vectorSumOrientation[activeEndOrientationIndex]) { // * // | // | // | // | // | // ---------------------* // // Do nothing. } else { // ---* // | // | // | // * // * | // | | // | | // --------*-------- // // or *--- // | // | // | // * // * | // | | // | | // --------*-------- // // or // // ----* // | // | // * // | // | // ---*--- // | // | // * var otherStartOrientationDimensionDisplacement = endPoint[otherStartOrientationDimension] - endOrientation[activeEndOrientationIndex] * edge_1.DEFAULT_STUB_LENGTH - startPoint[otherStartOrientationDimension]; pvjsonPoints[1] = {}; pvjsonPoints[1][activeStartOrientationDimension] = startPoint[activeStartOrientationDimension] + startOrientation[activeStartOrientationIndex] * edge_1.DEFAULT_STUB_LENGTH; pvjsonPoints[1][otherStartOrientationDimension] = startPoint[otherStartOrientationDimension] + otherStartOrientationDimensionDisplacement / 2; pvjsonPoints[2] = {}; pvjsonPoints[2][activeEndOrientationDimension] = endPoint[activeEndOrientationDimension] - endOrientation[activeEndOrientationIndex] * edge_1.DEFAULT_STUB_LENGTH; pvjsonPoints[2][otherEndOrientationDimension] = (pvjsonPoints[1][otherEndOrientationDimension] + endPoint[otherEndOrientationDimension]) / 2; } } pvjsonPoints.push(endPoint); return pointOrderReversed ? pvjsonPoints.reverse() : pvjsonPoints; } exports.calculateAllPoints = calculateAllPoints; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsY3VsYXRlQWxsUG9pbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2VkZ2UvY2FsY3VsYXRlQWxsUG9pbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLGdDQUFzRTtBQUN0RSw0Q0FVdUI7QUFTdkIsK0JBQTZDO0FBQzdDLDZDQUl1QjtBQUN2Qjs7Ozs7Ozs7SUFRSTtBQUVKLElBQU0sa0JBQWtCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7QUFFdEMsU0FBUyxxQ0FBcUMsQ0FBQyxXQUE2QjtJQUMxRSxJQUFNLHNCQUFzQixHQUFHLGNBQVMsQ0FDdEMsVUFBQyxpQkFBeUIsSUFBSyxPQUFBLGlCQUFpQixLQUFLLENBQUMsRUFBdkIsQ0FBdUIsRUFDdEQsV0FBVyxDQUNaLENBQUM7SUFDRixJQUFNLDBCQUEwQixHQUFHLGtCQUFrQixDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDOUUsSUFBTSx5QkFBeUIsR0FDN0IsMEJBQTBCLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztJQUNqRCxPQUFPO1FBQ0wsc0JBQXNCLHdCQUFBO1FBQ3RCLDBCQUEwQiw0QkFBQTtRQUMxQix5QkFBeUIsMkJBQUE7S0FDMUIsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxTQUFnQixrQkFBa0IsQ0FDaEMsY0FBc0MsRUFDdEMsWUFBc0MsRUFDdEMsWUFBc0M7SUFFdEMsSUFBSSxVQUFVLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBaUMsQ0FBQztJQUNuRSxJQUFJLFNBQVMsR0FBRyxjQUFjLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQzVDLENBQUM7SUFFYiw0RUFBNEU7SUFDNUUsNkVBQTZFO0lBQzdFLDhDQUE4QztJQUM5QyxJQUFJLENBQUMsaUNBQW1CLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FB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