cn.lzgabel.layouter.SimpleGridLayouter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bpmn-auto-layout Show documentation
Show all versions of bpmn-auto-layout Show documentation
Tools for auto layout bpmn files
package cn.lzgabel.layouter;
import java.awt.Dimension;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import cn.lzgabel.model.bpmn.BPMNUtils;
import cn.lzgabel.util.Util;
import org.activiti.bpmn.model.Activity;
import org.activiti.bpmn.model.BoundaryEvent;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.CallActivity;
import org.activiti.bpmn.model.Event;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.GraphicInfo;
import org.activiti.bpmn.model.Lane;
import org.activiti.bpmn.model.MessageFlow;
import org.activiti.bpmn.model.Pool;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.SubProcess;
import cn.lzgabel.model.grid.Cell;
import cn.lzgabel.model.grid.Grid;
import cn.lzgabel.model.grid.GridPosition;
public class SimpleGridLayouter extends Layouter {
private enum Direction {
DOWN, LEFT, RIGHT, UP
}
public HashMap> grids = new HashMap<>();
public Grid mainGrid;
private List containerSpanningFlows = new ArrayList<>();
private List temporarySequenceFlows = new ArrayList<>();
private HashMap>> markedCellsMap = new HashMap<>();
int cellWidth = 150;
int cellHeight = (int) ((double)cellWidth * 0.8);
int nodeWidth = (int) (cellWidth * 2 / 3); // 150 * 0.66 = 100
int nodeHeight = (int) (nodeWidth * 0.8);
int eventsize = (int) (cellWidth * 0.24);
public SimpleGridLayouter(BpmnModel model) {
super(model);
mainGrid = new Grid<>();
mainGrid.getColumns().get(0).remove(0);
}
public void applyGridToModel() {
mainGrid.setCellsize(cellHeight, cellWidth);
applyAbsoluteCoordinatesToModel();
SimpleOrthogonalFlowRouter.routeFlows(model);
}
public Grid layoutModelToGrid(boolean moveNodes) throws Exception {
containerSpanningFlows = BPMNUtils.findAndTemporarilyRemoveFlowsBetweenPartitions(model.getProcesses(), model);
temporarySequenceFlows = BPMNUtils.replaceAssociationsWithSequenceFlows(model);
layoutCallActivities();
layoutSubprocesses();
layoutPools();
layoutAndAppendProcessLanes();
if (mainGrid.isEmpty()) {
layoutSingleProcess(); // Process doesn't contains pools or lanes
}
recoverEdgesBetweenPartitions(model.getProcesses());
if(moveNodes)
{
moveNodesWithInterleavingEdges();
}
BPMNUtils.removeTemporarySequenceFlowsFromModel(temporarySequenceFlows, model);
return mainGrid;
}
public void applyAbsoluteCoordinatesToModel() {
Point absolutePosition = new Point(0, 0);
for (List> col : mainGrid.getColumns()) {
for (Cell cell : col) {
cell.absolutePosition = new Point(absolutePosition);
if (cell.getValue() != null) {
if (cell.getValue() instanceof SubProcess && BPMNUtils.activityIsExpanded(cell.getValue().getId(), model))
updateSubprocessGraphicInfo(cell.getValue().getId(), absolutePosition);
else if (cell.getValue() instanceof CallActivity && BPMNUtils.activityIsExpanded(cell.getValue().getId(), model))
updateCallActivityGraphicInfo(cell.getValue().getId(), absolutePosition);
else
updateElementGraphicInfo(cell.getValue().getId(), absolutePosition);
if (cell.getDocks().size() > 0) {
updateBoundaryEventGraphicInfo(cell, absolutePosition);
}
}
absolutePosition.y += cellHeight;
}
absolutePosition.y = 0;
absolutePosition.x += cellWidth;
}
for (Pool pool : model.getPools()) {
updatePoolGraphicInfo(pool);
}
for (Process process : model.getProcesses()) {
for (Lane lane : process.getLanes()) {
if (BPMNUtils.laneIsNotWithinPool(lane, model))
updateLaneGraphicInfo(lane);
}
}
}
private void addAllExpandedCallActivityProcessesToProcessGridMap(List processes, FlowElement flowElement) {
CallActivity callActivity = (CallActivity) flowElement;
if (BPMNUtils.activityIsExpanded(callActivity.getId(), model)) {
addCallActivityProcessToGridMap(processes, callActivity);
}
}
private void addBoundaryEventDock(Grid grid, BoundaryEvent boundaryEvent) {
FlowNode attachedToNode = boundaryEvent.getAttachedToRef();
grid.getCellByValue(attachedToNode).addDock(boundaryEvent);
}
private void addCallActivityProcessToGridMap(List processes, CallActivity callActivity) {
String id = callActivity.getCalledElement();
for (Process callActivityProcess : processes) {
if (callActivityProcess.getId().equals(id)) {
addProcessToGridMap(callActivityProcess);
}
}
}
private void addGridToMainGrid(Grid processGrid) {
if(!mainGrid.isEmpty())
{
mainGrid.addLastRow();
}
processGrid.getGridPosition().row = mainGrid.getGridSize().rows();
mainGrid.appendGrid(processGrid);
//if(processGrid.getGridPosition().row == 0)
//mainGrid.addLastRow();
}
private void addLanesToGridMap(List lanes) {
for (Lane lane : lanes) {
List flowNodes = gatherFlowNodesFromLane(lane);
Grid laneGrid = layoutFlowNodesToGrid(flowNodes);
grids.put(lane.getId(), laneGrid);
}
}
private List gatherFlowNodesFromLane(Lane lane) {
List flowReferences = lane.getFlowReferences();
List flowNodes = new ArrayList<>();
for (String ref : flowReferences) {
FlowElement e = model.getFlowElement(ref);
if (e instanceof FlowNode && !(e instanceof BoundaryEvent)) {
flowNodes.add((FlowNode) e);
}
}
return flowNodes;
}
private void addProcessToGridMap(Process process) {
List flowNodes = BPMNUtils.getFlowNodesFromFlowElementsList(process.getFlowElements());
Grid processGrid = layoutFlowNodesToGrid(flowNodes);
grids.put(process.getId(), processGrid);
}
private void createAndReserveCellsForSubprocess(SubProcess sp, GridPosition position, Grid grid) {
Grid spGrid = grids.get(sp.getId());
if(spGrid == null) {
addSubprocessGridMap(sp);
spGrid = grids.get(sp.getId());
}
int spRows = grids.get(sp.getId()).getGridSize().rows();
if(sp.getBoundaryEvents().size() > 0)
{
spRows--;
spRows--;
}
grid.addRowsBelowAndAbovePosition(position, spRows);
grid.createAndReserveCells(position, spGrid);
}
private void addSubprocessGridMap(SubProcess sp) {
Collection flowElements = sp.getFlowElements();
List flowNodes = BPMNUtils.getFlowNodesFromFlowElementsList(flowElements);
Grid subprocessGrid = layoutFlowNodesToGrid(flowNodes);
grids.put(sp.getId(), subprocessGrid);
}
private void appendLanesToMainGrid(Process process) {
if(!mainGrid.isEmpty())
{
mainGrid.addLastRow();
}
for (Lane lane : process.getLanes()) {
Grid laneGrid = grids.get(lane.getId());
laneGrid.getGridPosition().row = mainGrid.getGridSize().rows();
mainGrid.appendGrid(laneGrid);
}
}
private GridPosition calulateNodePosition(FlowNode node, Grid grid) {
GridPosition position = new GridPosition(0, 0);
Cell previousCell = null;
int incomingFlowCount = node.getIncomingFlows().size();
int outgoingFlowCount = node.getOutgoingFlows().size();
int boundaryEventCount = BPMNUtils.getBoundaryEventCount(node);
boolean positionSetByMarker = false;
if (incomingFlowCount == 0) {
if (outgoingFlowCount > 1) {
prepareGridForSplit(node, grid, position, outgoingFlowCount);
}
if(boundaryEventCount > 0)
{
prepareGridForBoundaryEvents(node, grid, position, boundaryEventCount, 1);
}
return position;
}
previousCell = getPreviousCell(node, grid);
GridPosition previousPosition = getPositionOfPreviousCell(grid, previousCell);
if(previousCell.getValue() instanceof SubProcess) {
Grid subprocessGrid = grids.get(previousCell.getValue().getId());
previousPosition.row += Math.floor((double)subprocessGrid.getGridSize().rows()/2.0);
}
position = new GridPosition(previousPosition);
if (isCellMarkerForPositionSetByPreviousNode(previousCell)) {
List> markedCells = markedCellsMap.get(previousCell.getValue());
if (isfollowingCellAlreadyInGrid(node, grid)) {
calculatePositionOfLoopElement(position, previousCell, markedCells);
} else {
position = markedCells.get(0).gridPosition;
markedCells.remove(markedCells.get(0));
}
positionSetByMarker = true;
}
if (!positionSetByMarker && BPMNUtils.isElementPartOfSequentialSequence(node, previousCell.getValue())) {
position.column = previousPosition.column + 1;
if (elementIsPartOfLoop(node, grid)) {
position = calculatePositionForLoopElement(grid, position);
}
}
if (outgoingFlowCount > 1) {
if(positionSetByMarker)
{
position.column--;
prepareGridForSplit(node, grid, position, outgoingFlowCount);
position.column++;
}else if(nodeLoopsBack(node, grid)){
if(outgoingFlowCount - 1 == 1)
{
position = getPositionOfPreviousCell(grid, previousCell);
position.column = previousPosition.column + 1;
}
}
else
{
prepareGridForSplit(node, grid, position, outgoingFlowCount);
previousCell = getPreviousCell(node, grid);
position = getPositionOfPreviousCell(grid, previousCell);
position.column = previousPosition.column + 1;
}
}
if (incomingFlowCount > 1) {
int rowSum = 0;
int prevCellCount = 0;
for (SequenceFlow e : node.getIncomingFlows()) {
FlowNode previousNode = (FlowNode) model.getFlowElement(e.getSourceRef());
if (grid.getCellByValue(previousNode) != null) { // one of the previous nodes is already in the grid
rowSum += grid.getCellByValue(previousNode).gridPosition.row;
prevCellCount++;
}
}
position.column = previousPosition.column + 1;
if(prevCellCount > 0) {
// 针对分支条件只有单边展示情况优化
if (rowSum <= 2) {
position.row = (rowSum % 2 == 0) ? rowSum-1 : rowSum+1 / prevCellCount;
} else {
position.row = rowSum / prevCellCount;
}
}
}
if(boundaryEventCount > 0)
{
position.column = previousPosition.column + 1;
while(grid.getCell(position) != null && grid.getCell(position).getValue() != null)
position.column = position.column + 1;
prepareGridForBoundaryEvents(node, grid, position, boundaryEventCount, 2);
}
return position;
}
private boolean nodeLoopsBack(FlowNode node, Grid grid) {
for(SequenceFlow flow : node.getOutgoingFlows())
{
String targetRef = flow.getTargetRef();
FlowNode targetNode = (FlowNode) model.getFlowElement(targetRef);
if(grid.getCellByValue(targetNode) != null)
return true;
}
return false;
}
private void prepareGridForBoundaryEvents(FlowNode node, Grid grid, GridPosition position, int boundaryEventCount, int colCount) {
for(int colCounter = 0; colCounter < colCount; colCounter++)
{
if(grid.getColumns().size() < position.column + colCounter + 2)
grid.addColumn();
}
markCellsForBoundaryEvents(node, position, boundaryEventCount, grid);
}
private void markCellsForBoundaryEvents(FlowNode node, GridPosition position, int boundaryEventCount, Grid grid) {
List> markedCells = new ArrayList>();
markedCellsMap.put(node, markedCells);
for (int i = 0; i < boundaryEventCount; i++) {
GridPosition markedCellPosition = new GridPosition(position.row + i + 1, position.column + 1);
if(node instanceof SubProcess && grids.get(node.getId()) != null)
{
int subprocessRows = grids.get(node.getId()).getGridSize().rows();
int subprocessColumns = grids.get(node.getId()).getGridSize().columns();
markedCellPosition.row += subprocessRows - 1;
markedCellPosition.column += subprocessColumns - 1;
}
while(grid.getGridSize().rows() < markedCellPosition.row + 1)
grid.addRowBelow(position.row + i);
while(grid.getGridSize().columns() < markedCellPosition.column + 1)
grid.addColumn();
Cell markedCell = grid.getCell(markedCellPosition);
markedCells.add(0, markedCell);
}
}
private void calculatePositionOfLoopElement(GridPosition position, Cell previousCell,
List> markedCells) {
int loopColumn = (previousCell.gridPosition.column + (position.column - 1)) / 2;
position.row = markedCells.get(0).gridPosition.row;
position.column = (loopColumn - 1);
shrinkMarkedRows(previousCell.getValue());
}
private boolean isfollowingCellAlreadyInGrid(FlowNode node, Grid grid) {
for (SequenceFlow outgoing : node.getOutgoingFlows()) {
FlowNode targetNode = (FlowNode) model.getFlowElement(outgoing.getTargetRef());
if (grid.getCellByValue(targetNode) != null)
return true;
}
return false;
}
private boolean isCellMarkerForPositionSetByPreviousNode(Cell previousCell) {
return markedCellsMap.get(previousCell.getValue()) != null && !markedCellsMap.get(previousCell.getValue()).isEmpty();
}
private void prepareGridForSplit(FlowNode node, Grid grid, GridPosition position, int outgoingFlowSize) {
if(grid.getColumns().size() <= position.column+2)
{
grid.addColumn();
grid.addColumn();
}
markCellsForSplit(node, position, outgoingFlowSize, grid);
}
private boolean elementIsPartOfLoop(FlowNode node, Grid grid) {
int outgoingFlowSize = BPMNUtils.getBoundaryEventCount(node);
if (outgoingFlowSize == 1) {
Cell subsequentCell = getSubsequentCell(node, grid);
if (subsequentCell != null && subsequentCell.getValue() != null) {
return true;
}
}
return false;
}
private GridPosition calculatePositionForLoopElement(Grid grid, GridPosition position) {
GridPosition preferedPosition = new GridPosition(position);
preferedPosition.column -= 2;
if (grid.getCell(preferedPosition).getValue() == null) {
position = preferedPosition;
} else {
grid.addRowAbove(position.column);
position.row--;
position.column--;
}
return position;
}
private Cell getSubsequentCell(FlowNode node, Grid grid) {
FlowNode firstTargetNode = BPMNUtils.getSubsequentNode(node, model);
Cell targetCell = grid.getCellByValue(firstTargetNode);
return targetCell;
}
private Cell getPreviousCell(FlowNode node, Grid grid) {
Cell previousCell;
FlowNode previousFlowNode;
previousFlowNode = getRightMostFlowNode(node.getIncomingFlows(), grid);
if (previousFlowNode instanceof BoundaryEvent) {
BoundaryEvent be = (BoundaryEvent) previousFlowNode;
previousFlowNode = be.getAttachedToRef();
}
previousCell = grid.getCellByValue(previousFlowNode);
return previousCell;
}
private GridPosition getPositionOfPreviousCell(Grid grid, Cell previousCell) {
GridPosition position = new GridPosition();
if (previousCell != null) {
if (previousCell.getValue() instanceof SubProcess || previousCell.getValue() instanceof CallActivity) {
Activity activity = (Activity) previousCell.getValue();
position = previousCell.gridPosition.clone();
if (BPMNUtils.activityIsExpanded(activity.getId(), model))
{
if (previousCell.getValue() instanceof CallActivity) {
position.column += grids.get(((CallActivity)activity).getCalledElement()).getGridSize().columns() - 1;
}
else if (previousCell.getValue() instanceof SubProcess) {
position.column += grids.get((activity).getId()).getGridSize().columns() - 1;
}
}
} else {
position = previousCell.gridPosition.clone();
}
} else
position.column = grid.getColumns().size() - 1;
return position;
}
private FlowNode getRightMostFlowNode(List incomingFlows, Grid grid) {
FlowNode rightMostNode = (FlowNode) model.getFlowElement(incomingFlows.iterator().next().getSourceRef());
int rightMostColumn = 0;
if (rightMostNode instanceof BoundaryEvent) {
BoundaryEvent be = (BoundaryEvent) rightMostNode;
FlowNode attachedTo = be.getAttachedToRef();
rightMostColumn = grid.getCellByValue(attachedTo).gridPosition.column;
} else {
rightMostColumn = grid.getCellByValue(rightMostNode).gridPosition.column;
}
for (SequenceFlow flow : incomingFlows) {
FlowNode node = (FlowNode) model.getFlowElement(flow.getSourceRef());
if (node instanceof BoundaryEvent) {
BoundaryEvent be = (BoundaryEvent) node;
node = be.getAttachedToRef();
}
Cell cell = grid.getCellByValue(node);
if(cell == null)
continue;
if (cell.gridPosition.column > rightMostColumn) {
rightMostNode = node;
rightMostColumn = cell.gridPosition.column;
}
if (node instanceof SubProcess) {
GraphicInfo gi = model.getGraphicInfo(node.getId());
if (gi.getExpanded() != null)
if (gi.getExpanded() == true) {
Grid spGrid = grids.get(node.getId());
if (cell.gridPosition.column + spGrid.getGridSize().columns() > rightMostColumn) {
rightMostNode = node;
rightMostColumn = cell.gridPosition.column + spGrid.getGridSize().columns();
}
}
}
if (node instanceof CallActivity) {
CallActivity callActivity = (CallActivity) node;
GraphicInfo gi = model.getGraphicInfo(callActivity.getId());
if (gi.getExpanded() != null)
if (gi.getExpanded() == true) {
Grid caGrid = grids.get(callActivity.getCalledElement());
if (cell.gridPosition.column + caGrid.getGridSize().columns() > rightMostColumn) {
rightMostNode = node;
rightMostColumn = cell.gridPosition.column + caGrid.getGridSize().columns();
}
}
}
}
return rightMostNode;
}
private void layoutAndAppendProcessLanes() {
for (Process process : model.getProcesses()) {
if (process.getLanes().size() != 0 && !BPMNUtils.isProcessInPool(process, model)) {
addLanesToGridMap(process.getLanes());
appendLanesToMainGrid(process);
}
}
}
private void layoutCallActivities() {
for (Process process : model.getProcesses()) {
for (FlowElement callActivity : process.findFlowElementsOfType(CallActivity.class)) {
addAllExpandedCallActivityProcessesToProcessGridMap(model.getProcesses(), callActivity);
}
}
}
private Grid layoutFlowNodesToGrid(List flowNodes) {
Grid grid = new Grid<>();
List sortedList = Util.topologicalSortNodes(flowNodes, model);
for (FlowNode node : sortedList) {
if (node instanceof BoundaryEvent) {
addBoundaryEventDock(grid, (BoundaryEvent) node);
} else {
GridPosition position = calulateNodePosition(node, grid);
if (node instanceof SubProcess && BPMNUtils.activityIsExpanded(node.getId(), model))
createAndReserveCellsForSubprocess((SubProcess) node, position, grid);
grid.addValue(node, position);
GridPosition actualPosition = grid.getCellByValue(node).gridPosition;
if(!actualPosition.equals(position))
{
if(markedCellsMap.containsKey(node))
{
int columnDifference = actualPosition.column - position.column;
List> newMarkedCellList = new ArrayList<>();
for(Cell cell : markedCellsMap.get(node))
{
GridPosition cellPosition = cell.gridPosition;
cellPosition.column += columnDifference;
newMarkedCellList.add(grid.getCell(cellPosition));
}
markedCellsMap.put(node, newMarkedCellList);
}
}
}
}
return grid;
}
private void layoutPools() {
for (Pool pool : model.getPools()) {
Process process = model.getProcess(pool.getId());
if(process == null)
{
addClosedPoolToGridMap(pool.getId());
addGridToMainGrid(grids.get(pool.getId()));
}
else if (process.getLanes().size() == 0) {
addProcessToGridMap(process);
addGridToMainGrid(grids.get(process.getId()));
} else {
addLanesToGridMap(process.getLanes());
appendLanesToMainGrid(process);
}
}
}
private void addClosedPoolToGridMap(String poolId) {
Grid poolGrid = new Grid<>();
grids.put(poolId, poolGrid);
}
private void layoutSingleProcess() {
for (Process process : model.getProcesses()) {
if (grids.containsKey(process.getId()))
continue;
else {
addProcessToGridMap(process);
addGridToMainGrid(grids.get(process.getId()));
}
}
}
private void layoutSubprocesses() {
for (Process process : model.getProcesses()) {
for (SubProcess subprocess : process.findFlowElementsOfType(SubProcess.class)) {
if(BPMNUtils.activityIsExpanded(subprocess.getId(), model))
addSubprocessGridMap(subprocess);
}
}
}
private void markCellsForSplit(FlowNode node, GridPosition position, int size, Grid grid) {
List> markedCells = new ArrayList<>();
markedCellsMap.put(node, markedCells);
if (size > 2) {
for (int i = size / 2 + 1; i < size; i++) {
int numberOfShapesInTheSplit = size;
int indexOfCurrentShape = i - 1;
int relativeYPosition = indexOfCurrentShape - numberOfShapesInTheSplit / 2;
int row = position.row + relativeYPosition;
GridPosition upperCellPosition = new GridPosition(row, position.column + 2);
grid.addRowAbove(row);
Cell upperCell = grid.getCell(upperCellPosition);
assert (upperCell != null);
markedCells.add(upperCell);
}
for (int i = size / 2; i >= 0; i--) {
int numberOfShapesInTheSplit = size;
int indexOfCurrentShape = i + 1;
if (size % 2 != 0) {
// 奇数个图形
indexOfCurrentShape = i;
}
int relativeYPosition = indexOfCurrentShape - numberOfShapesInTheSplit / 2;
int row = ((position.row + size / 2) - relativeYPosition);
GridPosition upperCellPosition = new GridPosition(row, position.column + 2);
grid.addRowBelow(row);
Cell upperCell = grid.getCell(upperCellPosition);
assert (upperCell != null);
markedCells.add(upperCell);
}
} else if (size <= 2) {
// 只有 2 个节点时处理
int currentRow = position.row;
GridPosition upperCellPosition = new GridPosition(currentRow - 1, position.column + 2);
while(grid.getCell(upperCellPosition) == null || grid.getCell(upperCellPosition).getValue() != null)
{
grid.addRowAbove(currentRow);
currentRow++;
upperCellPosition = new GridPosition(currentRow - 1, position.column + 2);
}
Cell upperCell = grid.getCell(upperCellPosition);
assert(upperCell != null);
markedCells.add(upperCell);
GridPosition lowerCellPosition = new GridPosition(currentRow + 1, position.column + 2);
while(grid.getCell(lowerCellPosition) == null || grid.getCell(lowerCellPosition).getValue() != null)
grid.addRowBelow(currentRow);
Cell lowerCell = grid.getCell(lowerCellPosition);
assert(lowerCell != null);
markedCells.add(lowerCell);
}
}
private void moveNodes(FlowNode startingFlowNode, int distance, Direction dir) throws Exception {
switch (dir) {
case RIGHT:
// collect all the nodes
List nodesPreparedForMove = BPMNUtils.findAllSubsequentFlowNodesInGroup(startingFlowNode, model);
// reverse list
Collections.reverse(nodesPreparedForMove);
// shift everything to one side
for (FlowNode node : nodesPreparedForMove) {
try {
mainGrid.shiftFlowNode(node, distance);
}catch(ArrayIndexOutOfBoundsException E) {
System.out.println("Node can't be moved");
System.out.println("Name:\t\t" + node.getName());
System.out.println("Dist:\t\t" + distance);
throw new Exception();
}
}
break;
default:
return;
}
}
private void moveNodesWithInterleavingEdges() throws Exception {
for (SequenceFlow flow : containerSpanningFlows) {
FlowNode source = (FlowNode) model.getFlowElement(flow.getSourceRef());
FlowNode target = (FlowNode) model.getFlowElement(flow.getTargetRef());
Cell srcCell = mainGrid.getCellByValue(source);
Cell trgCell = mainGrid.getCellByValue(target);
int distance = mainGrid.getColumnOf(srcCell) - mainGrid.getColumnOf(trgCell);
if (distance == 0) {
continue;
}
try {
moveNodes(target, distance, Direction.RIGHT);
}catch(Exception e) {
throw new Exception();
}
}
for (MessageFlow flow : model.getMessageFlows().values()) {
FlowNode source = (FlowNode) model.getFlowElement(flow.getSourceRef());
FlowNode target = (FlowNode) model.getFlowElement(flow.getTargetRef());
Cell srcCell = mainGrid.getCellByValue(source);
Cell trgCell = mainGrid.getCellByValue(target);
int distance = mainGrid.getColumnOf(srcCell) - mainGrid.getColumnOf(trgCell);
if (distance <= 0 || model.getPool(flow.getSourceRef()) != null || model.getPool(flow.getTargetRef()) != null) {
continue;
}
try {
moveNodes(target, distance, Direction.RIGHT);
}catch(Exception e) {
e.printStackTrace();
throw new Exception();
}
}
}
private void recoverEdgesBetweenPartitions(List processes) {
for (SequenceFlow flow : containerSpanningFlows) {
FlowNode source = (FlowNode) model.getFlowElement(flow.getSourceRef());
FlowNode target = (FlowNode) model.getFlowElement(flow.getTargetRef());
source.getOutgoingFlows().add(flow);
target.getIncomingFlows().add(flow);
}
}
private void shrinkMarkedRows(FlowNode node) {
List> markedRows = markedCellsMap.get(node);
if (markedRows.size() == 2) {
markedRows.clear();
}
}
private void updateBoundaryEventGraphicInfo(Cell cell, Point absolutePosition) {
int x = absolutePosition.x, y = absolutePosition.y;
int spGridModifierX = 0;
int spGridModifierY = 0;
if(cell.getValue() instanceof SubProcess && BPMNUtils.activityIsExpanded(cell.getValue().getId(), model))
{
Grid subprocessGrid = grids.get(cell.getValue().getId());
spGridModifierX = subprocessGrid.getAbsoluteSize().width - cellWidth;
spGridModifierY = subprocessGrid.getAbsoluteSize().height - cellHeight + (int)(eventsize * 0.5);
}
for (int i = 0; i < cell.getDocks().size(); i++) {
FlowNode dock = cell.getDocks().get(i);
dock.setName("");
GraphicInfo gi = model.getGraphicInfo(dock.getId());
switch (i) {
case 0:
x = (int) (absolutePosition.x + cellWidth * 0.4) + spGridModifierX;
y = (int) (absolutePosition.y + cellHeight * 0.65) + spGridModifierY;
cell.setAbsolutePositionOfDock(dock, new Point(x, y));
break;
case 1:
x = (int) (absolutePosition.x + cellWidth * 0.6) + spGridModifierX;
y = (int) (absolutePosition.y + cellHeight * 0.65) + spGridModifierY;
cell.setAbsolutePositionOfDock(dock, new Point(x, y));
break;
case 2:
//
break;
case 3:
//
break;
}
gi.setX(x);
gi.setY(y);
gi.setWidth(eventsize);
gi.setHeight(eventsize);
}
}
private void updateCallActivityGraphicInfo(String id, Point absolutePosition) {
GraphicInfo caGraphicInfo = model.getGraphicInfo(id);
CallActivity callActivity = (CallActivity) model.getFlowElement(id);
if (callActivity.getCalledElement() == null || caGraphicInfo.getExpanded() == null
|| caGraphicInfo.getExpanded() == false) {
int xMargin = (cellWidth - nodeWidth) / 2;
int yMargin = (cellHeight - nodeHeight) / 2;
caGraphicInfo.setX(absolutePosition.x + xMargin);
caGraphicInfo.setY(absolutePosition.y + yMargin);
caGraphicInfo.setWidth(nodeWidth);
caGraphicInfo.setHeight(nodeHeight);
return;
}
Grid processGrid = grids.get(callActivity.getCalledElement());
processGrid.setCellsize(cellHeight, cellWidth);
caGraphicInfo.setX(absolutePosition.x);
caGraphicInfo.setY(absolutePosition.y + processGrid.getAbsoluteSize().getHeight() * 0.05);
caGraphicInfo.setWidth(processGrid.getAbsoluteSize().getWidth());
caGraphicInfo.setHeight(processGrid.getAbsoluteSize().getHeight() * 0.9);
Point processElementPosition = new Point(absolutePosition);
for (List> col : processGrid.getColumns()) {
for (Cell cell : col) {
cell.absolutePosition = new Point(processElementPosition);
if (cell.getValue() != null) {
updateElementGraphicInfo(cell.getValue().getId(), processElementPosition);
if (cell.getDocks().size() > 0) {
updateBoundaryEventGraphicInfo(cell, processElementPosition);
}
}
processElementPosition.y += cellHeight;
}
processElementPosition.y = absolutePosition.y;
processElementPosition.x += cellWidth;
}
}
private void updateElementGraphicInfo(String key, Point absolutePosition) {
GraphicInfo elementGraphicInfo = model.getGraphicInfo(key);
if (model.getFlowElement(key) instanceof Activity) {
elementGraphicInfo.setWidth(nodeWidth);
elementGraphicInfo.setHeight(nodeWidth * 0.8);
}
if (model.getFlowElement(key) instanceof Event) {
elementGraphicInfo.setWidth(eventsize);
elementGraphicInfo.setHeight(eventsize);
}
int xMargin = (int) ((cellWidth - elementGraphicInfo.getWidth()) / 2);
int yMargin = (int) ((cellHeight - elementGraphicInfo.getHeight()) / 2);
elementGraphicInfo.setX(absolutePosition.x + xMargin);
elementGraphicInfo.setY(absolutePosition.y + yMargin);
}
private void updateLaneGraphicInfo(Lane lane) {
String laneId = lane.getId();
Grid laneGrid = grids.get(laneId);
laneGrid.setCellsize(cellHeight, cellWidth);
GraphicInfo flowNodeGraphicInfo = model.getGraphicInfo(lane.getId());
flowNodeGraphicInfo.setX(laneGrid.getAbsolutePosition().x);
flowNodeGraphicInfo.setY(laneGrid.getAbsolutePosition().y);
flowNodeGraphicInfo.setWidth(mainGrid.getAbsoluteSize().getWidth());
flowNodeGraphicInfo.setHeight(laneGrid.getAbsoluteSize().getHeight());
}
private void updateLaneWithinPoolGraphicInfo(Lane lane) {
String laneId = lane.getId();
Grid laneGrid = grids.get(laneId);
laneGrid.setCellsize(cellHeight, cellWidth);
int offset = 30;
GraphicInfo flowNodeGraphicInfo = model.getGraphicInfo(lane.getId());
flowNodeGraphicInfo.setX(laneGrid.getAbsolutePosition().x + offset);
flowNodeGraphicInfo.setY(laneGrid.getAbsolutePosition().y);
flowNodeGraphicInfo.setWidth(mainGrid.getAbsoluteSize().getWidth() - offset);
flowNodeGraphicInfo.setHeight(laneGrid.getAbsoluteSize().getHeight());
}
private void updatePoolGraphicInfo(Pool pool) {
String processRef = pool.getProcessRef();
Grid poolGrid = grids.get(processRef);
if(poolGrid == null)
poolGrid = grids.get(pool.getId());
if (poolGrid == null) {
Process process = BPMNUtils.getProcessFromModel(processRef, model);
if (process != null && process.getLanes().size() > 0) {
Point position = null;
Dimension size = new Dimension();
for (Lane lane : BPMNUtils.getProcessFromModel(processRef, model).getLanes()) {
Grid laneGrid = grids.get(lane.getId());
updateLaneGraphicInfo(lane);
if (position == null || laneGrid.getAbsolutePosition().y < position.y)
position = laneGrid.getAbsolutePosition();
size.height += laneGrid.getAbsoluteSize().getHeight();
updateLaneWithinPoolGraphicInfo(lane);
}
GraphicInfo poolGraphicInfo = model.getGraphicInfo(pool.getId());
poolGraphicInfo.setX(position.x);
poolGraphicInfo.setY(position.y);
poolGraphicInfo.setWidth(mainGrid.getAbsoluteSize().getWidth());
poolGraphicInfo.setHeight(size.getHeight());
}
return;
}
poolGrid.setCellsize(cellHeight, cellWidth);
GraphicInfo poolGraphicInfo = model.getGraphicInfo(pool.getId());
poolGraphicInfo.setX(poolGrid.getAbsolutePosition().x);
poolGraphicInfo.setY(poolGrid.getAbsolutePosition().y);
poolGraphicInfo.setWidth(mainGrid.getAbsoluteSize().getWidth());
poolGraphicInfo.setHeight(poolGrid.getAbsoluteSize().getHeight());
}
private void updateSubprocessGraphicInfo(String subprocessId, Point absolutePosition) {
GraphicInfo flowNodeGraphicInfo = model.getGraphicInfo(subprocessId);
Grid spGrid = grids.get(subprocessId);
spGrid.setCellsize(cellHeight, cellWidth);
if (!subprocessIsEmpty(subprocessId)) {
flowNodeGraphicInfo.setX(absolutePosition.x);
flowNodeGraphicInfo.setY(absolutePosition.y - spGrid.getAbsoluteSize().getHeight() / 3);
flowNodeGraphicInfo.setWidth(spGrid.getAbsoluteSize().getWidth());
flowNodeGraphicInfo.setHeight(spGrid.getAbsoluteSize().getHeight() * 1.67);
} else {
updateElementGraphicInfo(subprocessId, absolutePosition);
return;
}
Point spElementPosition = new Point(absolutePosition);
for (List> col : spGrid.getColumns()) {
for (Cell cell : col) {
cell.absolutePosition = new Point(spElementPosition);
if (cell.getValue() != null) {
updateElementGraphicInfo(cell.getValue().getId(), spElementPosition);
if (cell.getDocks().size() > 0) {
updateBoundaryEventGraphicInfo(cell, spElementPosition);
}
}
spElementPosition.y += cellHeight;
}
spElementPosition.y = absolutePosition.y;
spElementPosition.x += cellWidth;
}
}
private boolean subprocessIsEmpty(String subprocessId) {
if(grids.get(subprocessId).getColumns().size() > 1)
return false;
if(grids.get(subprocessId).getCell(new GridPosition(0,0)).getValue() != null)
return false;
return true;
}
}
| | | | | | | | | |
© 2015 - 2025 Weber Informatics LLC | Privacy Policy