端到端功能 节点展开与闭合 代码优化

This commit is contained in:
qinoy 2023-06-12 17:33:21 +08:00
parent ea80535d27
commit 9d42041fab
4 changed files with 51 additions and 129 deletions

View File

@ -125,24 +125,24 @@ public class GraphNodeCloseHandle {
if (ele.getString("id").equals(subProcessNode.getString("id"))) continue;
JSONObject eleProps = ele.getJSONObject("props");
if ("vertically".equals(direction)){ // 垂直布局
if (x + scope[0] < eleProps.getDoubleValue("x")) {
eleProps.put("x", eleProps.getDoubleValue("x") - scope[0] + SubProcessConst.SUB_PROCESS_SHAPE_W);
if (x + scope[2] < eleProps.getDoubleValue("x")) {
eleProps.put("x", eleProps.getDoubleValue("x") - scope[2] + SubProcessConst.SUB_PROCESS_SHAPE_W);
}
if (y +scope[1] < eleProps.getDoubleValue("y")){
eleProps.put("y", eleProps.getDoubleValue("y") - scope[1] + SubProcessConst.SUB_PROCESS_SHAPE_H);
}else if (y < eleProps.getDoubleValue("y") && eleProps.getDoubleValue("y") < y + scope[1]){
if (y +scope[3] < eleProps.getDoubleValue("y")){
eleProps.put("y", eleProps.getDoubleValue("y") - scope[3] + SubProcessConst.SUB_PROCESS_SHAPE_H);
}else if (y < eleProps.getDoubleValue("y") && eleProps.getDoubleValue("y") < y + scope[3]){
eleProps.put("y", y);
}
}else { // 横向布局
if (x + scope[0] < eleProps.getDoubleValue("x")){ // 节点在范围框右侧的节点
eleProps.put("x", eleProps.getDoubleValue("x") - scope[0] + SubProcessConst.SUB_PROCESS_SHAPE_W);
if (x + scope[2] < eleProps.getDoubleValue("x")){ // 节点在范围框右侧的节点
eleProps.put("x", eleProps.getDoubleValue("x") - scope[2] + SubProcessConst.SUB_PROCESS_SHAPE_W);
}else if (x < eleProps.getDoubleValue("x")
&& eleProps.getDoubleValue("x") < x + scope[0]
&& y + scope[1] < eleProps.getDoubleValue("y")){
&& eleProps.getDoubleValue("x") < x + scope[2]
&& y + scope[3] < eleProps.getDoubleValue("y")){
eleProps.put("x", x);
}
if (y + scope[1] < eleProps.getDoubleValue("y")){ // 节点在范围框下方的节点
eleProps.put("y", eleProps.getDoubleValue("y") - scope[1] + SubProcessConst.SUB_PROCESS_SHAPE_H);
if (y + scope[3] < eleProps.getDoubleValue("y")){ // 节点在范围框下方的节点
eleProps.put("y", eleProps.getDoubleValue("y") - scope[3] + SubProcessConst.SUB_PROCESS_SHAPE_H);
}
}
}

View File

@ -3,6 +3,9 @@ package com.actionsoft.apps.coe.method.process.subprocess.graph;
import com.actionsoft.apps.coe.method.process.subprocess.constant.LinkerDefConstant;
import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst;
import com.actionsoft.apps.coe.method.process.subprocess.graph.component.AbstractAdjMatrix;
import com.actionsoft.apps.coe.method.process.subprocess.graph.component.AbstractDefinitionHandle;
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.pal.pal.repository.designer.manage.CoeDesignerAPIManager;
import com.actionsoft.apps.coe.pal.pal.repository.designer.model.BaseModel;
@ -29,14 +32,12 @@ public class GraphNodeExpandHandle {
private String shapeId; // 总图中当前要展开的子流程图形ID
private String relationFileId; // 当前要展开的子流程图形所标识模型文件ID
private CoeDesignerAPIManager apiManager;
private JSONObject childProcessDefine; // 要展开的子流程模型信息
private JSONObject endToEndProcessDefine; // 总图的模型信息
private JSONObject scopeLimitationShape; // 范围标注框
private AbstractDefinitionHandle definitionHandle; // 当前总图 define 处理器
private AbstractDefinitionHandle subProcessNodeDefineHandle; // 子流程节点 define 处理器
private double[] scopeLimitationShapeBeforePoi;
private final ReentrantLock lock = new ReentrantLock();
public GraphNodeExpandHandle(String repositoryId, String shapeId, String endToEndProcessDefineStr) throws AWSException{
this.repositoryId = repositoryId;
this.shapeId = shapeId;
@ -44,45 +45,18 @@ public class GraphNodeExpandHandle {
apiManager = CoeDesignerAPIManager.getInstance();
try {
readChildProcessDefine();
readCurrentProcessDefine(endToEndProcessDefineStr);
relationFileId = SubProcessNodeDefineUtil.getSubProcessNodeRelationFileId(repositoryId, shapeId);
definitionHandle = new DefinitionThreadUnSafe(endToEndProcessDefineStr);
subProcessNodeDefineHandle = new DefinitionThreadUnSafe(SubProcessNodeDefineUtil.readSubProcessNodeDefine(repositoryId, shapeId));
toAssembleScopeLimitationShape();
} catch (Exception e) {
throw new AWSException(e);
}
}
/**
* 读取子流程节点的存储信息
* @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();
// 先去与总图存储的同级目录下读取 如果为空说明是初次读取
String childProcessDefineStr = apiManager.getChildProcessDefine(repositoryId, 0, relationFileId);
if (UtilString.isEmpty(childProcessDefineStr)){ // 初次读取 去源文件目录读取
BaseModel childProcessBaseModel = apiManager.getDefinition(relationFileId, 0);
if (childProcessBaseModel == null)
throw new AWSException("当前子流程节点内部可能没有图形元素,可以去添加后展开");
childProcessDefineStr = childProcessBaseModel.getDefinition();
}
childProcessDefine = JSONObject.parseObject(childProcessDefineStr);
}
/**
* 读取当前总图的存储信息
* @throws AWSException
*/
private void readCurrentProcessDefine(String endToEndProcessDefineStr) throws AWSException{
if (UtilString.isEmpty(endToEndProcessDefineStr))
throw new AWSException("参数异常,模型存储信息未传");
endToEndProcessDefine = JSONObject.parseObject(endToEndProcessDefineStr);
}
/**
* 组装范围标注框
* @return 范围标注框
@ -90,35 +64,12 @@ public class GraphNodeExpandHandle {
*/
private void toAssembleScopeLimitationShape() throws AWSException{
JSONObject scopeLimitationShape = ShapeUtil.getProcessShapeDefinition(SubProcessConst.SUB_PROCESS_METHOD_ID, "展开范围标注");
JSONObject childProcessElements = childProcessDefine.getJSONObject("elements");
JSONObject childProcessEleMaxX = childProcessElements.keySet()
.stream()
.filter(key -> !"linker".equals(childProcessElements.getJSONObject(key).getString("name")))
.map(key -> childProcessElements.getJSONObject(key).getJSONObject("props"))
.max((o1, o2) -> Double.compare(o1.getDoubleValue("x"), o2.getDoubleValue("x"))).get();
JSONObject childProcessEleMixX = childProcessElements.keySet()
.stream()
.filter(key -> !"linker".equals(childProcessElements.getJSONObject(key).getString("name")))
.map(key -> childProcessElements.getJSONObject(key).getJSONObject("props"))
.min((o1, o2) -> Double.compare(o1.getDoubleValue("x"), o2.getDoubleValue("x"))).get();
JSONObject childProcessEleMaxY = childProcessElements.keySet()
.stream()
.filter(key -> !"linker".equals(childProcessElements.getJSONObject(key).getString("name")))
.map(key -> childProcessElements.getJSONObject(key).getJSONObject("props"))
.max((o1, o2) -> Double.compare(o1.getDoubleValue("y"), o2.getDoubleValue("y"))).get();
JSONObject childProcessEleMinY = childProcessElements.keySet()
.stream()
.filter(key -> !"linker".equals(childProcessElements.getJSONObject(key).getString("name")))
.map(key -> childProcessElements.getJSONObject(key).getJSONObject("props"))
.min((o1, o2) -> Double.compare(o1.getDoubleValue("y"), o2.getDoubleValue("y"))).get();
// 当前节点所标识的子流程文件的 画布宽度与高度 减去边距
double scopeShapeW = childProcessEleMaxX.getDoubleValue("x") + childProcessEleMaxX.getDoubleValue("w") - childProcessEleMixX.getDoubleValue("x") + SubProcessConst.SCOPE_SHAPE_PADDING;
double scopeShapeH = childProcessEleMaxY.getDoubleValue("y") + childProcessEleMaxY.getDoubleValue("h") - childProcessEleMinY.getDoubleValue("y") + SubProcessConst.SCOPE_SHAPE_PADDING;
double[] scope = SubProcessNodeDefineUtil.calculateSubProcessNodeExpandScope(subProcessNodeDefineHandle);
// 计算下范围选择框在子流程所代表的模型文件的坐标
scopeLimitationShapeBeforePoi = new double[]{childProcessEleMixX.getDoubleValue("x") - SubProcessConst.SCOPE_SHAPE_PADDING / 2, childProcessEleMinY.getDoubleValue("y") - SubProcessConst.SCOPE_SHAPE_PADDING / 2};
scopeLimitationShapeBeforePoi = new double[]{scope[0], scope[1]};
JSONObject elements = endToEndProcessDefine.getJSONObject("elements");
JSONObject elements = definitionHandle.getElements();
// 找到当前要展开的子流程节点
JSONObject currentExpandShape = elements.getJSONObject(shapeId);
if (currentExpandShape == null)
@ -131,8 +82,8 @@ public class GraphNodeExpandHandle {
JSONObject scopeShapeProps = scopeLimitationShape.getJSONObject("props");
scopeShapeProps.put("x", x);
scopeShapeProps.put("y", y);
scopeShapeProps.put("w", scopeShapeW);
scopeShapeProps.put("h", scopeShapeH);
scopeShapeProps.put("w", scope[2]);
scopeShapeProps.put("h", scope[3]);
scopeShapeProps.put("zindex", 0);
scopeLimitationShape.put("dataAttributes", currentExpandShape.getJSONArray("dataAttributes"));
@ -169,12 +120,7 @@ public class GraphNodeExpandHandle {
// 2子流程节点内部元素处理
handleRelationModelNodePosition();
// 6保存总图模型信息 以及 子流程模型信息备份
// BaseModel baseModel = apiManager.getDefinition(repositoryId, 0);
// baseModel.setDefinition(endToEndProcessDefine.toJSONString());
// apiManager.storeDefinition(baseModel);
// apiManager.storeChildProcessDefine(baseModel, relationFileId, childProcessDefine.toJSONString());
return endToEndProcessDefine.toJSONString();
return definitionHandle.getDefine().toJSONString();
}
/**
@ -189,10 +135,10 @@ public class GraphNodeExpandHandle {
*/
private void handleEndToEndGraphNodeAndLinker(){
// 1删除当前要展开的节点
removeEndToEndGraphElements(shapeId);
definitionHandle.removeShape(shapeId);
// 2添加到总图中
addEndToEndGraphElements(scopeLimitationShape);
definitionHandle.addEle(shapeId, scopeLimitationShape);
// 3总图中符合范围选择框条件的节点 坐标更新
handleEndToEndGraphNodeExcluedExpandNode();
@ -204,16 +150,16 @@ public class GraphNodeExpandHandle {
// 5删除节点展开前的连线
removeEndToEndGraphOldLinker();
// 6获取所有节点坐标
JSONObject elements = endToEndProcessDefine.getJSONObject("elements");
JSONObject elements = definitionHandle.getElements();
double[][] vertexPosition = expandAdjMatrix.getVertexPosition(elements);
// 7构建新的连线
JSONObject processProperties = endToEndProcessDefine.getJSONObject("processProperties");
JSONObject processProperties = definitionHandle.getProcessProperties();
String direction = processProperties.getString("direction");
NodeExpandLinkerRender linkerRender = new NodeExpandLinkerRender(vertexPosition, expandAdjMatrix, scopeLimitationShape);
JSONArray linkers = linkerRender.toAssembleLinker(direction, shapeId);
for (Object o : linkers) {
JSONObject linker = (JSONObject) o;
addEndToEndGraphElements(linker);
definitionHandle.addEle(linker.getString("id"), linker);
}
// 8更新画布的大小
@ -221,7 +167,7 @@ public class GraphNodeExpandHandle {
double w = Arrays.stream(vertexPosition).mapToDouble(position -> position[0]).max().orElse(0.0);
double h = Arrays.stream(vertexPosition).mapToDouble(position -> position[1]).max().orElse(0.0);
JSONObject page = endToEndProcessDefine.getJSONObject("page");
JSONObject page = definitionHandle.getPage();
page.put("width", w + 300);
page.put("height", h + 300);
}
@ -239,7 +185,7 @@ public class GraphNodeExpandHandle {
double distanceY = scopeShapeY - scopeLimitationShapeBeforePoi[1];
// 根据范围标注框的坐标 调整子流程所有元素的坐标
JSONObject elements = childProcessDefine.getJSONObject("elements");
JSONObject elements = subProcessNodeDefineHandle.getElements();
for (String key : elements.keySet()) {
JSONObject ele = elements.getJSONObject(key);
// 元素分为两类 一类为图形 一类为连线
@ -263,7 +209,7 @@ public class GraphNodeExpandHandle {
props.put("y", distanceY + props.getDoubleValue("y"));
}
addEndToEndGraphElements(ele);
definitionHandle.addEle(key, ele);
}
}
@ -273,8 +219,8 @@ public class GraphNodeExpandHandle {
* 针对符合条件的节点 进行坐标调整
*/
private void handleEndToEndGraphNodeExcluedExpandNode(){
JSONObject elements = endToEndProcessDefine.getJSONObject("elements");
JSONObject processProperties = endToEndProcessDefine.getJSONObject("processProperties");
JSONObject elements = definitionHandle.getElements();
JSONObject processProperties = definitionHandle.getProcessProperties();
String direction = processProperties.getString("direction");
// 范围标注框 大小 位置
JSONObject scopeShapeProps = scopeLimitationShape.getJSONObject("props");
@ -306,7 +252,7 @@ public class GraphNodeExpandHandle {
}
}
addEndToEndGraphElements(ele);
definitionHandle.addEle(key, ele);
}
}
@ -318,7 +264,7 @@ public class GraphNodeExpandHandle {
List<String> nodeIdList = new ArrayList<>();
List<JSONObject> linkerList = new ArrayList<>();
JSONObject endToEndProcessElements = endToEndProcessDefine.getJSONObject("elements");
JSONObject endToEndProcessElements = definitionHandle.getElements();
for (String key : endToEndProcessElements.keySet()) {
JSONObject ele = endToEndProcessElements.getJSONObject(key);
if ("linker".equals(ele.getString("name"))) {
@ -335,7 +281,7 @@ public class GraphNodeExpandHandle {
* 删除总图中节点展开前的连线
*/
private void removeEndToEndGraphOldLinker(){
JSONObject elements = endToEndProcessDefine.getJSONObject("elements");
JSONObject elements = definitionHandle.getElements();
Set<String> eleKeys = new HashSet<>();
for (String key : elements.keySet()) {
JSONObject ele = elements.getJSONObject(key);
@ -344,7 +290,7 @@ public class GraphNodeExpandHandle {
}
}
for (String eleKey : eleKeys) {
removeEndToEndGraphElements(eleKey);
definitionHandle.removeShape(eleKey);
}
}
@ -354,37 +300,9 @@ public class GraphNodeExpandHandle {
*/
public void storeChildProcessDefine(){
BaseModel baseModel = apiManager.getDefinition(relationFileId, 0);
apiManager.storeChildProcessDefine(baseModel, relationFileId, childProcessDefine.toJSONString());
apiManager.storeChildProcessDefine(baseModel, relationFileId, subProcessNodeDefineHandle.getDefine().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();
}
}
}
/**

View File

@ -60,7 +60,7 @@ public class SubProcessNodeDefineUtil {
/**
* 计算子流程节点 展开后的宽度与高度
* @param definitionHandle
* @return double[]{w, h}
* @return double[]{x, y, w, h}
*/
public static double[] calculateSubProcessNodeExpandScope(AbstractDefinitionHandle definitionHandle){
JSONObject childProcessElements = definitionHandle.getElements();
@ -87,7 +87,11 @@ public class SubProcessNodeDefineUtil {
// 当前节点所标识的子流程文件的 画布宽度与高度 减去边距
double scopeShapeW = childProcessEleMaxX.getDoubleValue("x") + childProcessEleMaxX.getDoubleValue("w") - childProcessEleMixX.getDoubleValue("x") + SubProcessConst.SCOPE_SHAPE_PADDING;
double scopeShapeH = childProcessEleMaxY.getDoubleValue("y") + childProcessEleMaxY.getDoubleValue("h") - childProcessEleMinY.getDoubleValue("y") + SubProcessConst.SCOPE_SHAPE_PADDING;
return new double[]{scopeShapeW, scopeShapeH};
double scopeX = childProcessEleMixX.getDoubleValue("x") - SubProcessConst.SCOPE_SHAPE_PADDING / 2;
double scopeY = childProcessEleMinY.getDoubleValue("y") - SubProcessConst.SCOPE_SHAPE_PADDING / 2;
return new double[]{scopeX, scopeY, scopeShapeW, scopeShapeH};
}
/**
@ -98,8 +102,8 @@ public class SubProcessNodeDefineUtil {
* @return
*/
public static Set<String> getInScopeLimitationRangeEles(String shapeId, AbstractDefinitionHandle endToEndDefineHandle, AbstractDefinitionHandle subProcessDefineHandle){
double[] widthAndHeight = calculateSubProcessNodeExpandScope(subProcessDefineHandle); // 获取当前子流程节点展开后的范围标识框 宽度与高度
double scopeW = widthAndHeight[0], scopeH = widthAndHeight[1];
double[] scopeShapeProps = calculateSubProcessNodeExpandScope(subProcessDefineHandle); // 获取当前子流程节点展开后的范围标识框 宽度与高度
double scopeW = scopeShapeProps[2], scopeH = scopeShapeProps[3];
double scopeX = endToEndDefineHandle.getShapeByProps(shapeId).getDoubleValue("x");
double scopeY = endToEndDefineHandle.getShapeByProps(shapeId).getDoubleValue("y");
// 判断当前元素是否在范围选择框的范围内