端到端功能 节点展开与闭合功能优化
This commit is contained in:
parent
e7b489532a
commit
0e50564887
Binary file not shown.
@ -7,6 +7,7 @@ import com.actionsoft.apps.coe.method.process.subprocess.graph.component.Abstrac
|
||||
import com.actionsoft.apps.coe.method.process.subprocess.graph.util.DefinitionThreadUnSafe;
|
||||
import com.actionsoft.apps.coe.method.process.subprocess.graph.util.SubProcessNodeDefineUtil;
|
||||
import com.actionsoft.apps.coe.method.process.subprocess.mode.Node;
|
||||
import com.actionsoft.apps.coe.method.process.subprocess.mode.ScopeShapeMonitor;
|
||||
import com.actionsoft.apps.coe.pal.pal.repository.designer.manage.CoeDesignerAPIManager;
|
||||
import com.actionsoft.apps.coe.pal.pal.repository.designer.model.BaseModel;
|
||||
import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.cache.DesignerShapeRelationCache;
|
||||
@ -35,6 +36,7 @@ public class GraphNodeExpandHandle {
|
||||
private JSONObject scopeLimitationShape; // 范围标注框
|
||||
private AbstractDefinitionHandle definitionHandle; // 当前总图 define 处理器
|
||||
private AbstractDefinitionHandle subProcessNodeDefineHandle; // 子流程节点 define 处理器
|
||||
private ScopeShapeMonitor scopeShapeMonitor;
|
||||
|
||||
private double[] scopeLimitationShapeBeforePoi; // 范围选择框在子流程文件中的坐标
|
||||
|
||||
@ -51,6 +53,8 @@ public class GraphNodeExpandHandle {
|
||||
definitionHandle = new DefinitionThreadUnSafe(endToEndProcessDefineStr);
|
||||
subProcessNodeDefineHandle = new DefinitionThreadUnSafe(SubProcessNodeDefineUtil.readSubProcessNodeDefine(repositoryId, shapeId));
|
||||
|
||||
scopeShapeMonitor = new ScopeShapeMonitor(definitionHandle, subProcessNodeDefineHandle);
|
||||
|
||||
toAssembleScopeLimitationShape();
|
||||
} catch (Exception e) {
|
||||
throw new AWSException(e);
|
||||
@ -99,10 +103,13 @@ public class GraphNodeExpandHandle {
|
||||
*/
|
||||
public String handleNodeExpand() throws AWSException{
|
||||
|
||||
// 1、总图节点以及连线处理
|
||||
// 1、甄别总图中的范围标识框以及其内的节点
|
||||
scopeShapeMonitor.buildScopeShapeMonitors();
|
||||
|
||||
// 2、总图节点以及连线处理
|
||||
handleEndToEndGraphNodeAndLinker();
|
||||
|
||||
// 2、子流程节点内部元素处理
|
||||
// 3、子流程节点内部元素处理
|
||||
handleRelationModelNodePosition();
|
||||
|
||||
return definitionHandle.getDefine().toJSONString();
|
||||
@ -141,12 +148,15 @@ public class GraphNodeExpandHandle {
|
||||
JSONObject processProperties = definitionHandle.getProcessProperties();
|
||||
String direction = processProperties.getString("direction");
|
||||
NodeExpandLinkerRender linkerRender = new NodeExpandLinkerRender(vertexBounding, expandAdjMatrix);
|
||||
JSONArray linkers = linkerRender.toAssembleLinker(direction, shapeId);
|
||||
JSONArray linkers = linkerRender.toAssembleLinker(direction);
|
||||
for (Object o : linkers) {
|
||||
JSONObject linker = (JSONObject) o;
|
||||
definitionHandle.addEle(linker.getString("id"), linker);
|
||||
}
|
||||
|
||||
// 范围框内的元素 坐标更新
|
||||
scopeShapeMonitor.updateScopeShapeInnerEle();
|
||||
|
||||
// 8、更新画布的大小
|
||||
// 确定画布的宽度与高度
|
||||
double w = Arrays.stream(vertexBounding).mapToDouble(position -> position[0]).max().orElse(0.0);
|
||||
@ -220,20 +230,40 @@ public class GraphNodeExpandHandle {
|
||||
JSONObject props = ele.getJSONObject("props");
|
||||
if (ele.getString("id").equals(scopeLimitationShape.getString("id"))) continue;
|
||||
if ("vertically".equals(direction)){
|
||||
if (props.getDoubleValue("x") > scopeShapeX) { // 当前元素在待展开节点的右侧
|
||||
props.put("x", props.getDoubleValue("x") + scopeShapeW - SubProcessConst.SUB_PROCESS_SHAPE_W);
|
||||
if (props.getDoubleValue("x") > scopeShapeX && !scopeShapeMonitor.checkShapeIsScopeInRange(key)) { // 当前元素在待展开节点的右侧
|
||||
double rightMoveDistance = scopeShapeW - SubProcessConst.SUB_PROCESS_SHAPE_W;
|
||||
props.put("x", props.getDoubleValue("x") + rightMoveDistance);
|
||||
if (scopeShapeMonitor.checkShapeIsScopeShape(key)){
|
||||
scopeShapeMonitor.updateMonitorRightInfo(key, true, rightMoveDistance);
|
||||
}
|
||||
}
|
||||
if (props.getDoubleValue("y") > scopeShapeY || props.getDoubleValue("y") == scopeShapeY) { // 当前元素在待展开节点的下侧
|
||||
props.put("y", props.getDoubleValue("y") + scopeShapeH - SubProcessConst.SUB_PROCESS_SHAPE_H);
|
||||
if (props.getDoubleValue("y") >= scopeShapeY && !scopeShapeMonitor.checkShapeIsScopeInRange(key)) { // 当前元素在待展开节点的下侧
|
||||
double bottomMoveDistance = scopeShapeH - SubProcessConst.SUB_PROCESS_SHAPE_H;
|
||||
props.put("y", props.getDoubleValue("y") + bottomMoveDistance);
|
||||
if (scopeShapeMonitor.checkShapeIsScopeShape(key)){
|
||||
scopeShapeMonitor.updateMonitorBottomInfo(key, true, bottomMoveDistance);
|
||||
}
|
||||
}
|
||||
}else {
|
||||
if (props.getDoubleValue("x") > scopeShapeX) { // 当前元素在待展开节点的右侧
|
||||
props.put("x", props.getDoubleValue("x") + scopeShapeW - SubProcessConst.SUB_PROCESS_SHAPE_W);
|
||||
}else if (props.getDoubleValue("x") == scopeShapeX && props.getDoubleValue("y") > scopeShapeY) { // 当前元素与待展开节点在一列上 且在下侧
|
||||
props.put("x", props.getDoubleValue("x") + scopeShapeW - SubProcessConst.SUB_PROCESS_SHAPE_W);
|
||||
if (props.getDoubleValue("x") > scopeShapeX && !scopeShapeMonitor.checkShapeIsScopeInRange(key)) { // 当前元素在待展开节点的右侧
|
||||
double rightMoveDistance = scopeShapeW - SubProcessConst.SUB_PROCESS_SHAPE_W;
|
||||
props.put("x", props.getDoubleValue("x") + rightMoveDistance);
|
||||
if (scopeShapeMonitor.checkShapeIsScopeShape(key)){
|
||||
scopeShapeMonitor.updateMonitorRightInfo(key, true, rightMoveDistance);
|
||||
}
|
||||
}else if (props.getDoubleValue("x") == scopeShapeX && props.getDoubleValue("y") > scopeShapeY && !scopeShapeMonitor.checkShapeIsScopeInRange(key)) { // 当前元素与待展开节点在一列上 且在下侧
|
||||
double rightMoveDistance = scopeShapeW - SubProcessConst.SUB_PROCESS_SHAPE_W;
|
||||
props.put("x", props.getDoubleValue("x") + rightMoveDistance);
|
||||
if (scopeShapeMonitor.checkShapeIsScopeShape(key)){
|
||||
scopeShapeMonitor.updateMonitorRightInfo(key, true, rightMoveDistance);
|
||||
}
|
||||
}
|
||||
if (props.getDoubleValue("y") > scopeShapeY) { // 当前元素在待展开节点的下侧
|
||||
props.put("y", props.getDoubleValue("y") + scopeShapeH - SubProcessConst.SUB_PROCESS_SHAPE_H);
|
||||
if (props.getDoubleValue("y") > scopeShapeY && !scopeShapeMonitor.checkShapeIsScopeInRange(key)) { // 当前元素在待展开节点的下侧
|
||||
double bottomMoveDistance = scopeShapeH - SubProcessConst.SUB_PROCESS_SHAPE_H;
|
||||
props.put("y", props.getDoubleValue("y") + bottomMoveDistance);
|
||||
if (scopeShapeMonitor.checkShapeIsScopeShape(key)){
|
||||
scopeShapeMonitor.updateMonitorBottomInfo(key, true, bottomMoveDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -251,6 +281,7 @@ public class GraphNodeExpandHandle {
|
||||
List<JSONObject> linkerList = new ArrayList<>();
|
||||
JSONObject endToEndProcessElements = definitionHandle.getElements();
|
||||
for (String key : endToEndProcessElements.keySet()) {
|
||||
if (scopeShapeMonitor.checkShapeIsScopeInRange(key)) continue; // 范围框内的元素 暂不处理
|
||||
JSONObject ele = endToEndProcessElements.getJSONObject(key);
|
||||
if ("linker".equals(ele.getString("name"))) {
|
||||
linkerList.add(ele);
|
||||
@ -270,7 +301,7 @@ public class GraphNodeExpandHandle {
|
||||
Set<String> eleKeys = new HashSet<>();
|
||||
for (String key : elements.keySet()) {
|
||||
JSONObject ele = elements.getJSONObject(key);
|
||||
if ("linker".equals(ele.getString("name"))){
|
||||
if ("linker".equals(ele.getString("name")) && !scopeShapeMonitor.checkShapeIsScopeInRange(key)){
|
||||
eleKeys.add(key);
|
||||
}
|
||||
}
|
||||
@ -356,13 +387,11 @@ class NodeExpandLinkerRender{
|
||||
private List<String> nodeIds; // 图形节点ID集合
|
||||
private double[][] vertexPosition; // 所有节点的坐标以及宽高 double[][]{{x, y, w, h},{}}
|
||||
private NodeExpandAdjMatrix expandAdjMatrix; // 节点矩阵
|
||||
// private JSONObject scopeLimitationShape; // 范围标注框
|
||||
|
||||
public NodeExpandLinkerRender(double[][] vertexPosition, NodeExpandAdjMatrix expandAdjMatrix) {
|
||||
this.nodeIds = expandAdjMatrix.getNodeIds();
|
||||
this.vertexPosition = vertexPosition;
|
||||
this.expandAdjMatrix = expandAdjMatrix;
|
||||
// this.scopeLimitationShape = scopeLimitationShape;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -371,9 +400,8 @@ class NodeExpandLinkerRender{
|
||||
* @param shapeId 当前待展开节点ID
|
||||
* @return
|
||||
*/
|
||||
public JSONArray toAssembleLinker(String direction, String shapeId){
|
||||
public JSONArray toAssembleLinker(String direction){
|
||||
JSONArray linkers = new JSONArray();
|
||||
int index = nodeIds.indexOf(shapeId);
|
||||
for (int i = 0; i < vertexPosition.length; i++) {
|
||||
double[] fromBounding = vertexPosition[i];
|
||||
List<Integer> nextNodeIndex = expandAdjMatrix.getNeighbors(i);
|
||||
|
||||
@ -0,0 +1,230 @@
|
||||
package com.actionsoft.apps.coe.method.process.subprocess.mode;
|
||||
|
||||
import com.actionsoft.apps.coe.method.process.subprocess.graph.component.AbstractDefinitionHandle;
|
||||
import com.actionsoft.apps.coe.method.process.subprocess.graph.util.SubProcessNodeDefineUtil;
|
||||
import com.actionsoft.exception.AWSException;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author oYang
|
||||
* @Description 虚线范围框及其内部元素的监视器模型
|
||||
* @createTime 2023年06月13日 14:46:00
|
||||
*/
|
||||
public class ScopeShapeMonitor {
|
||||
|
||||
private AbstractDefinitionHandle definitionHandle; // 总图 define 处理器
|
||||
private AbstractDefinitionHandle subProcessDefineHandle; // 子流程节点 define 处理器
|
||||
private Map<String, MonitorInfo> scopeShapeMonitorMap; // 范围框及内部元素集合
|
||||
|
||||
public ScopeShapeMonitor(AbstractDefinitionHandle definitionHandle, AbstractDefinitionHandle subProcessDefineHandle) {
|
||||
this.definitionHandle = definitionHandle;
|
||||
this.subProcessDefineHandle = subProcessDefineHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建范围标识框及其内部元素的监视器模型
|
||||
* @param definitionHandle 总图 define 处理器
|
||||
* @param subProcessDefineHandle 子流程节点 define 处理器
|
||||
* @return Map<String, MonitorInfo>
|
||||
*/
|
||||
public void buildScopeShapeMonitors(){
|
||||
JSONObject elements = definitionHandle.getElements();
|
||||
Set<String> scopeShapeKeySet = elements.keySet().stream().filter(key -> "scopeLimitation".equals(elements.getJSONObject(key).getString("name"))).collect(Collectors.toSet());
|
||||
if (scopeShapeKeySet.size() == 0) return;
|
||||
|
||||
Map<String, MonitorInfo> scopeShapeMonitorMap = new HashMap<>();
|
||||
for (String scopeShapeKey : scopeShapeKeySet) {
|
||||
Set<String> inScopeLimitationRangeEles = SubProcessNodeDefineUtil.getInScopeLimitationRangeEles(scopeShapeKey, definitionHandle, subProcessDefineHandle);
|
||||
MonitorInfo monitorInfo = new MonitorInfo(scopeShapeKey, false, 0.0, false, 0.0, inScopeLimitationRangeEles);
|
||||
scopeShapeMonitorMap.put(scopeShapeKey, monitorInfo);
|
||||
}
|
||||
this.scopeShapeMonitorMap = scopeShapeMonitorMap;
|
||||
}
|
||||
|
||||
public Map<String, MonitorInfo> getScopeShapeMonitorMap() {
|
||||
return scopeShapeMonitorMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新范围框的监视属性信息
|
||||
* @param scopeShapeId 当前范围框图形ID
|
||||
* @param isRightMove 是否右移
|
||||
* @param rightMoveDistance 右移动距离
|
||||
* @throws AWSException
|
||||
*/
|
||||
public void updateMonitorRightInfo(String scopeShapeId, boolean isRightMove, double rightMoveDistance) throws AWSException{
|
||||
if (scopeShapeMonitorMap == null) return;
|
||||
if (!scopeShapeMonitorMap.containsKey(scopeShapeId))
|
||||
throw new AWSException("【参数异常】当前范围框监视器不包含图形ID【" + scopeShapeId + "】");
|
||||
MonitorInfo monitorInfo = scopeShapeMonitorMap.get(scopeShapeId);
|
||||
monitorInfo.setRightMove(isRightMove);
|
||||
monitorInfo.setRightMoveDistance(rightMoveDistance);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新范围框的监视属性信息
|
||||
* @param scopeShapeId 当前范围框图形ID
|
||||
* @param isBottomMove 是否下移
|
||||
* @param bottomMoveDistance 下移距离
|
||||
* @throws AWSException
|
||||
*/
|
||||
public void updateMonitorBottomInfo(String scopeShapeId, boolean isBottomMove, double bottomMoveDistance) throws AWSException{
|
||||
if (scopeShapeMonitorMap == null) return;
|
||||
if (!scopeShapeMonitorMap.containsKey(scopeShapeId))
|
||||
throw new AWSException("【参数异常】当前范围框监视器不包含图形ID【" + scopeShapeId + "】");
|
||||
MonitorInfo monitorInfo = scopeShapeMonitorMap.get(scopeShapeId);
|
||||
monitorInfo.setBottomMove(isBottomMove);
|
||||
monitorInfo.setBottomMoveDistance(bottomMoveDistance);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查当前元素是否是某一个范围框内的元素
|
||||
* @param shapeId
|
||||
* @return
|
||||
*/
|
||||
public boolean checkShapeIsScopeInRange(String shapeId){
|
||||
boolean flag = false;
|
||||
if (scopeShapeMonitorMap != null){
|
||||
for (String key : scopeShapeMonitorMap.keySet()) {
|
||||
MonitorInfo monitorInfo = scopeShapeMonitorMap.get(key);
|
||||
Set<String> inRangeShapeIdSet = monitorInfo.getInRangeShapeIdSet();
|
||||
if (inRangeShapeIdSet.contains(shapeId)){
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查当前图形是否是范围框元素
|
||||
* @param shapeId
|
||||
* @return
|
||||
*/
|
||||
public boolean checkShapeIsScopeShape(String shapeId){
|
||||
boolean flag = false;
|
||||
if (scopeShapeMonitorMap != null){
|
||||
flag = scopeShapeMonitorMap.containsKey(shapeId);
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新范围内元素 坐标
|
||||
*/
|
||||
public void updateScopeShapeInnerEle(){
|
||||
if (scopeShapeMonitorMap != null){
|
||||
for (String scopeShapeKey : scopeShapeMonitorMap.keySet()) {
|
||||
MonitorInfo monitorInfo = scopeShapeMonitorMap.get(scopeShapeKey);
|
||||
Set<String> inRangeShapeIdSet = monitorInfo.getInRangeShapeIdSet();
|
||||
if (monitorInfo.isRightMove()){
|
||||
double rightMoveDistance = monitorInfo.getRightMoveDistance();
|
||||
for (String key : inRangeShapeIdSet) {
|
||||
JSONObject shape = definitionHandle.getShapeByKey(key);
|
||||
if ("linker".equals(shape.getString("name"))){
|
||||
JSONObject from = shape.getJSONObject("from");
|
||||
from.put("x", from.getDoubleValue("x") + rightMoveDistance);
|
||||
JSONObject to = shape.getJSONObject("to");
|
||||
to.put("x", to.getDoubleValue("x") + rightMoveDistance);
|
||||
|
||||
JSONArray points = shape.getJSONArray("points");
|
||||
for (Object o : points) {
|
||||
JSONObject point = (JSONObject) o;
|
||||
point.put("x", point.getDoubleValue("x") + rightMoveDistance);
|
||||
}
|
||||
|
||||
}else {
|
||||
JSONObject props = definitionHandle.getShapeByProps(key);
|
||||
props.put("x", props.getDoubleValue("x") + rightMoveDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (monitorInfo.isBottomMove()){
|
||||
double bottomMoveDistance = monitorInfo.getBottomMoveDistance();
|
||||
for (String key : inRangeShapeIdSet) {
|
||||
JSONObject shape = definitionHandle.getShapeByKey(key);
|
||||
if ("linker".equals(shape.getString("name"))){
|
||||
JSONObject from = shape.getJSONObject("from");
|
||||
from.put("y", from.getDoubleValue("y") + bottomMoveDistance);
|
||||
JSONObject to = shape.getJSONObject("to");
|
||||
to.put("y", to.getDoubleValue("y") + bottomMoveDistance);
|
||||
|
||||
JSONArray points = shape.getJSONArray("points");
|
||||
for (Object o : points) {
|
||||
JSONObject point = (JSONObject) o;
|
||||
point.put("y", point.getDoubleValue("y") + bottomMoveDistance);
|
||||
}
|
||||
}else {
|
||||
JSONObject props = definitionHandle.getShapeByProps(key);
|
||||
props.put("y", props.getDoubleValue("y") + bottomMoveDistance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MonitorInfo {
|
||||
|
||||
private String scopeShapeId; // 当前虚线范围框的图形ID
|
||||
private boolean isRightMove; // 范围框是否右移
|
||||
private double rightMoveDistance; // 右移动距离
|
||||
private boolean isBottomMove; // 范围框是否下移
|
||||
private double bottomMoveDistance; // 下移距离
|
||||
|
||||
private Set<String> inRangeShapeIdSet; // 范围内的图形与连线的ID集合
|
||||
|
||||
public MonitorInfo(String scopeShapeId, boolean isRightMove, double rightMoveDistance, boolean isBottomMove, double bottomMoveDistance, Set<String> inRangeShapeIdSet) {
|
||||
this.scopeShapeId = scopeShapeId;
|
||||
this.isRightMove = isRightMove;
|
||||
this.rightMoveDistance = rightMoveDistance;
|
||||
this.isBottomMove = isBottomMove;
|
||||
this.bottomMoveDistance = bottomMoveDistance;
|
||||
this.inRangeShapeIdSet = inRangeShapeIdSet;
|
||||
}
|
||||
|
||||
public boolean isRightMove() {
|
||||
return isRightMove;
|
||||
}
|
||||
|
||||
public double getRightMoveDistance() {
|
||||
return rightMoveDistance;
|
||||
}
|
||||
|
||||
public boolean isBottomMove() {
|
||||
return isBottomMove;
|
||||
}
|
||||
|
||||
public double getBottomMoveDistance() {
|
||||
return bottomMoveDistance;
|
||||
}
|
||||
|
||||
public void setRightMove(boolean rightMove) {
|
||||
isRightMove = rightMove;
|
||||
}
|
||||
|
||||
public void setRightMoveDistance(double rightMoveDistance) {
|
||||
this.rightMoveDistance = rightMoveDistance;
|
||||
}
|
||||
|
||||
public void setBottomMove(boolean bottomMove) {
|
||||
isBottomMove = bottomMove;
|
||||
}
|
||||
|
||||
public void setBottomMoveDistance(double bottomMoveDistance) {
|
||||
this.bottomMoveDistance = bottomMoveDistance;
|
||||
}
|
||||
|
||||
public Set<String> getInRangeShapeIdSet() {
|
||||
return inRangeShapeIdSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user