端到端功能 节点展开与闭合 连线优化

This commit is contained in:
qinoy 2023-06-13 13:47:11 +08:00
parent 54f1793929
commit e7b489532a
7 changed files with 216 additions and 218 deletions

View File

@ -86,11 +86,11 @@ public class GraphNodeCloseHandle {
String direction = definitionHandle.getProcessProperties().getString("direction"); String direction = definitionHandle.getProcessProperties().getString("direction");
graphPartNodePoiRenderAgain(elements, direction, subProcessNode); graphPartNodePoiRenderAgain(elements, direction, subProcessNode);
// 3收集现有元素坐标 // 3收集现有元素坐标
double[][] vertexPosition = closeAdjMatrix.getVertexPosition(elements); double[][] vertexBounding = closeAdjMatrix.getVertexBounding(elements);
// 4删除现有连线 // 4删除现有连线
removeEndToEndGraphOldLinker(); removeEndToEndGraphOldLinker();
// 5构建新的连线 // 5构建新的连线
NodeCloseLinkerRender linkerRender = new NodeCloseLinkerRender(vertexPosition, closeAdjMatrix, scopeLimitationShape); NodeCloseLinkerRender linkerRender = new NodeCloseLinkerRender(vertexBounding, closeAdjMatrix);
JSONArray linkers = linkerRender.toAssembleLinker(direction, shapeId); JSONArray linkers = linkerRender.toAssembleLinker(direction, shapeId);
for (Object o : linkers) { for (Object o : linkers) {
JSONObject linker = (JSONObject) o; JSONObject linker = (JSONObject) o;
@ -99,8 +99,8 @@ public class GraphNodeCloseHandle {
// 6更新画布的大小 // 6更新画布的大小
// 确定画布的宽度与高度 // 确定画布的宽度与高度
double w = Arrays.stream(vertexPosition).mapToDouble(position -> position[0]).max().orElse(0.0); double w = Arrays.stream(vertexBounding).mapToDouble(position -> position[0]).max().orElse(0.0);
double h = Arrays.stream(vertexPosition).mapToDouble(position -> position[1]).max().orElse(0.0); double h = Arrays.stream(vertexBounding).mapToDouble(position -> position[1]).max().orElse(0.0);
JSONObject page = definitionHandle.getPage(); JSONObject page = definitionHandle.getPage();
page.put("width", w + 300); page.put("width", w + 300);
@ -257,19 +257,23 @@ class NodeCloseAdjMatrix extends AbstractAdjMatrix {
} }
/** /**
* 获取总图中节点展开前的所有节点坐标 * 获取总图中节点展开前的所有节点坐标以及宽高
* @param elements * @param elements
* @return * @return double[][]{{x,y,w,h},{x,y,w,h}
*/ */
public double[][] getVertexPosition(JSONObject elements){ public double[][] getVertexBounding(JSONObject elements){
double[][] position = new double[nodeIds.size()][2]; double[][] position = new double[nodeIds.size()][4];
for (int i = 0; i < nodeIds.size(); i++) { for (int i = 0; i < nodeIds.size(); i++) {
JSONObject shape = elements.getJSONObject(nodeIds.get(i)); JSONObject shape = elements.getJSONObject(nodeIds.get(i));
JSONObject props = shape.getJSONObject("props"); JSONObject props = shape.getJSONObject("props");
double x = props.getDoubleValue("x"); double x = props.getDoubleValue("x");
double y = props.getDoubleValue("y"); double y = props.getDoubleValue("y");
double w = props.getDoubleValue("w");
double h = props.getDoubleValue("h");
position[i][0] = x; position[i][0] = x;
position[i][1] = y; position[i][1] = y;
position[i][2] = w;
position[i][3] = h;
} }
return position; return position;
} }
@ -283,13 +287,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 JSONObject scopeLimitationShape; // 范围标注框 // private JSONObject scopeLimitationShape; // 范围标注框
public NodeCloseLinkerRender(double[][] vertexPosition, NodeCloseAdjMatrix closeAdjMatrix, JSONObject scopeLimitationShape) { public NodeCloseLinkerRender(double[][] vertexPosition, NodeCloseAdjMatrix closeAdjMatrix) {
this.nodeIds = closeAdjMatrix.getNodeIds(); this.nodeIds = closeAdjMatrix.getNodeIds();
this.vertexPosition = vertexPosition; this.vertexPosition = vertexPosition;
this.closeAdjMatrix = closeAdjMatrix; this.closeAdjMatrix = closeAdjMatrix;
this.scopeLimitationShape = scopeLimitationShape; // this.scopeLimitationShape = scopeLimitationShape;
} }
/** /**
@ -302,22 +306,14 @@ class NodeCloseLinkerRender{
JSONArray linkers = new JSONArray(); JSONArray linkers = new JSONArray();
int index = nodeIds.indexOf(shapeId); int index = nodeIds.indexOf(shapeId);
for (int i = 0; i < vertexPosition.length; i++) { for (int i = 0; i < vertexPosition.length; i++) {
boolean currentExpandNodeIsStart = false; double[] fromBounding = vertexPosition[i];
if (i == index){
// currentExpandNodeIsStart = true; // 当前待展开的节点此处应是范围选择框为连线的出发点
}
double[] fromPoi = vertexPosition[i];
List<Integer> nextNodeIndex = closeAdjMatrix.getNeighbors(i); List<Integer> nextNodeIndex = closeAdjMatrix.getNeighbors(i);
if (nextNodeIndex.size() > 0){ // 说明当前节点有连线 if (nextNodeIndex.size() > 0){ // 说明当前节点有连线
for (Integer nodeIndex : nextNodeIndex) { for (Integer nodeIndex : nextNodeIndex) {
boolean currentExpandNodeIsEnd = false; double[] toBounding = vertexPosition[nodeIndex];
if (nodeIndex.intValue() == index){
// currentExpandNodeIsEnd = true; // 当前待展开的节点 此处应是范围选择框为连线的终点
}
double[] toPoi = vertexPosition[nodeIndex];
double[][] turnPoi = "horizontal".equals(direction) double[][] turnPoi = "horizontal".equals(direction)
? calculationLinkerPointInHorizLayOut(fromPoi, toPoi, currentExpandNodeIsStart, currentExpandNodeIsEnd) ? calculationLinkerPointInHorizLayOut(fromBounding, toBounding)
: calculationLinkerPointInVertLayOut(fromPoi, toPoi, currentExpandNodeIsStart, currentExpandNodeIsEnd); : calculationLinkerPointInVertLayOut(fromBounding, toBounding);
double[] angleArr = calculationLinkerAngle(turnPoi[0], turnPoi[turnPoi.length - 1], turnPoi[1], turnPoi[turnPoi.length - 2]); double[] angleArr = calculationLinkerAngle(turnPoi[0], turnPoi[turnPoi.length - 1], turnPoi[1], turnPoi[turnPoi.length - 2]);
// 构建连线 // 构建连线
JSONObject linkerObj = JSONObject.parseObject(LinkerDefConstant.linker); JSONObject linkerObj = JSONObject.parseObject(LinkerDefConstant.linker);
@ -354,66 +350,65 @@ class NodeCloseLinkerRender{
return linkers; return linkers;
} }
private double[][] calculationLinkerPointInVertLayOut(double[] fromPoi, double[] toPoi, boolean currentExpandNodeIsStart, boolean currentExpandNodeIsEnd) { private double[][] calculationLinkerPointInVertLayOut(double[] fromBounding, double[] toBounding) {
double fromX = fromPoi[0],fromY = fromPoi[1],toX = toPoi[0],toY = toPoi[1]; double fromX = fromBounding[0],fromY = fromBounding[1], fromW = fromBounding[2], fromH = fromBounding[3], toX = toBounding[0], toY = toBounding[1], toW = toBounding[2], toH = toBounding[3];
double scopeShapeW = scopeLimitationShape.getJSONObject("props").getDoubleValue("w"), scopeShapeH = scopeLimitationShape.getJSONObject("props").getDoubleValue("h");
if (fromY == toY){ // 水平 分析可知 水平方向上不会出现 从左到右直连的情况 只有 右边节点右侧锚点出 向上走 左折 连到左侧节点上方锚点 if (fromY == toY){ // 水平 分析可知 水平方向上不会出现 从左到右直连的情况 只有 右边节点右侧锚点出 向上走 左折 连到左侧节点上方锚点
double[] startPoi = new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] startPoi = new double[]{fromX + fromW, fromY + fromH / 2};
double[] turnPoi1 = new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] turnPoi1 = new double[]{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2};
double[] turnPoi2 = new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}; double[] turnPoi2 = new double[]{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2};
double[] turnPoi3 = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}; double[] turnPoi3 = new double[]{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2};
double[] endPoi = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}; double[] endPoi = new double[]{toX + toW / 2, toY};
return new double[][]{startPoi, turnPoi1, turnPoi2, turnPoi3, endPoi}; return new double[][]{startPoi, turnPoi1, turnPoi2, turnPoi3, endPoi};
}else if (fromX == toX){ // 垂直 分析可知 垂直方向上应该不会有 toY < fromY 的情况 鉴于数据不确定性 先写上 }else if (fromX == toX){ // 垂直 分析可知 垂直方向上应该不会有 toY < fromY 的情况 鉴于数据不确定性 先写上
double[] startPoi = fromY < toY double[] startPoi = fromY < toY
? new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H)} ? new double[]{fromX + fromW / 2, fromY + fromH}
: new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; : new double[]{fromX + fromW, fromY + fromH / 2};
double[] endPoi = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}; double[] endPoi = new double[]{toX + toW / 2, toY};
return fromY < toY return fromY < toY
? new double[][]{ ? new double[][]{
startPoi, startPoi,
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 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 + ((currentExpandNodeIsStart || currentExpandNodeIsEnd) ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + ((currentExpandNodeIsStart || currentExpandNodeIsEnd) ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 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 + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 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 - fromY == SubProcessConst.SHAPE_VERT_INTERVAL
? new double[][] ? new double[][]
{ {
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H)}, {fromX + fromW / 2, fromY + fromH},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY} {toX + toW / 2, toY}
} }
: new double[][] : new double[][]
{ {
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H)}, {fromX + fromW / 2, fromY + fromH},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + 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 + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY} {toX + toW / 2, toY}
}; };
}else if (fromX < toX && fromY < toY){ // 目标节点在第四象限 }else if (fromX < toX && fromY < toY){ // 目标节点在第四象限
return new double[][]{ return new double[][]{
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H)}, {fromX + fromW / 2, fromY + fromH},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY} {toX + toW / 2, toY}
}; };
}else { }else {
// fromX < toX && fromY > toY 目标节点在第一象限 分析可知 纵向排布的情况下 应该不会出现目标节点在第一象限的情况 // fromX < toX && fromY > toY 目标节点在第一象限 分析可知 纵向排布的情况下 应该不会出现目标节点在第一象限的情况
@ -422,80 +417,79 @@ class NodeCloseLinkerRender{
return new double[2][2]; return new double[2][2];
} }
private double[][] calculationLinkerPointInHorizLayOut(double[] fromPoi, double[] toPoi, boolean currentExpandNodeIsStart, boolean currentExpandNodeIsEnd) { private double[][] calculationLinkerPointInHorizLayOut(double[] fromBounding, double[] toBounding) {
double fromX = fromPoi[0],fromY = fromPoi[1],toX = toPoi[0],toY = toPoi[1]; double fromX = fromBounding[0],fromY = fromBounding[1], fromW = fromBounding[2], fromH = fromBounding[3], toX = toBounding[0], toY = toBounding[1], toW = toBounding[2], toH = toBounding[3];
double scopeShapeW = scopeLimitationShape.getJSONObject("props").getDoubleValue("w"), scopeShapeH = scopeLimitationShape.getJSONObject("props").getDoubleValue("h");
if (fromY == toY) { // 水平 方向上 存在从左向右直连的情况 但不存在从右向左直连的情况 水平方向上 从左向右 应是 右出 向上 左折 向下 if (fromY == toY) { // 水平 方向上 存在从左向右直连的情况 但不存在从右向左直连的情况 水平方向上 从左向右 应是 右出 向上 左折 向下
return fromX < toX return fromX < toX
? new double[][] ? new double[][]
{ {
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{toX - SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY + (currentExpandNodeIsEnd ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {toX - SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY + toH / 2},
{toX, toY + (currentExpandNodeIsEnd ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2} {toX, toY + toH / 2}
} }
: new double[][] : new double[][]
{ {
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY} {toX + toW / 2, toY}
}; };
}else if (fromX == toX) { // 垂直 }else if (fromX == toX) { // 垂直
// 节点横向分布 连线按照大原则 垂直 不存在 fromY < toY 的情况 也就是不存在 连线从上到下直连的情况 // 节点横向分布 连线按照大原则 垂直 不存在 fromY < toY 的情况 也就是不存在 连线从上到下直连的情况
double[] startPoint = new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
double[] endPoint = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{startPoint, return new double[][]{startPoint,
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 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 + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
double turnPointX = fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2; double turnPointX = fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2;
if (fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点 if (fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点
double[] endPoint = new double[]{toX, toY + (currentExpandNodeIsEnd ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] endPoint = new double[]{toX, toY + toH / 2};
return new double[][]{startPoint,{turnPointX, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2},{turnPointX, toY + (currentExpandNodeIsEnd ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, endPoint}; return new double[][]{startPoint,{turnPointX, fromY + fromH / 2},{turnPointX, toY + toH / 2}, endPoint};
}else { // 不相邻节点 存在三个折点 }else { // 不相邻节点 存在三个折点
double[] endPoint = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{ return new double[][]{
startPoint, startPoint,
{turnPointX, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {turnPointX, fromY + fromH / 2},
{turnPointX, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {turnPointX, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 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 + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
double[] endPoint = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{ return new double[][]{
startPoint, startPoint,
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 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 + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
if (fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点 if (fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点
double turnPointX = fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2; double turnPointX = fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2;
double[] endPoint = new double[]{toX, toY + (currentExpandNodeIsEnd ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] endPoint = new double[]{toX, toY + toH / 2};
return new double[][]{ return new double[][]{
startPoint, startPoint,
{turnPointX, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {turnPointX, fromY + fromH / 2},
{turnPointX, toY + (currentExpandNodeIsEnd ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {turnPointX, toY + toH / 2},
endPoint endPoint
}; };
}else { // 不相邻节点 存在三个折点 }else { // 不相邻节点 存在三个折点
double[] endPoint = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{ return new double[][]{
startPoint, startPoint,
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint endPoint
}; };
} }

View File

@ -36,7 +36,7 @@ public class GraphNodeExpandHandle {
private AbstractDefinitionHandle definitionHandle; // 当前总图 define 处理器 private AbstractDefinitionHandle definitionHandle; // 当前总图 define 处理器
private AbstractDefinitionHandle subProcessNodeDefineHandle; // 子流程节点 define 处理器 private AbstractDefinitionHandle subProcessNodeDefineHandle; // 子流程节点 define 处理器
private double[] scopeLimitationShapeBeforePoi; private double[] scopeLimitationShapeBeforePoi; // 范围选择框在子流程文件中的坐标
public GraphNodeExpandHandle(String repositoryId, String shapeId, String endToEndProcessDefineStr) throws AWSException{ public GraphNodeExpandHandle(String repositoryId, String shapeId, String endToEndProcessDefineStr) throws AWSException{
this.repositoryId = repositoryId; this.repositoryId = repositoryId;
@ -99,21 +99,6 @@ public class GraphNodeExpandHandle {
*/ */
public String handleNodeExpand() throws AWSException{ public String handleNodeExpand() throws AWSException{
// Thread t1 = new Thread(() -> {
// // 1总图节点以及连线处理
// handleEndToEndGraphNodeAndLinker(direction);
// });
// t1.start();
//
// Thread t2 = new Thread(() -> {
// // 2子流程节点内部元素处理
// handleRelationModelNodePosition();
// });
// t2.start();
//
// t1.join();
// t2.join();
// 1总图节点以及连线处理 // 1总图节点以及连线处理
handleEndToEndGraphNodeAndLinker(); handleEndToEndGraphNodeAndLinker();
@ -151,11 +136,11 @@ public class GraphNodeExpandHandle {
removeEndToEndGraphOldLinker(); removeEndToEndGraphOldLinker();
// 6获取所有节点坐标 // 6获取所有节点坐标
JSONObject elements = definitionHandle.getElements(); JSONObject elements = definitionHandle.getElements();
double[][] vertexPosition = expandAdjMatrix.getVertexPosition(elements); double[][] vertexBounding = expandAdjMatrix.getVertexBounding(elements);
// 7构建新的连线 // 7构建新的连线
JSONObject processProperties = definitionHandle.getProcessProperties(); JSONObject processProperties = definitionHandle.getProcessProperties();
String direction = processProperties.getString("direction"); String direction = processProperties.getString("direction");
NodeExpandLinkerRender linkerRender = new NodeExpandLinkerRender(vertexPosition, expandAdjMatrix, scopeLimitationShape); NodeExpandLinkerRender linkerRender = new NodeExpandLinkerRender(vertexBounding, expandAdjMatrix);
JSONArray linkers = linkerRender.toAssembleLinker(direction, shapeId); JSONArray linkers = linkerRender.toAssembleLinker(direction, shapeId);
for (Object o : linkers) { for (Object o : linkers) {
JSONObject linker = (JSONObject) o; JSONObject linker = (JSONObject) o;
@ -164,8 +149,8 @@ public class GraphNodeExpandHandle {
// 8更新画布的大小 // 8更新画布的大小
// 确定画布的宽度与高度 // 确定画布的宽度与高度
double w = Arrays.stream(vertexPosition).mapToDouble(position -> position[0]).max().orElse(0.0); double w = Arrays.stream(vertexBounding).mapToDouble(position -> position[0]).max().orElse(0.0);
double h = Arrays.stream(vertexPosition).mapToDouble(position -> position[1]).max().orElse(0.0); double h = Arrays.stream(vertexBounding).mapToDouble(position -> position[1]).max().orElse(0.0);
JSONObject page = definitionHandle.getPage(); JSONObject page = definitionHandle.getPage();
page.put("width", w + 300); page.put("width", w + 300);
@ -341,19 +326,23 @@ class NodeExpandAdjMatrix extends AbstractAdjMatrix {
} }
/** /**
* 获取总图中节点展开前的所有节点坐标 * 获取总图中节点展开前的所有节点坐标以及宽高
* @param elements * @param elements
* @return * @return double[][]{{x,y,w,h},{x,y,w,h}
*/ */
public double[][] getVertexPosition(JSONObject elements){ public double[][] getVertexBounding(JSONObject elements){
double[][] position = new double[nodeIds.size()][2]; double[][] position = new double[nodeIds.size()][4];
for (int i = 0; i < nodeIds.size(); i++) { for (int i = 0; i < nodeIds.size(); i++) {
JSONObject shape = elements.getJSONObject(nodeIds.get(i)); JSONObject shape = elements.getJSONObject(nodeIds.get(i));
JSONObject props = shape.getJSONObject("props"); JSONObject props = shape.getJSONObject("props");
double x = props.getDoubleValue("x"); double x = props.getDoubleValue("x");
double y = props.getDoubleValue("y"); double y = props.getDoubleValue("y");
double w = props.getDoubleValue("w");
double h = props.getDoubleValue("h");
position[i][0] = x; position[i][0] = x;
position[i][1] = y; position[i][1] = y;
position[i][2] = w;
position[i][3] = h;
} }
return position; return position;
} }
@ -365,15 +354,15 @@ class NodeExpandAdjMatrix extends AbstractAdjMatrix {
class NodeExpandLinkerRender{ class NodeExpandLinkerRender{
private List<String> nodeIds; // 图形节点ID集合 private List<String> nodeIds; // 图形节点ID集合
private double[][] vertexPosition; // 所有节点的坐标 private double[][] vertexPosition; // 所有节点的坐标以及宽高 double[][]{{x, y, w, h},{}}
private NodeExpandAdjMatrix expandAdjMatrix; // 节点矩阵 private NodeExpandAdjMatrix expandAdjMatrix; // 节点矩阵
private JSONObject scopeLimitationShape; // 范围标注框 // private JSONObject scopeLimitationShape; // 范围标注框
public NodeExpandLinkerRender(double[][] vertexPosition, NodeExpandAdjMatrix expandAdjMatrix, JSONObject scopeLimitationShape) { public NodeExpandLinkerRender(double[][] vertexPosition, NodeExpandAdjMatrix expandAdjMatrix) {
this.nodeIds = expandAdjMatrix.getNodeIds(); this.nodeIds = expandAdjMatrix.getNodeIds();
this.vertexPosition = vertexPosition; this.vertexPosition = vertexPosition;
this.expandAdjMatrix = expandAdjMatrix; this.expandAdjMatrix = expandAdjMatrix;
this.scopeLimitationShape = scopeLimitationShape; // this.scopeLimitationShape = scopeLimitationShape;
} }
/** /**
@ -386,22 +375,14 @@ class NodeExpandLinkerRender{
JSONArray linkers = new JSONArray(); JSONArray linkers = new JSONArray();
int index = nodeIds.indexOf(shapeId); int index = nodeIds.indexOf(shapeId);
for (int i = 0; i < vertexPosition.length; i++) { for (int i = 0; i < vertexPosition.length; i++) {
boolean currentExpandNodeIsStart = false; double[] fromBounding = vertexPosition[i];
if (i == index){
currentExpandNodeIsStart = true; // 当前待展开的节点此处应是范围选择框为连线的出发点
}
double[] fromPoi = vertexPosition[i];
List<Integer> nextNodeIndex = expandAdjMatrix.getNeighbors(i); List<Integer> nextNodeIndex = expandAdjMatrix.getNeighbors(i);
if (nextNodeIndex.size() > 0){ // 说明当前节点有连线 if (nextNodeIndex.size() > 0){ // 说明当前节点有连线
for (Integer nodeIndex : nextNodeIndex) { for (Integer nodeIndex : nextNodeIndex) {
boolean currentExpandNodeIsEnd = false; double[] toBounding = vertexPosition[nodeIndex];
if (nodeIndex.intValue() == index){
currentExpandNodeIsEnd = true; // 当前待展开的节点 此处应是范围选择框为连线的终点
}
double[] toPoi = vertexPosition[nodeIndex];
double[][] turnPoi = "horizontal".equals(direction) double[][] turnPoi = "horizontal".equals(direction)
? calculationLinkerPointInHorizLayOut(fromPoi, toPoi, currentExpandNodeIsStart, currentExpandNodeIsEnd) ? calculationLinkerPointInHorizLayOut(fromBounding, toBounding)
: calculationLinkerPointInVertLayOut(fromPoi, toPoi, currentExpandNodeIsStart, currentExpandNodeIsEnd); : calculationLinkerPointInVertLayOut(fromBounding, toBounding);
double[] angleArr = calculationLinkerAngle(turnPoi[0], turnPoi[turnPoi.length - 1], turnPoi[1], turnPoi[turnPoi.length - 2]); double[] angleArr = calculationLinkerAngle(turnPoi[0], turnPoi[turnPoi.length - 1], turnPoi[1], turnPoi[turnPoi.length - 2]);
// 构建连线 // 构建连线
JSONObject linkerObj = JSONObject.parseObject(LinkerDefConstant.linker); JSONObject linkerObj = JSONObject.parseObject(LinkerDefConstant.linker);
@ -438,66 +419,66 @@ class NodeExpandLinkerRender{
return linkers; return linkers;
} }
private double[][] calculationLinkerPointInVertLayOut(double[] fromPoi, double[] toPoi, boolean currentExpandNodeIsStart, boolean currentExpandNodeIsEnd) { private double[][] calculationLinkerPointInVertLayOut(double[] fromBounding, double[] toBounding) {
double fromX = fromPoi[0],fromY = fromPoi[1],toX = toPoi[0],toY = toPoi[1]; double fromX = fromBounding[0],fromY = fromBounding[1], fromW = fromBounding[2], fromH = fromBounding[3], toX = toBounding[0], toY = toBounding[1], toW = toBounding[2], toH = toBounding[3];
double scopeShapeW = scopeLimitationShape.getJSONObject("props").getDoubleValue("w"), scopeShapeH = scopeLimitationShape.getJSONObject("props").getDoubleValue("h"); // double scopeShapeW = scopeLimitationShape.getJSONObject("props").getDoubleValue("w"), scopeShapeH = scopeLimitationShape.getJSONObject("props").getDoubleValue("h");
if (fromY == toY){ // 水平 分析可知 水平方向上不会出现 从左到右直连的情况 只有 右边节点右侧锚点出 向上走 左折 连到左侧节点上方锚点 if (fromY == toY){ // 水平 分析可知 水平方向上不会出现 从左到右直连的情况 只有 右边节点右侧锚点出 向上走 左折 连到左侧节点上方锚点
double[] startPoi = new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] startPoi = new double[]{fromX + fromW, fromY + fromH / 2};
double[] turnPoi1 = new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] turnPoi1 = new double[]{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2};
double[] turnPoi2 = new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}; double[] turnPoi2 = new double[]{fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2};
double[] turnPoi3 = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}; double[] turnPoi3 = new double[]{toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2};
double[] endPoi = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}; double[] endPoi = new double[]{toX + toW / 2, toY};
return new double[][]{startPoi, turnPoi1, turnPoi2, turnPoi3, endPoi}; return new double[][]{startPoi, turnPoi1, turnPoi2, turnPoi3, endPoi};
}else if (fromX == toX){ // 垂直 分析可知 垂直方向上应该不会有 toY < fromY 的情况 鉴于数据不确定性 先写上 }else if (fromX == toX){ // 垂直 分析可知 垂直方向上应该不会有 toY < fromY 的情况 鉴于数据不确定性 先写上
double[] startPoi = fromY < toY double[] startPoi = fromY < toY
? new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H)} ? new double[]{fromX + fromW / 2, fromY + fromH}
: new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; : new double[]{fromX +fromW, fromY + fromH / 2};
double[] endPoi = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}; double[] endPoi = new double[]{toX + toW / 2, toY};
return fromY < toY return fromY < toY
? new double[][]{ ? new double[][]{
startPoi, startPoi,
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 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 + ((currentExpandNodeIsStart || currentExpandNodeIsEnd) ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + ((currentExpandNodeIsStart || currentExpandNodeIsEnd) ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 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 + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 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 - fromY == SubProcessConst.SHAPE_VERT_INTERVAL
? new double[][] ? new double[][]
{ {
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H)}, {fromX + fromW / 2, fromY + fromH},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY} {toX + toW / 2, toY}
} }
: new double[][] : new double[][]
{ {
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H)}, {fromX + fromW / 2, fromY + fromH},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + 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 + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY} {toX + toW / 2, toY}
}; };
}else if (fromX < toX && fromY < toY){ // 目标节点在第四象限 }else if (fromX < toX && fromY < toY){ // 目标节点在第四象限
return new double[][]{ return new double[][]{
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H)}, {fromX + fromW / 2, fromY + fromH},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW / 2, fromY + fromH + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY} {toX + toW / 2, toY}
}; };
}else { }else {
// fromX < toX && fromY > toY 目标节点在第一象限 分析可知 纵向排布的情况下 应该不会出现目标节点在第一象限的情况 // fromX < toX && fromY > toY 目标节点在第一象限 分析可知 纵向排布的情况下 应该不会出现目标节点在第一象限的情况
@ -506,80 +487,80 @@ class NodeExpandLinkerRender{
return new double[2][2]; return new double[2][2];
} }
private double[][] calculationLinkerPointInHorizLayOut(double[] fromPoi, double[] toPoi, boolean currentExpandNodeIsStart, boolean currentExpandNodeIsEnd) { private double[][] calculationLinkerPointInHorizLayOut(double[] fromBounding, double[] toBounding) {
double fromX = fromPoi[0],fromY = fromPoi[1],toX = toPoi[0],toY = toPoi[1]; double fromX = fromBounding[0],fromY = fromBounding[1], fromW = fromBounding[2], fromH = fromBounding[3], toX = toBounding[0], toY = toBounding[1], toW = toBounding[2], toH = toBounding[3];
double scopeShapeW = scopeLimitationShape.getJSONObject("props").getDoubleValue("w"), scopeShapeH = scopeLimitationShape.getJSONObject("props").getDoubleValue("h"); // double scopeShapeW = scopeLimitationShape.getJSONObject("props").getDoubleValue("w"), scopeShapeH = scopeLimitationShape.getJSONObject("props").getDoubleValue("h");
if (fromY == toY) { // 水平 方向上 存在从左向右直连的情况 但不存在从右向左直连的情况 水平方向上 从左向右 应是 右出 向上 左折 向下 if (fromY == toY) { // 水平 方向上 存在从左向右直连的情况 但不存在从右向左直连的情况 水平方向上 从左向右 应是 右出 向上 左折 向下
return fromX < toX return fromX < toX
? new double[][] ? new double[][]
{ {
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{toX - SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY + (currentExpandNodeIsEnd ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {toX - SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY + toH / 2},
{toX, toY + (currentExpandNodeIsEnd ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2} {toX, toY + toH / 2}
} }
: new double[][] : new double[][]
{ {
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY} {toX + toW / 2, toY}
}; };
}else if (fromX == toX) { // 垂直 }else if (fromX == toX) { // 垂直
// 节点横向分布 连线按照大原则 垂直 不存在 fromY < toY 的情况 也就是不存在 连线从上到下直连的情况 // 节点横向分布 连线按照大原则 垂直 不存在 fromY < toY 的情况 也就是不存在 连线从上到下直连的情况
double[] startPoint = new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
double[] endPoint = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{startPoint, return new double[][]{startPoint,
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 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 + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
double turnPointX = fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2; double turnPointX = fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2;
if (fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点 if (fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点
double[] endPoint = new double[]{toX, toY + (currentExpandNodeIsEnd ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] endPoint = new double[]{toX, toY + toH / 2};
return new double[][]{startPoint,{turnPointX, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2},{turnPointX, toY + (currentExpandNodeIsEnd ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, endPoint}; return new double[][]{startPoint,{turnPointX, fromY + fromH / 2},{turnPointX, toY + toH / 2}, endPoint};
}else { // 不相邻节点 存在三个折点 }else { // 不相邻节点 存在三个折点
double[] endPoint = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{ return new double[][]{
startPoint, startPoint,
{turnPointX, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {turnPointX, fromY + fromH / 2},
{turnPointX, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {turnPointX, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 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 + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
double[] endPoint = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{ return new double[][]{
startPoint, startPoint,
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 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 + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] startPoint = new double[]{fromX + fromW, fromY + fromH / 2};
if (fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点 if (fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点
double turnPointX = fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2; double turnPointX = fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2;
double[] endPoint = new double[]{toX, toY + (currentExpandNodeIsEnd ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}; double[] endPoint = new double[]{toX, toY + toH / 2};
return new double[][]{ return new double[][]{
startPoint, startPoint,
{turnPointX, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {turnPointX, fromY + fromH / 2},
{turnPointX, toY + (currentExpandNodeIsEnd ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {turnPointX, toY + toH / 2},
endPoint endPoint
}; };
}else { // 不相邻节点 存在三个折点 }else { // 不相邻节点 存在三个折点
double[] endPoint = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}; double[] endPoint = new double[]{toX + toW / 2, toY};
return new double[][]{ return new double[][]{
startPoint, startPoint,
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + fromH / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {fromX + fromW + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2}, {toX + toW / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint endPoint
}; };
} }

View File

@ -65,5 +65,11 @@ public abstract class AbstractDefinitionHandle {
public abstract JSONObject getShapeByProps(String key); public abstract JSONObject getShapeByProps(String key);
/**
* 获取ele元素中图形的边界
* @return double [x, y, w, h]
*/
public abstract double[] getShapeBounding(String key);
} }

View File

@ -83,4 +83,15 @@ public class DefinitionThreadSafe extends AbstractDefinitionHandle {
lock.unlock(); lock.unlock();
} }
} }
@Override
public double[] getShapeBounding(String key) {
lock.lock();
try {
JSONObject props = getShapeByProps(key);
return new double[]{props.getDoubleValue("x"), props.getDoubleValue("y"), props.getDoubleValue("w"), props.getDoubleValue("h")};
} finally {
lock.unlock();
}
}
} }

View File

@ -5,7 +5,7 @@ import com.alibaba.fastjson.JSONObject;
/** /**
* @author oYang * @author oYang
* @Description TODO * @Description 操作 definition 工具类 线程不安全
* @createTime 2023年06月09日 11:29:00 * @createTime 2023年06月09日 11:29:00
*/ */
public class DefinitionThreadUnSafe extends AbstractDefinitionHandle { public class DefinitionThreadUnSafe extends AbstractDefinitionHandle {
@ -48,4 +48,10 @@ public class DefinitionThreadUnSafe extends AbstractDefinitionHandle {
public JSONObject getShapeByProps(String key) { public JSONObject getShapeByProps(String key) {
return getShapeByKey(key).getJSONObject("props"); return getShapeByKey(key).getJSONObject("props");
} }
@Override
public double[] getShapeBounding(String key) {
JSONObject props = getShapeByProps(key);
return new double[]{props.getDoubleValue("x"), props.getDoubleValue("y"), props.getDoubleValue("w"), props.getDoubleValue("h")};
}
} }

View File

@ -134,10 +134,10 @@ class SubProcess {
for (let key in elements) { for (let key in elements) {
let shape = elements[key]; let shape = elements[key];
if (shape.name == 'linker') continue; if (shape.name == 'linker') continue;
if (shape.name == 'scopeLimitation') { // if (shape.name == 'scopeLimitation') {
$.simpleAlert("同一时间仅支持一个子流程节点展开", "warning"); // $.simpleAlert("同一时间仅支持一个子流程节点展开", "warning");
return; // return;
} // }
if (key == param.shapeId){ if (key == param.shapeId){
shapeText = shape.text; shapeText = shape.text;
} }