| | |
| | | package com.zt.life.modules.mainPart.taskReliability.service; |
| | | |
| | | import cn.hutool.core.convert.Convert; |
| | | import cn.hutool.json.JSONArray; |
| | | import cn.hutool.json.JSONObject; |
| | | import com.zt.common.service.BaseService; |
| | |
| | | import com.zt.life.modules.mainPart.basicInfo.dao.XhProductModelDao; |
| | | import com.zt.life.modules.mainPart.basicInfo.model.ProductImg; |
| | | import com.zt.life.modules.mainPart.taskReliability.dao.*; |
| | | import com.zt.life.modules.mainPart.taskReliability.dto.ModelLinePairDto; |
| | | import com.zt.life.modules.mainPart.taskReliability.model.*; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | |
| | | public static final String OPE_TYPE_SWITCH = "switch"; |
| | | public static final String OPE_TYPE_VOTE = "vote"; |
| | | public static final String OPE_TYPE_BRIDGE = "bridge"; |
| | | |
| | | // 节点 |
| | | /* 自动布局:start与end的大小 */ |
| | | public static final int LAYOUT_START_END_SIZE_X = 60; |
| | | public static final int LAYOUT_START_END_SIZE_Y = 40; |
| | | /* 自动布局:虚框的大小 */ |
| | | public static final int LAYOUT_DASHED_BOX_SIZE_X = 60; |
| | | public static final int LAYOUT_DASHED_BOX_SIZE_Y = 40; |
| | | /* 自动布局:逻辑运算符的大小 */ |
| | | public static final int LAYOUT_OPE_NODE_SIZE_X = 50; |
| | | public static final int LAYOUT_OPE_NODE_SIZE_Y = 50; |
| | | /* 自动布局:设备节点的大小 */ |
| | | public static final int LAYOUT_DEVICE_NODE_SIZE_X = 60; |
| | | public static final int LAYOUT_DEVICE_NODE_SIZE_Y = 60; |
| | | /* 自动布局:connect的大小 */ |
| | | public static final int LAYOUT_CONNECT_SIZE_X = 10; |
| | | public static final int LAYOUT_CONNECT_SIZE_Y = 10; |
| | | |
| | | // 单元格(存放节点) |
| | | /* 自动布局:单元格大小 */ |
| | | public static final int LAYOUT_CELL_SIZE_X = 120; |
| | | public static final int LAYOUT_CELL_SIZE_Y = 120; |
| | | /* 自动布局:节点占据单元格数量 */ |
| | | public static final int LAYOUT_CELL_NUM_NODE_X = 1; |
| | | public static final int LAYOUT_CELL_NUM_NODE_Y = 1; |
| | | public static final int LAYOUT_CELL_NUM_CONNECT_X = 1; |
| | | public static final int LAYOUT_CELL_NUM_CONNECT_Y = 1; |
| | | |
| | | @Autowired |
| | | private ModelLineDao modelLineDao; |
| | |
| | | |
| | | // 1. 解析出节点与边 |
| | | getNodeAndLineFromRbd(modelRbd.getId(), rbdJsonArray, modelNodeList, modelLineList, productImgList); |
| | | |
| | | // 2. 转换为树型结构 |
| | | RbdTreeNode root = recognizeRbd(modelNodeList, modelLineList); |
| | | // 3. 递归计算RBD的布局空间大小 |
| | | // 3. 将桥联转换为3支路的并联 |
| | | convertBridgeToThreeBranchParallel(root); |
| | | // 4. 递归计算RBD的布局空间大小 |
| | | calcLayoutSize(root); |
| | | |
| | | // 4. 递归计算RBD的布局空间参数(x、y坐标) |
| | | // 5. 递归计算RBD的布局空间参数(x、y坐标) |
| | | root.setBlockX(0); |
| | | root.setBlockY(0); |
| | | Map<String, RbdTreeNode> nodeMap = new HashMap<>(); |
| | | calcPosition(rbdJsonArray, root, nodeMap, false); |
| | | setEdgeRouter(rbdJsonArray, nodeMap); |
| | | |
| | | // 5. 保存自动布局模型 |
| | | // 6. 保存自动布局模型 |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("cells", rbdJsonArray); |
| | | modelRbd.setContent(jsonObject.toString()); |
| | | modelRbdDao.updateById(modelRbd); |
| | | |
| | | return result; |
| | | /* |
| | | // 3. 复制产品节点(node)到list |
| | | List<ModelNode> modelNodeAndVnodeList = modelNodeList.stream().filter(item -> |
| | | "node".equals(item.getNodeType())).collect(Collectors.toList()); |
| | | // 4. 不断将基本模型(串联、并联、旁联、表决、桥联)替换为虚节点而简化图形,直至无法简化为止。 |
| | | // result = getAlgorithmFromRbd(modelRbd, modelNodeList, modelLineList, algorithmList, modelNodeAndVnodeList); |
| | | } |
| | | |
| | | // 6. 递归计算RBD的布局空间大小 |
| | | calcLayoutSize(modelRbd, algorithmList, modelNodeAndVnodeList); |
| | | Collections.reverse(algorithmList); |
| | | RbdTreeNode root2 = listToTree(algorithmList.get(0).getComputerList(), algorithmList, modelNodeAndVnodeList); |
| | | private void calcPosition(JSONArray rbdJsonArray, RbdTreeNode block, Map<String, RbdTreeNode> nodeMap, Boolean lastIsSeries) { |
| | | if ("node,start,end,connect,parallel,switch,vote,bridge".contains(block.getNodeType())) { |
| | | setNodePositionXY(rbdJsonArray, block, nodeMap); |
| | | } else { |
| | | |
| | | RbdTreeNode root = new RbdTreeNode(); |
| | | Double descentWidth = block.getDescentWidth(); |
| | | if (descentWidth == null || descentWidth == 0.0) { |
| | | descentWidth = block.getBlockWidth(); |
| | | } |
| | | Double descentHeight = block.getDescentHeight(); |
| | | if (descentHeight == null || descentHeight == 0.0) { |
| | | descentHeight = block.getBlockHeight(); |
| | | } |
| | | List<RbdTreeNode> children = block.getChildren(); |
| | | if (OPE_TYPE_SERIES.equals(block.getAlgorithmType())) { |
| | | Double subBlockX = block.getBlockX(); |
| | | for (RbdTreeNode child : children) { |
| | | |
| | | root.setId(Convert.toLong("20000")); |
| | | double selfBlockWidth = child.getBlockWidth() * descentWidth / block.getBlockWidth(); |
| | | child.setDescentWidth(selfBlockWidth); |
| | | child.setBlockWidth(selfBlockWidth); |
| | | if (lastIsSeries) |
| | | child.setDescentHeight(descentHeight); |
| | | else |
| | | child.setDescentHeight(block.getBlockHeight()); |
| | | |
| | | root.setName("end"); |
| | | root.setNodeType("vnode"); |
| | | root.setAlgorithmType("parallel"); |
| | | root.setPicId("20000"); |
| | | root.setPairStartNodeId("10000"); |
| | | child.setBlockHeight(block.getBlockHeight() ); |
| | | child.setBlockY(block.getBlockY()); |
| | | child.setBlockX(subBlockX); |
| | | calcPosition(rbdJsonArray, child, nodeMap,true); |
| | | subBlockX = subBlockX + selfBlockWidth; |
| | | } |
| | | } else { |
| | | Double subBlockY = block.getBlockY() + (descentHeight - block.getObjectHeight())/ 2; |
| | | for (RbdTreeNode child : children) { |
| | | child.setDescentWidth(block.getBlockWidth()); |
| | | child.setDescentHeight(block.getBlockHeight()); |
| | | |
| | | root.setBlockWidthNum(root2.getBlockWidthNum() + 2); |
| | | root.setBlockHeightNum(root2.getBlockHeightNum()); |
| | | root.getChildren().add(root2); |
| | | if (!"vnode".equals(child.getNodeType())) { |
| | | child.setBlockWidth(block.getBlockWidth()); |
| | | } |
| | | |
| | | // 7. 递归计算RBD的布局空间参数(x、y坐标) |
| | | root.setBlockX(0); |
| | | root.setBlockY(0); |
| | | child.setBlockX(block.getBlockX()); |
| | | child.setBlockY(subBlockY); |
| | | calcPosition(rbdJsonArray, child, nodeMap, false); |
| | | subBlockY = subBlockY + child.getBlockHeight(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | Map<String, RbdTreeNode> nodeMap = new HashMap<>(); |
| | | calcPosition(rbdJsonArray, root, nodeMap); |
| | | setEdgeRouter(rbdJsonArray, nodeMap); |
| | | private void setNodePositionXY(JSONArray rbdJsonArray, RbdTreeNode block, Map<String, RbdTreeNode> nodeMap) { |
| | | Double x = block.getBlockX() + (block.getBlockWidth() - block.getObjectWidth()) / 2; |
| | | Double y = block.getBlockY() + (block.getBlockHeight() - block.getObjectHeight()) / 2; |
| | | block.setX(x); |
| | | block.setY(y); |
| | | nodeMap.put(block.getPicId(), block); |
| | | setRbdNodePosition(rbdJsonArray, block.getPicId(), x, y); |
| | | } |
| | | |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("cells", rbdJsonArray); |
| | | modelRbd.setContent(jsonObject.toString()); |
| | | // calcLayoutPosition(modelRbd, algorithmList, modelNodeAndVnodeList); |
| | | private void setRbdNodePosition(JSONArray rbdJsonArray, |
| | | String id, |
| | | double x, |
| | | double y) { |
| | | for (int i = 0; i < rbdJsonArray.size(); i++) { |
| | | JSONObject jsonObject = rbdJsonArray.getJSONObject(i); |
| | | if (id.equals(jsonObject.get("id").toString())) { |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "position/x".split("/"), x); |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "position/y".split("/"), y); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 8. 保存自动布局模型 |
| | | // 更新RBD数据 |
| | | // modelRbd.setAutoLayoutContent("测试文字"); |
| | | // modelRbdDao.updateById(modelRbd); |
| | | */ |
| | | private void setEdgeRouter(JSONArray rbdJsonArray, Map<String, RbdTreeNode> nodeMap) { |
| | | for (int i = 0; i < rbdJsonArray.size(); i++ |
| | | ) { |
| | | JSONObject jsonObject = rbdJsonArray.getJSONObject(i); |
| | | if (jsonObject.get("shape").equals("edge")) { |
| | | String sourceId = JsonUtils2.getJsonValueByPath(jsonObject, "source/cell".split("/")).toString(); |
| | | String targetId = JsonUtils2.getJsonValueByPath(jsonObject, "target/cell".split("/")).toString(); |
| | | RbdTreeNode sourceNode = nodeMap.get(sourceId); |
| | | RbdTreeNode targetNode = nodeMap.get(targetId); |
| | | if (sourceNode != null) { |
| | | if ("connect".equals(sourceNode.getNodeType()) && !"10000".equals(sourceId)) { |
| | | if (sourceNode.getY() + sourceNode.getObjectHeight() / 2 == targetNode.getY() + targetNode.getObjectHeight() / 2) { |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/startDirections".split("/"), "right".split(",")); |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/endDirections".split("/"), "left".split(",")); |
| | | } else { |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/startDirections".split("/"), "top,bottom".split(",")); |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/endDirections".split("/"), "left".split(",")); |
| | | } |
| | | } |
| | | } |
| | | if (targetNode != null) { |
| | | if ("parallel,vote,switch,bridge".contains(targetNode.getNodeType())) { |
| | | if (sourceNode.getY() + sourceNode.getObjectHeight() / 2 == targetNode.getY() + targetNode.getObjectHeight() / 2) { |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/startDirections".split("/"), "right".split("")); |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/endDirections".split("/"), "left".split("")); |
| | | } else { |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/startDirections".split("/"), "right".split("")); |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/endDirections".split("/"), "top,bottom".split("")); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void calcLayoutSize(RbdTreeNode root) { |
| | | double childrenWidth = 0.0; |
| | | double childrenHeight = 0.0; |
| | | double lineWidth = 120; |
| | | double lineHeight = 90; |
| | | if (!"vnode".equals(root.getNodeType())) { |
| | | root.setBlockWidth(root.getObjectWidth() + lineWidth); |
| | | root.setBlockHeight(root.getObjectHeight() + lineHeight); |
| | | } else { |
| | | for (RbdTreeNode treeNode : root.getChildren()) { |
| | | calcLayoutSize(treeNode); |
| | | if ("series".equals(root.getAlgorithmType())) { |
| | | childrenWidth += treeNode.getBlockWidth(); |
| | | childrenHeight = Math.max(childrenHeight, treeNode.getBlockHeight()); |
| | | } else if ("parallel,switch,vote".contains(root.getAlgorithmType())) { |
| | | childrenWidth = Math.max(childrenWidth, treeNode.getBlockWidth()); |
| | | childrenHeight += treeNode.getBlockHeight(); |
| | | } |
| | | } |
| | | if ("bridge".equals(root.getAlgorithmType())) { |
| | | childrenWidth = Math.max(root.getChildren().get(0).getBlockWidth() + root.getChildren().get(1).getBlockWidth(), |
| | | root.getChildren().get(2).getBlockWidth()); |
| | | childrenWidth = Math.max(root.getChildren().get(3).getBlockWidth() + root.getChildren().get(4).getBlockWidth(), |
| | | childrenWidth); |
| | | childrenHeight += Math.max(root.getChildren().get(0).getBlockHeight(), root.getChildren().get(1).getBlockHeight()); |
| | | childrenHeight += root.getChildren().get(2).getBlockHeight(); |
| | | childrenHeight += Math.max(root.getChildren().get(3).getBlockHeight(), root.getChildren().get(4).getBlockHeight()); |
| | | } |
| | | root.setObjectWidth(childrenWidth); |
| | | root.setObjectHeight(childrenHeight); |
| | | root.setBlockWidth(childrenWidth); |
| | | root.setBlockHeight(childrenHeight); |
| | | } |
| | | } |
| | | |
| | | private void getNodeAndLineFromRbd(Long modelId, |
| | |
| | | String productType = JsonUtils2.getJsonValueByPath(jsonObject, "data/productType".split("/")).toString(); |
| | | productImg.setProductType(productType); |
| | | if ("product_sb".equals(productType)) { |
| | | jsonValue = JsonUtils2.getJsonValueByPath(jsonObject, "data/deviceNo".split("/")); |
| | | if (jsonValue != null && StringUtils.isNotBlank(jsonValue.toString())) { |
| | | modelNode.setDeviceNo(Integer.valueOf(jsonValue.toString())); |
| | | } else { |
| | | modelNode.setDeviceNo(0); |
| | | } |
| | | jsonValue = JsonUtils2.getJsonValueByPath(jsonObject, "data/reliabDistribType".split("/")); |
| | | if (jsonValue != null && StringUtils.isNotBlank(jsonValue.toString())) { |
| | | productImg.setReliabDistribType(Integer.valueOf(jsonValue.toString())); |
| | |
| | | } |
| | | |
| | | private RbdTreeNode recognizeRbd(List<ModelNode> modelNodeList, |
| | | List<ModelLine> modelLineList) { |
| | | List<ModelLine> modelLineList) { |
| | | Map<String, Integer> vnodeCounter = new HashMap<>(); |
| | | vnodeCounter.put("vnodeCounter", 0); |
| | | RbdTreeNode root = new RbdTreeNode(); |
| | |
| | | endNode.setNodeType("end"); |
| | | endNode.setPicId(end.getPicId()); |
| | | endNode.setPairStartNodeId(end.getPairStartNodeId()); |
| | | endNode.setMyWidth(end.getWidth()); |
| | | endNode.setMyHeight(end.getHeight()); |
| | | endNode.setObjectWidth(end.getWidth()); |
| | | endNode.setObjectHeight(end.getHeight()); |
| | | root.getChildren().add(endNode); |
| | | ModelLine lineRight = modelLineList.stream().filter(item -> |
| | | item.getEndCell().equals(end.getPicId())).collect(Collectors.toList()).get(0); |
| | |
| | | } |
| | | |
| | | private void recognizeOneBranch(RbdTreeNode parent, |
| | | ModelLine lineRight, // 串联的起始线(右边) |
| | | ModelLine lineLeft, // 串联的结束线(左边) |
| | | List<ModelNode> modelNodeList, |
| | | List<ModelLine> modelLineList, |
| | | Map<String, Integer> vnodeCounter) { |
| | | ModelLine lineRight, // 串联的起始线(右边) |
| | | ModelLine lineLeft, // 串联的结束线(左边) |
| | | List<ModelNode> modelNodeList, |
| | | List<ModelLine> modelLineList, |
| | | Map<String, Integer> vnodeCounter) { |
| | | ModelLine inLine = lineRight; |
| | | for (;;) { |
| | | for (; ; ) { |
| | | ModelLine searchLine = inLine; |
| | | ModelNode node = modelNodeList.stream().filter(item -> |
| | | searchLine.getBeginCell().equals(item.getPicId())).collect(Collectors.toList()).get(0); |
| | |
| | | treeNode.setNodeType(node.getNodeType()); |
| | | treeNode.setPicId(node.getPicId()); |
| | | treeNode.setDataId(node.getDataId()); |
| | | treeNode.setMyWidth(node.getWidth()); |
| | | treeNode.setMyHeight(node.getHeight()); |
| | | treeNode.setDeviceNo(node.getDeviceNo()); |
| | | treeNode.setObjectWidth(node.getWidth()); |
| | | treeNode.setObjectHeight(node.getHeight()); |
| | | parent.getChildren().add(treeNode); |
| | | inLine = modelLineList.stream().filter(item -> |
| | | item.getEndCell().equals(node.getPicId())).collect(Collectors.toList()).get(0); |
| | |
| | | treeNode.setName(node.getNodeType()); |
| | | treeNode.setNodeType(node.getNodeType()); |
| | | treeNode.setPicId(node.getPicId()); |
| | | treeNode.setMyWidth(node.getWidth()); |
| | | treeNode.setMyHeight(node.getHeight()); |
| | | treeNode.setObjectWidth(node.getWidth()); |
| | | treeNode.setObjectHeight(node.getHeight()); |
| | | parent.getChildren().add(treeNode); |
| | | break; |
| | | } else if ("connect".equals(node.getNodeType())) { |
| | |
| | | treeNode.setName(connect.getNodeType()); |
| | | treeNode.setNodeType(connect.getNodeType()); |
| | | treeNode.setPicId(connect.getPicId()); |
| | | treeNode.setMyWidth(connect.getWidth()); |
| | | treeNode.setMyHeight(connect.getHeight()); |
| | | treeNode.setObjectWidth(connect.getWidth()); |
| | | treeNode.setObjectHeight(connect.getHeight()); |
| | | subNode.getChildren().add(treeNode); |
| | | RbdTreeNode subNodeOpe = new RbdTreeNode(); |
| | | subNodeOpe.setAlgorithmType(node.getNodeType()); |
| | |
| | | treeNode.setNodeType(node.getNodeType()); |
| | | treeNode.setPicId(node.getPicId()); |
| | | treeNode.setPairStartNodeId(node.getPairStartNodeId()); |
| | | treeNode.setMyWidth(node.getWidth()); |
| | | treeNode.setMyHeight(node.getHeight()); |
| | | treeNode.setObjectWidth(node.getWidth()); |
| | | treeNode.setObjectHeight(node.getHeight()); |
| | | subNode.getChildren().add(treeNode); |
| | | recognizeOpeBlock(subNodeOpe, |
| | | node, |
| | |
| | | } |
| | | |
| | | private void recognizeOpeBlock(RbdTreeNode parent, |
| | | ModelNode rightNode, // rbd中的右节点(包括end及4种运算符) |
| | | List<ModelNode> modelNodeList, |
| | | List<ModelLine> modelLineList, |
| | | Map<String, Integer> vnodeCounter) { |
| | | ModelNode rightNode, // rbd中的右节点(包括end及4种运算符) |
| | | List<ModelNode> modelNodeList, |
| | | List<ModelLine> modelLineList, |
| | | Map<String, Integer> vnodeCounter) { |
| | | if ("parallel,vote,switch".contains(parent.getAlgorithmType())) { |
| | | ModelNode searchNode = rightNode; |
| | | List<ModelLine> lines = modelLineList.stream().filter(item -> |
| | |
| | | parent.getChildren().add(subNode); |
| | | recognizeOneBranch(subNode, line, null, modelNodeList, modelLineList, vnodeCounter); |
| | | } else { |
| | | recognizeOneBranch(parent, line,null, modelNodeList, modelLineList, vnodeCounter); |
| | | recognizeOneBranch(parent, line, null, modelNodeList, modelLineList, vnodeCounter); |
| | | } |
| | | } |
| | | } else if ("bridge".contains(parent.getAlgorithmType())) { |
| | |
| | | |
| | | /** |
| | | * 按自上而下的顺序排序 |
| | | */ |
| | | */ |
| | | private List<ModelLine> sortLine(List<ModelLine> lines, |
| | | List<ModelNode> modelNodeList) { |
| | | for (ModelLine line : lines) { |
| | |
| | | } |
| | | |
| | | private void createAlgorithm(Long modelId, |
| | | RbdTreeNode root, |
| | | List<Algorithm> algorithmList, |
| | | List<ModelNode> modelNodeAndVnodeList) { |
| | | RbdTreeNode root, |
| | | List<Algorithm> algorithmList, |
| | | List<ModelNode> modelNodeAndVnodeList) { |
| | | List<RbdTreeNode> children = root.getChildren(); |
| | | if (children.size() == 0) { |
| | | ModelNode node = new ModelNode(); |
| | |
| | | node.setId(root.getId()); |
| | | node.setPicId(root.getPicId()); |
| | | node.setDataId(root.getDataId()); |
| | | node.setDeviceNo(root.getDeviceNo()); |
| | | node.setNodeType(root.getNodeType()); |
| | | node.setName(root.getName()); |
| | | node.setVoteNum(root.getVoteNum()); |
| | |
| | | * 对树形结构进行预处理,包括: |
| | | * 1)将root的algorithmType替换为end,并去掉start和end节点 |
| | | * 2)start与end间只有1个逻辑运算块,则去掉最外层的series |
| | | * |
| | | * @param root |
| | | */ |
| | | private void deleteStartEnd(RbdTreeNode root) { |
| | | root.setAlgorithmType("end"); |
| | | List<RbdTreeNode> children = root.getChildren(); |
| | | children.remove(children.size()-1); |
| | | children.remove(children.size() - 1); |
| | | children.remove(0); |
| | | if (children.size()>1 || |
| | | if (children.size() > 1 || |
| | | !"vnode".equals(children.get(0).getNodeType())) { |
| | | RbdTreeNode subNode = new RbdTreeNode(); |
| | | subNode.setAlgorithmType("series"); |
| | |
| | | |
| | | /** |
| | | * 对树形结构进行预处理: |
| | | * 去掉逻辑运算块中用于排版的外层series |
| | | * 去掉逻辑运算块中用于排版的外层series |
| | | * |
| | | * @param root |
| | | */ |
| | | private void deleteSeriesForAutoArrange(RbdTreeNode root) { |
| | |
| | | } |
| | | } |
| | | |
| | | private void setEdgeRouter(JSONArray rbdJsonArray, Map<String, RbdTreeNode> nodeMap) { |
| | | for (int i = 0; i < rbdJsonArray.size(); i++ |
| | | ) { |
| | | JSONObject jsonObject = rbdJsonArray.getJSONObject(i); |
| | | if (jsonObject.get("shape").equals("edge")) { |
| | | String sourceId = JsonUtils2.getJsonValueByPath(jsonObject, "source/cell".split("/")).toString(); |
| | | String targetId = JsonUtils2.getJsonValueByPath(jsonObject, "target/cell".split("/")).toString(); |
| | | RbdTreeNode sourceNode = nodeMap.get(sourceId); |
| | | RbdTreeNode targetNode = nodeMap.get(targetId); |
| | | if (sourceNode != null) { |
| | | if ("connect".equals(sourceNode.getNodeType()) && !"10000".equals(sourceId)){ |
| | | if (sourceNode.getY()+sourceNode.getMyHeight()/2 == targetNode.getY()+targetNode.getMyHeight()/2){ |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/startDirections".split("/"),"right".split(",")); |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/endDirections".split("/"),"left".split(",")); |
| | | }else{ |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/startDirections".split("/"),"top,bottom".split(",")); |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/endDirections".split("/"),"left".split(",")); |
| | | } |
| | | } |
| | | } |
| | | if (targetNode != null) { |
| | | if ("parallel,vote".contains(targetNode.getNodeType())){ |
| | | if (sourceNode.getY()+sourceNode.getMyHeight()/2 == targetNode.getY()+targetNode.getMyHeight()/2){ |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/startDirections".split("/"),"right".split("")); |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/endDirections".split("/"),"left".split("")); |
| | | }else{ |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/startDirections".split("/"),"right".split("")); |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "router/args/endDirections".split("/"),"top,bottom".split("")); |
| | | } |
| | | } |
| | | } |
| | | /** |
| | | * 用于自动排版:将桥联转换为3支路的并联 |
| | | * @param root |
| | | * @return |
| | | */ |
| | | private void convertBridgeToThreeBranchParallel(RbdTreeNode root) { |
| | | List<RbdTreeNode> children = root.getChildren(); |
| | | for (RbdTreeNode treeNode : children) { |
| | | if ("bridge".equals(treeNode.getAlgorithmType())) { |
| | | treeNode.setAlgorithmType("parallel"); |
| | | List<RbdTreeNode> list = new ArrayList<>(); |
| | | RbdTreeNode subNode = new RbdTreeNode(); |
| | | subNode.setAlgorithmType("series"); |
| | | subNode.setId(UUIDUtil.generateId()); |
| | | subNode.setName("v10000"); |
| | | subNode.setNodeType("vnode"); |
| | | subNode.getChildren().add(treeNode.getChildren().get(0)); |
| | | subNode.getChildren().add(treeNode.getChildren().get(1)); |
| | | list.add(subNode); |
| | | list.add(treeNode.getChildren().get(2)); |
| | | subNode = new RbdTreeNode(); |
| | | subNode.setAlgorithmType("series"); |
| | | subNode.setId(UUIDUtil.generateId()); |
| | | subNode.setName("v10001"); |
| | | subNode.setNodeType("vnode"); |
| | | subNode.getChildren().add(treeNode.getChildren().get(3)); |
| | | subNode.getChildren().add(treeNode.getChildren().get(4)); |
| | | list.add(subNode); |
| | | treeNode.setChildren(list); |
| | | } |
| | | convertBridgeToThreeBranchParallel(treeNode); |
| | | } |
| | | } |
| | | |
| | | private void setNodePositionXY(JSONArray rbdJsonArray, RbdTreeNode block, Map<String, RbdTreeNode> nodeMap) { |
| | | Double x = block.getBlockX() + (block.getBlockWidth() - block.getMyWidth()) / 2; |
| | | Double y = block.getBlockY() + (block.getBlockHeight() - block.getMyHeight()) / 2; |
| | | block.setX(x); |
| | | block.setY(y); |
| | | nodeMap.put(block.getPicId(),block); |
| | | setRbdNodePosition(rbdJsonArray, block.getPicId(), x, y); |
| | | } |
| | | |
| | | /* |
| | | private void calcPosition(JSONArray rbdJsonArray, RbdTreeNode block, Map<String, RbdTreeNode> nodeMap) { |
| | | if (block.getNodeType().equals("node")) { |
| | | setNodePositionXY(rbdJsonArray, block,nodeMap); |
| | |
| | | |
| | | // 设置connect的位置 |
| | | RbdTreeNode connectBlock = new RbdTreeNode(); |
| | | connectBlock.setMyWidth(getRbdNodeInfo(rbdJsonArray, block.getPairStartNodeId(), "size/width")); |
| | | connectBlock.setMyHeight(getRbdNodeInfo(rbdJsonArray, block.getPairStartNodeId(), "size/height")); |
| | | connectBlock.setObjectWidth(getRbdNodeInfo(rbdJsonArray, block.getPairStartNodeId(), "size/width")); |
| | | connectBlock.setObjectHeight(getRbdNodeInfo(rbdJsonArray, block.getPairStartNodeId(), "size/height")); |
| | | connectBlock.setNodeType("connect"); |
| | | connectBlock.setPicId(block.getPairStartNodeId()); |
| | | connectBlock.setBlockX(block.getBlockX()); |
| | |
| | | |
| | | opeBlock.setPicId(block.getPicId()); |
| | | opeBlock.setNodeType("parallel"); |
| | | opeBlock.setMyWidth(getRbdNodeInfo(rbdJsonArray, block.getPicId(), "size/width")); |
| | | opeBlock.setMyHeight(getRbdNodeInfo(rbdJsonArray, block.getPicId(), "size/height")); |
| | | opeBlock.setObjectWidth(getRbdNodeInfo(rbdJsonArray, block.getPicId(), "size/width")); |
| | | opeBlock.setObjectHeight(getRbdNodeInfo(rbdJsonArray, block.getPicId(), "size/height")); |
| | | opeBlock.setBlockX(block.getBlockX() + blockWidth - LAYOUT_CELL_SIZE_X); |
| | | opeBlock.setBlockY(firstSubBlockY); |
| | | opeBlock.setBlockWidth(LAYOUT_CELL_SIZE_X); |
| | |
| | | } |
| | | |
| | | } |
| | | |
| | | private RbdTreeNode listToTree(String id, |
| | | List<Algorithm> algorithmList, |
| | | List<ModelNode> modelNodeAndVnodeList) { |
| | | |
| | | List<Algorithm> algos = algorithmList.stream().filter(item -> |
| | | id.equals(item.getId().toString())).collect(Collectors.toList()); |
| | | |
| | | RbdTreeNode subNode = new RbdTreeNode(); |
| | | subNode.setId(Convert.toLong(id)); |
| | | ModelNode nd = modelNodeAndVnodeList.stream().filter(item -> |
| | | id.equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | subNode.setName(nd.getName()); |
| | | subNode.setNodeType(nd.getNodeType()); |
| | | subNode.setPicId(nd.getPicId()); |
| | | |
| | | if (!"vnode".equals(nd.getNodeType())) { |
| | | subNode.setMyWidth(nd.getWidth()); |
| | | subNode.setMyHeight(nd.getHeight()); |
| | | } |
| | | subNode.setBlockWidthNum(nd.getVnodeCellNumX()); |
| | | subNode.setBlockHeightNum(nd.getVnodeCellNumY()); |
| | | subNode.setPairStartNodeId(nd.getPairStartNodeId()); |
| | | subNode.setPairEndNodeId(nd.getPairEndNodeId()); |
| | | if (algos.size() > 0) { |
| | | Algorithm algo = algos.get(0); |
| | | subNode.setAlgorithmType(algo.getAlgorithmType()); |
| | | String str = algo.getComputerList(); |
| | | String[] ids = str.split(","); |
| | | for (String subId : ids) { |
| | | subNode.getChildren().add(listToTree(subId, algorithmList, modelNodeAndVnodeList)); |
| | | } |
| | | } |
| | | return subNode; |
| | | } |
| | | |
| | | /* |
| | | */ |
| | | |
| | | /** |
| | | * 根据顶层RBD的位置(x,y),自顶向下递归计算各个节点的位置(x,y) |
| | | * |
| | | * @param modelRbd |
| | | * @param algorithmList |
| | | * @param modelNodeAndVnodeList |
| | | *//* |
| | | |
| | | private void calcLayoutPosition(ModelRbd modelRbd, |
| | | List<Algorithm> algorithmList, |
| | | List<ModelNode> modelNodeAndVnodeList) { |
| | | String rbdsonStr = modelRbd.getContent(); |
| | | JSONArray rbdJsonArray = new JSONObject(rbdsonStr).getJSONArray("cells"); |
| | | Algorithm endAlgo = algorithmList.stream().filter(item -> |
| | | "end".equals(item.getAlgorithmType())).collect(Collectors.toList()).get(0); |
| | | ModelNode topNode = modelNodeAndVnodeList.stream().filter(item -> |
| | | endAlgo.getComputerList().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | Algorithm topAlgo = algorithmList.stream().filter(item -> |
| | | endAlgo.getComputerList().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | // 将topNode的坐标定为Cell(0,0),反算所有节点的坐标 |
| | | // 1. 计算节点的Cell位置 |
| | | calcNodeLayoutPositionCell(rbdJsonArray, algorithmList, modelNodeAndVnodeList, topNode, topAlgo, 0, 0, |
| | | topNode.getVnodeCellNumX(), topNode.getVnodeCellNumY()); |
| | | // 2. 计算节点的x,y坐标位置 |
| | | calcNodeLayoutPosition(rbdJsonArray, algorithmList, modelNodeAndVnodeList, topNode, topAlgo); |
| | | // 3. 设置start的位置 |
| | | double distance = 200.0; |
| | | double y = (topNode.getPositionCellY() + topNode.getVnodeCellNumY() / 2) * LAYOUT_CELL_SIZE_Y + (LAYOUT_CELL_SIZE_Y - LAYOUT_START_END_SIZE_Y) / 2; |
| | | setRbdNodePosition(rbdJsonArray, "10000", 0 - distance, y); |
| | | // 4. 设置end的位置 |
| | | double x = topNode.getVnodeCellNumX() * LAYOUT_CELL_SIZE_X + distance - LAYOUT_START_END_SIZE_X; |
| | | setRbdNodePosition(rbdJsonArray, "20000", x, y); |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("cells", rbdJsonArray); |
| | | modelRbd.setContent(jsonObject.toString()); |
| | | } |
| | | */ |
| | | |
| | | /* |
| | | // 递归函数(计算各节点的x,y坐标位置) |
| | | private void calcNodeLayoutPosition(JSONArray rbdJsonArray, |
| | | List<Algorithm> algorithmList, |
| | | List<ModelNode> modelNodeAndVnodeList, |
| | | ModelNode node, |
| | | Algorithm algo) { |
| | | // 未使用设备的实际宽、高 |
| | | double x; |
| | | double y; |
| | | if ("node".equals(node.getNodeType())) { |
| | | x = node.getPositionCellX() * LAYOUT_CELL_SIZE_X + (LAYOUT_CELL_SIZE_X - LAYOUT_DEVICE_NODE_SIZE_X) / 2; |
| | | y = node.getPositionCellY() * LAYOUT_CELL_SIZE_Y + (LAYOUT_CELL_SIZE_Y - LAYOUT_DEVICE_NODE_SIZE_Y) / 2; |
| | | node.setPositionX(x); |
| | | node.setPositionY(y); |
| | | setRbdNodePosition(rbdJsonArray, node.getPicId(), node.getPositionX(), node.getPositionY()); |
| | | } else if ("vnode".equals(node.getNodeType())) { |
| | | String[] computerNodeListStr = algo.getComputerList().split(","); |
| | | switch (algo.getAlgorithmType()) { |
| | | case OPE_TYPE_SERIES: |
| | | case OPE_TYPE_PARALLEL: |
| | | case OPE_TYPE_SWITCH: |
| | | case OPE_TYPE_VOTE: |
| | | for (String nodeStr : computerNodeListStr) { |
| | | ModelNode childNode = modelNodeAndVnodeList.stream().filter(item -> |
| | | nodeStr.equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | List<Algorithm> childAlgos = algorithmList.stream().filter(item -> |
| | | childNode.getId().equals(item.getId())).collect(Collectors.toList()); |
| | | Algorithm childAlgo = childAlgos.size() > 0 ? childAlgos.get(0) : null; |
| | | calcNodeLayoutPosition(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | childNode, |
| | | childAlgo); |
| | | } |
| | | if (OPE_TYPE_PARALLEL.equals(algo.getAlgorithmType()) |
| | | || OPE_TYPE_SWITCH.equals(algo.getAlgorithmType()) |
| | | || OPE_TYPE_VOTE.equals(algo.getAlgorithmType())) { |
| | | // 设置connect的位置 |
| | | x = node.getPositionCellX() * LAYOUT_CELL_SIZE_X + (LAYOUT_CELL_SIZE_X - LAYOUT_CONNECT_SIZE_X) / 2; |
| | | y = (node.getPositionCellY() + node.getVnodeCellNumY() / 2) * LAYOUT_CELL_SIZE_Y + (LAYOUT_CELL_SIZE_Y - LAYOUT_CONNECT_SIZE_Y) / 2; |
| | | setRbdNodePosition(rbdJsonArray, node.getPairStartNodeId(), x, y); |
| | | // 设置运算符的位置 |
| | | x = (node.getPositionCellX() + node.getVnodeCellNumX() - 1) * LAYOUT_CELL_SIZE_X + (LAYOUT_CELL_SIZE_X - LAYOUT_OPE_NODE_SIZE_X) / 2; |
| | | y = (node.getPositionCellY() + node.getVnodeCellNumY() / 2) * LAYOUT_CELL_SIZE_Y + (LAYOUT_CELL_SIZE_Y - LAYOUT_OPE_NODE_SIZE_Y) / 2; |
| | | setRbdNodePosition(rbdJsonArray, node.getPicId(), x, y); |
| | | } |
| | | break; |
| | | case OPE_TYPE_BRIDGE: |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 递归函数(计算各节点的Cell位置,以左上角为Cell位置0,0) |
| | | private void calcNodeLayoutPositionCell(JSONArray rbdJsonArray, |
| | | List<Algorithm> algorithmList, |
| | | List<ModelNode> modelNodeAndVnodeList, |
| | | ModelNode node, |
| | | Algorithm algo, |
| | | double originCellX, |
| | | double originCellY, |
| | | double maxX, |
| | | double maxY) { |
| | | if ("node".equals(node.getNodeType())) { |
| | | //设置node(设备节点)Cell位置 |
| | | double width = LAYOUT_DEVICE_NODE_SIZE_X * maxX; |
| | | double hight = LAYOUT_DEVICE_NODE_SIZE_Y * maxY; |
| | | double x = originCellX + (width - LAYOUT_DEVICE_NODE_SIZE_X) / 2; |
| | | double y = originCellY + (hight - LAYOUT_DEVICE_NODE_SIZE_Y) / 2; |
| | | node.setPositionCellX(x); |
| | | node.setPositionCellY(y); |
| | | } else if ("vnode".equals(node.getNodeType())) { |
| | | String[] computerNodeListStr = algo.getComputerList().split(","); |
| | | switch (algo.getAlgorithmType()) { |
| | | case OPE_TYPE_SERIES: |
| | | case OPE_TYPE_PARALLEL: |
| | | case OPE_TYPE_SWITCH: |
| | | case OPE_TYPE_VOTE: |
| | | double preNodeCellX = 0.0; |
| | | double preNodeCellY = 0.0; |
| | | for (String nodeStr : computerNodeListStr) { |
| | | ModelNode childNode = modelNodeAndVnodeList.stream().filter(item -> |
| | | nodeStr.equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | List<Algorithm> childAlgos = algorithmList.stream().filter(item -> |
| | | childNode.getId().equals(item.getId())).collect(Collectors.toList()); |
| | | Algorithm childAlgo = childAlgos.size() > 0 ? childAlgos.get(0) : null; |
| | | if (OPE_TYPE_SERIES.equals(algo.getAlgorithmType())) { |
| | | calcNodeLayoutPositionCell(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | childNode, |
| | | childAlgo, |
| | | originCellX + preNodeCellX, |
| | | originCellY, node.getVnodeCellNumX(), node.getVnodeCellNumY() |
| | | ); |
| | | preNodeCellX += childNode.getVnodeCellNumX(); |
| | | } else { |
| | | calcNodeLayoutPositionCell(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | childNode, |
| | | childAlgo, |
| | | originCellX + 1, |
| | | originCellY + preNodeCellY, node.getVnodeCellNumX(), node.getVnodeCellNumY()); |
| | | preNodeCellY += childNode.getVnodeCellNumY(); |
| | | } |
| | | } |
| | | */ |
| | | /* |
| | | // 设置运算符的Cell位置 |
| | | if (OPE_TYPE_SERIES.equals(algo.getAlgorithmType())) { |
| | | node.setPositionCellX(originCellX); |
| | | } else { |
| | | node.setPositionCellX(originCellX + node.getVnodeCellNumX() - 1); |
| | | } |
| | | node.setPositionCellY(originCellY + node.getVnodeCellNumY()/2); |
| | | *//* |
| | | |
| | | // 需节点代表整个逻辑单元,因此其坐标为originCellX和originCellX |
| | | node.setPositionCellX(originCellX); |
| | | node.setPositionCellY(originCellX); |
| | | break; |
| | | case OPE_TYPE_BRIDGE: |
| | | */ |
| | | /* |
| | | ModelNode node1 = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[0].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | ModelNode node2 = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[1].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | ModelNode node3 = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[2].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | ModelNode node4 = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[3].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | ModelNode node5 = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[4].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | Algorithm algo1 = algorithmList.stream().filter(item -> |
| | | node1.getId().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | Algorithm algo2 = algorithmList.stream().filter(item -> |
| | | node2.getId().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | Algorithm algo3 = algorithmList.stream().filter(item -> |
| | | node3.getId().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | Algorithm algo4 = algorithmList.stream().filter(item -> |
| | | node4.getId().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | Algorithm algo5 = algorithmList.stream().filter(item -> |
| | | node5.getId().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | // 1,计算三行的总高度 |
| | | // 1.1 计算第一行两个节点的高度 |
| | | int firstRowCellNumY = Math.max(node1.getVnodeCellNumY(), node2.getVnodeCellNumY()); |
| | | // 1.2 计算第二行桥联节点的高度 |
| | | int secondRowCellNumY = node3.getVnodeCellNumY(); |
| | | // 1.3 计算第三行两个节点的高度 |
| | | int thirdRowCellNumY = Math.max(node4.getVnodeCellNumY(), node5.getVnodeCellNumY()); |
| | | // int totalCellNumY = firstRowCellNumY + secondRowCellNumY + thirdRowCellNumY; |
| | | // 2. 计算三行各节点的坐标 |
| | | // 2.1 计算第一行两个节点的坐标 |
| | | calcNodeLayoutPositionCell(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | node1, |
| | | algo1, |
| | | originCellX + 1, |
| | | originCellY); |
| | | calcNodeLayoutPositionCell(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | node2, |
| | | algo2, |
| | | originCellX + 1 + node1.getPositionCellX(), |
| | | originCellY); |
| | | // 2.2 计算第二行桥联节点的坐标 |
| | | calcNodeLayoutPositionCell(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | node3, |
| | | algo3, |
| | | originCellX + 1, |
| | | originCellY + firstRowCellNumY); |
| | | // 2.3 计算第三行两个节点的坐标 |
| | | calcNodeLayoutPositionCell(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | node4, |
| | | algo4, |
| | | originCellX + 1, |
| | | originCellY + firstRowCellNumY + secondRowCellNumY); |
| | | calcNodeLayoutPositionCell(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | node5, |
| | | algo5, |
| | | originCellX + 1 + node4.getPositionCellX(), |
| | | originCellY + firstRowCellNumY + secondRowCellNumY); |
| | | // 2.4 计算桥联运算符的坐标 |
| | | node.setPositionCellX(originCellX + 1); |
| | | node.setPositionCellY(originCellY + node.getVnodeCellNumY()/2); |
| | | *//* |
| | | |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | */ |
| | | private void setRbdNodePosition(JSONArray rbdJsonArray, |
| | | String id, |
| | | double x, |
| | | double y) { |
| | | for (int i = 0; i < rbdJsonArray.size(); i++) { |
| | | JSONObject jsonObject = rbdJsonArray.getJSONObject(i); |
| | | if (id.equals(jsonObject.get("id").toString())) { |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "position/x".split("/"), x); |
| | | JsonUtils2.setJsonValueByPath(jsonObject, "position/y".split("/"), y); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private Double getRbdNodeInfo(JSONArray rbdJsonArray, |
| | | String picId, |
| | | String path) { |
| | | for (int i = 0; i < rbdJsonArray.size(); i++) { |
| | | JSONObject jsonObject = rbdJsonArray.getJSONObject(i); |
| | | if (picId.equals(jsonObject.get("id").toString())) { |
| | | return Convert.toDouble(JsonUtils2.getJsonValueByPath(jsonObject, path.split("/"))); |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 自底向上递归合计出整个RBD的大小(横向及纵向所占单元格的数量) |
| | | * |
| | | * @param modelRbd |
| | | * @param algorithmList |
| | | * @param modelNodeAndVnodeList |
| | | */ |
| | | private void calcLayoutSize( |
| | | ModelRbd modelRbd, |
| | | List<Algorithm> algorithmList, |
| | | List<ModelNode> modelNodeAndVnodeList) { |
| | | Algorithm endAlgo = algorithmList.stream().filter(item -> |
| | | "end".equals(item.getAlgorithmType())).collect(Collectors.toList()).get(0); |
| | | ModelNode topNode = modelNodeAndVnodeList.stream().filter(item -> |
| | | endAlgo.getComputerList().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | Algorithm topAlgo = algorithmList.stream().filter(item -> |
| | | endAlgo.getComputerList().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | calcNodeLayoutSize(algorithmList, modelNodeAndVnodeList, topNode, topAlgo); |
| | | } |
| | | |
| | | // 递归函数 |
| | | private void calcNodeLayoutSize(List<Algorithm> algorithmList, |
| | | List<ModelNode> modelNodeAndVnodeList, |
| | | ModelNode node, |
| | | Algorithm algo) { |
| | | if ("node".equals(node.getNodeType())) { |
| | | //设置node(设备节点)布局信息 |
| | | // node.setWidth(LAYOUT_DEVICE_NODE_SIZE_X); |
| | | // node.setHeight(LAYOUT_DEVICE_NODE_SIZE_Y); |
| | | node.setCellNumX(LAYOUT_CELL_NUM_NODE_X); |
| | | node.setCellNumY(LAYOUT_CELL_NUM_NODE_Y); |
| | | node.setVnodeCellNumX(node.getCellNumX()); |
| | | node.setVnodeCellNumY(node.getCellNumY()); |
| | | } else if ("vnode".equals(node.getNodeType())) { |
| | | // 1. 设置vnode(运算节点)布局信息(其实串联没有运算符,不需要设置,但是设置了也没有坏处,所以不作区分) |
| | | // node.setWidth(LAYOUT_OPE_NODE_SIZE_X); |
| | | // node.setHeight(LAYOUT_OPE_NODE_SIZE_Y); |
| | | node.setCellNumX(LAYOUT_CELL_NUM_NODE_X); |
| | | node.setCellNumY(LAYOUT_CELL_NUM_NODE_Y); |
| | | |
| | | // 2. 设置虚节点布局信息 |
| | | // 2.1 设置虚节点内各运算对象的布局信息 |
| | | String[] computerNodeListStr = algo.getComputerList().split(","); |
| | | for (String nodeStr : computerNodeListStr) { |
| | | ModelNode childNode = modelNodeAndVnodeList.stream().filter(item -> |
| | | nodeStr.equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | List<Algorithm> childAlgos = algorithmList.stream().filter(item -> |
| | | childNode.getId().equals(item.getId())).collect(Collectors.toList()); |
| | | Algorithm childAlgo = childAlgos.size() > 0 ? childAlgos.get(0) : null; |
| | | calcNodeLayoutSize(algorithmList, |
| | | modelNodeAndVnodeList, |
| | | childNode, |
| | | childAlgo); |
| | | } |
| | | // 2.2 设置虚节点总的布局信息到运算节点中 |
| | | setVnodeLayoutNum(computerNodeListStr, modelNodeAndVnodeList, node, algo); |
| | | } |
| | | } |
| | | |
| | | private void setVnodeLayoutNum(String[] computerNodeListStr, |
| | | List<ModelNode> modelNodeAndVnodeList, |
| | | ModelNode vnode, |
| | | Algorithm algo) { |
| | | int numX = 0; |
| | | int numY = 0; |
| | | // 1. 计算串、并、旁联、表决 |
| | | for (String nodeStr : computerNodeListStr) { |
| | | ModelNode childNode = modelNodeAndVnodeList.stream().filter(item -> |
| | | nodeStr.equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | switch (algo.getAlgorithmType()) { |
| | | case OPE_TYPE_SERIES: |
| | | numX += childNode.getVnodeCellNumX(); |
| | | numY = childNode.getVnodeCellNumY() > numY ? childNode.getVnodeCellNumY() : numY; |
| | | break; |
| | | case OPE_TYPE_PARALLEL: |
| | | case OPE_TYPE_SWITCH: |
| | | case OPE_TYPE_VOTE: |
| | | numX = childNode.getVnodeCellNumX() > numX ? childNode.getVnodeCellNumX() : numX; |
| | | numY += childNode.getVnodeCellNumY(); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | if (OPE_TYPE_PARALLEL.equals(algo.getAlgorithmType()) |
| | | || OPE_TYPE_SWITCH.equals(algo.getAlgorithmType()) |
| | | || OPE_TYPE_VOTE.equals(algo.getAlgorithmType())) { |
| | | // 加上connect的大小 |
| | | numX += LAYOUT_CELL_NUM_CONNECT_X; |
| | | numX += vnode.getCellNumX(); |
| | | } |
| | | // 2. 计算桥联 |
| | | if (OPE_TYPE_BRIDGE.equals(algo.getAlgorithmType())) { |
| | | // 桥联支路算一行,整个桥联共3行 |
| | | // 2.1 计算第一行 |
| | | ModelNode node1 = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[0].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | ModelNode node2 = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[1].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | ModelNode node3 = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[2].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | ModelNode node4 = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[3].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | ModelNode node5 = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[4].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | int numX1 = node1.getCellNumX() + node2.getCellNumX(); |
| | | int numY1 = node1.getCellNumY() > node2.getCellNumY() ? node1.getCellNumY() : node2.getCellNumY(); |
| | | // 2.2 计算第二行(桥联支路,横向画图) |
| | | int numX2 = node3.getCellNumX(); |
| | | int numY2 = node3.getCellNumY(); |
| | | // 2.3 计算第三行 |
| | | int numX3 = node4.getCellNumX() + node5.getCellNumX(); |
| | | int numY3 = node4.getCellNumY() > node5.getCellNumY() ? node4.getCellNumY() : node5.getCellNumY(); |
| | | numX = Math.max(Math.max(numX1, numX2), numX3); |
| | | numY = numY1 + numY2 + numY3; |
| | | // 2.4 加上connect的大小 |
| | | numX += LAYOUT_CELL_NUM_CONNECT_X; |
| | | numX += vnode.getCellNumX(); |
| | | } |
| | | vnode.setVnodeCellNumX(numX); |
| | | vnode.setVnodeCellNumY(numY); |
| | | } |
| | | } |