diff --git a/java/src/main/java/io/process/analytics/tools/bpmn/generator/converter/AlgoToDisplayModelConverter.java b/java/src/main/java/io/process/analytics/tools/bpmn/generator/converter/AlgoToDisplayModelConverter.java index 37ceba4..04efa24 100644 --- a/java/src/main/java/io/process/analytics/tools/bpmn/generator/converter/AlgoToDisplayModelConverter.java +++ b/java/src/main/java/io/process/analytics/tools/bpmn/generator/converter/AlgoToDisplayModelConverter.java @@ -15,9 +15,9 @@ */ package io.process.analytics.tools.bpmn.generator.converter; -import java.util.ArrayList; import java.util.List; +import io.process.analytics.tools.bpmn.generator.converter.waypoint.WayPointsComputer; import io.process.analytics.tools.bpmn.generator.model.*; import lombok.Builder; import lombok.RequiredArgsConstructor; @@ -82,195 +82,20 @@ public DisplayModel convert(Grid grid, Diagram diagram) { .rx(y(10)).strokeWidth(y(5)).build()); } + WayPointsComputer wayPointsComputer = new WayPointsComputer(grid, model.flowNodes); diagram.getEdges() .stream() - .map(edge -> new DisplayEdge(edge.getId(), inferWayPoints(edge, grid, model.flowNodes))) + .map(edge -> new DisplayEdge(edge.getId(), wayPointsComputer.inferWayPoints(edge))) .forEach(model::edge); return model.build(); } - private List inferWayPoints(Edge edge, Grid grid, List flowNodes) { - Position positionFrom = getPositionOfShape(grid, edge.getFrom()); - Position positionTo = getPositionOfShape(grid, edge.getTo()); - - EdgeDirection edgeDirection = computeEdgeDirection(positionFrom, positionTo, grid); - - DisplayFlowNode flowNodeFrom = getFlowNode(flowNodes, positionFrom.getShape()); - DisplayFlowNode flowNodeTo = getFlowNode(flowNodes, positionTo.getShape()); - - return computeWayPoints(edgeDirection, flowNodeFrom, flowNodeTo); - } - - private List computeWayPoints(EdgeDirection edgeDirection, DisplayFlowNode flowNodeFrom, DisplayFlowNode flowNodeTo) { - DisplayDimension dimensionFrom = flowNodeFrom.dimension; - DisplayDimension dimensionTo = flowNodeTo.dimension; - - List wayPoints = new ArrayList<>(); - switch (edgeDirection) { - case HorizontalLeftToRight: - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width, dimensionFrom.y + dimensionFrom.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x, dimensionTo.y + dimensionTo.height / 2)); - break; - case HorizontalRightToLeft: - wayPoints.add(new DisplayPoint(dimensionFrom.x, dimensionFrom.y + dimensionFrom.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width, dimensionTo.y + dimensionTo.height / 2)); - break; - case BottomLeftToTopRight_FirstHorizontal: // horizontal then vertical - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width, dimensionFrom.y + dimensionFrom.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionFrom.y + dimensionFrom.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y + dimensionTo.height)); - break; - case BottomLeftToTopRight_FirstVertical: // vertical then horizontal - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionFrom.y)); - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionTo.y + dimensionTo.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x, dimensionTo.y + dimensionTo.height / 2)); - break; - case BottomRightToTopLeft_FirstHorizontal: // horizontal then vertical - wayPoints.add(new DisplayPoint(dimensionFrom.x, dimensionFrom.y + dimensionFrom.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, - dimensionFrom.y + dimensionFrom.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y + dimensionTo.height)); - break; - case BottomRightToTopLeft_FirstVertical: // vertical then horizontal - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionFrom.y)); - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionTo.y + dimensionTo.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y + dimensionTo.height / 2)); - break; - case TopLeftToBottomRight_FirstHorizontal: // horizontal then vertical - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width, dimensionFrom.y + dimensionFrom.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionFrom.y + dimensionFrom.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y)); - break; - case TopLeftToBottomRight_FirstVertical: // vertical then horizontal - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionFrom.y + dimensionTo.height)); - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionTo.y + dimensionTo.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x, dimensionTo.y + dimensionTo.height / 2)); - break; - case TopRightToBottomLeft_FirstHorizontal: // horizontal then vertical - wayPoints.add(new DisplayPoint(dimensionFrom.x, dimensionFrom.y + dimensionFrom.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionFrom.y + dimensionFrom.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y)); - break; - case TopRightToBottomLeft_FirstVertical: // vertical then horizontal - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionFrom.y + dimensionTo.height)); - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionTo.y + dimensionTo.height / 2)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y + dimensionTo.height / 2)); - break; - case VerticalBottomToTop: - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionFrom.y)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y + dimensionTo.height)); - break; - case VerticalTopToBottom: - wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionFrom.y + dimensionFrom.height)); - wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y)); - break; - default: - // do nothing - } - return wayPoints; - } - - private DisplayFlowNode getFlowNode(List flowNodes, String flowNodeId) { - return flowNodes.stream() - .filter(f -> flowNodeId.equals(f.bpmnElementId)) - .findFirst() - .get(); // always exist, otherwise error occur on flow node generation - } - - private Position getPositionOfShape(Grid grid, String shapeId) { - return grid.getPositions() - .stream() - .filter(p -> shapeId.equals(p.getShape())) - .findFirst() - .get(); // always exist, otherwise error occur on flow node generation - } - - // visible for testing - static EdgeDirection computeEdgeDirection(Position positionFrom, Position positionTo, Grid grid) { - EdgeDirection edgeDirection = null; - if (positionFrom.getX() == positionTo.getX()) { - if (positionFrom.getY() < positionTo.getY()) { - edgeDirection = EdgeDirection.VerticalTopToBottom; - } - else { - edgeDirection = EdgeDirection.VerticalBottomToTop; - } - } - else if (positionFrom.getY() == positionTo.getY()) { - if (positionFrom.getX() < positionTo.getX()) { - edgeDirection = EdgeDirection.HorizontalLeftToRight; - } - else { - edgeDirection = EdgeDirection.HorizontalRightToLeft; - } - } else if (positionFrom.getX() < positionTo.getX()) { - if (positionFrom.getY() < positionTo.getY()) { - boolean shapeExistAtRightPositionFrom = grid.getPositions() - .stream() - .filter(p -> p.getY() == positionFrom.getY()) - .anyMatch(p -> p.getX() == positionFrom.getX() + 1); - edgeDirection = shapeExistAtRightPositionFrom || (isGatewayAt(positionFrom) && (!isGatewayAt(positionTo) || isGatewaySplitAt(positionTo))) ? EdgeDirection.TopLeftToBottomRight_FirstVertical : EdgeDirection.TopLeftToBottomRight_FirstHorizontal; - } - else { - if (isGatewayAt(positionFrom)) { - edgeDirection = !isGatewaySplitAt(positionFrom) || isGatewayAt(positionTo) && !isGatewaySplitAt(positionTo) ? EdgeDirection.BottomLeftToTopRight_FirstHorizontal : EdgeDirection.BottomLeftToTopRight_FirstVertical; - } else { - boolean shapeExistAbovePositionFrom = grid.getPositions() - .stream() - .filter(p -> p.getX() == positionFrom.getX()) - .anyMatch(p -> p.getY() == positionFrom.getY() - 1); - edgeDirection = shapeExistAbovePositionFrom || isGatewayAt(positionTo) ? EdgeDirection.BottomLeftToTopRight_FirstHorizontal : EdgeDirection.BottomLeftToTopRight_FirstVertical; - } - } - } else { - if (positionFrom.getY() < positionTo.getY()) { - boolean shapeExistAtLeftPositionFrom = grid.getPositions() - .stream() - .filter(p -> p.getY() == positionFrom.getY()) - .anyMatch(p -> p.getX() == positionFrom.getX() - 1); - edgeDirection = shapeExistAtLeftPositionFrom ? EdgeDirection.TopRightToBottomLeft_FirstVertical : EdgeDirection.TopRightToBottomLeft_FirstHorizontal; - } else { - boolean shapeExistAbovePositionFrom = grid.getPositions() - .stream() - .filter(p -> p.getX() == positionFrom.getX()) - .anyMatch(p -> p.getY() == positionFrom.getY() - 1); - edgeDirection = shapeExistAbovePositionFrom ? EdgeDirection.BottomRightToTopLeft_FirstHorizontal : EdgeDirection.BottomRightToTopLeft_FirstVertical; - } - } - - return edgeDirection; - } - - private static boolean isGatewayAt(Position position) { - return ShapeType.GATEWAY.equals(position.getShapeType()); - } - - private static boolean isGatewaySplitAt(Position position) { - return isGatewayAt(position) && position.isSplitGateway(); - } - - // visible for testing - static enum EdgeDirection { - HorizontalLeftToRight, - HorizontalRightToLeft, - VerticalBottomToTop, - VerticalTopToBottom, - BottomLeftToTopRight_FirstHorizontal, - BottomLeftToTopRight_FirstVertical, - BottomRightToTopLeft_FirstHorizontal, - BottomRightToTopLeft_FirstVertical, - TopLeftToBottomRight_FirstHorizontal, - TopLeftToBottomRight_FirstVertical, - TopRightToBottomLeft_FirstHorizontal, - TopRightToBottomLeft_FirstVertical, - } - - private int x(int percentage) { + private static int x(int percentage) { return CELL_WIDTH * percentage / 100; } - private int y(int percentage) { + private static int y(int percentage) { return CELL_HEIGHT * percentage / 100; } diff --git a/java/src/main/java/io/process/analytics/tools/bpmn/generator/converter/waypoint/GridSearcher.java b/java/src/main/java/io/process/analytics/tools/bpmn/generator/converter/waypoint/GridSearcher.java new file mode 100644 index 0000000..5c95405 --- /dev/null +++ b/java/src/main/java/io/process/analytics/tools/bpmn/generator/converter/waypoint/GridSearcher.java @@ -0,0 +1,58 @@ +/* + * Copyright 2021 Bonitasoft S.A. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.process.analytics.tools.bpmn.generator.converter.waypoint; + +import io.process.analytics.tools.bpmn.generator.model.Grid; +import io.process.analytics.tools.bpmn.generator.model.Position; +import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; + +import java.util.List; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@Log4j2 +public class GridSearcher { + + private final Grid grid; + + public Position getPositionOfShape(String shapeId) { + return grid.getPositions() + .stream() + .filter(p -> shapeId.equals(p.getShape())) + .findFirst() + .get(); // always exist, otherwise error occur on flow node generation + } + + public boolean isShapeExistAtLeft(Position position) { + return grid.getPositions() + .stream() + .filter(p -> p.getY() == position.getY()) + .anyMatch(p -> p.getX() == position.getX() - 1); + } + + public boolean isShapeExistAtRight(final Position position) { + return grid.getPositions() + .stream() + .filter(p -> p.getY() == position.getY()) + .anyMatch(p -> p.getX() == position.getX() + 1); + } + + public boolean isShapeExistAbove(final Position positionFrom) { + return grid.getPositions() + .stream() + .filter(p -> p.getX() == positionFrom.getX()) + .anyMatch(p -> p.getY() == positionFrom.getY() - 1); + } + +} diff --git a/java/src/main/java/io/process/analytics/tools/bpmn/generator/converter/waypoint/WayPointsComputer.java b/java/src/main/java/io/process/analytics/tools/bpmn/generator/converter/waypoint/WayPointsComputer.java new file mode 100644 index 0000000..4ab8924 --- /dev/null +++ b/java/src/main/java/io/process/analytics/tools/bpmn/generator/converter/waypoint/WayPointsComputer.java @@ -0,0 +1,209 @@ +/* + * Copyright 2021 Bonitasoft S.A. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.process.analytics.tools.bpmn.generator.converter.waypoint; + +import io.process.analytics.tools.bpmn.generator.converter.AlgoToDisplayModelConverter.DisplayDimension; +import io.process.analytics.tools.bpmn.generator.converter.AlgoToDisplayModelConverter.DisplayFlowNode; +import io.process.analytics.tools.bpmn.generator.converter.AlgoToDisplayModelConverter.DisplayPoint; +import io.process.analytics.tools.bpmn.generator.model.Edge; +import io.process.analytics.tools.bpmn.generator.model.Grid; +import io.process.analytics.tools.bpmn.generator.model.Position; +import io.process.analytics.tools.bpmn.generator.model.ShapeType; +import lombok.extern.log4j.Log4j2; + +import java.util.ArrayList; +import java.util.List; + +@Log4j2 +public class WayPointsComputer { + + private final List flowNodes; + private final GridSearcher gridSearcher; + + public WayPointsComputer(final Grid grid, final List flowNodes) { + this.flowNodes = flowNodes; + gridSearcher = new GridSearcher(grid); + } + + public List inferWayPoints(Edge edge) { + Position positionFrom = gridSearcher.getPositionOfShape(edge.getFrom()); + Position positionTo = gridSearcher.getPositionOfShape(edge.getTo()); + + EdgeDirection edgeDirection = computeEdgeDirection(positionFrom, positionTo); + + DisplayFlowNode flowNodeFrom = getFlowNode(flowNodes, positionFrom.getShape()); + DisplayFlowNode flowNodeTo = getFlowNode(flowNodes, positionTo.getShape()); + + return computeWayPoints(edgeDirection, flowNodeFrom, flowNodeTo); + } + + private static List computeWayPoints(EdgeDirection edgeDirection, DisplayFlowNode flowNodeFrom, + DisplayFlowNode flowNodeTo) { + DisplayDimension dimensionFrom = flowNodeFrom.dimension; + DisplayDimension dimensionTo = flowNodeTo.dimension; + + List wayPoints = new ArrayList<>(); + switch (edgeDirection) { + case HorizontalLeftToRight: + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width, + dimensionFrom.y + dimensionFrom.height / 2)); + wayPoints.add(new DisplayPoint(dimensionTo.x, dimensionTo.y + dimensionTo.height / 2)); + break; + case HorizontalRightToLeft: + wayPoints.add(new DisplayPoint(dimensionFrom.x, dimensionFrom.y + dimensionFrom.height / 2)); + wayPoints.add( + new DisplayPoint(dimensionTo.x + dimensionTo.width, dimensionTo.y + dimensionTo.height / 2)); + break; + case BottomLeftToTopRight_FirstHorizontal: // horizontal then vertical + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width, + dimensionFrom.y + dimensionFrom.height / 2)); + wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, + dimensionFrom.y + dimensionFrom.height / 2)); + wayPoints.add( + new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y + dimensionTo.height)); + break; + case BottomLeftToTopRight_FirstVertical: // vertical then horizontal + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionFrom.y)); + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, + dimensionTo.y + dimensionTo.height / 2)); + wayPoints.add(new DisplayPoint(dimensionTo.x, dimensionTo.y + dimensionTo.height / 2)); + break; + case BottomRightToTopLeft_FirstHorizontal: // horizontal then vertical + wayPoints.add(new DisplayPoint(dimensionFrom.x, dimensionFrom.y + dimensionFrom.height / 2)); + wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, + dimensionFrom.y + dimensionFrom.height / 2)); + wayPoints.add( + new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y + dimensionTo.height)); + break; + case BottomRightToTopLeft_FirstVertical: // vertical then horizontal + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionFrom.y)); + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, + dimensionTo.y + dimensionTo.height / 2)); + wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, + dimensionTo.y + dimensionTo.height / 2)); + break; + case TopLeftToBottomRight_FirstHorizontal: // horizontal then vertical + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width, + dimensionFrom.y + dimensionFrom.height / 2)); + wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, + dimensionFrom.y + dimensionFrom.height / 2)); + wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y)); + break; + case TopLeftToBottomRight_FirstVertical: // vertical then horizontal + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, + dimensionFrom.y + dimensionTo.height)); + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, + dimensionTo.y + dimensionTo.height / 2)); + wayPoints.add(new DisplayPoint(dimensionTo.x, dimensionTo.y + dimensionTo.height / 2)); + break; + case TopRightToBottomLeft_FirstHorizontal: // horizontal then vertical + wayPoints.add(new DisplayPoint(dimensionFrom.x, dimensionFrom.y + dimensionFrom.height / 2)); + wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, + dimensionFrom.y + dimensionFrom.height / 2)); + wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y)); + break; + case TopRightToBottomLeft_FirstVertical: // vertical then horizontal + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, + dimensionFrom.y + dimensionTo.height)); + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, + dimensionTo.y + dimensionTo.height / 2)); + wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, + dimensionTo.y + dimensionTo.height / 2)); + break; + case VerticalBottomToTop: + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, dimensionFrom.y)); + wayPoints.add( + new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y + dimensionTo.height)); + break; + case VerticalTopToBottom: + wayPoints.add(new DisplayPoint(dimensionFrom.x + dimensionFrom.width / 2, + dimensionFrom.y + dimensionFrom.height)); + wayPoints.add(new DisplayPoint(dimensionTo.x + dimensionTo.width / 2, dimensionTo.y)); + break; + default: + // do nothing + } + return wayPoints; + } + + private static DisplayFlowNode getFlowNode(List flowNodes, String flowNodeId) { + return flowNodes.stream() + .filter(f -> flowNodeId.equals(f.bpmnElementId)) + .findFirst() + .get(); // always exist, otherwise error occur on flow node generation + } + + // visible for testing + EdgeDirection computeEdgeDirection(Position positionFrom, Position positionTo) { + EdgeDirection edgeDirection = null; + if (positionFrom.getX() == positionTo.getX()) { + if (positionFrom.getY() < positionTo.getY()) { + edgeDirection = EdgeDirection.VerticalTopToBottom; + } else { + edgeDirection = EdgeDirection.VerticalBottomToTop; + } + } else if (positionFrom.getY() == positionTo.getY()) { + if (positionFrom.getX() < positionTo.getX()) { + edgeDirection = EdgeDirection.HorizontalLeftToRight; + } else { + edgeDirection = EdgeDirection.HorizontalRightToLeft; + } + } else if (positionFrom.getX() < positionTo.getX()) { + if (positionFrom.getY() < positionTo.getY()) { + boolean shapeExistAtRightPositionFrom = gridSearcher.isShapeExistAtRight(positionFrom); + edgeDirection = shapeExistAtRightPositionFrom + || (isGatewayAt(positionFrom) && (!isGatewayAt(positionTo) || isGatewaySplitAt(positionTo))) + ? EdgeDirection.TopLeftToBottomRight_FirstVertical + : EdgeDirection.TopLeftToBottomRight_FirstHorizontal; + } else { + if (isGatewayAt(positionFrom)) { + edgeDirection = !isGatewaySplitAt(positionFrom) + || isGatewayAt(positionTo) && !isGatewaySplitAt(positionTo) + ? EdgeDirection.BottomLeftToTopRight_FirstHorizontal + : EdgeDirection.BottomLeftToTopRight_FirstVertical; + } else { + boolean shapeExistAbovePositionFrom = gridSearcher.isShapeExistAbove(positionFrom); + edgeDirection = shapeExistAbovePositionFrom || isGatewayAt(positionTo) + ? EdgeDirection.BottomLeftToTopRight_FirstHorizontal + : EdgeDirection.BottomLeftToTopRight_FirstVertical; + } + } + } else { + if (positionFrom.getY() < positionTo.getY()) { + boolean shapeExistAtLeftPositionFrom = gridSearcher.isShapeExistAtLeft(positionFrom); + edgeDirection = shapeExistAtLeftPositionFrom ? EdgeDirection.TopRightToBottomLeft_FirstVertical + : EdgeDirection.TopRightToBottomLeft_FirstHorizontal; + } else { + boolean shapeExistAbovePositionFrom = gridSearcher.isShapeExistAbove(positionFrom); + edgeDirection = shapeExistAbovePositionFrom ? EdgeDirection.BottomRightToTopLeft_FirstHorizontal + : EdgeDirection.BottomRightToTopLeft_FirstVertical; + } + } + + return edgeDirection; + } + + private static boolean isGatewayAt(Position position) { + return ShapeType.GATEWAY.equals(position.getShapeType()); + } + + private static boolean isGatewaySplitAt(Position position) { + return isGatewayAt(position) && position.isSplitGateway(); + } + + // visible for testing + static enum EdgeDirection { + HorizontalLeftToRight, HorizontalRightToLeft, VerticalBottomToTop, VerticalTopToBottom, BottomLeftToTopRight_FirstHorizontal, BottomLeftToTopRight_FirstVertical, BottomRightToTopLeft_FirstHorizontal, BottomRightToTopLeft_FirstVertical, TopLeftToBottomRight_FirstHorizontal, TopLeftToBottomRight_FirstVertical, TopRightToBottomLeft_FirstHorizontal, TopRightToBottomLeft_FirstVertical, + } + +} diff --git a/java/src/test/java/io/process/analytics/tools/bpmn/generator/converter/AlgoToDisplayModelConverterTest.java b/java/src/test/java/io/process/analytics/tools/bpmn/generator/converter/waypoint/WayPointsComputerTest.java similarity index 97% rename from java/src/test/java/io/process/analytics/tools/bpmn/generator/converter/AlgoToDisplayModelConverterTest.java rename to java/src/test/java/io/process/analytics/tools/bpmn/generator/converter/waypoint/WayPointsComputerTest.java index be66b51..2a9cb5f 100644 --- a/java/src/test/java/io/process/analytics/tools/bpmn/generator/converter/AlgoToDisplayModelConverterTest.java +++ b/java/src/test/java/io/process/analytics/tools/bpmn/generator/converter/waypoint/WayPointsComputerTest.java @@ -10,20 +10,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package io.process.analytics.tools.bpmn.generator.converter; +package io.process.analytics.tools.bpmn.generator.converter.waypoint; -import io.process.analytics.tools.bpmn.generator.converter.AlgoToDisplayModelConverter.EdgeDirection; +import io.process.analytics.tools.bpmn.generator.converter.waypoint.WayPointsComputer.EdgeDirection; import io.process.analytics.tools.bpmn.generator.model.Grid; import io.process.analytics.tools.bpmn.generator.model.Position; import io.process.analytics.tools.bpmn.generator.model.Shape; import io.process.analytics.tools.bpmn.generator.model.ShapeType; import org.junit.jupiter.api.Test; -import static io.process.analytics.tools.bpmn.generator.converter.AlgoToDisplayModelConverter.EdgeDirection.*; +import static io.process.analytics.tools.bpmn.generator.converter.waypoint.WayPointsComputer.EdgeDirection.*; import static io.process.analytics.tools.bpmn.generator.model.Shape.shape; import static org.assertj.core.api.Assertions.assertThat; -class AlgoToDisplayModelConverterTest { +class WayPointsComputerTest { @Test public void computeEdgeDirection_same_row_from_on_left() { @@ -286,7 +286,7 @@ private static EdgeDirection computeEdgeDirection(Position positionFrom, Positio } private static EdgeDirection computeEdgeDirection(Position positionFrom, Position positionTo, Grid grid) { - return AlgoToDisplayModelConverter.computeEdgeDirection(positionFrom, positionTo, grid); + return new WayPointsComputer(grid, null).computeEdgeDirection(positionFrom, positionTo); } private static Position positionSameRow(int x) {