端到端功能 节点展开与闭合 引入观察者模式优化节点位置变更 以及优化连线渲染处理器

This commit is contained in:
qinoy 2023-06-17 15:55:59 +08:00
parent 6b00e2e46c
commit b59b8ed3f9
8 changed files with 394 additions and 53 deletions

View File

@ -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.DefinitionThreadUnSafe;
import com.actionsoft.apps.coe.method.process.subprocess.graph.util.SubProcessNodeDefineUtil; import com.actionsoft.apps.coe.method.process.subprocess.graph.util.SubProcessNodeDefineUtil;
import com.actionsoft.apps.coe.method.process.subprocess.mode.ScopeShapeMonitor; import com.actionsoft.apps.coe.method.process.subprocess.mode.ScopeShapeMonitor;
import com.actionsoft.apps.coe.method.process.subprocess.observers.node.NodeSubject;
import com.actionsoft.apps.coe.pal.pal.repository.cache.PALRepositoryCache; import com.actionsoft.apps.coe.pal.pal.repository.cache.PALRepositoryCache;
import com.actionsoft.apps.coe.pal.pal.repository.designer.manage.CoeDesignerAPIManager; 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.model.BaseModel;
@ -36,6 +37,7 @@ public class GraphNodeCloseHandle {
private AbstractDefinitionHandle definitionHandle; // 当前总图 define 处理器 private AbstractDefinitionHandle definitionHandle; // 当前总图 define 处理器
private AbstractDefinitionHandle subProcessNodeDefineHandle; // 子流程节点 define 处理器 private AbstractDefinitionHandle subProcessNodeDefineHandle; // 子流程节点 define 处理器
private ScopeShapeMonitor scopeShapeMonitor; // 范围选择框及其内部元素监视器 private ScopeShapeMonitor scopeShapeMonitor; // 范围选择框及其内部元素监视器
private NodeSubject nodeSubject; // 当前操作的节点主题类
public GraphNodeCloseHandle(String repositoryId, String shapeId, String endToEndProcessDefineStr) throws AWSException{ public GraphNodeCloseHandle(String repositoryId, String shapeId, String endToEndProcessDefineStr) throws AWSException{
this.repositoryId = repositoryId; this.repositoryId = repositoryId;
@ -54,6 +56,10 @@ public class GraphNodeCloseHandle {
scopeLimitationShape = definitionHandle.getShapeByKey(shapeId); scopeLimitationShape = definitionHandle.getShapeByKey(shapeId);
scopeShapeMonitor = new ScopeShapeMonitor(definitionHandle); scopeShapeMonitor = new ScopeShapeMonitor(definitionHandle);
scopeShapeMonitor.buildScopeShapeMonitors();
nodeSubject = new NodeSubject(definitionHandle, scopeShapeMonitor, shapeId, "close");
nodeSubject.buildObservers();
} catch (AWSException e) { } catch (AWSException e) {
throw new AWSException(e); throw new AWSException(e);
@ -71,8 +77,6 @@ public class GraphNodeCloseHandle {
// 1处理范围选择框及其内部节点 // 1处理范围选择框及其内部节点
removeScopeShapeAndInRangeEle(); removeScopeShapeAndInRangeEle();
scopeShapeMonitor.buildScopeShapeMonitors();
// 2处理总图中的节点与连线 // 2处理总图中的节点与连线
handleEndToEndGraphNodeAndLinker(); handleEndToEndGraphNodeAndLinker();
@ -85,6 +89,11 @@ public class GraphNodeCloseHandle {
// 1创建对应子流程节点 // 1创建对应子流程节点
JSONObject subProcessNode = buildSubProcessNode(shapeId, scopeLimitationShape); JSONObject subProcessNode = buildSubProcessNode(shapeId, scopeLimitationShape);
definitionHandle.addEle(shapeId, subProcessNode); definitionHandle.addEle(shapeId, subProcessNode);
// 通知其它节点位置更新
nodeSubject.setScopeW(subProcessNode.getJSONObject("props").getDoubleValue("w"));
nodeSubject.setScopeH(subProcessNode.getJSONObject("props").getDoubleValue("h"));
// 2根据现有连线关系创建邻接矩阵 // 2根据现有连线关系创建邻接矩阵
NodeCloseAdjMatrix closeAdjMatrix = buildEndToEndGraphAdjMatrix(); NodeCloseAdjMatrix closeAdjMatrix = buildEndToEndGraphAdjMatrix();
closeAdjMatrix.buildAdjMatrix(); closeAdjMatrix.buildAdjMatrix();
@ -92,13 +101,13 @@ public class GraphNodeCloseHandle {
JSONObject elements = definitionHandle.getElements(); JSONObject elements = definitionHandle.getElements();
// 更新因节点展开后 坐标发生变化的节点坐标 // 更新因节点展开后 坐标发生变化的节点坐标
String direction = definitionHandle.getProcessProperties().getString("direction"); String direction = definitionHandle.getProcessProperties().getString("direction");
graphPartNodePoiRenderAgain(elements, direction, subProcessNode); // graphPartNodePoiRenderAgain(elements, direction, subProcessNode);
// 3收集现有元素坐标 // 3收集现有元素坐标
double[][] vertexBounding = closeAdjMatrix.getVertexBounding(elements); double[][] vertexBounding = closeAdjMatrix.getVertexBounding(elements);
// 4删除现有连线 // 4删除现有连线
removeEndToEndGraphOldLinker(); removeEndToEndGraphOldLinker();
// 5构建新的连线 // 5构建新的连线
NodeCloseLinkerRender linkerRender = new NodeCloseLinkerRender(vertexBounding, closeAdjMatrix); NodeCloseLinkerRender linkerRender = new NodeCloseLinkerRender(vertexBounding, closeAdjMatrix, definitionHandle);
JSONArray linkers = linkerRender.toAssembleLinker(direction); JSONArray linkers = linkerRender.toAssembleLinker(direction);
for (Object o : linkers) { for (Object o : linkers) {
JSONObject linker = (JSONObject) o; JSONObject linker = (JSONObject) o;
@ -305,6 +314,8 @@ public class GraphNodeCloseHandle {
} }
definitionHandle.removeShape(shapeId); definitionHandle.removeShape(shapeId);
scopeShapeMonitor.removeScopeShapeByKey(shapeId);
} }
} }
@ -374,11 +385,13 @@ class NodeCloseLinkerRender{
private List<String> nodeIds; // 图形节点ID集合 private List<String> nodeIds; // 图形节点ID集合
private double[][] vertexPosition; // 所有节点的坐标 private double[][] vertexPosition; // 所有节点的坐标
private NodeCloseAdjMatrix closeAdjMatrix; // 节点矩阵 private NodeCloseAdjMatrix closeAdjMatrix; // 节点矩阵
private AbstractDefinitionHandle definitionHandle;
public NodeCloseLinkerRender(double[][] vertexPosition, NodeCloseAdjMatrix closeAdjMatrix) { public NodeCloseLinkerRender(double[][] vertexPosition, NodeCloseAdjMatrix closeAdjMatrix, AbstractDefinitionHandle definitionHandle) {
this.nodeIds = closeAdjMatrix.getNodeIds(); this.nodeIds = closeAdjMatrix.getNodeIds();
this.vertexPosition = vertexPosition; this.vertexPosition = vertexPosition;
this.closeAdjMatrix = closeAdjMatrix; this.closeAdjMatrix = closeAdjMatrix;
this.definitionHandle = definitionHandle;
} }
/** /**
@ -451,38 +464,38 @@ class NodeCloseLinkerRender{
return fromY < toY return fromY < toY
? new double[][]{ ? new double[][]{
startPoi, startPoi,
{fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + getCurrentRowMaxH(fromY) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoi} endPoi}
: new double[][]{ : new double[][]{
startPoi, startPoi,
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoi}; endPoi};
}else { // 分布在四个象限内 }else { // 分布在四个象限内
if (fromX > toX && fromY > toY){ // 目标节点在第二象限 if (fromX > toX && fromY > toY){ // 目标节点在第二象限
return new double[][]{ return new double[][]{
{fromX + fromW, fromY + fromH / 2}, {fromX + fromW, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY} {toX + toW / 2, toY}
}; };
}else if (fromX > toX && fromY < toY){ // 目标节点在第三象限 }else if (fromX > toX && fromY < toY){ // 目标节点在第三象限
return toY - fromY == SubProcessConst.SHAPE_VERT_INTERVAL return toY - getCurrentRowMaxH(fromY) == SubProcessConst.SHAPE_VERT_INTERVAL // 相邻行节点
? new double[][] ? new double[][]
{ {
{fromX + fromW / 2, fromY + fromH}, {fromX + fromW / 2, fromY + fromH},
{fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + getCurrentRowMaxH(fromY) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY} {toX + toW / 2, toY}
} }
: new double[][] : new double[][]
{ {
{fromX + fromW / 2, fromY + fromH}, {fromX + fromW / 2, fromY + fromH},
{fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + getCurrentRowMaxH(fromY) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + getCurrentRowMaxH(fromY) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY} {toX + toW / 2, toY}
@ -490,7 +503,7 @@ class NodeCloseLinkerRender{
}else if (fromX < toX && fromY < toY){ // 目标节点在第四象限 }else if (fromX < toX && fromY < toY){ // 目标节点在第四象限
return new double[][]{ return new double[][]{
{fromX + fromW / 2, fromY + fromH}, {fromX + fromW / 2, fromY + fromH},
{fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + getCurrentRowMaxH(fromY) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY} {toX + toW / 2, toY}
}; };
@ -508,7 +521,7 @@ class NodeCloseLinkerRender{
? new double[][] ? new double[][]
{ {
{fromX + fromW, fromY + fromH / 2}, {fromX + fromW, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{toX - SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY + toH / 2}, {toX - SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY + toH / 2},
{toX, toY + toH / 2} {toX, toY + toH / 2}
} }
@ -525,15 +538,15 @@ class NodeCloseLinkerRender{
double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
double[] endPoint = new double[]{toX + toW / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{startPoint, return new double[][]{startPoint,
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint}; endPoint};
}else { }else {
if (fromX < toX && fromY > toY){ // 目标节点在第一象限 if (fromX < toX && fromY > toY){ // 目标节点在第一象限
double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
double turnPointX = fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2; double turnPointX = fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2;
if (fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点 if (fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点
double[] endPoint = new double[]{toX, toY + toH / 2}; double[] endPoint = new double[]{toX, toY + toH / 2};
return new double[][]{startPoint,{turnPointX, fromY + fromH / 2},{turnPointX, toY + toH / 2}, endPoint}; return new double[][]{startPoint,{turnPointX, fromY + fromH / 2},{turnPointX, toY + toH / 2}, endPoint};
}else { // 不相邻节点 存在三个折点 }else { // 不相邻节点 存在三个折点
@ -551,15 +564,15 @@ class NodeCloseLinkerRender{
double[] endPoint = new double[]{toX + toW / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{ return new double[][]{
startPoint, startPoint,
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint endPoint
}; };
}else if (fromX < toX && fromY < toY){ // 目标节点在第四象限 }else if (fromX < toX && fromY < toY){ // 目标节点在第四象限
double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
if (fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点 if (fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点
double turnPointX = fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2; double turnPointX = fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2;
double[] endPoint = new double[]{toX, toY + toH / 2}; double[] endPoint = new double[]{toX, toY + toH / 2};
return new double[][]{ return new double[][]{
startPoint, startPoint,
@ -571,8 +584,8 @@ class NodeCloseLinkerRender{
double[] endPoint = new double[]{toX + toW / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{ return new double[][]{
startPoint, startPoint,
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint endPoint
}; };
@ -584,6 +597,35 @@ class NodeCloseLinkerRender{
return new double[2][2]; return new double[2][2];
} }
/**
* 获取当前同一列图形的最大宽度 在水平布局中
* @param fromShapeX 当前图形的 x 坐标
* @return
*/
private double getCurrentColMaxW(double fromShapeX){
JSONObject elements = definitionHandle.getElements();
JSONObject props = elements.keySet().stream()
.filter(key -> !"linker".equals(elements.getJSONObject(key).getString("name")) && fromShapeX == elements.getJSONObject(key).getJSONObject("props").getDoubleValue("x"))
.map(key -> elements.getJSONObject(key).getJSONObject("props"))
.max(Comparator.comparing(o -> o.getDoubleValue("w"))).get();
return props.getDoubleValue("w");
}
/**
* 获取当前同一行图形的最大高度 在垂直布局中
* @param fromShapeY
* @return
*/
private double getCurrentRowMaxH(double fromShapeY){
JSONObject elements = definitionHandle.getElements();
JSONObject props = elements.keySet().stream()
.filter(key -> !"linker".equals(elements.getJSONObject(key).getString("name")) && fromShapeY == elements.getJSONObject(key).getJSONObject("props").getDoubleValue("y"))
.map(key -> elements.getJSONObject(key).getJSONObject("props"))
.max(Comparator.comparing(o -> o.getDoubleValue("h"))).get();
return props.getDoubleValue("h");
}
/** /**
* 计算angle值 * 计算angle值
* @param fromPoi 起始节点坐标 * @param fromPoi 起始节点坐标

View File

@ -8,6 +8,7 @@ import com.actionsoft.apps.coe.method.process.subprocess.graph.util.DefinitionTh
import com.actionsoft.apps.coe.method.process.subprocess.graph.util.SubProcessNodeDefineUtil; 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.Node;
import com.actionsoft.apps.coe.method.process.subprocess.mode.ScopeShapeMonitor; import com.actionsoft.apps.coe.method.process.subprocess.mode.ScopeShapeMonitor;
import com.actionsoft.apps.coe.method.process.subprocess.observers.node.NodeSubject;
import com.actionsoft.apps.coe.pal.pal.repository.designer.manage.CoeDesignerAPIManager; 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.model.BaseModel;
import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.cache.DesignerShapeRelationCache; import com.actionsoft.apps.coe.pal.pal.repository.designer.relation.cache.DesignerShapeRelationCache;
@ -37,6 +38,7 @@ public class GraphNodeExpandHandle {
private AbstractDefinitionHandle definitionHandle; // 当前总图 define 处理器 private AbstractDefinitionHandle definitionHandle; // 当前总图 define 处理器
private AbstractDefinitionHandle subProcessNodeDefineHandle; // 子流程节点 define 处理器 private AbstractDefinitionHandle subProcessNodeDefineHandle; // 子流程节点 define 处理器
private ScopeShapeMonitor scopeShapeMonitor; // 范围选择框及其内部元素监视器 private ScopeShapeMonitor scopeShapeMonitor; // 范围选择框及其内部元素监视器
private NodeSubject nodeSubject; // 当前操作的节点主题类
private double[] scopeLimitationShapeBeforePoi; // 范围选择框在子流程文件中的坐标 private double[] scopeLimitationShapeBeforePoi; // 范围选择框在子流程文件中的坐标
@ -54,6 +56,11 @@ public class GraphNodeExpandHandle {
subProcessNodeDefineHandle = new DefinitionThreadUnSafe(SubProcessNodeDefineUtil.readSubProcessNodeDefine(repositoryId, shapeId)); subProcessNodeDefineHandle = new DefinitionThreadUnSafe(SubProcessNodeDefineUtil.readSubProcessNodeDefine(repositoryId, shapeId));
scopeShapeMonitor = new ScopeShapeMonitor(definitionHandle); scopeShapeMonitor = new ScopeShapeMonitor(definitionHandle);
// 1构建范围框监视器模型 并关联内部元素
scopeShapeMonitor.buildScopeShapeMonitors();
nodeSubject = new NodeSubject(definitionHandle, scopeShapeMonitor, shapeId, "expand");
nodeSubject.buildObservers();
toAssembleScopeLimitationShape(); toAssembleScopeLimitationShape();
} catch (Exception e) { } catch (Exception e) {
@ -93,6 +100,10 @@ public class GraphNodeExpandHandle {
scopeLimitationShape.put("dataAttributes", currentExpandShape.getJSONArray("dataAttributes")); scopeLimitationShape.put("dataAttributes", currentExpandShape.getJSONArray("dataAttributes"));
this.scopeLimitationShape = scopeLimitationShape; this.scopeLimitationShape = scopeLimitationShape;
// 通知其它节点位置更新
nodeSubject.setScopeW(scope[2]);
nodeSubject.setScopeH(scope[3]);
} }
/** /**
@ -103,9 +114,6 @@ public class GraphNodeExpandHandle {
*/ */
public String handleNodeExpand() throws AWSException{ public String handleNodeExpand() throws AWSException{
// 1构建范围框监视器模型 并关联内部元素
scopeShapeMonitor.buildScopeShapeMonitors();
// 2总图节点以及连线处理 // 2总图节点以及连线处理
handleEndToEndGraphNodeAndLinker(); handleEndToEndGraphNodeAndLinker();
@ -136,7 +144,7 @@ public class GraphNodeExpandHandle {
definitionHandle.addEle(shapeId, scopeLimitationShape); definitionHandle.addEle(shapeId, scopeLimitationShape);
// 3总图中符合范围选择框条件的节点 坐标更新 // 3总图中符合范围选择框条件的节点 坐标更新
handleEndToEndGraphNodeExcluedExpandNode(); // handleEndToEndGraphNodeExcluedExpandNode();
// 4构建邻接矩阵 // 4构建邻接矩阵
NodeExpandAdjMatrix expandAdjMatrix = buildEndToEndGraphAdjMatrix(); NodeExpandAdjMatrix expandAdjMatrix = buildEndToEndGraphAdjMatrix();
@ -150,7 +158,7 @@ public class GraphNodeExpandHandle {
// 7构建新的连线 // 7构建新的连线
JSONObject processProperties = definitionHandle.getProcessProperties(); JSONObject processProperties = definitionHandle.getProcessProperties();
String direction = processProperties.getString("direction"); String direction = processProperties.getString("direction");
NodeExpandLinkerRender linkerRender = new NodeExpandLinkerRender(vertexBounding, expandAdjMatrix); NodeExpandLinkerRender linkerRender = new NodeExpandLinkerRender(vertexBounding, expandAdjMatrix, definitionHandle);
JSONArray linkers = linkerRender.toAssembleLinker(direction); JSONArray linkers = linkerRender.toAssembleLinker(direction);
for (Object o : linkers) { for (Object o : linkers) {
JSONObject linker = (JSONObject) o; JSONObject linker = (JSONObject) o;
@ -410,14 +418,16 @@ class NodeExpandAdjMatrix extends AbstractAdjMatrix {
*/ */
class NodeExpandLinkerRender{ class NodeExpandLinkerRender{
private AbstractDefinitionHandle definitionHandle; // 总图 define 处理器
private List<String> nodeIds; // 图形节点ID集合 private List<String> nodeIds; // 图形节点ID集合
private double[][] vertexPosition; // 所有节点的坐标以及宽高 double[][]{{x, y, w, h},{}} private double[][] vertexPosition; // 所有节点的坐标以及宽高 double[][]{{x, y, w, h},{}}
private NodeExpandAdjMatrix expandAdjMatrix; // 节点矩阵 private NodeExpandAdjMatrix expandAdjMatrix; // 节点矩阵
public NodeExpandLinkerRender(double[][] vertexPosition, NodeExpandAdjMatrix expandAdjMatrix) { public NodeExpandLinkerRender(double[][] vertexPosition, NodeExpandAdjMatrix expandAdjMatrix, AbstractDefinitionHandle definitionHandle) {
this.nodeIds = expandAdjMatrix.getNodeIds(); this.nodeIds = expandAdjMatrix.getNodeIds();
this.vertexPosition = vertexPosition; this.vertexPosition = vertexPosition;
this.expandAdjMatrix = expandAdjMatrix; this.expandAdjMatrix = expandAdjMatrix;
this.definitionHandle = definitionHandle;
} }
/** /**
@ -491,38 +501,38 @@ class NodeExpandLinkerRender{
return fromY < toY return fromY < toY
? new double[][]{ ? new double[][]{
startPoi, startPoi,
{fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + getCurrentRowMaxH(fromY) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoi} endPoi}
: new double[][]{ : new double[][]{
startPoi, startPoi,
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoi}; endPoi};
}else { // 分布在四个象限内 }else { // 分布在四个象限内
if (fromX > toX && fromY > toY){ // 目标节点在第二象限 if (fromX > toX && fromY > toY){ // 目标节点在第二象限
return new double[][]{ return new double[][]{
{fromX + fromW, fromY + fromH / 2}, {fromX + fromW, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY} {toX + toW / 2, toY}
}; };
}else if (fromX > toX && fromY < toY){ // 目标节点在第三象限 }else if (fromX > toX && fromY < toY){ // 目标节点在第三象限
return toY - fromY == SubProcessConst.SHAPE_VERT_INTERVAL return toY - getCurrentRowMaxH(fromY) == SubProcessConst.SHAPE_VERT_INTERVAL // 相邻行节点
? new double[][] ? new double[][]
{ {
{fromX + fromW / 2, fromY + fromH}, {fromX + fromW / 2, fromY + fromH},
{fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + getCurrentRowMaxH(fromY) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY} {toX + toW / 2, toY}
} }
: new double[][] : new double[][]
{ {
{fromX + fromW / 2, fromY + fromH}, {fromX + fromW / 2, fromY + fromH},
{fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + getCurrentRowMaxH(fromY) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + getCurrentRowMaxH(fromY) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY} {toX + toW / 2, toY}
@ -530,7 +540,7 @@ class NodeExpandLinkerRender{
}else if (fromX < toX && fromY < toY){ // 目标节点在第四象限 }else if (fromX < toX && fromY < toY){ // 目标节点在第四象限
return new double[][]{ return new double[][]{
{fromX + fromW / 2, fromY + fromH}, {fromX + fromW / 2, fromY + fromH},
{fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + getCurrentRowMaxH(fromY) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY} {toX + toW / 2, toY}
}; };
@ -549,7 +559,7 @@ class NodeExpandLinkerRender{
? new double[][] ? new double[][]
{ {
{fromX + fromW, fromY + fromH / 2}, {fromX + fromW, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{toX - SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY + toH / 2}, {toX - SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY + toH / 2},
{toX, toY + toH / 2} {toX, toY + toH / 2}
} }
@ -566,15 +576,15 @@ class NodeExpandLinkerRender{
double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
double[] endPoint = new double[]{toX + toW / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{startPoint, return new double[][]{startPoint,
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint}; endPoint};
}else { }else {
if (fromX < toX && fromY > toY){ // 目标节点在第一象限 if (fromX < toX && fromY > toY){ // 目标节点在第一象限
double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
double turnPointX = fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2; double turnPointX = fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2;
if (fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点 if (fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点
double[] endPoint = new double[]{toX, toY + toH / 2}; double[] endPoint = new double[]{toX, toY + toH / 2};
return new double[][]{startPoint,{turnPointX, fromY + fromH / 2},{turnPointX, toY + toH / 2}, endPoint}; return new double[][]{startPoint,{turnPointX, fromY + fromH / 2},{turnPointX, toY + toH / 2}, endPoint};
}else { // 不相邻节点 存在三个折点 }else { // 不相邻节点 存在三个折点
@ -592,15 +602,15 @@ class NodeExpandLinkerRender{
double[] endPoint = new double[]{toX + toW / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{ return new double[][]{
startPoint, startPoint,
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint endPoint
}; };
}else if (fromX < toX && fromY < toY){ // 目标节点在第四象限 }else if (fromX < toX && fromY < toY){ // 目标节点在第四象限
double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
if (fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点 if (fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点
double turnPointX = fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2; double turnPointX = fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2;
double[] endPoint = new double[]{toX, toY + toH / 2}; double[] endPoint = new double[]{toX, toY + toH / 2};
return new double[][]{ return new double[][]{
startPoint, startPoint,
@ -612,8 +622,8 @@ class NodeExpandLinkerRender{
double[] endPoint = new double[]{toX + toW / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{ return new double[][]{
startPoint, startPoint,
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + getCurrentColMaxW(fromX) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint endPoint
}; };
@ -625,6 +635,34 @@ class NodeExpandLinkerRender{
return new double[2][2]; return new double[2][2];
} }
/**
* 获取当前同一列图形的最大宽度 在水平布局中
* @param fromShapeX 当前图形的 x 坐标
* @return
*/
private double getCurrentColMaxW(double fromShapeX){
JSONObject elements = definitionHandle.getElements();
JSONObject props = elements.keySet().stream()
.filter(key -> !"linker".equals(elements.getJSONObject(key).getString("name")) && fromShapeX == elements.getJSONObject(key).getJSONObject("props").getDoubleValue("x"))
.map(key -> elements.getJSONObject(key).getJSONObject("props"))
.max(Comparator.comparing(o -> o.getDoubleValue("w"))).get();
return props.getDoubleValue("w");
}
/**
* 获取当前同一行图形的最大高度 在垂直布局中
* @param fromShapeY
* @return
*/
private double getCurrentRowMaxH(double fromShapeY){
JSONObject elements = definitionHandle.getElements();
JSONObject props = elements.keySet().stream()
.filter(key -> !"linker".equals(elements.getJSONObject(key).getString("name")) && fromShapeY == elements.getJSONObject(key).getJSONObject("props").getDoubleValue("y"))
.map(key -> elements.getJSONObject(key).getJSONObject("props"))
.max(Comparator.comparing(o -> o.getDoubleValue("h"))).get();
return props.getDoubleValue("h");
}
/** /**
* 计算angle值 * 计算angle值
* @param fromPoi 起始节点坐标 * @param fromPoi 起始节点坐标

View File

@ -71,6 +71,12 @@ public class ScopeShapeMonitor {
return scopeShapeMonitorMap; return scopeShapeMonitorMap;
} }
public void removeScopeShapeByKey(String scopeShapeId){
if (scopeShapeMonitorMap.containsKey(scopeShapeId)){
scopeShapeMonitorMap.remove(scopeShapeId);
}
}
/** /**
* 更新范围框的监视属性信息 * 更新范围框的监视属性信息
* @param scopeShapeId 当前范围框图形ID * @param scopeShapeId 当前范围框图形ID

View File

@ -0,0 +1,11 @@
package com.actionsoft.apps.coe.method.process.subprocess.observers;
/**
* @author oYang
* @Description 观察者接口
* @createTime 2023年06月16日 09:37:00
*/
public interface Observer {
void update(double deltaX, double deltaY);
}

View File

@ -0,0 +1,22 @@
package com.actionsoft.apps.coe.method.process.subprocess.observers;
/**
* @author oYang
* @Description 主题接口
* @createTime 2023年06月16日 09:45:00
*/
public interface Subject {
void addRightNodeObserver(Observer o);
void addBottomNodeObserver(Observer o);
void removeRightObserver(Observer o);
void removeBottomObserver(Observer o);
void notifyRightObservers(double deltaX, double deltaY);
void notifyBottomObservers(double deltaX, double deltaY);
}

View File

@ -0,0 +1,40 @@
package com.actionsoft.apps.coe.method.process.subprocess.observers.node;
import com.actionsoft.apps.coe.method.process.subprocess.graph.component.AbstractDefinitionHandle;
import com.actionsoft.apps.coe.method.process.subprocess.mode.ScopeShapeMonitor;
import com.actionsoft.apps.coe.method.process.subprocess.observers.Observer;
import com.alibaba.fastjson.JSONObject;
/**
* @author oYang
* @Description 画布中除当前操作节点外 其它的节点观察者类 当前的操作节点的宽度与高度发生变化时 其它的观察者节点位置根据增量调整
* @createTime 2023年06月16日 10:23:00
*/
public class NodeObserver implements Observer {
private AbstractDefinitionHandle definitionHandle;
private ScopeShapeMonitor scopeShapeMonitor; // 总图目前已存在的范围框监视模型
private String nodeKey; // 画布中的节点元素的Id
public NodeObserver(AbstractDefinitionHandle definitionHandle, ScopeShapeMonitor scopeShapeMonitor, String nodeKey) {
this.definitionHandle = definitionHandle;
this.scopeShapeMonitor = scopeShapeMonitor;
this.nodeKey = nodeKey;
}
@Override
public void update(double deltaX, double deltaY) {
if (deltaX != 0) {
definitionHandle.updateShapeX(nodeKey, definitionHandle.getShapeX(nodeKey) + deltaX);
if (scopeShapeMonitor.checkShapeIsScopeShape(nodeKey)){
scopeShapeMonitor.updateMonitorXInfo(nodeKey, true, deltaX);
}
}
if (deltaY != 0) {
definitionHandle.updateShapeY(nodeKey, definitionHandle.getShapeY(nodeKey) + deltaY);
if (scopeShapeMonitor.checkShapeIsScopeShape(nodeKey)){
scopeShapeMonitor.updateMonitorYInfo(nodeKey, true, deltaY);
}
}
}
}

View File

@ -0,0 +1,182 @@
package com.actionsoft.apps.coe.method.process.subprocess.observers.node;
import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst;
import com.actionsoft.apps.coe.method.process.subprocess.graph.component.AbstractDefinitionHandle;
import com.actionsoft.apps.coe.method.process.subprocess.mode.ScopeShapeMonitor;
import com.actionsoft.apps.coe.method.process.subprocess.observers.Observer;
import com.actionsoft.apps.coe.method.process.subprocess.observers.Subject;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* @author oYang
* @Description 当前展开或者闭合的操作节点的主题类
* @createTime 2023年06月16日 10:19:00
*/
public class NodeSubject implements Subject {
private AbstractDefinitionHandle definitionHandle; // 总图 define 处理器
private ScopeShapeMonitor scopeShapeMonitor; // 总图目前已存在的范围框监视模型
private String scopeShapeId; // 当前展开或者闭合的节点ID
private double scopeX; // 当前展开或者闭合的节点 x
private double scopeY; // 当前展开或者闭合的节点 y
private double scopeW; // 当前展开或者闭合的节点 w
private double scopeH; // 当前展开或者闭合的节点 h
private String action; // expand / close
private List<Observer> rightObservers = new ArrayList<>();
private List<Observer> bottomObservers = new ArrayList<>();
public NodeSubject(AbstractDefinitionHandle definitionHandle, ScopeShapeMonitor scopeShapeMonitor, String scopeShapeId, String action) {
this.definitionHandle = definitionHandle;
this.scopeShapeMonitor = scopeShapeMonitor;
this.scopeShapeId = scopeShapeId;
JSONObject props = this.definitionHandle.getShapeByProps(scopeShapeId);
this.scopeX = props.getDoubleValue("x");
this.scopeY = props.getDoubleValue("y");
this.scopeW = props.getDoubleValue("w");
this.scopeH = props.getDoubleValue("h");
this.action = action;
}
// 构建当前节点的观察者列表
public void buildObservers(){
JSONObject elements = definitionHandle.getElements();
for (String key : elements.keySet()) {
JSONObject ele = elements.getJSONObject(key);
if ("linker".equals(ele.getString("name"))) continue; // 连线不在这处理
if (key.equals(scopeShapeId)) continue; // 当前被操作的节点 不处理
if (scopeShapeMonitor.checkShapeIsScopeInRange(key)) continue; // 在已存在的范围框内部的元素不在这处理
JSONObject props = ele.getJSONObject("props");
double x = props.getDoubleValue("x");
double y = props.getDoubleValue("y");
NodeObserver nodeObserver = new NodeObserver(definitionHandle, scopeShapeMonitor, key);
if (scopeX < x) {
addRightNodeObserver(nodeObserver);
}
if (scopeY < y) {
addBottomNodeObserver(nodeObserver);
}
}
}
public void setScopeW(double scopeW) {
// 计算 x 方向上的增量
if ("expand".equals(action)){ // 展开操作
double colMaxScopeW = getTheSameColMaxScopeW();
if (scopeW > colMaxScopeW){
double deltaX = scopeW - colMaxScopeW;
notifyRightObservers(deltaX, 0);
}
}else { // 闭合操作
double colMaxScopeW = getTheSameColMaxScopeWUnSelf();
if (this.scopeW > colMaxScopeW) {
double deltaX = colMaxScopeW - this.scopeW;
notifyRightObservers(deltaX, 0);
}
}
}
public void setScopeH(double scopeH) {
// 计算 y 方向上的增量
if ("expand".equals(action)){ // 展开操作
double rowMaxScopeH = getTheSameRowMaxScopeH();
if (scopeH > rowMaxScopeH){
double deltaY = scopeH - rowMaxScopeH;
notifyBottomObservers(0, deltaY);
}
}else { // 闭合操作
double rowMaxScopeH = getTheSameRowMaxScopeHUnSelf();
if (this.scopeH > rowMaxScopeH) {
double delatY = rowMaxScopeH - this.scopeH;
notifyBottomObservers(0, delatY);
}
}
}
// 获取当前操作节点同一列节点的最大宽度
private double getTheSameColMaxScopeW(){
JSONObject elements = definitionHandle.getElements();
JSONObject props = elements.keySet().stream()
.filter(key -> !"linker".equals(elements.getJSONObject(key).getString("name")) && scopeX == elements.getJSONObject(key).getJSONObject("props").getDoubleValue("x"))
.map(key -> elements.getJSONObject(key).getJSONObject("props"))
.max(Comparator.comparing(o -> o.getDoubleValue("w")))
.orElse(null);
return props.getDoubleValue("w");
}
// 获取当前操作节点同一列节点的最大宽度 不包含当前操作节点
private double getTheSameColMaxScopeWUnSelf(){
JSONObject elements = definitionHandle.getElements();
JSONObject props = elements.keySet().stream()
.filter(key -> !key.equals(scopeShapeId) && !"linker".equals(elements.getJSONObject(key).getString("name")) && scopeX == elements.getJSONObject(key).getJSONObject("props").getDoubleValue("x"))
.map(key -> elements.getJSONObject(key).getJSONObject("props"))
.max(Comparator.comparing(o -> o.getDoubleValue("w")))
.orElse(null);
if (props == null) // 如果为空 说明同一列就一个节点就是当前操作的节点
return SubProcessConst.SUB_PROCESS_SHAPE_W;
return props.getDoubleValue("w");
}
// 获取当前操作节点同一行节点的最大高度
private double getTheSameRowMaxScopeH(){
JSONObject elements = definitionHandle.getElements();
JSONObject props = elements.keySet().stream()
.filter(key -> !"linker".equals(elements.getJSONObject(key).getString("name")) && scopeY == elements.getJSONObject(key).getJSONObject("props").getDoubleValue("y"))
.map(key -> elements.getJSONObject(key).getJSONObject("props"))
.max(Comparator.comparing(o -> o.getDoubleValue("h")))
.orElse(null);
return props.getDoubleValue("h");
}
// 获取当前操作节点同一行节点的最大高度 不包含当前操作节点
private double getTheSameRowMaxScopeHUnSelf(){
JSONObject elements = definitionHandle.getElements();
JSONObject props = elements.keySet().stream()
.filter(key -> !key.equals(scopeShapeId) && !"linker".equals(elements.getJSONObject(key).getString("name")) && scopeY == elements.getJSONObject(key).getJSONObject("props").getDoubleValue("y"))
.map(key -> elements.getJSONObject(key).getJSONObject("props"))
.max(Comparator.comparing(o -> o.getDoubleValue("h")))
.orElse(null);
if (props == null)
return SubProcessConst.SUB_PROCESS_SHAPE_H;
return props.getDoubleValue("h");
}
@Override
public void addRightNodeObserver(Observer o) {
rightObservers.add(o);
}
@Override
public void addBottomNodeObserver(Observer o) {
bottomObservers.add(o);
}
@Override
public void removeRightObserver(Observer o) {
rightObservers.remove(o);
}
@Override
public void removeBottomObserver(Observer o) {
bottomObservers.remove(o);
}
@Override
public void notifyRightObservers(double deltaX, double deltaY) {
for (Observer observer : rightObservers) {
observer.update(deltaX, deltaY);
}
}
@Override
public void notifyBottomObservers(double deltaX, double deltaY) {
for (Observer observer : bottomObservers) {
observer.update(deltaX, deltaY);
}
}
}