|
@@ -1,466 +0,0 @@
|
|
-package com.persagy.adm.diagram.core;
|
|
|
|
-
|
|
|
|
-import cn.hutool.core.collection.CollUtil;
|
|
|
|
-import cn.hutool.core.util.IdUtil;
|
|
|
|
-import cn.hutool.core.util.StrUtil;
|
|
|
|
-import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
|
|
-import com.persagy.adm.diagram.core.model.*;
|
|
|
|
-import com.persagy.adm.diagram.core.model.base.Container;
|
|
|
|
-import com.persagy.adm.diagram.core.model.base.IComponent;
|
|
|
|
-import com.persagy.adm.diagram.core.model.base.IDataBind;
|
|
|
|
-import com.persagy.adm.diagram.core.model.base.IEquipHolder;
|
|
|
|
-import com.persagy.adm.diagram.core.model.legend.Anchor;
|
|
|
|
-import com.persagy.adm.diagram.core.model.legend.Legend;
|
|
|
|
-import com.persagy.adm.diagram.core.model.logic.CalcContext;
|
|
|
|
-import com.persagy.adm.diagram.core.model.logic.DataFilter;
|
|
|
|
-import com.persagy.adm.diagram.core.model.template.DiagramTemplate;
|
|
|
|
-import com.persagy.adm.diagram.core.model.template.MainPipe;
|
|
|
|
-import com.persagy.adm.diagram.core.model.virtual.PackNode;
|
|
|
|
-import com.persagy.dmp.digital.entity.ObjectRelation;
|
|
|
|
-
|
|
|
|
-import java.util.*;
|
|
|
|
-import java.util.stream.Collectors;
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * 处理系统图的计算逻辑
|
|
|
|
- * @author zhaoyk
|
|
|
|
- */
|
|
|
|
-public class DiagramBuilder {
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 设备容器限制,避免模板设置不当导致过多节点
|
|
|
|
- */
|
|
|
|
- public static int equipLimit = 50;
|
|
|
|
-
|
|
|
|
- private CalcContext context;
|
|
|
|
-
|
|
|
|
- private Diagram diagram;
|
|
|
|
-
|
|
|
|
- private DiagramTemplate template;
|
|
|
|
-
|
|
|
|
- private DataStrategy dataStrategy;
|
|
|
|
-
|
|
|
|
- private HashMap<String, List<Legend>> legendsCache = new HashMap<>();
|
|
|
|
-
|
|
|
|
- private HashSet<String> refRelTypes = new HashSet<>();
|
|
|
|
-
|
|
|
|
- public DiagramBuilder(CalcContext context, DataStrategy dataStrategy) {
|
|
|
|
- this.context = context;
|
|
|
|
- this.diagram = context.getDiagram();
|
|
|
|
- this.template = context.getTemplate();
|
|
|
|
- this.dataStrategy = dataStrategy;
|
|
|
|
-
|
|
|
|
- this.context.setDataStrategy(dataStrategy);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private boolean hasDynGroup(List<Container> containers) {
|
|
|
|
- for(Container con : containers) {
|
|
|
|
- if(con.getDynGroup() != null){
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //加载设备数据,并进行计算处理
|
|
|
|
- public void buildEquipNodeAndContainer(List<Container> containers, List<ObjectNode> optionalObjs){
|
|
|
|
- //去掉已经使用的数据项
|
|
|
|
- if(context.getEquipMap().size() > 0) {
|
|
|
|
- optionalObjs = optionalObjs.stream().filter(obj -> !context.getEquipMap().containsKey(obj.get("id").asText())).collect(Collectors.toList());
|
|
|
|
- } else {
|
|
|
|
- optionalObjs = new ArrayList<>(optionalObjs);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(hasDynGroup(containers)) {
|
|
|
|
- //TODO 动态组计算
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(template.getMainPipes() != null) {
|
|
|
|
- for(MainPipe mainPipe : template.getMainPipes()) {
|
|
|
|
- if (mainPipe.isBindEquipment() && mainPipe.getDataObject() == null){
|
|
|
|
- Iterator<ObjectNode> iter = optionalObjs.iterator();
|
|
|
|
- while (iter.hasNext()) {
|
|
|
|
- ObjectNode obj = iter.next();
|
|
|
|
- if(match(obj, mainPipe)) {
|
|
|
|
- mainPipe.setDataObject(obj);
|
|
|
|
- mainPipe.setDataObjectId(obj.get("id").asText());
|
|
|
|
-
|
|
|
|
- context.getEquipMap().put(mainPipe.getDataObjectId(), mainPipe);
|
|
|
|
-
|
|
|
|
- iter.remove();
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- for(Container con : containers) {
|
|
|
|
- if(con.isEquipmentBox()) {
|
|
|
|
- Iterator<ObjectNode> iter = optionalObjs.iterator();
|
|
|
|
- while (iter.hasNext()) {
|
|
|
|
- ObjectNode obj = iter.next();
|
|
|
|
- if (match(obj, con)) {
|
|
|
|
- if(con.getEquipPack() != null) {
|
|
|
|
- addPackData(con, obj);
|
|
|
|
- } else {
|
|
|
|
- addEquipNode(con, obj);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- iter.remove();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- handleNodes();
|
|
|
|
-
|
|
|
|
- handleContainers(containers);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void buildMainPipe(){
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void addEquipNode(Container con, ObjectNode obj){
|
|
|
|
- if(con.getChildren().size() > equipLimit) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- EquipmentNode node = new EquipmentNode();
|
|
|
|
- node.setId(IdUtil.fastSimpleUUID());
|
|
|
|
- node.setDataObjectId(obj.get("id").asText());
|
|
|
|
- node.setObjClassCode(DiagramBuilder.getClassCode(obj));
|
|
|
|
- node.setDataObject(obj);
|
|
|
|
-
|
|
|
|
- initNode(node, DiagramBuilder.getName(obj), con);
|
|
|
|
-
|
|
|
|
- Legend legend = findLegend(node.getObjClassCode(), obj);
|
|
|
|
- node.setLegendId(legend.getId());
|
|
|
|
- node.setLegend(legend);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void initNode(EquipmentNode node, String name, Container con){
|
|
|
|
- con.addComp(node);
|
|
|
|
- node.setContainerId(con.getId());
|
|
|
|
- node.setLayoutIndex(con.getChildren().size() - 1);
|
|
|
|
-
|
|
|
|
- Label label = new Label();
|
|
|
|
- label.setId(IdUtil.fastSimpleUUID());
|
|
|
|
- label.setContent(name);
|
|
|
|
- node.setLabel(label);
|
|
|
|
-
|
|
|
|
- diagram.getNodes().add(node);
|
|
|
|
- context.getEquipMap().put(node.getDataObjectId(), node);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void addPackData(Container con, ObjectNode obj){
|
|
|
|
- PackNode pn = null;
|
|
|
|
- String classCode = getClassCode(obj);
|
|
|
|
- Legend legend = null;
|
|
|
|
- //single
|
|
|
|
- if(!con.getEquipPack().isPackByType()) {
|
|
|
|
- String packName = con.getEquipPack().getPackName();
|
|
|
|
- if(StrUtil.isBlank(packName)) {
|
|
|
|
- packName = getTypeName(classCode);
|
|
|
|
- }
|
|
|
|
- if(con.getChildren().size() == 0) {
|
|
|
|
- pn = newPackNode(PackNode.SINGLE_PACK, con, packName);
|
|
|
|
- } else {
|
|
|
|
- pn = (PackNode) con.getChildren().get(0);
|
|
|
|
- }
|
|
|
|
- } else { //group
|
|
|
|
- for(IComponent comp : con.getChildren()) {
|
|
|
|
- PackNode item = (PackNode) comp;
|
|
|
|
- if(item.getObjClassCode().equals(classCode)){
|
|
|
|
- pn = item;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if(pn == null) {
|
|
|
|
- pn = newPackNode(classCode, con, getTypeName(classCode));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (pn.getLegend() == null) {
|
|
|
|
- if(con.getEquipPack().getLegendId() != null) {
|
|
|
|
- legend = dataStrategy.getLegend(con.getEquipPack().getLegendId(), classCode.substring(0, 4));
|
|
|
|
- }
|
|
|
|
- if(legend == null) {
|
|
|
|
- legend = findLegend(classCode, null);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pn.setLegendId(legend.getId());
|
|
|
|
- pn.setLegend(legend);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- pn.add(classCode);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private PackNode newPackNode(String objClsCode, Container con, String packName){
|
|
|
|
- PackNode pn = new PackNode();
|
|
|
|
- pn.setId(IdUtil.fastSimpleUUID());
|
|
|
|
- pn.setObjClassCode(objClsCode);
|
|
|
|
-
|
|
|
|
- initNode(pn, packName, con);
|
|
|
|
-
|
|
|
|
- return pn;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private boolean match(ObjectNode obj, IEquipHolder equipHolder) {
|
|
|
|
- String classCode = DiagramBuilder.getClassCode(obj);
|
|
|
|
- if(equipHolder.getEquipmentTypes() != null && equipHolder.getEquipmentTypes().contains(classCode)) {
|
|
|
|
- DataFilter filter = equipHolder.getDataFilter();
|
|
|
|
- if(filter != null) {
|
|
|
|
- return filter.filter(obj, context);
|
|
|
|
- }
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 对节点进行处理,并返回图例锚点会使用到的关系类型
|
|
|
|
- */
|
|
|
|
- private void handleNodes() {
|
|
|
|
- for(DiagramNode node : diagram.getNodes()) {
|
|
|
|
- if(PackNode.TYPE.equals(node.getCompType())) {
|
|
|
|
- PackNode pn = (PackNode)node;
|
|
|
|
- pn.getLabel().setContent(pn.getLabel().getContent() + ":" + pn.totalCount());
|
|
|
|
- statRelTypes(pn);
|
|
|
|
- } else if(EquipmentNode.TYPE.equals(node.getCompType())) {
|
|
|
|
- statRelTypes((EquipmentNode)node);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void statRelTypes(EquipmentNode equipmentNode){
|
|
|
|
- List<Anchor> anchors = equipmentNode.getLegend().getAnchors();
|
|
|
|
- if(anchors != null) {
|
|
|
|
- for(Anchor anchor : anchors) {
|
|
|
|
- if(anchor.getAcceptRelations() != null) {
|
|
|
|
- anchor.getAcceptRelations().forEach(rel -> refRelTypes.add(rel));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void handleContainers(List<Container> containers) {
|
|
|
|
- for(Container con : containers) {
|
|
|
|
- if(con.isEquipmentBox()) {
|
|
|
|
- if(Boolean.TRUE.equals(con.getProp(Container.PROP_AUTO_HIDDEN)) && CollUtil.isEmpty(con.getChildren())) {
|
|
|
|
- con.setHidden(true);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private String getTypeName(String classCode){
|
|
|
|
- //TODO
|
|
|
|
- return classCode;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private Legend findLegend(String classCode, ObjectNode obj){
|
|
|
|
- List<Legend> legends = legendsCache.get(classCode);
|
|
|
|
- if (legends == null) {
|
|
|
|
- legends = dataStrategy.getLegendsForEquipment(classCode);
|
|
|
|
- if (legends == null) {
|
|
|
|
- legends = new ArrayList<>();
|
|
|
|
- }
|
|
|
|
- legendsCache.put(classCode, legends);
|
|
|
|
- }
|
|
|
|
- if(legends.size() > 0) {
|
|
|
|
- Legend l0 = null, l1 = null;
|
|
|
|
- for(Legend legend : legends) {
|
|
|
|
- //系统图类型匹配
|
|
|
|
- boolean typeMatch = CollUtil.isNotEmpty(legend.getDiagramTypes()) && legend.getDiagramTypes().contains(diagram.getType());
|
|
|
|
- //过滤条件匹配
|
|
|
|
- boolean filterMatch;
|
|
|
|
- if(obj != null && legend.getDataFilter() != null) {
|
|
|
|
- filterMatch = legend.getDataFilter().filter(obj, context);
|
|
|
|
- } else {
|
|
|
|
- filterMatch = true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(typeMatch && filterMatch) {
|
|
|
|
- return legend;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(typeMatch && l0 == null) {
|
|
|
|
- l0 = legend;
|
|
|
|
- }
|
|
|
|
- if(filterMatch && l1 == null) {
|
|
|
|
- l1 = legend;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if(l0 != null) {
|
|
|
|
- return l0;
|
|
|
|
- }
|
|
|
|
- if(l1 != null) {
|
|
|
|
- return l1;
|
|
|
|
- }
|
|
|
|
- //没有优先匹配的话取第一个
|
|
|
|
- return legends.get(0);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //返回一个缺省图例
|
|
|
|
- return emptyLegend();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void buildLines(List<ObjectNode> optionalRels){
|
|
|
|
- //去掉已经使用的关系项
|
|
|
|
- if(context.getLineMap().size() > 0) {
|
|
|
|
- optionalRels = optionalRels.stream().filter(obj -> !context.getLineMap().containsKey(obj.get("id").asText())).collect(Collectors.toList());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- for(ObjectNode rel : optionalRels) {
|
|
|
|
- IDataBind fromObj = context.getEquipMap().get(rel.get(ObjectRelation.OBJ_FROM_HUM).asText());
|
|
|
|
- IDataBind toObj = context.getEquipMap().get(rel.get(ObjectRelation.OBJ_TO_HUM).asText());
|
|
|
|
-
|
|
|
|
- if(fromObj != null && toObj != null) {
|
|
|
|
- String relType = rel.get(ObjectRelation.GRAPH_CODE_HUM).asText() + '/' + rel.get(ObjectRelation.REL_CODE_HUM).asText();
|
|
|
|
- ConnectPoint from = getConnectPoint(fromObj, relType, toObj);
|
|
|
|
- if(from != null) {
|
|
|
|
- ConnectPoint to = getConnectPoint(toObj, relType, fromObj);
|
|
|
|
- if(to != null) {
|
|
|
|
- Line line = new Line();
|
|
|
|
- line.setFrom(from);
|
|
|
|
- line.setTo(to);
|
|
|
|
- line.setRelType(relType);
|
|
|
|
- line.setDataObject(rel);
|
|
|
|
- line.setDataObjectId(rel.get("id").asText());
|
|
|
|
-
|
|
|
|
- addLine(line);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private ConnectPoint getConnectPoint(IDataBind obj, String relType, IDataBind theOtherEnd){
|
|
|
|
- ObjectNode theOtherData = (ObjectNode) theOtherEnd.getDataObject();
|
|
|
|
- String theOtherType = getClassCode(theOtherData);
|
|
|
|
-
|
|
|
|
- if(obj instanceof EquipmentNode) {
|
|
|
|
- EquipmentNode en = (EquipmentNode)obj;
|
|
|
|
- Anchor anchor = null;
|
|
|
|
- List<Anchor> anchors = en.getLegend().getAnchors();
|
|
|
|
- if(CollUtil.isNotEmpty(anchors)) {
|
|
|
|
- Anchor anchor1 = null; //部分匹配
|
|
|
|
- for (Anchor a : anchors) {
|
|
|
|
- Boolean relMatch = null; //关系匹配
|
|
|
|
- Boolean equipMatch = null; //另一端设备匹配
|
|
|
|
-
|
|
|
|
- if(CollUtil.isNotEmpty(a.getAcceptRelations())) {
|
|
|
|
- relMatch = a.getAcceptRelations().contains(relType);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(!Boolean.FALSE.equals(relMatch)) {
|
|
|
|
- if(CollUtil.isNotEmpty(a.getToEquipmentTypes())) {
|
|
|
|
- equipMatch = a.getToEquipmentTypes().contains(theOtherType);
|
|
|
|
- }
|
|
|
|
- if(!Boolean.FALSE.equals(equipMatch) && a.getToDataFilter() != null) {
|
|
|
|
- equipMatch = a.getToDataFilter().filter(theOtherData, context);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(!Boolean.FALSE.equals(relMatch) && !Boolean.FALSE.equals(equipMatch)) {
|
|
|
|
- if(relMatch == null || equipMatch == null) {
|
|
|
|
- //部分匹配
|
|
|
|
- if(anchor1 == null) {
|
|
|
|
- anchor1 = a;
|
|
|
|
- } else if(CollUtil.isNotEmpty(anchor1.getLines()) && CollUtil.isEmpty(a.getLines())) {
|
|
|
|
- anchor1 = a;
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- //完全匹配
|
|
|
|
- if(CollUtil.isEmpty(a.getLines())) { //优先每个锚点只有一条连线
|
|
|
|
- anchor = a;
|
|
|
|
- break;
|
|
|
|
- } else if(anchor == null) {
|
|
|
|
- anchor = a;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if(anchor == null && anchor1 != null) {
|
|
|
|
- anchor = anchor1;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(anchor != null) {
|
|
|
|
- ConnectPoint cp = new ConnectPoint();
|
|
|
|
- cp.setHostType(EquipmentNode.TYPE);
|
|
|
|
- cp.setHostId(en.getId());
|
|
|
|
- cp.setAnchorCode(anchor.getCode());
|
|
|
|
- cp.setHostObj(en);
|
|
|
|
- return cp;
|
|
|
|
- }
|
|
|
|
- } else if(obj instanceof MainPipe) {
|
|
|
|
- MainPipe mp = (MainPipe)obj;
|
|
|
|
- if(CollUtil.isEmpty(mp.getConnectEquips()) || mp.getConnectEquips().contains(theOtherType)) {
|
|
|
|
- ConnectPoint cp = new ConnectPoint();
|
|
|
|
- cp.setHostType(MainPipe.TYPE);
|
|
|
|
- cp.setHostId(mp.getId());
|
|
|
|
- cp.setHostObj(mp);
|
|
|
|
- return cp;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void addLine(Line line) {
|
|
|
|
- line.setId(IdUtil.fastSimpleUUID());
|
|
|
|
- markAnchorLine(line.getFrom(), line);
|
|
|
|
- markAnchorLine(line.getTo(), line);
|
|
|
|
- diagram.getLines().add(line);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void markAnchorLine(ConnectPoint p, Line line){
|
|
|
|
- EquipmentNode en = p.getEquipmentNode();
|
|
|
|
- if (en != null) {
|
|
|
|
- Anchor anchor = en.getLegend().getAnchor(p.getAnchorCode());
|
|
|
|
- anchor.addLine(line);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public HashSet<String> getRefRelTypes() {
|
|
|
|
- return refRelTypes;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public Diagram getDiagram() {
|
|
|
|
- return diagram;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public DataStrategy getDataStrategy() {
|
|
|
|
- return dataStrategy;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public static String getName(ObjectNode obj){
|
|
|
|
- String name = null;
|
|
|
|
- if(obj.get("localName") != null) {
|
|
|
|
- name = obj.get("localName").asText();
|
|
|
|
- }
|
|
|
|
- if(StrUtil.isBlank(name) && obj.get("name") != null) {
|
|
|
|
- name = obj.get("name").asText();
|
|
|
|
- }
|
|
|
|
- if(name == null)
|
|
|
|
- System.out.println();
|
|
|
|
- return name;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public static String getClassCode(ObjectNode obj){
|
|
|
|
- if(obj != null && obj.get("classCode") != null) {
|
|
|
|
- return obj.get("classCode").asText();
|
|
|
|
- }
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public static Legend emptyLegend(){
|
|
|
|
- Legend l = new Legend();
|
|
|
|
- l.setWidth(100);
|
|
|
|
- l.setHeight(100);
|
|
|
|
- return l;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-}
|
|
|