节点位置分布算法
This commit is contained in:
parent
c008985d94
commit
016a3eca2b
Binary file not shown.
@ -0,0 +1,184 @@
|
|||||||
|
package com.actionsoft.apps.coe.method.process.subprocess.graph;
|
||||||
|
|
||||||
|
import com.actionsoft.apps.coe.method.process.subprocess.mode.Node;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图模型节点布局
|
||||||
|
* 依托需求定制 算法
|
||||||
|
* @author oYang
|
||||||
|
* @create 2023-05-16 15:55
|
||||||
|
*/
|
||||||
|
public class GraphLayout {
|
||||||
|
|
||||||
|
private final int[][] adjMatrix; // 邻接矩阵
|
||||||
|
private final List<Node> nodeList; // 节点集合
|
||||||
|
private final boolean[] isPosition; // 节点位置是否确定标记
|
||||||
|
private double canvasWidth; // 画布宽度
|
||||||
|
private double canvasHeight; // 画布高度
|
||||||
|
private final double vertInterval; // 垂直间隔
|
||||||
|
private final double horizInterval; // 水平间隔
|
||||||
|
private final double[][] position; // 节点坐标
|
||||||
|
private final double shapeW; // 图形节点的宽度
|
||||||
|
private final double shapeH; // 图形节点的高度
|
||||||
|
|
||||||
|
|
||||||
|
public GraphLayout(int[][] adjMatrix, List<Node> nodeList) {
|
||||||
|
this.adjMatrix = adjMatrix;
|
||||||
|
this.nodeList = nodeList;
|
||||||
|
this.isPosition = new boolean[nodeList.size()];
|
||||||
|
|
||||||
|
this.vertInterval = 50.0;
|
||||||
|
this.horizInterval = 80.0;
|
||||||
|
|
||||||
|
this.shapeW = 100.0;
|
||||||
|
this.shapeH = 70.0;
|
||||||
|
|
||||||
|
this.position = new double[nodeList.size()][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断当前节点是否存在后置流程
|
||||||
|
* @param nodeIndex 当前节点在集合中的索引
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean existOutLink(int nodeIndex){
|
||||||
|
boolean flag = false;
|
||||||
|
for (int i = 0; i < adjMatrix[nodeIndex].length; i++) {
|
||||||
|
if (adjMatrix[nodeIndex][i] == 1){
|
||||||
|
flag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算当前节点存在几个后置流程
|
||||||
|
* @param nodeIndex
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int countOutLinks(int nodeIndex){
|
||||||
|
int num = 0;
|
||||||
|
for (int i = 0; i < adjMatrix[nodeIndex].length; i++) {
|
||||||
|
if (adjMatrix[nodeIndex][i] == 1){
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前节点的所有后置节点的索引
|
||||||
|
* @param nodeIndex
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private List<Integer> getRearNodeIndex(int nodeIndex){
|
||||||
|
List<Integer> nodeIndexSet = new ArrayList<>();
|
||||||
|
for (int i = 0; i < adjMatrix[nodeIndex].length; i++) {
|
||||||
|
if (adjMatrix[nodeIndex][i] == 1){
|
||||||
|
nodeIndexSet.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nodeIndexSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCanvasWidth(){
|
||||||
|
return canvasWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCanvasHeight(){
|
||||||
|
return canvasHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 节点布局
|
||||||
|
*/
|
||||||
|
public double[][] layOut(){
|
||||||
|
double tempY = 0.0; // 记录第一列的高度
|
||||||
|
for (int i = 0; i < nodeList.size(); i++) {
|
||||||
|
// 第一个节点直接放到画布的左上角
|
||||||
|
if (i == 0) {
|
||||||
|
position[i][0] = 100.0;
|
||||||
|
position[i][1] = 100.0;
|
||||||
|
tempY = 100.0; // 更新第一列的高度
|
||||||
|
isPosition[i] = true;
|
||||||
|
if (existOutLink(i)){ // 如果存在后置节点 并且后置节点还未渲染
|
||||||
|
calculationRearNodePosition(i);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!isPosition[i]){
|
||||||
|
position[i][0] = 100.0;
|
||||||
|
position[i][1] = tempY + shapeH + vertInterval;
|
||||||
|
tempY = position[i][1]; // 更新第一列的高度
|
||||||
|
// 存在后置节点
|
||||||
|
if (existOutLink(i)){
|
||||||
|
calculationRearNodePosition(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 确定画布的宽度与高度
|
||||||
|
double w = Arrays.stream(position).mapToDouble(position -> position[0]).max().getAsDouble();
|
||||||
|
double h = Arrays.stream(position).mapToDouble(position -> position[1]).max().getAsDouble();
|
||||||
|
|
||||||
|
this.canvasWidth = w + 200.0;
|
||||||
|
this.canvasHeight = h + 200.0;
|
||||||
|
|
||||||
|
// 打印节点坐标与画布大小
|
||||||
|
System.out.printf("画布(%.2f, %.2f)", canvasWidth, canvasHeight);
|
||||||
|
for (int i = 0; i < position.length; i++) {
|
||||||
|
System.out.printf("坐标(%.2f, %.2f)", position[i][0], position[i][1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算当前节点所有后置节点的位置
|
||||||
|
* @param nodeIndex
|
||||||
|
*/
|
||||||
|
private void calculationRearNodePosition(int nodeIndex){
|
||||||
|
// 获取后置节点的索引
|
||||||
|
List<Integer> rearNodeIndexSet = getRearNodeIndex(nodeIndex);
|
||||||
|
for (int i = 0; i < rearNodeIndexSet.size(); i++) {
|
||||||
|
int rearNodeIndex = rearNodeIndexSet.get(i).intValue();
|
||||||
|
if (!isPosition[rearNodeIndex]) {
|
||||||
|
position[rearNodeIndex][0] = position[nodeIndex][0] + shapeW + horizInterval; // 上一个节点的x坐标 + 图形宽度 + 间隔 = 当前节点的x坐标
|
||||||
|
if (i == 0) {
|
||||||
|
position[rearNodeIndex][1] = position[nodeIndex][1]; // 上一个节点的y坐标 与 第一个后置节点的y坐标一致
|
||||||
|
}else {
|
||||||
|
position[rearNodeIndex][1] = position[nodeIndex][1] + shapeH + i * vertInterval; // 非第一个后置节点的y坐标 = 上一个节点的y坐标 + 后置节点索引 * 垂直间隔
|
||||||
|
}
|
||||||
|
isPosition[rearNodeIndex] = true;
|
||||||
|
|
||||||
|
if (existOutLink(rearNodeIndex)) {
|
||||||
|
calculationRearNodePosition(rearNodeIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 生成邻接矩阵
|
||||||
|
int[][] matrix = {
|
||||||
|
{0,1,0,0},
|
||||||
|
{0,0,1,0},
|
||||||
|
{0,0,0,0},
|
||||||
|
{1,0,0,0},
|
||||||
|
};
|
||||||
|
ArrayList<Node> nodes = new ArrayList<>(4);
|
||||||
|
Node node1 = new Node("");
|
||||||
|
Node node2 = new Node("");
|
||||||
|
Node node3 = new Node("");
|
||||||
|
Node node4 = new Node("");
|
||||||
|
nodes.add(node1);
|
||||||
|
nodes.add(node2);
|
||||||
|
nodes.add(node3);
|
||||||
|
nodes.add(node4);
|
||||||
|
GraphLayout graphLayout = new GraphLayout(matrix, nodes);
|
||||||
|
graphLayout.layOut();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,16 +1,21 @@
|
|||||||
package com.actionsoft.apps.coe.method.process.subprocess.graph;
|
package com.actionsoft.apps.coe.method.process.subprocess.graph;
|
||||||
|
|
||||||
import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst;
|
import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst;
|
||||||
|
import com.actionsoft.apps.coe.method.process.subprocess.mode.Node;
|
||||||
|
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;
|
||||||
import com.actionsoft.apps.coe.pal.pal.repository.designer.util.CoeDesignerUtil;
|
import com.actionsoft.apps.coe.pal.pal.repository.designer.util.CoeDesignerUtil;
|
||||||
import com.actionsoft.apps.coe.pal.pal.repository.designer.util.ShapeUtil;
|
import com.actionsoft.apps.coe.pal.pal.repository.designer.util.ShapeUtil;
|
||||||
|
import com.actionsoft.apps.coe.pal.pal.repository.model.PALRepositoryModel;
|
||||||
import com.actionsoft.bpms.util.UUIDGener;
|
import com.actionsoft.bpms.util.UUIDGener;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class GraphRender {
|
public class GraphRender {
|
||||||
|
|
||||||
private final int numVertex;
|
private final List<Node> nodeList;
|
||||||
private final double width; // 画布宽度
|
private final double width; // 画布宽度
|
||||||
private final double height; // 画布高度
|
private final double height; // 画布高度
|
||||||
private final double shapeInterval = 80.0; // 图形节点在画布上的间隔
|
private final double shapeInterval = 80.0; // 图形节点在画布上的间隔
|
||||||
@ -20,10 +25,10 @@ public class GraphRender {
|
|||||||
private final String modelId;
|
private final String modelId;
|
||||||
|
|
||||||
|
|
||||||
public GraphRender(int numVertex, String modelId, String definition) {
|
public GraphRender(List<Node> nodeList, String modelId, String definition, double width, double height) {
|
||||||
this.numVertex = numVertex;
|
this.nodeList = nodeList;
|
||||||
this.width = numVertex * (shapeInterval + nodeW);
|
this.width = width;
|
||||||
this.height = numVertex * (shapeInterval + nodeH);
|
this.height = height;
|
||||||
|
|
||||||
this.definition = definition;
|
this.definition = definition;
|
||||||
this.modelId = modelId;
|
this.modelId = modelId;
|
||||||
@ -35,13 +40,15 @@ public class GraphRender {
|
|||||||
page.put("width", width);
|
page.put("width", width);
|
||||||
page.put("height", height);
|
page.put("height", height);
|
||||||
JSONObject elements = defineJsonObj.getJSONObject("elements");
|
JSONObject elements = defineJsonObj.getJSONObject("elements");
|
||||||
for (int i = 0; i < numVertex; i++) {
|
for (int i = 0; i < nodeList.size(); i++) {
|
||||||
|
PALRepositoryModel repositoryModel = PALRepositoryCache.getCache().get(nodeList.get(i).getId());
|
||||||
JSONObject subProcessNode = ShapeUtil.getProcessShapeDefinition(SubProcessConst.SUB_PROCESS_METHOD_ID, "子流程");
|
JSONObject subProcessNode = ShapeUtil.getProcessShapeDefinition(SubProcessConst.SUB_PROCESS_METHOD_ID, "子流程");
|
||||||
String nodeId = UUIDGener.getObjectId();
|
String nodeId = UUIDGener.getObjectId();
|
||||||
subProcessNode.put("id", nodeId);
|
subProcessNode.put("id", nodeId);
|
||||||
JSONObject subProcessNodeProps = subProcessNode.getJSONObject("props");
|
JSONObject subProcessNodeProps = subProcessNode.getJSONObject("props");
|
||||||
subProcessNodeProps.put("x", position[i][0]);
|
subProcessNodeProps.put("x", position[i][0]);
|
||||||
subProcessNodeProps.put("y", position[i][1]);
|
subProcessNodeProps.put("y", position[i][1]);
|
||||||
|
subProcessNode.put("text", repositoryModel.getName());
|
||||||
elements.put(nodeId, subProcessNode);
|
elements.put(nodeId, subProcessNode);
|
||||||
}
|
}
|
||||||
defineJsonObj.put("elements",elements);
|
defineJsonObj.put("elements",elements);
|
||||||
|
|||||||
@ -0,0 +1,197 @@
|
|||||||
|
package com.actionsoft.apps.coe.method.process.subprocess.graph;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图模型节点布局
|
||||||
|
* 采用 PageRank 算法
|
||||||
|
* @author oYang
|
||||||
|
* @create 2023-05-16 11:10
|
||||||
|
*/
|
||||||
|
public class PageRankLayout {
|
||||||
|
|
||||||
|
private int[][] matrix; // 邻接矩阵
|
||||||
|
private double width; // 画布宽度
|
||||||
|
private double height; // 画布高度
|
||||||
|
private int maxIter; // 最大迭代次数
|
||||||
|
private double damp; // 阻尼因子
|
||||||
|
private int nodeSize; // 节点数
|
||||||
|
private double[] pageRankVal; // PageRank数据
|
||||||
|
private final double shapeInterval = 80.0; // 图形节点在画布上的间隔
|
||||||
|
private final double nodeW = 100.0; // 图形节点默认宽度
|
||||||
|
private final double nodeH = 70.0; // 图形节点默认高度
|
||||||
|
|
||||||
|
public PageRankLayout(int[][] matrix, int maxIter) {
|
||||||
|
this.matrix = matrix;
|
||||||
|
this.maxIter = maxIter;
|
||||||
|
this.damp = 0.85;
|
||||||
|
this.nodeSize = matrix.length;
|
||||||
|
this.pageRankVal = new double[nodeSize];
|
||||||
|
|
||||||
|
this.width = matrix.length * (shapeInterval + nodeW);
|
||||||
|
this.height = matrix.length * (shapeInterval + nodeH);
|
||||||
|
|
||||||
|
// 初始化每个节点的 PageRank 值为 1/N
|
||||||
|
Arrays.fill(pageRankVal, 1.0/nodeSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算每个节点的入度加权平均值
|
||||||
|
*/
|
||||||
|
public void calculatePageRankVal(){
|
||||||
|
for (int iter = 0; iter < maxIter; iter++) {
|
||||||
|
double[] nextPR = new double[nodeSize];
|
||||||
|
for (int i = 0; i < nodeSize; i++) {
|
||||||
|
double sum = 0.0;
|
||||||
|
for (int j = 0; j < nodeSize; j++) {
|
||||||
|
if (matrix[j][i] == 1) {
|
||||||
|
sum += pageRankVal[j] / countOutLinks(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nextPR[i] = (1 - damp) / nodeSize + damp * sum;
|
||||||
|
}
|
||||||
|
pageRankVal = nextPR;
|
||||||
|
}
|
||||||
|
// 输出结果
|
||||||
|
for (int i = 0; i < nodeSize; i++) {
|
||||||
|
System.out.printf("Node %d: PageRank = %.3f\n", i, pageRankVal[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据节点邻接矩阵计算节点的出度
|
||||||
|
* @param nodeIndex
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int countOutLinks(int nodeIndex){
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < matrix[nodeIndex].length; i++) {
|
||||||
|
if (matrix[nodeIndex][i] == 1) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据节点邻接矩阵计算节点入度
|
||||||
|
* @param nodeIndex
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int countInputLinks(int nodeIndex){
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < matrix.length; i++) {
|
||||||
|
if (matrix[i][nodeIndex] == 1){
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void layOut(){
|
||||||
|
int n = pageRankVal.length;
|
||||||
|
// 计算 PageRank 值最大的节点,将该节点定位在画布的中心
|
||||||
|
int maxIndex = 0;
|
||||||
|
double maxPageRank = pageRankVal[0];
|
||||||
|
for (int i = 1; i < n; i++) {
|
||||||
|
if (pageRankVal[i] > maxPageRank) {
|
||||||
|
maxIndex = i;
|
||||||
|
maxPageRank = pageRankVal[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double centerX = width / 2;
|
||||||
|
double centerY = height / 2;
|
||||||
|
|
||||||
|
// 计算其它节点相对于最大节点的 PageRank 值的比例关系,以及节点数量的平方根
|
||||||
|
double scale = Math.sqrt(n);
|
||||||
|
double[] distX = new double[n];
|
||||||
|
double[] distY = new double[n];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
if (i == maxIndex) {
|
||||||
|
distX[i] = 0;
|
||||||
|
distY[i] = 0;
|
||||||
|
} else {
|
||||||
|
double ratio = pageRankVal[i] / pageRankVal[maxIndex];
|
||||||
|
distX[i] = ratio * Math.cos(2 * Math.PI * i / n);
|
||||||
|
distY[i] = ratio * Math.sin(2 * Math.PI * i / n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将节点的 PageRank 值乘以比例关系和节点数量的平方根,得到节点在横向和竖向上的缩放比例
|
||||||
|
double[] scaleX = new double[n];
|
||||||
|
double[] scaleY = new double[n];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
scaleX[i] = distX[i] * scale;
|
||||||
|
scaleY[i] = distY[i] * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将横向和竖向上的缩放比例分别乘以画布的宽度和高度,得到节点在画布上的实际坐标
|
||||||
|
double[] x = new double[n];
|
||||||
|
double[] y = new double[n];
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
x[i] = centerX + (int)(scaleX[i] * 200);
|
||||||
|
y[i] = centerY + (int)(scaleY[i] * 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < nodeSize; i++) {
|
||||||
|
System.out.printf("NodeIndex %d: Position [%f%n,%f%n]", i, x[i], y[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据节点 PageRank 值计算节点坐标
|
||||||
|
*
|
||||||
|
* @param pageRank 节点 PageRank 值
|
||||||
|
* @param canvasWidth 画布宽度
|
||||||
|
* @param canvasHeight 画布高度
|
||||||
|
* @return 节点坐标数组,每个点都是 (x, y) 形式
|
||||||
|
*/
|
||||||
|
public double[][] computeNodeCoordinates() {
|
||||||
|
int n = pageRankVal.length;
|
||||||
|
double[][] nodeCoords = new double[n][2];
|
||||||
|
|
||||||
|
double maxPageRank = Double.NEGATIVE_INFINITY;
|
||||||
|
for (double x : pageRankVal) {
|
||||||
|
maxPageRank = Math.max(maxPageRank, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
double centerX = width / 2.0;
|
||||||
|
double centerY = height / 2.0;
|
||||||
|
double radius = Math.min(centerX, centerY) - 50; // 保留一些边距避免节点被切掉
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
double angle = 2 * Math.PI * i / n;
|
||||||
|
double x = centerX + (pageRankVal[i] / maxPageRank) * radius * Math.cos(angle);
|
||||||
|
double y = centerY + (pageRankVal[i] / maxPageRank) * radius * Math.sin(angle);
|
||||||
|
nodeCoords[i][0] = x;
|
||||||
|
nodeCoords[i][1] = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodeCoords;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 生成邻接矩阵
|
||||||
|
int[][] matrix = {
|
||||||
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 1, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
PageRankLayout pageRankLayout = new PageRankLayout(matrix, 100);
|
||||||
|
pageRankLayout.calculatePageRankVal();
|
||||||
|
double[][] nodeCoords = pageRankLayout.computeNodeCoordinates();
|
||||||
|
|
||||||
|
// 输出每个节点在直角坐标系中的坐标
|
||||||
|
for (int i = 0; i < nodeCoords.length; i++) {
|
||||||
|
System.out.printf("(%.2f, %.2f)\n", nodeCoords[i][0], nodeCoords[i][1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,10 +1,7 @@
|
|||||||
package com.actionsoft.apps.coe.method.process.subprocess.web;
|
package com.actionsoft.apps.coe.method.process.subprocess.web;
|
||||||
|
|
||||||
import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst;
|
import com.actionsoft.apps.coe.method.process.subprocess.constant.SubProcessConst;
|
||||||
import com.actionsoft.apps.coe.method.process.subprocess.graph.ForceDirectedGraphLayout;
|
import com.actionsoft.apps.coe.method.process.subprocess.graph.*;
|
||||||
import com.actionsoft.apps.coe.method.process.subprocess.graph.GraphAdjMatrix;
|
|
||||||
import com.actionsoft.apps.coe.method.process.subprocess.graph.GraphRender;
|
|
||||||
import com.actionsoft.apps.coe.method.process.subprocess.graph.VertexPreHandle;
|
|
||||||
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.vo.SubProcessTagVo;
|
import com.actionsoft.apps.coe.method.process.subprocess.mode.vo.SubProcessTagVo;
|
||||||
import com.actionsoft.apps.coe.pal.constant.CoEConstant;
|
import com.actionsoft.apps.coe.pal.constant.CoEConstant;
|
||||||
@ -229,12 +226,11 @@ public class SubProcessWeb extends ActionWeb {
|
|||||||
// 构建有向图邻接矩阵
|
// 构建有向图邻接矩阵
|
||||||
GraphAdjMatrix graphAdjMatrix = new GraphAdjMatrix(nodeList);
|
GraphAdjMatrix graphAdjMatrix = new GraphAdjMatrix(nodeList);
|
||||||
graphAdjMatrix.buildAdjMatrix(nodeIndexMap);
|
graphAdjMatrix.buildAdjMatrix(nodeIndexMap);
|
||||||
// graphAdjMatrix.printAdjMatrix();
|
graphAdjMatrix.printAdjMatrix();
|
||||||
|
|
||||||
// 获取节点分布
|
// 获取节点分布
|
||||||
ForceDirectedGraphLayout graphLayout = new ForceDirectedGraphLayout(graphAdjMatrix.getAdjMatrix());
|
GraphLayout graphLayout = new GraphLayout(graphAdjMatrix.getAdjMatrix(), nodeList);
|
||||||
graphLayout.run();
|
double[][] position = graphLayout.layOut();
|
||||||
double[][] position = graphLayout.getPosition();
|
|
||||||
|
|
||||||
// 新建模型
|
// 新建模型
|
||||||
PALRepositoryModel parentModel = PALRepositoryCache.getCache().get(locationId);
|
PALRepositoryModel parentModel = PALRepositoryCache.getCache().get(locationId);
|
||||||
@ -259,7 +255,7 @@ public class SubProcessWeb extends ActionWeb {
|
|||||||
baseModel.setDefinition(obj.getString("define"));
|
baseModel.setDefinition(obj.getString("define"));
|
||||||
|
|
||||||
// 节点渲染
|
// 节点渲染
|
||||||
GraphRender graphRender = new GraphRender(nodeList.size(), model.getId(), baseModel.getDefinition());
|
GraphRender graphRender = new GraphRender(nodeList, model.getId(), baseModel.getDefinition(), graphLayout.getCanvasWidth(), graphLayout.getCanvasHeight());
|
||||||
graphRender.handleShapeNodeRender(position);
|
graphRender.handleShapeNodeRender(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user