端到端功能 节点展开部分代码提交

This commit is contained in:
qinoy 2023-05-30 16:32:05 +08:00
parent 17e75db1c0
commit acb645d381
4 changed files with 207 additions and 57 deletions

View File

@ -17,7 +17,6 @@ public class GraphAdjMatrix {
private int[][] adjMatrix; // 邻接矩阵
private List<Node> vertexList; // 存储节点
private int numEdges; // 边的数目
/**
* 构造函数 初始化邻接矩阵
@ -26,7 +25,6 @@ public class GraphAdjMatrix {
public GraphAdjMatrix(List<Node> nodeList) {
adjMatrix = new int[nodeList.size()][nodeList.size()];
vertexList = nodeList;
numEdges = 0;
}
/**
@ -34,7 +32,6 @@ public class GraphAdjMatrix {
*/
public void addEdge(int u, int v) {
adjMatrix[u][v] = 1; // 设置邻接矩阵中相应的位置为 1
numEdges++;
}
/**
@ -57,14 +54,6 @@ public class GraphAdjMatrix {
return adjMatrix[u][v] == 1;
}
/**
* 获取边的树目
* @return
*/
public int getNumEdges(){
return numEdges;
}
/**
* 获取邻接矩阵
* @return

View File

@ -1,6 +1,7 @@
package com.actionsoft.apps.coe.method.process.subprocess.graph;
import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst;
import com.actionsoft.apps.coe.method.process.subprocess.mode.Node;
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;
@ -11,7 +12,9 @@ import com.actionsoft.exception.AWSException;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
/**
* 图节点展开处理
@ -22,8 +25,11 @@ public class GraphNodeExpandHandle {
private String shapeId; // 总图中当前要展开的子流程图形ID
private String relationFileId; // 当前要展开的子流程图形所标识模型文件ID
private CoeDesignerAPIManager apiManager;
private String childProcessDefine; // 要展开的子流程模型信息
private String endToEndProcessDefine; // 总图的模型信息
private JSONObject childProcessDefine; // 要展开的子流程模型信息
private JSONObject endToEndProcessDefine; // 总图的模型信息
private JSONObject scopeLimitationShape; // 范围标注框
private final ReentrantLock lock = new ReentrantLock();
public GraphNodeExpandHandle(String repositoryId, String shapeId) {
this.repositoryId = repositoryId;
@ -33,35 +39,37 @@ public class GraphNodeExpandHandle {
readChildProcessDefine();
readCurrentProcessDefine();
toAssembleScopeLimitationShape();
}
/**
* 读取子流程节点的存储信息
* @throws AWSException
*/
public void readChildProcessDefine() throws AWSException{
private void readChildProcessDefine() throws AWSException{
List<DesignerShapeRelationModel> childProcessModelList = DesignerShapeRelationCache.getListByAttrId(repositoryId, shapeId, SubProcessConst.CHILD_PROCESS);
DesignerShapeRelationModel relationModel = childProcessModelList.stream().findFirst().orElse(null);
if (relationModel == null)
throw new AWSException("未找到当前节点所标识的子流程文件信息");
relationFileId = relationModel.getRelationFileId();
// 先去与总图存储的同级目录下读取 如果为空说明是初次读取
childProcessDefine = apiManager.getChildProcessDefine(repositoryId, 0, relationFileId);
if (UtilString.isEmpty(childProcessDefine)){ // 初次读取 去源文件目录读取
String childProcessDefineStr = apiManager.getChildProcessDefine(repositoryId, 0, relationFileId);
if (UtilString.isEmpty(childProcessDefineStr)){ // 初次读取 去源文件目录读取
BaseModel childProcessBaseModel = apiManager.getDefinition(relationFileId, 0);
childProcessDefine = childProcessBaseModel.getDefinition();
childProcessDefineStr = childProcessBaseModel.getDefinition();
}
childProcessDefine = JSONObject.parseObject(childProcessDefineStr);
}
/**
* 读取当前总图的存储信息
* @throws AWSException
*/
public void readCurrentProcessDefine() throws AWSException{
private void readCurrentProcessDefine() throws AWSException{
BaseModel baseModel = apiManager.getDefinition(repositoryId, 0);
if (baseModel == null)
throw new AWSException("未找到当前总图存储的模型信息");
endToEndProcessDefine = baseModel.getDefinition();
endToEndProcessDefine = JSONObject.parseObject(baseModel.getDefinition());
}
/**
@ -69,16 +77,14 @@ public class GraphNodeExpandHandle {
* @return 范围标注框
* @throws AWSException
*/
private JSONObject toAssembleScopeLimitationShape() throws AWSException{
private void toAssembleScopeLimitationShape() throws AWSException{
JSONObject scopeLimitationShape = ShapeUtil.getProcessShapeDefinition(SubProcessConst.SUB_PROCESS_METHOD_ID, "展开范围标注");
JSONObject childProcessDefineObj = JSONObject.parseObject(childProcessDefine);
JSONObject childProcessPage = childProcessDefineObj.getJSONObject("page");
JSONObject childProcessPage = childProcessDefine.getJSONObject("page");
// 当前节点所标识的子流程文件的 画布宽度与高度 减去边距
double childProcessPageWidth = childProcessPage.getDoubleValue("width") - childProcessPage.getDoubleValue("padding") * 2;
double childProcessPageHeight = childProcessPage.getDoubleValue("height") - childProcessPage.getDoubleValue("padding") * 2;
JSONObject endToEndProcessDefineObj = JSONObject.parseObject(endToEndProcessDefine);
JSONObject elements = endToEndProcessDefineObj.getJSONObject("elements");
JSONObject elements = endToEndProcessDefine.getJSONObject("elements");
// 找到当前要展开的子流程节点
JSONObject currentExpandShape = elements.getJSONObject(shapeId);
if (currentExpandShape == null)
@ -87,29 +93,63 @@ public class GraphNodeExpandHandle {
double x = props.getDoubleValue("x");
double y = props.getDoubleValue("y");
// 当前要展开的子流程节点的坐标赋给范围标注框
scopeLimitationShape.put("id", shapeId);
JSONObject scopeShapeProps = scopeLimitationShape.getJSONObject("props");
scopeShapeProps.put("x", x);
scopeShapeProps.put("y", y);
scopeShapeProps.put("w", childProcessPageWidth);
scopeShapeProps.put("h", childProcessPageHeight);
scopeShapeProps.put("zindex", 1);
return scopeLimitationShape;
this.scopeLimitationShape = scopeLimitationShape;
}
/**
* 节点展开
*/
public void handleNodeExpand() throws Exception{
Thread t1 = new Thread(() -> {
// 1子流程节点内部元素处理 包括范围标注框处理
handleRelationModelNodePosition();
});
t1.start();
Thread t2 = new Thread(() -> {
// 2子流程节点外部其它节点的位置处理
handleEndToEndGraphNodeExcluedExpandNode();
});
t2.start();
t1.join();
t2.join();
// 3构建邻接矩阵
NodeExpandAdjMatrix expandAdjMatrix = buildEndToEndGraphAdjMatrix();
expandAdjMatrix.buildAdjMatrix();
// 5根据邻接矩阵重新连线
// 6保存总图模型信息 以及 子流程模型信息备份
}
/**
* 处理子流程中所有节点的坐标
*/
public void handleRelationModelNodePosition(){
private void handleRelationModelNodePosition(){
// 删除当前要展开的节点
removeEndToEndGraphElements(shapeId);
// 添加到总图中
addEndToEndGraphElements(scopeLimitationShape);
// 范围标注框 坐标
JSONObject scopeLimitationShape = toAssembleScopeLimitationShape();
JSONObject scopeShapeProps = scopeLimitationShape.getJSONObject("props");
double scopeShapeX = scopeShapeProps.getDoubleValue("x");
double scopeShapeY = scopeShapeProps.getDoubleValue("y");
// 根据范围标注框的坐标 调整子流程所有元素的坐标
JSONObject childProcessDefineObj = JSONObject.parseObject(childProcessDefine);
JSONObject elements = childProcessDefineObj.getJSONObject("elements");
JSONObject elements = childProcessDefine.getJSONObject("elements");
for (String key : elements.keySet()) {
JSONObject ele = elements.getJSONObject(key);
JSONObject props = ele.getJSONObject("props");
@ -124,10 +164,61 @@ public class GraphNodeExpandHandle {
point.put("y", point.getDoubleValue("y") + scopeShapeY);
}
}
addEndToEndGraphElements(ele);
}
}
// 找到总图中 x坐标 >= 范围标注框x坐标 y坐标 >= 范围标注框y坐标 的图形
/**
* 处理总图中的节点
* 节点x > 范围标注框x || 节点y < 范围标注框y
* 针对符合条件的节点 进行坐标调整
*/
private void handleEndToEndGraphNodeExcluedExpandNode(){
JSONObject elements = endToEndProcessDefine.getJSONObject("elements");
// 范围标注框 大小 位置
JSONObject scopeShapeProps = scopeLimitationShape.getJSONObject("props");
double scopeShapeX = scopeShapeProps.getDoubleValue("x");
double scopeShapeY = scopeShapeProps.getDoubleValue("y");
double scopeShapeW = scopeShapeProps.getDoubleValue("w");
double scopeShapeH = scopeShapeProps.getDoubleValue("h");
for (String key : elements.keySet()) {
JSONObject ele = elements.getJSONObject(key);
JSONObject props = ele.getJSONObject("props");
if (props.getDoubleValue("x") > scopeShapeX) { // 当前元素在待展开节点的右侧
props.put("x", props.getDoubleValue("x") + scopeShapeW);
}
if (props.getDoubleValue("y") > scopeShapeY) { // 当前元素在待展开节点的下侧
props.put("y", props.getDoubleValue("y") + scopeShapeH);
}
addEndToEndGraphElements(ele);
}
}
/**
* 构建节点展开前 端到端总图的邻接矩阵
* 方便后续节点展开或者闭合进行重新连线
*/
private NodeExpandAdjMatrix buildEndToEndGraphAdjMatrix(){
List<String> nodeIdList = new ArrayList<>();
List<JSONObject> linkerList = new ArrayList<>();
JSONObject endToEndProcessElements = endToEndProcessDefine.getJSONObject("elements");
for (String key : endToEndProcessElements.keySet()) {
JSONObject ele = endToEndProcessDefine.getJSONObject(key);
if ("linker".equals(ele.getString("name"))) {
linkerList.add(ele);
// 删除旧有的连线
removeEndToEndGraphElements(key);
}else {
nodeIdList.add(key);
}
}
NodeExpandAdjMatrix expandAdjMatrix = new NodeExpandAdjMatrix(nodeIdList, linkerList);
return expandAdjMatrix;
}
/**
@ -136,6 +227,96 @@ public class GraphNodeExpandHandle {
*/
public void storeChildProcessDefine(){
BaseModel baseModel = apiManager.getDefinition(relationFileId, 0);
apiManager.storeChildProcessDefine(baseModel, relationFileId, childProcessDefine);
apiManager.storeChildProcessDefine(baseModel, relationFileId, childProcessDefine.toJSONString());
}
/**
* 总图中添加元素
* @param ele
*/
private void addEndToEndGraphElements(JSONObject ele){
JSONObject elements = endToEndProcessDefine.getJSONObject("elements");
String id = ele.getString("id");
lock.lock();
try{
elements.put(id, ele);
}finally {
lock.unlock();
}
}
/**
* 总图中删除元素
* @param key
*/
private void removeEndToEndGraphElements(String key){
JSONObject elements = endToEndProcessDefine.getJSONObject("elements");
lock.lock();
try{
elements.remove(key);
}finally {
lock.unlock();
}
}
}
class NodeExpandAdjMatrix{
private int[][] adjMatrix;
private List<String> nodeIds;
private List<JSONObject> linkerList;
public NodeExpandAdjMatrix(List<String> nodeIds, List<JSONObject> linkerList) {
this.adjMatrix = new int[nodeIds.size()][nodeIds.size()];
this.nodeIds = nodeIds;
this.linkerList = linkerList;
}
/**
* 添加一条从顶点 u 到顶点 v 的有向边
*/
public void addEdge(int u, int v) {
adjMatrix[u][v] = 1; // 设置邻接矩阵中相应的位置为 1
}
/**
* 获取从顶点 u 出发可以到达的所有顶点
*/
public List<Integer> getNeighbors(int u) {
List<Integer> neighbors = new ArrayList<>();
for (int i = 0; i < nodeIds.size(); i++) {
if (adjMatrix[u][i] == 1) {
neighbors.add(i);
}
}
return neighbors;
}
/**
* 判断从顶点 u 是否可以到达顶点 v
*/
public boolean hasEdge(int u, int v) {
return adjMatrix[u][v] == 1;
}
/**
* 获取邻接矩阵
* @return
*/
public int[][] getAdjMatrix(){
return adjMatrix;
}
/**
* 构建邻接矩阵
*/
public void buildAdjMatrix(){
for (JSONObject linker : linkerList) {
JSONObject from = linker.getJSONObject("from");
JSONObject to = linker.getJSONObject("to");
int fromIndex = nodeIds.indexOf(from.getString("id"));
int toIndex = nodeIds.indexOf(to.getString("id"));
addEdge(fromIndex, toIndex);
}
}
}

View File

@ -321,32 +321,12 @@ public class SubProcessWeb extends ActionWeb {
*
* */
// 获取子流程标识的文件存储信息
List<DesignerShapeRelationModel> childProcessModelList = DesignerShapeRelationCache.getListByAttrId(repositoryId, shapeId, SubProcessConst.CHILD_PROCESS);
DesignerShapeRelationModel relationModel = childProcessModelList.stream().findFirst().orElse(null);
if (relationModel == null)
throw new AWSException("未找到当前节点所标识的子流程文件信息");
String relationFileId = relationModel.getRelationFileId();
CoeDesignerAPIManager apiManager = CoeDesignerAPIManager.getInstance();
BaseModel childProcessBaseModel = apiManager.getDefinition(relationFileId, 0);
String childProcessDefinition = childProcessBaseModel.getDefinition();
JSONObject childProcessDefineObj = JSONObject.parseObject(childProcessDefinition);
JSONObject childProcessPage = childProcessDefineObj.getJSONObject("page");
// 当前节点所标识的子流程文件的 画布宽度与高度 减去边距
double childProcessPageWidth = childProcessPage.getDoubleValue("width") - childProcessPage.getDoubleValue("padding") * 2;
double childProcessPageHeight = childProcessPage.getDoubleValue("height") - childProcessPage.getDoubleValue("padding") * 2;
// 获取总图的存储数据
BaseModel baseModel = CoeDesignerAPIManager.getInstance().getDefinition(repositoryId, 0);
String definition = baseModel.getDefinition();
JSONObject defineJsonObj = JSONObject.parseObject(definition);
JSONObject elements = defineJsonObj.getJSONObject("elements");
JSONObject shapeObj = elements.getJSONObject(shapeId);
JSONObject shapeProps = shapeObj.getJSONObject("props");
// 当前节点的坐标
double x = shapeProps.getDoubleValue("x");
double y = shapeProps.getDoubleValue("y");
GraphNodeExpandHandle nodeExpandHandle = new GraphNodeExpandHandle(repositoryId, shapeId);
try {
nodeExpandHandle.handleNodeExpand();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}