端到端功能 节点展开 纵向布局连线处理部分代码提交

This commit is contained in:
qinoy 2023-05-31 14:18:02 +08:00
parent 7e4770bc14
commit 5bd745ee3e
2 changed files with 174 additions and 13 deletions

View File

@ -164,8 +164,8 @@ public class GraphNodeExpandHandle {
JSONObject elements = endToEndProcessDefine.getJSONObject("elements");
double[][] vertexPosition = expandAdjMatrix.getVertexPosition(elements);
// 7构建新的连线
NodeExpandLinkerRender linkerRender = new NodeExpandLinkerRender(vertexPosition, expandAdjMatrix);
JSONArray linkers = linkerRender.toAssembleLinker(direction);
NodeExpandLinkerRender linkerRender = new NodeExpandLinkerRender(vertexPosition, expandAdjMatrix, scopeLimitationShape);
JSONArray linkers = linkerRender.toAssembleLinker(direction, shapeId);
for (Object o : linkers) {
JSONObject linker = (JSONObject) o;
addEndToEndGraphElements(linker);
@ -221,10 +221,10 @@ public class GraphNodeExpandHandle {
if ("linker".equals(ele.getString("name"))) continue; // 连线先不处理
JSONObject props = ele.getJSONObject("props");
if (props.getDoubleValue("x") > scopeShapeX) { // 当前元素在待展开节点的右侧
props.put("x", props.getDoubleValue("x") + scopeShapeW);
props.put("x", props.getDoubleValue("x") + scopeShapeW - SubProcessConst.SUB_PROCESS_SHAPE_W);
}
if (props.getDoubleValue("y") > scopeShapeY) { // 当前元素在待展开节点的下侧
props.put("y", props.getDoubleValue("y") + scopeShapeH);
props.put("y", props.getDoubleValue("y") + scopeShapeH - SubProcessConst.SUB_PROCESS_SHAPE_H);
}
addEndToEndGraphElements(ele);
@ -414,29 +414,41 @@ class NodeExpandLinkerRender{
private List<String> nodeIds; // 图形节点ID集合
private double[][] vertexPosition; // 所有节点的坐标
private NodeExpandAdjMatrix expandAdjMatrix; // 节点矩阵
private JSONObject scopeLimitationShape; // 范围标注框
public NodeExpandLinkerRender(double[][] vertexPosition, NodeExpandAdjMatrix expandAdjMatrix) {
public NodeExpandLinkerRender(double[][] vertexPosition, NodeExpandAdjMatrix expandAdjMatrix, JSONObject scopeLimitationShape) {
this.nodeIds = expandAdjMatrix.getNodeIds();
this.vertexPosition = vertexPosition;
this.expandAdjMatrix = expandAdjMatrix;
this.scopeLimitationShape = scopeLimitationShape;
}
/**
* 根据连线方向 组装连线
* @param direction 连线方向
* @param shapeId 当前待展开节点ID
* @return
*/
public JSONArray toAssembleLinker(String direction){
public JSONArray toAssembleLinker(String direction, String shapeId){
JSONArray linkers = new JSONArray();
int index = nodeIds.indexOf(shapeId);
for (int i = 0; i < vertexPosition.length; i++) {
boolean currentExpandNodeIsStart = false;
if (i == index){
currentExpandNodeIsStart = true; // 当前待展开的节点此处应是范围选择框为连线的出发点
}
double[] fromPoi = vertexPosition[i];
List<Integer> nextNodeIndex = expandAdjMatrix.getNeighbors(i);
if (nextNodeIndex.size() > 0){ // 说明当前节点有连线
for (Integer nodeIndex : nextNodeIndex) {
boolean currentExpandNodeIsEnd = false;
if (nodeIndex.intValue() == index){
currentExpandNodeIsEnd = true; // 当前待展开的节点 此处应是范围选择框为连线的终点
}
double[] toPoi = vertexPosition[nodeIndex];
double[][] turnPoi = "horizontal".equals(direction)
? calculationLinkerPointInHorizLayOut(fromPoi, toPoi)
: calculationLinkerPointInVertLayOut(fromPoi, toPoi);
? calculationLinkerPointInHorizLayOut(fromPoi, toPoi, currentExpandNodeIsStart, currentExpandNodeIsEnd)
: calculationLinkerPointInVertLayOut(fromPoi, toPoi, currentExpandNodeIsStart, currentExpandNodeIsEnd);
double[] angleArr = calculationLinkerAngle(fromPoi, toPoi, turnPoi[1], turnPoi[turnPoi.length - 2]);
// 构建连线
JSONObject linkerObj = JSONObject.parseObject(LinkerDefConstant.linker);
@ -473,13 +485,162 @@ class NodeExpandLinkerRender{
return linkers;
}
private double[][] calculationLinkerPointInVertLayOut(double[] fromPoi, double[] toPoi) {
return null;
private double[][] calculationLinkerPointInVertLayOut(double[] fromPoi, double[] toPoi, boolean currentExpandNodeIsStart, boolean currentExpandNodeIsEnd) {
double fromX = fromPoi[0],fromY = fromPoi[1],toX = toPoi[0],toY = toPoi[1];
double scopeShapeW = scopeLimitationShape.getDoubleValue("w"), scopeShapeH = scopeLimitationShape.getDoubleValue("h");
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[] 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[] turnPoi2 = new double[]{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + 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[] endPoi = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY};
return new double[][]{startPoi, turnPoi1, turnPoi2, turnPoi3, endPoi};
}else if (fromX == toX){ // 垂直 分析可知 垂直方向上应该不会有 toY < fromY 的情况 鉴于数据不确定性 先写上
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 + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2};
double[] endPoi = new double[]{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY};
return fromY < toY
? new double[][]{
startPoi,
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoi}
: new double[][]{
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 + ((currentExpandNodeIsStart || currentExpandNodeIsEnd) ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + 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},
endPoi};
}else { // 分布在四个象限内
if (fromX > toX && fromY > toY){ // 目标节点在第二象限
return new double[][]{
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W), fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) / 2},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + 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 + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}
};
}else if (fromX > toX && fromY < toY){ // 目标节点在第三象限
return toY - fromY == SubProcessConst.SHAPE_VERT_INTERVAL
? new double[][]
{
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H)},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}
}
: new double[][]
{
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H)},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + 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 + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) + 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 + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}
};
}else if (fromX < toX && fromY < toY){ // 目标节点在第四象限
return new double[][]{
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H)},
{fromX + (currentExpandNodeIsStart ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, fromY + (currentExpandNodeIsStart ? scopeShapeH : SubProcessConst.SUB_PROCESS_SHAPE_H) + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + (currentExpandNodeIsEnd ? scopeShapeW : SubProcessConst.SUB_PROCESS_SHAPE_W) / 2, toY}
};
}else {
// fromX < toX && fromY > toY 目标节点在第一象限 分析可知 纵向排布的情况下 应该不会出现目标节点在第一象限的情况
}
}
return new double[2][2];
}
private double[][] calculationLinkerPointInHorizLayOut(double[] fromPoi, double[] toPoi) {
return null;
private double[][] calculationLinkerPointInHorizLayOut(double[] fromPoi, double[] toPoi, boolean currentExpandNodeIsStart, boolean currentExpandNodeIsEnd) {
double fromX = fromPoi[0],fromY = fromPoi[1],toX = toPoi[0],toY = toPoi[1];
if (fromY == toY) { // 水平 方向上 存在从左向右直连的情况 但不存在从右向左直连的情况 水平方向上 从左向右 应是 右出 向上 左折 向下
return fromX < toX
? new double[][]
{
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2},
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2},
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2},
{toX, toY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2}
}
: new double[][]
{
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2},
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2},
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY}
};
}else if (fromX == toX) { // 垂直
// 节点横向分布 连线按照大原则 垂直 不存在 fromY < toY 的情况 也就是不存在 连线从上到下直连的情况
double[] startPoint = new double[]{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2};
double[] endPoint = new double[]{toX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY};
return new double[][]{startPoint,
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2},
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint};
}else {
if (fromX < toX && fromY > toY){ // 目标节点在第一象限
double[] startPoint = new double[]{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2};
double turnPointX = fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2;
if (fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点
double[] endPoint = new double[]{toX, toY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2};
return new double[][]{startPoint,{turnPointX, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2},{turnPointX, toY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2}, endPoint};
}else { // 不相邻节点 存在三个折点
double[] endPoint = new double[]{toX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY};
return new double[][]{
startPoint,
{turnPointX, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2},
{turnPointX, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint
};
}
}else if (fromX > toX && fromY > toY){ // 目标节点在第二象限 无论节点是否相邻 都按照三个折点走
double[] startPoint = new double[]{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2};
double[] endPoint = new double[]{toX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY};
return new double[][]{
startPoint,
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2},
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint
};
}else if (fromX > toX && fromY < toY){ // 目标节点在第三象限
double[] startPoint = new double[]{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H};
double[] endPoint = new double[]{toX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY};
return new double[][]{
startPoint,
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY - SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint
};
}else if (fromX < toX && fromY < toY){ // 目标节点在第四象限
double[] startPoint = new double[]{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2};
if (fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL == toX){ // 相邻节点 存在两个折点
double turnPointX = fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2;
double[] endPoint = new double[]{toX, toY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2};
return new double[][]{
startPoint,
{turnPointX, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2},
{turnPointX, toY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2},
endPoint
};
}else { // 不相邻节点 存在三个折点
double[] endPoint = new double[]{toX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY + SubProcessConst.SUB_PROCESS_SHAPE_H};
return new double[][]{
startPoint,
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, fromY + SubProcessConst.SUB_PROCESS_SHAPE_H / 2},
{fromX + SubProcessConst.SUB_PROCESS_SHAPE_W + SubProcessConst.SHAPE_HORIZ_INTERVAL / 2, toY + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
{toX + SubProcessConst.SUB_PROCESS_SHAPE_W / 2, toY + SubProcessConst.SUB_PROCESS_SHAPE_H + SubProcessConst.SHAPE_VERT_INTERVAL / 2},
endPoint
};
}
}
}
return new double[2][2];
}
/**