| | |
| | | import com.zt.common.utils.UUIDUtil; |
| | | import com.zt.life.modules.mainPart.basicInfo.dao.ParamDataDao; |
| | | import com.zt.life.modules.mainPart.basicInfo.dao.XhProductModelDao; |
| | | import com.zt.life.modules.mainPart.basicInfo.model.ParamData; |
| | | import com.zt.life.modules.mainPart.basicInfo.model.ProductImg; |
| | | import com.zt.life.modules.mainPart.basicInfo.model.XhProductModel; |
| | | 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.dom4j.Element; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import com.zt.common.db.query.QueryFilter; |
| | |
| | | */ |
| | | @Service |
| | | public class ModelLineService extends BaseService<ModelLineDao, ModelLine> { |
| | | private static final Logger logger = LoggerFactory.getLogger(ModelLineService.class); |
| | | |
| | | // 运算 |
| | | public static final String OPE_TYPE_SERIES = "series"; |
| | | public static final String OPE_TYPE_PARALLEL = "parallel"; |
| | | 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; |
| | | @Autowired |
| | |
| | | modelRbdDao.deleteByModelId(modelId); |
| | | |
| | | modelRbdDao.insert(modelRbd); |
| | | } |
| | | |
| | | // 自动排版RBD |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public boolean layout(ModelRbd modelRbd) { |
| | | boolean result = true; |
| | | if (modelRbd==null) return result; |
| | | Long modelId = modelRbd.getId(); |
| | | result = layoutRbd(modelRbd); |
| | | return result; |
| | | } |
| | | |
| | | private boolean layoutRbd(ModelRbd modelRbd) { |
| | | boolean result = true; |
| | | String rbdsonStr = modelRbd.getContent(); |
| | | |
| | | JSONArray rbdJsonArray = new JSONObject(rbdsonStr).getJSONArray("cells"); |
| | | if (rbdJsonArray == null) return result; |
| | | |
| | | // 解析结果存放list |
| | | List<ModelNode> modelNodeList = new ArrayList<>(); |
| | | List<ModelLine> modelLineList = new ArrayList<>(); |
| | | List<Algorithm> algorithmList = new ArrayList<>(); |
| | | List<ProductImg> productImgList = new ArrayList<>(); // 暂不使用(而使用数据库中的可靠性参数) |
| | | |
| | | // 1. 解析出节点与边 |
| | | getNodeAndLineFromRbd(modelRbd.getId(), rbdJsonArray, modelNodeList, modelLineList, productImgList); |
| | | // 2. 对于有多根入口线的产品节点,将其上的表决、旁联关系剥离成运算符节点,添加到该节点的前面,并添加相应的边 |
| | | peelOperationFromProductNode(modelRbd.getId(), modelNodeList, modelLineList); |
| | | // 3. 计算所有节点的入口线数及出口线数 |
| | | calcInOutLineNumAllNode(modelNodeList, modelLineList); |
| | | // 4. 复制产品节点(node)到list |
| | | List<ModelNode> modelNodeAndVnodeList = modelNodeList.stream().filter(item -> |
| | | "node".equals(item.getNodeType())).collect(Collectors.toList()); |
| | | // 5. 不断将基本模型(串联、并联、旁联、表决、桥联)替换为虚节点而简化图形,直至无法简化为止。 |
| | | result = getAlgorithmFromRbd(modelRbd, modelNodeList, modelLineList, algorithmList, modelNodeAndVnodeList); |
| | | |
| | | // 6. 递归计算RBD的布局空间大小 |
| | | calcLayoutSize(modelRbd, algorithmList, modelNodeAndVnodeList); |
| | | // 7. 递归计算RBD的布局空间参数(x、y坐标) |
| | | calcLayoutPosition(modelRbd, algorithmList, modelNodeAndVnodeList); |
| | | |
| | | // 8. 保存自动布局模型 |
| | | // 更新RBD数据 |
| | | // modelRbd.setAutoLayoutContent("测试文字"); |
| | | modelRbdDao.updateById(modelRbd); |
| | | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 根据顶层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); |
| | | // 将toNode的中心坐标定为(0,0),反算所有节点的坐标 |
| | | // 1. 计算并设置start的位置 |
| | | double x = -topNode.getVnodeCellNumX()*LAYOUT_CELL_SIZE_X/2 - LAYOUT_START_END_SIZE_X; |
| | | double y = -LAYOUT_START_END_SIZE_Y/2; |
| | | setRbdNodePosition(rbdJsonArray, "10000", x, y); |
| | | // 2. 计算并设置节点的位置 |
| | | calcNodeLayoutPosition(rbdJsonArray, algorithmList, modelNodeAndVnodeList, topNode, topAlgo, 0, 0); |
| | | // 3. 计算并设置end的位置 |
| | | x = topNode.getVnodeCellNumX()*LAYOUT_CELL_SIZE_X/2; |
| | | setRbdNodePosition(rbdJsonArray, "20000", x ,y); |
| | | JSONObject jsonObject = new JSONObject(); |
| | | jsonObject.put("cells", rbdJsonArray); |
| | | modelRbd.setContent(jsonObject.toString()); |
| | | } |
| | | |
| | | // 递归函数 |
| | | private void calcNodeLayoutPosition(JSONArray rbdJsonArray, |
| | | List<Algorithm> algorithmList, |
| | | List<ModelNode> modelNodeAndVnodeList, |
| | | ModelNode node, |
| | | Algorithm algo, |
| | | double x, |
| | | double y) { |
| | | if ("node".equals(node.getNodeType())) { |
| | | //设置node(设备节点)布局信息 |
| | | node.setPositionX(x - node.getCellNumX()*LAYOUT_CELL_SIZE_X/2); |
| | | node.setPositionY(y - node.getCellNumY()*LAYOUT_CELL_SIZE_Y/2); |
| | | setRbdNodePosition(rbdJsonArray, node.getPicId().toString(), node.getPositionX(), node.getPositionY()); |
| | | } else if ("vnode".equals(node.getNodeType())) { |
| | | String[] computerNodeListStr = algo.getComputerList().split(","); |
| | | switch (algo.getAlgorithmType()) { |
| | | case OPE_TYPE_SERIES: |
| | | int sumCellNumX = 0; |
| | | for (String nodeStr : computerNodeListStr) { |
| | | ModelNode childNode = modelNodeAndVnodeList.stream().filter(item -> |
| | | nodeStr.equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | sumCellNumX += childNode.getVnodeCellNumX(); |
| | | } |
| | | for (int i=0; i<computerNodeListStr.length; i++) { |
| | | int idx = i; |
| | | ModelNode childNode = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[idx].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | if (0==i) { |
| | | double childNodeX = x - sumCellNumX * LAYOUT_CELL_SIZE_X / 2; |
| | | double childNodeY = y - childNode.getVnodeCellNumY() * LAYOUT_CELL_SIZE_Y / 2; |
| | | if ("node".equals(childNode.getNodeType())) { |
| | | childNode.setPositionX(childNodeX); |
| | | childNode.setPositionY(childNodeY); |
| | | setRbdNodePosition(rbdJsonArray, childNode.getPicId().toString(), childNode.getPositionX(), childNode.getPositionY()); |
| | | } else { |
| | | Algorithm childAlgo = algorithmList.stream().filter(item -> |
| | | childNode.getId().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | calcNodeLayoutPosition(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | childNode, |
| | | childAlgo, |
| | | childNodeX, |
| | | childNodeY); |
| | | } |
| | | } else { |
| | | int idxPre = i - 1; |
| | | ModelNode childNodePre = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[idxPre].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | int idxMe = i; |
| | | double childNodeX = childNodePre.getPositionX() + childNodePre.getVnodeCellNumX()*LAYOUT_CELL_SIZE_X; |
| | | double childNodeY = y - childNode.getVnodeCellNumY()*LAYOUT_CELL_SIZE_Y/2; |
| | | if ("node".equals(childNode.getNodeType())) { |
| | | childNode.setPositionX(childNodeX); |
| | | childNode.setPositionY(childNodeY); |
| | | setRbdNodePosition(rbdJsonArray, childNode.getPicId().toString(), childNode.getPositionX(), childNode.getPositionY()); |
| | | } else { |
| | | ModelNode childNodeMe = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[idxMe].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | Algorithm childAlgoMe = algorithmList.stream().filter(item -> |
| | | childNodeMe.getId().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | calcNodeLayoutPosition(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | childNode, |
| | | childAlgoMe, |
| | | childNodePre.getPositionX() + childNodePre.getVnodeCellNumX() * LAYOUT_CELL_SIZE_X, |
| | | y - childNodeMe.getVnodeCellNumY() * LAYOUT_CELL_SIZE_Y / 2); |
| | | } |
| | | } |
| | | } |
| | | break; |
| | | case OPE_TYPE_PARALLEL: |
| | | case OPE_TYPE_SWITCH: |
| | | case OPE_TYPE_VOTE: |
| | | int sumCellNumY = 0; |
| | | for (String nodeStr : computerNodeListStr) { |
| | | ModelNode childNode = modelNodeAndVnodeList.stream().filter(item -> |
| | | nodeStr.equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | sumCellNumY += childNode.getVnodeCellNumY(); |
| | | } |
| | | for (int i=0; i<computerNodeListStr.length; i++) { |
| | | int idx = i; |
| | | ModelNode childNode = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[idx].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | if (0==i) { |
| | | double childNodeX = x - childNode.getVnodeCellNumX()*LAYOUT_CELL_SIZE_X/2; |
| | | double childNodeY = y - sumCellNumY*LAYOUT_CELL_SIZE_Y/2; |
| | | if ("node".equals(childNode.getNodeType())) { |
| | | childNode.setPositionX(childNodeX); |
| | | childNode.setPositionY(childNodeY); |
| | | setRbdNodePosition(rbdJsonArray, childNode.getPicId(), childNode.getPositionX(), childNode.getPositionY()); |
| | | } else { |
| | | Algorithm childAlgo = algorithmList.stream().filter(item -> |
| | | childNode.getId().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | calcNodeLayoutPosition(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | childNode, |
| | | childAlgo, |
| | | childNodeX, |
| | | childNodeY); |
| | | } |
| | | } else { |
| | | int idxPre = i - 1; |
| | | ModelNode childNodePre = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[idxPre].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | int idxMe = i; |
| | | ModelNode childNodeMe = modelNodeAndVnodeList.stream().filter(item -> |
| | | computerNodeListStr[idxMe].equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | double childNodeX = x - childNodeMe.getVnodeCellNumY() * LAYOUT_CELL_SIZE_Y / 2; |
| | | double childNodeY = childNodePre.getPositionY() + childNodePre.getVnodeCellNumY() * LAYOUT_CELL_SIZE_Y; |
| | | if ("node".equals(childNodeMe.getNodeType())) { |
| | | childNodeMe.setPositionX(childNodeX); |
| | | childNodeMe.setPositionY(childNodeY); |
| | | setRbdNodePosition(rbdJsonArray, childNodeMe.getPicId(), childNodeMe.getPositionX(), childNodeMe.getPositionY()); |
| | | } else { |
| | | Algorithm childAlgoMe = algorithmList.stream().filter(item -> |
| | | childNodeMe.getId().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | calcNodeLayoutPosition(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | childNodeMe, |
| | | childAlgoMe, |
| | | childNodeX, |
| | | childNodeY); |
| | | } |
| | | } |
| | | } |
| | | 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 计算第一行两个节点的坐标 |
| | | calcNodeLayoutPosition(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | node1, |
| | | algo1, |
| | | x - (node1.getVnodeCellNumX() + node2.getVnodeCellNumX())*LAYOUT_CELL_SIZE_X/2, |
| | | y - (totalCellNumY-firstRowCellNumY+node1.getVnodeCellNumY())*LAYOUT_CELL_SIZE_Y/2); |
| | | calcNodeLayoutPosition(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | node2, |
| | | algo2, |
| | | x + (node1.getVnodeCellNumX() + node2.getVnodeCellNumX())*LAYOUT_CELL_SIZE_X/2, |
| | | y - (totalCellNumY-firstRowCellNumY+node2.getVnodeCellNumY())*LAYOUT_CELL_SIZE_Y/2); |
| | | // 2.2 计算第二行桥联节点的坐标 |
| | | calcNodeLayoutPosition(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | node2, |
| | | algo2, |
| | | x - node3.getVnodeCellNumX()*LAYOUT_CELL_SIZE_X/2, |
| | | y - (totalCellNumY/2-firstRowCellNumY)*LAYOUT_CELL_SIZE_Y); |
| | | // 2.3 计算第三行两个节点的坐标 |
| | | calcNodeLayoutPosition(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | node1, |
| | | algo1, |
| | | x - (node1.getVnodeCellNumX() + node2.getVnodeCellNumX())*LAYOUT_CELL_SIZE_X/2, |
| | | y - (totalCellNumY-firstRowCellNumY+node1.getVnodeCellNumY())*LAYOUT_CELL_SIZE_Y/2); |
| | | calcNodeLayoutPosition(rbdJsonArray, |
| | | algorithmList, |
| | | modelNodeAndVnodeList, |
| | | node2, |
| | | algo2, |
| | | x + (node1.getVnodeCellNumX() + node2.getVnodeCellNumX())*LAYOUT_CELL_SIZE_X/2, |
| | | y - (totalCellNumY-firstRowCellNumY+node2.getVnodeCellNumY())*LAYOUT_CELL_SIZE_Y/2); |
| | | // 2.4 计算桥联运算符的坐标 |
| | | // 2.5 计算左侧配对的connect的坐标 |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 自底向上递归合计出整个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); |
| | | if ("node".equals(childNode.getNodeType())) { |
| | | childNode.setWidth(LAYOUT_DEVICE_NODE_SIZE_X); |
| | | childNode.setHeight(LAYOUT_DEVICE_NODE_SIZE_Y); |
| | | childNode.setCellNumX(LAYOUT_CELL_NUM_NODE_X); |
| | | childNode.setCellNumY(LAYOUT_CELL_NUM_NODE_Y); |
| | | childNode.setVnodeCellNumX(node.getCellNumX()); |
| | | childNode.setVnodeCellNumY(node.getCellNumY()); |
| | | } else { |
| | | Algorithm childAlgo = algorithmList.stream().filter(item -> |
| | | childNode.getId().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | 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.getCellNumX(); |
| | | numY = childNode.getCellNumY() > numY ? childNode.getCellNumY() : numY; |
| | | break; |
| | | case OPE_TYPE_PARALLEL: |
| | | case OPE_TYPE_SWITCH: |
| | | case OPE_TYPE_VOTE: |
| | | numX = childNode.getCellNumX() > numX ? childNode.getCellNumX() : numX; |
| | | numY += childNode.getCellNumY(); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | } |
| | | if (OPE_TYPE_PARALLEL.equals(algo.getAlgorithmType()) |
| | | || OPE_TYPE_SWITCH.equals(algo.getAlgorithmType()) |
| | | || OPE_TYPE_VOTE.equals(algo.getAlgorithmType())) { |
| | | // 设置connect的大小 |
| | | ModelNode connect = modelNodeAndVnodeList.stream().filter(item -> |
| | | vnode.getPairStartNodeId().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | connect.setWidth(LAYOUT_CONNECT_SIZE_X); |
| | | connect.setHeight(LAYOUT_CONNECT_SIZE_Y); |
| | | connect.setCellNumX(LAYOUT_CELL_NUM_CONNECT_X); |
| | | connect.setCellNumY(LAYOUT_CELL_NUM_CONNECT_Y); |
| | | numX += connect.getCellNumX(); |
| | | 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的大小 |
| | | ModelNode connect = modelNodeAndVnodeList.stream().filter(item -> |
| | | vnode.getPairStartNodeId().equals(item.getId().toString())).collect(Collectors.toList()).get(0); |
| | | connect.setWidth(LAYOUT_CONNECT_SIZE_X); |
| | | connect.setHeight(LAYOUT_CONNECT_SIZE_Y); |
| | | connect.setCellNumX(LAYOUT_CELL_NUM_CONNECT_X); |
| | | connect.setCellNumY(LAYOUT_CELL_NUM_CONNECT_Y); |
| | | numX += connect.getCellNumX(); |
| | | numX += vnode.getCellNumX(); |
| | | } |
| | | vnode.setVnodeCellNumX(numX); |
| | | vnode.setVnodeCellNumY(numY); |
| | | } |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | |
| | | if (jsonValue!=null && StringUtils.isNotBlank(jsonValue.toString())) { |
| | | modelNode.setVoteNum(Integer.valueOf(jsonValue.toString())); |
| | | } |
| | | jsonValue = JsonUtils2.getJsonValueByPath(jsonObject, "data/startNodeId".split("/")); |
| | | if (jsonValue!=null && StringUtils.isNotBlank(jsonValue.toString())) { |
| | | modelNode.setPairStartNodeId(jsonValue.toString()); |
| | | } |
| | | jsonValue = JsonUtils2.getJsonValueByPath(jsonObject, "data/endNodeId".split("/")); |
| | | if (jsonValue!=null && StringUtils.isNotBlank(jsonValue.toString())) { |
| | | modelNode.setPairEndNodeId(jsonValue.toString()); |
| | | } |
| | | if ("node".equals(modelNode.getNodeType())) { |
| | | ProductImg productImg = new ProductImg(); |
| | | String dataId = JsonUtils2.getJsonValueByPath(jsonObject, "data/dataId".split("/")).toString(); |