wente
2024-12-04 142c2321e95bdb274f7451e2f070847a631f32c4
web/src/views/modules/taskReliability/RBD-edit-img.vue
@@ -16,8 +16,12 @@
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="saveDiagram()">暂存</el-button>
              <el-button type="primary" @click="analyzeDiagram()">保存</el-button>
              <el-button type="primary" @click="analyzeDiagram()">提交</el-button>
              <el-button type="primary" @click="clearDiagram()">清空图形</el-button>
              <el-checkbox style="margin: 0 10px 0 10px" v-model="dataForm.autoLayout" :true-label="1" :false-label="0">
                是否开启一键排版
              </el-checkbox>
              <el-button type="primary" @click="layoutDiagram()" :disabled="!dataForm.autoLayout">一键排版</el-button>
              <el-button @click="leftAlign()">
                <i style="font-size: 1rem;" class="wt-iconfont icon-zuoduiqi"></i>
              </el-button>
@@ -37,16 +41,19 @@
                <i style="font-size: 1rem;" class="wt-iconfont icon-diduiqi"></i>
              </el-button>
            </el-form-item>
            <el-form-item>
              <el-button @click="undo()">撤销</el-button>
              <el-button @click="redo()">重做</el-button>
            </el-form-item>
            <el-form-item>
              <zt-button type="delete" @click="deleteCompment()"/>
            </el-form-item>
          </el-form>
          <div id="containerImg" style="border: 1px solid #EAEBEE;border-radius: 6px;
        box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);height: 100%">
          </div>
          <config-node v-show="type === 'node'" :id="id" :diagramId="diagramId" :globalGridAttr="globalGridAttr"
                       :graph="graph"
                       :nodeType="nodeType"
                       :projectId="projectId"
                       :shape="shape"/>
          <config-edge v-show="type === 'edge'" :id="id" :globalGridAttr="globalGridAttr" :graph="graph"/>
          <config-node ref="configNode" v-show="type === 'node'"/>
          <config-edge ref="configEdge" v-show="type === 'edge'"/>
        </div>
      </el-col>
    </el-row>
@@ -54,494 +61,941 @@
</template>
<script>
import {Graph, Shape, Addon, Cell} from '@antv/x6'
import ConfigNode from './ConfigNode/index.vue'
import ConfigEdge from './ConfigEdge/index.vue'
import {removeCurrentTabHandle} from '@/commonJS/common'
import {setHartBeat} from '@/commonJS/common';
import Cookies from 'js-cookie'
  import {Graph, Shape, Addon, Cell} from '@antv/x6'
  import ConfigNode from './ConfigNode/configNode.vue'
  import ConfigEdge from './ConfigEdge/configEdge.vue'
  import {setHartBeat} from '@/commonJS/common';
  import Cookies from 'js-cookie'
  import {getUUID} from '../../../../packages/utils'
  // import Mousetrap from 'mousetrap'
  // var Mousetrap = require('mousetrap');
  // import RBDDefault from './RBD-default.json'
export default {
  name: 'RBD-edit-img',
  /*props: {
  },*/
  props: {
    projectId: {
      type: String
    },
    diagarmId: {
      type: String
    },
    pageCode: {
      default: 'wlt_pz'
    },
    flowCode: {
      type: String,
      default: 'wltFlow'
    },
  },
  components: {
    ConfigNode,
    ConfigEdge
  },
  data() {
    return {
      nodeAdded: false,
      connectNode: {},
      modelId: '',
      modelName: '',
      modelType: '',
      timer: null,
      imgsList: [
        {imgPath: 'start', imgName: 'start', nodeType: 'start', imgWidth: 60, imgHeight: 60, imgId: '1', data: {}},
        {imgPath: 'end', imgName: 'end', nodeType: 'end', imgWidth: 60, imgHeight: 60, imgId: '2', data: {}},
        {
          imgPath: 'connect',
          imgName: 'connect',
          nodeType: 'connect',
          imgWidth: 30,
          imgHeight: 30,
          imgId: '3',
          data: {}
        },
        {
          imgPath: 'switch',
          imgName: 'switch',
          nodeType: 'switch',
          imgWidth: 60,
          imgHeight: 60,
          imgId: '5',
          data: {}
        },
        {imgPath: 'vote', imgName: 'vote', nodeType: 'vote', imgWidth: 60, imgHeight: 60, imgId: '6', data: {}},
      ],
      imgsList2: [
        // {imgPath:'logo',imgName:'logo',nodeType:'node',,nodeTypeExt:'',productType:'',statusImg:'',imgWidth:60,imgHeight:60,imgId:'100',dataId:'123456'},
      ],
      combiningImages: [
        {
          imgPath: 'switch',
          imgName: 'switch',
          nodeType: 'switch',
          imgWidth: 60,
          imgHeight: 60,
          imgId: '5',
          data: {}
        },
        {imgPath: 'vote', imgName: 'vote', nodeType: 'vote', imgWidth: 60, imgHeight: 60, imgId: '6', data: {}}
      ],
      nodeType: '',
      first: true,
      shape: '',
      projectList: [],
      diagramList: [],
      diagramId: '',
      projectId: '',
      diagramJson: '',
      diagramIdDisabled: false,
      dataForm: {
        id: null,
        content: null,
        publishContent: null,
        hasPublish: 0,
        urlPref: '',
  export default {
    name: 'RBD-edit-img',
    props: {
      projectId: {
        type: String
      },
      // emptyJson: {
      //   // 节点
      //   nodes: [
      //     {
      //       id: 'node1', // String,可选,节点的唯一标识
      //       width: 500,   // Number,可选,节点大小的 width 值
      //       height: 300,  // Number,可选,节点大小的 height 值
      //       label: '该项目还未配置厂家网络图',
      //       attrs: {
      //         body: {
      //           strokeWidth: 0
      //         },
      //       }
      //       //   text: {
      //       //     text: '该项目还未编制网络图',
      //       //     // fontSize: 56,
      //       //     fill: 'rgba(0,0,0,0.7)'
      //       //   },
      //       // },
      //     }
      //   ],
      // },
      type: '',
      id: '',
      graph: null,
      globalGridAttr: {
        productType: '',
        voteNum: '',
        repairMttcr: '',
        repairMttcrOther: '',
        repairDistribType: '',
        reliabDistribType: '',
        taskMtbcfOther: '',
        isRepair: 0,
        taskMtbcf: '',
        numberInputValue: '',
        statusImg: '',
        nodeTypeExt: '',
        type: 'mesh',
        size: 10,
        color: '#e5e5e5',
        thickness: 1,
        colorSecond: '#d0d0d0',
        thicknessSecond: 1,
        factor: 4,
        bgColor: '#e5e5e5',
        showImage: true,
        repeat: 'watermark',
        position: 'center',
        bgSize: JSON.stringify({width: 150, height: 150}),
        opacity: 0.1,
        stroke: '#5F95FF',
        strokeWidth: 1,
        connector: 'rounded',
        router: 'manhattan',
        label: '',
        nodeStroke: '#5F95FF',
        nodeStrokeWidth: 1,
        nodeFill: '#ffffff',
        nodeFontSize: 12,
        nodeColor: '#080808',
        nodeText: '',
        nodeDate: '',
        nodeUsers: '',
        nodeDataDate: '',
        nodeDataText: '',
        dataId: '',
        inspectName: '',
        distance: 0.5,
        angle: 0,
      diagarmId: {
        type: String
      },
      isReady: false,
      curCel: Cell,
      left_p: document.documentElement.clientHeight - 100,
      ports: {
        groups: {
          top: {
            position: {name: 'top'},
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: '#5F95FF',
                strokeWidth: 1,
                fill: '#fff',
                style: {
                  visibility: 'hidden',
                },
      pageCode: {
        default: 'wlt_pz'
      },
      flowCode: {
        type: String,
        default: 'wltFlow'
      },
    },
    components: {
      ConfigNode,
      ConfigEdge
    },
    computed: {
      RBDDefault() {
        let url = `${window.SITE_CONFIG['apiURL']}/sysPictureBase/getSvgImage?token=${Cookies.get('token')}&id=`
        let result = `
        {
          "cells":
          [
            {
              "position": {
                "x": -600,
                "y": 0
              },
            },
          },
          right: {
            position: {name: 'right'},
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: '#5F95FF',
                strokeWidth: 1,
                fill: '#fff',
                style: {
                  visibility: 'hidden',
                },
              "size": {
                "width": 60,
                "height": 40
              },
            },
          },
          bottom: {
            position: {name: 'bottom'},
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: '#5F95FF',
                strokeWidth: 1,
                fill: '#fff',
                style: {
                  visibility: 'hidden',
              "attrs": {
                "text": {
                  "refY": "100%",
                  "textVerticalAnchor": "top",
                  "text": "",
                  "refY2": 4
                },
                "image": {
                  "xlink:href": "${url}10011"
                }
              },
            },
          },
          left: {
            position: {name: 'left'},
            attrs: {
              circle: {
                r: 4,
                magnet: true,
                stroke: '#5F95FF',
                strokeWidth: 1,
                fill: '#fff',
                style: {
                  visibility: 'hidden',
              "visible": true,
              "shape": "image",
              "id": "10000",
              "data": {
                "type": "imageNodes",
                "endNodeId": "20000",
                "dataId": "",
                "nodeType": "start",
                "nodeTypeExt": "",
                "voteNum": ""
              },
              "ports": {
                "groups": {
                  "top": {
                    "position": {
                      "name": "top"
                    },
                    "attrs": {
                      "circle": {
                        "r": 4,
                        "magnet": true,
                        "stroke": "#5F95FF",
                        "strokeWidth": 1,
                        "fill": "#fff",
                        "style": {
                          "visibility": "hidden"
                        }
                      }
                    }
                  },
                  "right": {
                    "position": {
                      "name": "right"
                    },
                    "attrs": {
                      "circle": {
                        "r": 4,
                        "magnet": true,
                        "stroke": "#5F95FF",
                        "strokeWidth": 1,
                        "fill": "#fff",
                        "style": {
                          "visibility": "hidden"
                        }
                      }
                    }
                  },
                  "bottom": {
                    "position": {
                      "name": "bottom"
                    },
                    "attrs": {
                      "circle": {
                        "r": 4,
                        "magnet": true,
                        "stroke": "#5F95FF",
                        "strokeWidth": 1,
                        "fill": "#fff",
                        "style": {
                          "visibility": "hidden"
                        }
                      }
                    }
                  },
                  "left": {
                    "position": {
                      "name": "left"
                    },
                    "attrs": {
                      "circle": {
                        "r": 4,
                        "magnet": true,
                        "stroke": "#5F95FF",
                        "strokeWidth": 1,
                        "fill": "#fff",
                        "style": {
                          "visibility": "hidden"
                        }
                      }
                    }
                  }
                },
                "items": [
                  {
                    "id": "top1",
                    "group": "top"
                  },
                  {
                    "id": "right1",
                    "group": "right"
                  },
                  {
                    "id": "bottom1",
                    "group": "bottom"
                  },
                  {
                    "id": "left1",
                    "group": "left"
                  }
                ]
              },
              "zIndex": 1
            },
          },
        },
        items: [
            {
              "position": {
                "x": 0,
                "y": 0
              },
              "size": {
                "width": 60,
                "height": 40
              },
              "attrs": {
                "text": {
                  "refY": "100%",
                  "textVerticalAnchor": "top",
                  "text": "",
                  "refY2": 4
                },
                "image": {
                  "xlink:href": "${url}10015"
                }
              },
              "visible": true,
              "shape": "image",
              "id": 15000,
              "data": {
                "type": "imageNodes",
                "dataId": "",
                "nodeType": "dashedBox",
                "nodeTypeExt": "",
                "voteNum": ""
              },
              "ports": {
                "groups": {
                  "top": {
                    "position": {
                      "name": "top"
                    },
                    "attrs": {
                      "circle": {
                        "r": 4,
                        "magnet": true,
                        "stroke": "#5F95FF",
                        "fill": "#fff",
                        "style": {
                          "visibility": "hidden"
                        }
                      }
                    }
                  },
                  "right": {
                    "position": {
                      "name": "right"
                    },
                    "attrs": {
                      "circle": {
                        "r": 4,
                        "magnet": true,
                        "stroke": "#5F95FF",
                        "strokeWidth": 1,
                        "fill": "#fff",
                        "style": {
                          "visibility": "hidden"
                        }
                      }
                    }
                  },
                  "bottom": {
                    "position": {
                      "name": "bottom"
                    },
                    "attrs": {
                      "circle": {
                        "r": 4,
                        "magnet": true,
                        "stroke": "#5F95FF",
                        "strokeWidth": 1,
                        "fill": "#fff",
                        "style": {
                          "visibility": "hidden"
                        }
                      }
                    }
                  },
                  "left": {
                    "position": {
                      "name": "left"
                    },
                    "attrs": {
                      "circle": {
                        "r": 4,
                        "magnet": true,
                        "stroke": "#5F95FF",
                        "strokeWidth": 1,
                        "fill": "#fff",
                        "style": {
                          "visibility": "hidden"
                        }
                      }
                    }
                  }
                },
                "items": [
                  {
                    "id": "top1",
                    "group": "top"
                  },
                  {
                    "id": "right1",
                    "group": "right"
                  },
                  {
                    "id": "bottom1",
                    "group": "bottom"
                  },
                  {
                    "id": "left1",
                    "group": "left"
                  }
                ]
              },
              "zIndex": 2
            },
            {
              "position": {
                "x": 600,
                "y": 0
              },
              "size": {
                "width": 60,
                "height": 40
              },
              "attrs": {
                "text": {
                  "refY": "100%",
                  "textVerticalAnchor": "top",
                  "text": "",
                  "refY2": 4
                },
                "image": {
                  "xlink:href": "${url}10012"
                }
              },
              "visible": true,
              "shape": "image",
              "id": "20000",
              "data": {
                "type": "imageNodes",
                "startNodeId": "10000",
                "dataId": "",
                "nodeType": "end",
                "nodeTypeExt": "",
                "voteNum": ""
              },
              "ports": {
                "groups": {
                  "top": {
                    "position": {
                      "name": "top"
                    },
                    "attrs": {
                      "circle": {
                        "r": 4,
                        "magnet": true,
                        "stroke": "#5F95FF",
                        "strokeWidth": 1,
                        "fill": "#fff",
                        "style": {
                          "visibility": "hidden"
                        }
                      }
                    }
                  },
                  "right": {
                    "position": {
                      "name": "right"
                    },
                    "attrs": {
                      "circle": {
                        "r": 4,
                        "magnet": true,
                        "stroke": "#5F95FF",
                        "strokeWidth": 1,
                        "fill": "#fff",
                        "style": {
                          "visibility": "hidden"
                        }
                      }
                    }
                  },
                  "bottom": {
                    "position": {
                      "name": "bottom"
                    },
                    "attrs": {
                      "circle": {
                        "r": 4,
                        "magnet": true,
                        "stroke": "#5F95FF",
                        "strokeWidth": 1,
                        "fill": "#fff",
                        "style": {
                          "visibility": "hidden"
                        }
                      }
                    }
                  },
                  "left": {
                    "position": {
                      "name": "left"
                    },
                    "attrs": {
                      "circle": {
                        "r": 4,
                        "magnet": true,
                        "stroke": "#5F95FF",
                        "strokeWidth": 1,
                        "fill": "#fff",
                        "style": {
                          "visibility": "hidden"
                        }
                      }
                    }
                  }
                },
                "items": [
                  {
                    "id": "top1",
                    "group": "top"
                  },
                  {
                    "id": "right1",
                    "group": "right"
                  },
                  {
                    "id": "bottom1",
                    "group": "bottom"
                  },
                  {
                    "id": "left1",
                    "group": "left"
                  }
                ]
              },
              "zIndex": 3
            },
            {
              "shape": "edge",
              "id": "66c81c68-0827-4a3c-8343-e2c453d3e9e7",
              "router": {
                "name": "manhattan",
                "args": {
                        "startDirections": ["right"],
                        "endDirections": ["left"]
                       }
              },
              "connector": {
                "name": "rounded"
              },
              "source": {
                "cell": "10000"
              },
              "target": {
                "cell": 15000
              },
              "zIndex": -1
            },
            {
              "shape": "edge",
              "id": "a0f3cf90-6d37-4ee0-a254-90b4ec2b6a7f",
              "router": {
                "name": "manhattan",
                "args": {
                        "startDirections": ["right"],
                        "endDirections": ["left"]
                       }
              },
              "connector": {
                "name": "rounded"
              },
              "source": {
                "cell": 15000
              },
              "target": {
                "cell": "20000"
              },
              "zIndex": -1
            }
          ]
        }
        `
        return JSON.parse(result)
      }
    },
    data() {
      return {
        canAdd: true,
        nodeX: '',
        nodeY: '',
        isFirstLoad: true,
        hasMoveNode: false,
        hasMoveSingleNode: null,
        nodeAdded: false,
        connectNode: {},
        modelId: '',
        modelName: '',
        modelType: '',
        timer: null,
        imagesList: [
          {
            id: 'top1',
            group: 'top',
            imgPath: 'switch',
            imgName: '',
            nodeType: 'switch',
            imgWidth: 50,
            imgHeight: 50,
            imgId: '9',
            data: {}
          },
          {imgPath: 'vote', imgName: '', nodeType: 'vote', imgWidth: 50, imgHeight: 50, imgId: '6', data: {}},
          {
            imgPath: 'parallel',
            imgName: '',
            nodeType: 'parallel',
            imgWidth: 50,
            imgHeight: 50,
            imgId: '5',
            data: {}
          },
          {
            id: 'right1',
            group: 'right',
          },
          {
            id: 'bottom1',
            group: 'bottom',
          },
          {
            id: 'left1',
            group: 'left',
            imgPath: 'bridgeConnection',
            imgName: '',
            nodeType: 'bridgeConnection',
            imgWidth: 50,
            imgHeight: 50,
            imgId: '10',
            data: {}
          },
        ],
      }
    }
  },
  watch: {
    '$route.params.configId'() {
      // alert('$route.params.projectId change')
      this.projectId = this.$route.params.projectId
      //this.diagramId = this.$route.params.diagramId
      console.log(this.$route.params.projectId, 'this.$route.params.projectId')
      console.log(this.$route.params.diagramId, 'this.$route.params.diagramId')
    }
  },
  mounted() {
    //this.initDigram()
    this.type = 'grid'
  },
  methods: {
    init(row) {
      this.modelName = row.modelName
      this.dataForm.id = row.id
      // this.productId = row.productId
      // this.getProduct(row.productId)
      this.initDigram(row.productId)
      console.log(this.dataForm, 'init(row){')
    },
    async getDiagram(modelId) {
      let params = {
        modelId: modelId,
        urlPref: window.SITE_CONFIG['apiURL'],
        token: Cookies.get('token'),
      }
      let res = await this.$http.get(`/taskReliability/ModelLine/getDiagram`, {params: params})
      console.log(res, 'async getDiagram( res')
      if (res.data !== null && (res.data.content != null)) {
        this.dataForm = res.data
        console.log(this.dataForm, 'this.dataForm in getDiagram')
        if (this.dataForm.content != '') {
          this.diagramJson = JSON.parse(this.dataForm.content)
        }
        // console.log(this.dataForm.content,'this.Diagram content')
        console.log(this.diagramJson, 'this.Diagram json')
        this.graph.fromJSON(this.diagramJson)
        this.graph.positionContent('left')
        // this.graph.centerContent()
        // this.graph.zoomToFit()
      } else {
        await this.clearDiagram()
      }
    },
    async clearDiagram() {
      this.dataForm.id = null
      // this.graph.fromJSON(this.emptyJson)
      this.graph.fromJSON('')
      // this.graph.centerContent()
      // this.graph.zoomToFit()
      // this.graph.freeze()
    },
    async initDigram(productId) {
      this.timer = setHartBeat(10, 240);
      console.log(document.documentElement.clientWidth, 'document.documentElement.clientWidth')
      console.log(document.documentElement.clientHeight, 'document.documentElement.clientHeight')
      this.graph = new Graph({
        container: document.getElementById('containerImg'),
        width: document.documentElement.clientWidth,
        height: document.documentElement.clientHeight - 200,
        // async: true,
        grid: {
          visible: true,
        imagesList2: [],
        nodeType: '',
        first: true,
        shape: '',
        projectList: [],
        diagramList: [],
        diagramId: '',
        projectId: '',
        diagramJson: '',
        diagramIdDisabled: false,
        dataForm: {
          id: null,
          pid: null,
          model_tag: '',
          model_name: '',
          product_id: null,
          content: null,
          publishContent: null,
          hasPublish: 0,
          urlPref: '',
          nodeArr: [],
          autoLayout: 1,
        },
        autoResize: true,
        history: {
          enabled: true,
          beforeAddCommand(event, args) {
            if (args.key === 'tools') {
              console.log(args.key, 'event, args')
              return false
            }
          },
        },
        // panning: {
        //   enabled: true,
        // },
        scroller: {
          enabled: true,
          pageVisible: true,
          autoResize: true,
          pageBreak: true,
          pannable: true,
          minVisibleWidth: 200,
          minVisibleHeight: 200,
          modifiers: 'shift',
        },
        mousewheel: {
          enabled: true,
          zoomAtMousePosition: true,
          modifiers: 'ctrl',
          minScale: 0.5,
          maxScale: 3,
        },
        connecting: {
        type: '',
        id: '',
        graph: null,
        globalGridAttr: {
          productType: '',
          voteNum: '',
          repairMttcr: '',
          repairMttcrOtherParams2: '',
          repairMttcrOtherParams3: '',
          repairDistribType: '',
          reliabDistribType: '',
          taskMtbcfOtherParams2: '',
          taskMtbcfOtherParams3: '',
          isRepair: 0,
          taskMtbcf: '',
          numberInputValue: '',
          statusImg: '',
          nodeTypeExt: '',
          type: 'mesh',
          size: 10,
          color: '#e5e5e5',
          thickness: 1,
          colorSecond: '#d0d0d0',
          thicknessSecond: 1,
          factor: 4,
          bgColor: '#e5e5e5',
          showImage: true,
          repeat: 'watermark',
          position: 'center',
          bgSize: JSON.stringify({width: 150, height: 150}),
          opacity: 0.1,
          stroke: '#5F95FF',
          strokeWidth: 1,
          connector: 'rounded',
          router: {
            name: 'manhattan',
            // args: {
            //   padding: 1,
            // },
          },
          connector: {
            name: 'rounded',
            args: {
              radius: 5,
              startDirections: ['top', 'bottom'], // 从下方开始
              endDirections: ['left'],      // 向左方结束
            },
          },
          anchor: 'center',
          connectionPoint: 'anchor',
          allowBlank: false,
          snap: {
            radius: 20,
          },
          createEdge() {
            return new Shape.Edge({
          label: '',
          nodeStroke: '#5F95FF',
          nodeStrokeWidth: 1,
          nodeFill: '#ffffff',
          nodeFontSize: 12,
          nodeColor: '#080808',
          nodeText: '',
          nodeDate: '',
          nodeUsers: '',
          nodeDataDate: '',
          nodeDataText: '',
          dataId: '',
          inspectName: '',
          distance: 0.5,
          angle: 0,
        },
        isReady: false,
        curCel: Cell,
        left_p: document.documentElement.clientHeight - 100,
        ports: {
          groups: {
            top: {
              position: {name: 'top'},
              attrs: {
                line: {
                  stroke: '#A2B1C3',
                  strokeWidth: 2,
                  targetMarker: 'classic'
                }
              },
              labels: [{
                attrs: {
                  body: {
                    stroke: '#5F95FF',
                circle: {
                  r: 4,
                  magnet: true,
                  stroke: '#5F95FF',
                  strokeWidth: 1,
                  fill: '#fff',
                  style: {
                    visibility: 'hidden',
                  },
                  text: {
                    text: ''
                },
              },
            },
            right: {
              position: {name: 'right'},
              attrs: {
                circle: {
                  r: 4,
                  magnet: true,
                  stroke: '#5F95FF',
                  strokeWidth: 1,
                  fill: '#fff',
                  style: {
                    visibility: 'hidden',
                  },
                },
              },
            },
            bottom: {
              position: {name: 'bottom'},
              attrs: {
                circle: {
                  r: 4,
                  magnet: true,
                  stroke: '#5F95FF',
                  strokeWidth: 1,
                  fill: '#fff',
                  style: {
                    visibility: 'hidden',
                  },
                },
              },
            },
            left: {
              position: {name: 'left'},
              attrs: {
                circle: {
                  r: 4,
                  magnet: true,
                  stroke: '#5F95FF',
                  strokeWidth: 1,
                  fill: '#fff',
                  style: {
                    visibility: 'hidden',
                  },
                },
              },
            },
          },
          items: [
            {
              id: 'top1',
              group: 'top',
            },
            {
              id: 'right1',
              group: 'right',
            },
            {
              id: 'bottom1',
              group: 'bottom',
            },
            {
              id: 'left1',
              group: 'left',
            },
          ],
        }
      }
    },
    watch: {
      '$route.params.configId'() {
        // alert('$route.params.projectId change')
        this.projectId = this.$route.params.projectId
        //this.diagramId = this.$route.params.diagramId
        console.log(this.$route.params.projectId, 'this.$route.params.projectId')
        console.log(this.$route.params.diagramId, 'this.$route.params.diagramId')
      }
    },
    mounted() {
      //this.initDigram()
      this.type = 'grid'
    },
    methods: {
      init(row) {
        this.modelName = row.modelName
        this.dataForm.id = row.id
        // this.productId = row.productId
        // this.getProduct(row.productId)
        this.initDigram(row.productId)
        console.log(this.dataForm, 'init(row){')
      },
      async getDiagram(modelId) {
        this.isFirstLoad = true;
        let params = {
          modelId: modelId,
          urlPref: window.SITE_CONFIG['apiURL'],
          token: Cookies.get('token'),
        }
        let res = await this.$http.get(`/taskReliability/ModelLine/getDiagram`, {params: params})
        this.dataForm = res.data
        this.dataForm.autoLayout = parseInt(this.dataForm.autoLayout)
        if (res.data.content != null) {
          console.log(this.dataForm, 'getDiagram datafrom')
          console.log(res.data, 'getDiagram res.data')
          this.diagramJson = JSON.parse(this.dataForm.content)
          this.graph.fromJSON(this.diagramJson)
          this.isFirstLoad = false;
          console.log(this.diagramJson.cells.length, 'this.diagramJson.cells.length')
          this.graph.positionContent('left')
          // this.graph.centerContent()
          // this.graph.zoomToFit()
        } else {
          this.graph.fromJSON(this.RBDDefault)
          this.isFirstLoad = false
        }
      },
      async clearDiagram() {
        // this.graph.fromJSON(this.emptyJson)
        console.log(this.RBDDefault, 'clearDiagram')
        this.graph.fromJSON(this.RBDDefault)
        this.graph.positionContent('left')
        this.isFirstLoad = false;
        // this.graph.centerContent()
        // this.graph.zoomToFit()
        // this.graph.freeze()
      },
      async initDigram(productId) {
        this.timer = setHartBeat(10, 240);
        console.log(document.documentElement.clientWidth, 'document.documentElement.clientWidth')
        console.log(document.documentElement.clientHeight, 'document.documentElement.clientHeight')
        this.graph = new Graph({
          container: document.getElementById('containerImg'),
          width: document.documentElement.clientWidth,
          height: document.documentElement.clientHeight - 200,
          // async: true,
          grid: {
            visible: true,
          },
          autoResize: true,
          history: {
            enabled: true,
            beforeAddCommand(event, args) {
              if (args.key === 'tools') {
                // console.log(args.key, 'event, args')
                return false
              }
            },
          },
          scroller: {
            enabled: true,
            pageVisible: true,
            autoResize: true,
            pageBreak: true,
            pannable: true,
            minVisibleWidth: 200,
            minVisibleHeight: 200,
            modifiers: 'shift',
          },
          mousewheel: {
            enabled: true,
            zoomAtMousePosition: true,
            modifiers: 'ctrl',
            minScale: 0.5,
            maxScale: 3,
          },
          connecting: {
            router: {
              name: 'manhattan',
              args: {
                startDirections: ['top', 'bottom'], // 从下方开始
                endDirections: ['left'],      // 向左方结束
              },
            },
            connector: {
              name: 'rounded',
              args: {
                radius: 5,
              },
            },
            anchor: 'center',
            connectionPoint: 'anchor',
            allowBlank: false,
            allowLoop: false, // 是否允许创建循环连线,即边的起始节点和终止节点为同一节点,默认为 true
            snap: {
              radius: 20,
            },
            createEdge() {
              return new Shape.Edge({
                attrs: {
                  line: {
                    //  sourceMarker: 'block', // 实心箭头
                    stroke: '#A2B1C3',
                    strokeWidth: 2,
                    targetMarker: null
                  }
                },
                position: {
                  distance: 0.5,
                  angle: 180,
                  options: {
                    keepGradient: true,
                    ensureLegibility: true
                labels: [{
                  attrs: {
                    body: {
                      stroke: '#5F95FF',
                    },
                    text: {
                      text: ''
                    }
                  },
                  position: {
                    distance: 0.5,
                    angle: 180,
                    options: {
                      keepGradient: true,
                      ensureLegibility: true
                    }
                  }
                }],
                tools: {
                  name: 'segments',
                  args: {
                    attrs: {fill: '#666'},
                  },
                },
                zIndex: -100,
              })
            },
            validateConnection({targetMagnet}) {
              return !!targetMagnet
            },
          },
          highlighting: {
            magnetAdsorbed: {
              name: 'stroke',
              args: {
                attrs: {
                  fill: '#5F95FF',
                  stroke: '#5F95FF',
                },
              },
            },
          },
          resizing: true,
          rotating: true,
          selecting: {
            enabled: true,
            rubberband: true,
            rubberEdge: true,
            showNodeSelectionBox: true,
          },
          snapline: true,
          keyboard: true,
          clipboard: true,
        })
        this.graph.centerContent()
        const stencil = new Addon.Stencil({
          // getDragNode: (node) => {
          // node.removeAttrs('title')
          // },
          getDropNode: (node) => {
            this.canAdd = true
            const {width, height} = node.size()
            if (node.getData().type && node.getData().type === 'imageNodes2') {
              const nodes = this.graph.getNodes()
              let deviceNoArr = []
              for (const node2 of nodes) {
                console.log(node2, 'saveDiagram node')
                if (node2.getData().nodeType == 'node' && node2.getData().dataId) {
                  if (node2.getData().dataId == node.getData().dataId) {
                    deviceNoArr.push(node2.getData().deviceNo)
                  }
                }
              }],
              tools: {
                name: 'segments',
                args: {
                  attrs: {fill: '#666'},
                },
              },
              zIndex: 0,
            })
          },
          validateConnection({targetMagnet}) {
            return !!targetMagnet
          },
        },
        highlighting: {
          magnetAdsorbed: {
            name: 'stroke',
            args: {
              attrs: {
                fill: '#5F95FF',
                stroke: '#5F95FF',
              },
            },
          },
        },
        resizing: true,
        rotating: true,
        selecting: {
          enabled: true,
          rubberband: true,
          rubberEdge: true,
          // showNodeSelectionBox: true,
        },
        snapline: true,
        keyboard: true,
        clipboard: true,
      })
      this.graph.centerContent()
      const stencil = new Addon.Stencil({
        getDragNode: (node) => node.clone({keepId: true}),
        getDropNode: (node) => {
          if (node.getData().type && node.getData().type === 'imageNodes2') {
            return node.clone({keepId: true})
          } else {
            return node.clone()
          }
        },
        validateNode: (node) => {
          const existingNodes = this.graph.getNodes(); // 获取画布上所有节点
          for (const existingNode of existingNodes) {
            if (existingNode.id === node.id) {
              this.$message({message: '该设备节点已在画布上,无法再次绘制', type: 'warning'})
              return false; // 取消添加节点操作
              }
              let no = 0
              console.log(node, 'node')
              console.log(deviceNoArr, 'deviceNoArr')
              for (let i = 1; i <= node.getData().basicUnitNum; i++) {
                if (deviceNoArr.findIndex(item => item === i) === -1) {
                  no = i
                  if (node.getData().basicUnitNum >= 1) {
                    node.getData().deviceNo = i
                    if(node.getData().deviceNo > 1){
                      node.attr('text/text', node.attr('text/text') + '-' + i)
                    }
                  }
                  break
                }
              }
              if (no === 0) {
                this.canAdd = false
              }
            }
          }
        },
        title: '',
        target: this.graph,
        stencilGraphWidth: 200,
        stencilGraphHeight: 280,
        collapsable: true,
        groups: [
          {
            title: '运算符号',
            name: 'group1',
            return node.clone()
          },
          {
            title: '组合图',
            name: 'combiningImages',
            graphHeight: 100,
          validateNode: (node) => {
            if (!this.canAdd) {
              this.$message({message: '该设备节点已在画布上,无法再次绘制', type: 'warning'})
              return false
            }
          },
          {
            title: '设备节点',
            name: 'group2',
            graphHeight: '',
            layoutOptions: {
              rowHeight: 90,
          title: '',
          target: this.graph,
          stencilGraphWidth: 240,
          stencilGraphHeight: 280,
          collapsable: true,
          groups: [
            {
              title: '运算符号',
              name: 'group1',
              graphHeight: 200,
            },
          }
        ],
        layoutOptions: {
          columns: 2,
          columnWidth: 105,
        },
      })
      document.getElementById('stencilImg').appendChild(stencil.container)
      const imageNodes = this.imgsList.map((item) =>
            {
              title: '设备节点',
              name: 'group2',
              graphHeight: '',
              layoutOptions: {
                rowHeight: 100,
              },
            }
          ],
          layoutOptions: {
            columns: 2,
            columnWidth: 130,
          },
        })
        document.getElementById('stencilImg').appendChild(stencil.container)
        const imageNodes = this.imagesList.map((item) =>
          this.graph.createNode({
            shape: 'image',
            // imageUrl: require('/public/modelImg/' + item.imgPath + '.png'),
            width: item.imgWidth,
            height: item.imgHeight,
            id: item.imgId,
            data: {
              type: 'imageNodes',
              dataId: '',
              startNodeId: '',
              endNodeId: '20000',
              nodeType: item.nodeType,
              nodeTypeExt: '',
              voteNum: ''
@@ -565,664 +1019,1516 @@
            },
            ports: {...this.ports},
          }),
      )
      const combiningImages = this.combiningImages.map((item) =>
        )
        let params = {
          productId: productId
        }
        let res = await this.$http.get(`/basicInfo/XhProductModel/getProduct`, {params: params})
        this.imagesList2 = res.data
        /*for(let i =0;i<this.imagesList2.length;i++){
        }*/
        console.log(this.imagesList2, 'getProduct(productId)234567890')
        const imageNodes2 = this.imagesList2.map((item) =>
          this.graph.createNode({
            shape: 'image',
            // imageUrl: require('/public/modelImg/' + item.imgPath + '.png'),
            width: item.imgWidth,
            height: item.imgHeight,
            data: {
              type: 'imageNodes',
              dataId: '',
              nodeType: item.nodeType,
              nodeTypeExt: '',
              voteNum: ''
            },
            attrs: {
              image: {
                'xlink:href': '/modelImg/' + item.imgPath + '.svg',
              },
              text: {
                text: item.imgName,
                fontSize: 14,
                style: {
                  color: this.globalGridAttr.nodeColor
                },
                refX: 0.5,
                refY: '100%',
                refY2: 4,
                textAnchor: 'middle',
                textVerticalAnchor: 'top',
              },
            },
            ports: {...this.ports},
          }),
      )
      let params = {
        productId: productId
      }
      let res = await this.$http.get(`/basicInfo/XhProductModel/getProduct`, {params: params})
      this.imgsList2 = res.data
      console.log(this.imgsList2, 'getProduct(productId)234567890')
      const imageNodes2 = this.imgsList2.map((item) =>
          this.graph.createNode({
            shape: 'image',
            imageUrl: `${window.SITE_CONFIG['apiURL']}/sysPictureBase/getProductImg?token=${Cookies.get('token')}&id=${item.imgPath}`,
            //imageUrl: `${window.SITE_CONFIG['apiURL']}/sysPictureBase/getProductImg?token=${Cookies.get('token')}&id=${item.imgPath}`,
            width: 60,
            height: 60,
            id: item.dataId, // 手动设置节点的 ID
            height: 70,
            //id: item.dataId, // 手动设置节点的 ID
            data: {
              type: 'imageNodes2',
              isRepair: item.isRepair,
              dataId: item.dataId,
              basicUnitNum: item.basicUnitNum,
              deviceNo: 1,
              nodeType: item.nodeType,
              nodeTypeExt: item.nodeTypeExt,
              productType: item.productType,
              statusImg: item.statusImg,
              reliabDistribType: item.reliabDistribType,
              repairDistribType: item.repairDistribType,
              repairMttcr: item.repairMttcr,
              repairMttcrOther: item.repairMttcrOther,
              reliabDistribType: item.reliabDistribType ? item.reliabDistribType : 1,
              taskMtbcf: item.taskMtbcf,
              taskMtbcfOther: item.taskMtbcfOther,
              taskMtbcfOther2: item.taskMtbcfOtherParams2,
              taskMtbcfOther3: item.taskMtbcfOtherParams3,
              isRepair: item.isRepair,
              repairDistribType: item.repairDistribType ? item.repairDistribType : 1,
              repairMttcr: item.repairMttcr,
              repairMttcrOther2: item.repairMttcrOtherParams2,
              repairMttcrOther3: item.repairMttcrOtherParams3,
              successRate: item.successRate,
              imgHeight: item.imgHeight,
              imgWidth: item.imgWidth,
              voteNum: '',
            },
            attrs: {
              image: {
                'xlink:href': `${window.SITE_CONFIG['apiURL']}/basicInfo/XhProductModel/getImg?token=${Cookies.get('token')}&id=${item.dataId}&t=${new Date().getTime()}`,
                //'xlink:href': urlObject.createObjectURL(new Blob([item.svgContent])),
              },
              title: {
                text: item.basicUnitNum > 1 ? item.basicUnitNum : '',
                refX: 15,
                refY: 10,
                fill: '#748be7',
                fontSize: 14,
                fontWeight: 'bold',
                'text-anchor': 'start',
              },
              text: {
                text: item.imgName,
                fontSize: 14,
                style: {
                  color: this.globalGridAttr.nodeColor
                },
                refX: 0.5,
                refY: '100%',
                refY: '85%',
                refY2: 4,
                textAnchor: 'middle',
                textVerticalAnchor: 'top',
                textWrap: {
                  width: 120,      // 宽度为 120px换行
                  ellipsis: false,  // 文本超出显示范围时,自动添加省略号
                  breakWord: true, // 是否截断单词
                }
              },
            },
            tools: [
            markup: [
              {
                name: 'button',
                args: {
                  markup: [
                    {
                      tagName: 'image',
                      selector: 'icon',
                      attrs: {
                        // 'xlink:href': 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*evDjT5vjkX0AAAAAAAAAAAAAARQnAQ',
                        'xlink:href': item.statusImg,
                        width: 30,
                        height: 30,
                        x: 0,
                        y: 0
                      }
                    }
                  ]
                }
              }
                tagName: 'image',
                selector: 'image',
              },
              {
                tagName: 'text',
                selector: 'title',
              },
              {
                tagName: 'text',
                selector: 'text',
              },
            ],
            // tools: [
            //   {
            //     name: 'button',
            //     args: {
            //       markup: [
            //         {
            //           tagName: 'image',
            //           selector: 'icon',
            //           attrs: {
            //             'xlink:href': 'https://gw.alipayobjects.com/mdn/rms_43231b/afts/img/A*evDjT5vjkX0AAAAAAAAAAAAAARQnAQ',
            //             // 'xlink:href': item.statusImg,
            //             width: 30,
            //             height: 30,
            //             x: 0,
            //             y: 0
            //           }
            //         }
            //       ]
            //     }
            //   }
            // ],
            ports: {...this.ports},
          }),
      )
      stencil.load(imageNodes, 'group1')
      stencil.load(imageNodes2, 'group2')
      stencil.load(combiningImages, 'combiningImages')
        )
        stencil.load(imageNodes, 'group1')
        stencil.load(imageNodes2, 'group2')
      this.graph.bindKey(['meta+c', 'ctrl+c'], () => {
        const cells = this.graph.getSelectedCells()
        if (cells.length) {
          this.graph.copy(cells)
        }
        return false
      })
// konami code!
        // 单击node节点
        // this.graph.on('node:click', ({ e, x, y, node, view}) => {
        //   Mousetrap.bind('up', function(e) {
        //     e.preventDefault();
        //     node.getBBox().x
        //     node.getBBox().y
        //     setTimeout(()=>{
        //       node.position(node.getBBox().x,node.getBBox().y -0.5)
        //       console.log(x,y,'按下了↑键 up');
        //     },100)
        //   })
        //   Mousetrap.bind('down', function(e) {
        //     e.preventDefault();
        //     setTimeout(()=>{
        //       node.position(node.getBBox().x,node.getBBox().y+0.5)
        //       console.log(x,y,'按下了↓键 down');
        //     },100)
        //
        //   })
        //   Mousetrap.bind('left', function(e) {
        //     e.preventDefault();
        //     setTimeout(()=>{
        //       node.position(node.getBBox().x-0.5,node.getBBox().y)
        //       console.log(x,y,'按下了←键 left');
        //     },100)
        //
        //   })
        //   Mousetrap.bind('right', function(e) {
        //     e.preventDefault();
        //     setTimeout(()=>{
        //       node.position(node.getBBox().x+0.5,node.getBBox().y)
        //       console.log(x,y,'按下了→键 right');
        //     },100)
        //   })
        // })
        this.graph.bindKey(['meta+c', 'ctrl+c'], () => {
          const cells = this.graph.getSelectedCells()
          if (cells.length) {
            this.graph.copy(cells)
          }
          return false
        })
      this.graph.bindKey(['meta+x', 'ctrl+x'], () => {
        const cells = this.graph.getSelectedCells()
        if (cells.length) {
          this.graph.cut(cells)
        }
        return false
      })
      this.graph.bindKey(['meta+v', 'ctrl+v'], () => {
        if (!this.graph.isClipboardEmpty()) {
          const cells = this.graph.paste({offset: 32})
          this.graph.cleanSelection()
          this.graph.select(cells)
        }
        return false
      })
//undo redo
      this.graph.bindKey(['meta+z', 'ctrl+z'], () => {
        if (this.graph.history.canUndo()) {
          this.graph.history.undo()
        }
        return false
      })
      this.graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
        if (this.graph.history.canRedo()) {
          this.graph.history.redo()
        }
        return false
      })
        this.graph.bindKey(['meta+x', 'ctrl+x'], () => {
          const cells = this.graph.getSelectedCells()
          if (cells.length) {
            this.graph.cut(cells)
          }
          return false
        })
        this.graph.bindKey(['meta+v', 'ctrl+v'], () => {
          if (!this.graph.isClipboardEmpty()) {
            const cells = this.graph.paste({offset: 32})
            this.graph.cleanSelection()
            this.graph.select(cells)
          }
          return false
        })
// select all
      this.graph.bindKey(['meta+a', 'ctrl+a'], () => {
        const nodes = this.graph.getNodes()
        if (nodes) {
          this.graph.select(nodes)
        }
      })
        this.graph.bindKey(['meta+a', 'ctrl+a'], () => {
          const nodes = this.graph.getNodes()
          if (nodes) {
            this.graph.select(nodes)
          }
        })
//delete
      this.graph.bindKey('delete', () => {
        this.graph.bindKey('delete', () => {
          this.deleteCompment()
        })
// zoom
        this.graph.bindKey(['ctrl+1', 'meta+1'], () => {
          const zoom = this.graph.zoom()
          if (zoom < 1.5) {
            this.graph.zoom(0.1)
          }
        })
        this.graph.bindKey(['ctrl+2', 'meta+2'], () => {
          const zoom = this.graph.zoom()
          if (zoom > 0.5) {
            this.graph.zoom(-0.1)
          }
        })
        this.graph.on('blank:click', ({cell}) => {
          // this.reset()
          // this.type.value = "grid"
          this.type = 'grid'
          // this.id = cell.id
        })
        // 监听节点添加事件
        this.graph.on('node:added', ({node}) => {
          node.setAttrs({
            title: {text: ''},
          })
          if (this.isFirstLoad) {
            return
          }
          if (node.getData().isSelfCreated) {
            return
          }
          const nodeType = node.getData().nodeType; // 获取节点的类型
          const nodeObj = node
          console.log(node.id, 'node.id')
          let intersectNode = this.findIntersectsNode(node)
          if (intersectNode) { // 当有节点相交 ==>并行
            this.addBranch(intersectNode, nodeObj)
            return
          } else {
            let isSelfCreated = null
            try {
              isSelfCreated = node.getData().isSelfCreated
            } catch (e) {
            }
            if (!isSelfCreated) {
              let intersectEdge = this.findIntersectsEdge(this.graph, node)
              if (intersectEdge) { // 当有边相交 ==>串联
                this.addNodeAndInsertEdge(intersectEdge, nodeObj)
                return
              } else {
                //提示
              }
            }
          }
          node.remove()
        });
        this.graph.on('cell:contextmenu', ({cell}) => {
          // this.type.value = cell.isNode() ? "node" : "edge"
          this.type = cell.isNode() ? 'node' : 'edge'
          /*          this.shape = cell.shape
                    this.id = cell.id*/
          if (this.type === 'node') {
            //this.nodeType = cell.getData().nodeType
            this.$refs.configNode.loadData(cell)
          } else {
            this.$refs.configNode.loadData(cell)
          }
        })
        //单击边节点
        this.graph.on('edge:click', ({edge}) => {
          // this.reset()
          // edge.attr('line/stroke', 'orange')
          // edge.prop('labels/0', {
          //   attrs: {
          //     body: {
          //       stroke: 'orange',
          //     },
          //   },
          //
          // })
        })
        // 控制连接桩显示/隐藏
        this.graph.on('node:delete', ({view, e}) => {
          e.stopPropagation()
          view.cell.remove()
        })
        this.graph.on('node:customevent', ({name, view, e}) => {
          if (name === 'node:delete') {
            e.stopPropagation()
            view.cell.remove()
          }
        })
        // 双击编辑
        this.graph.on('cell:dblclick', ({cell, e}) => {
          const isNode = cell.isNode()
          const name = cell.isNode() ? 'node-editor' : 'edge-editor'
          cell.removeTool(name)
          cell.addTools({
            name,
            args: {
              event: e,
              attrs: {
                backgroundColor: isNode ? '#EFF4FF' : '#FFF',
                text: {
                  fontSize: 16,
                  fill: '#262626',
                },
              },
            },
          })
        })
        // this.graph.on('node:mouseenter', ({node}) => {
        //   const container = document.getElementById('containerImg')
        //   const ports = container.querySelectorAll(
        //     '.x6-port-body',
        //   )
        //   this.showPorts(ports, true)
        // })
        // this.graph.on('node:mouseleave', ({node}) => {
        //   // if (node.hasTool('button-remove')) {
        //   //   node.removeTool('button-remove')
        //   // }
        //   const container = document.getElementById('containerImg')
        //   const ports = container.querySelectorAll(
        //     '.x6-port-body',
        //   )
        //   this.showPorts(ports, false)
        // })
        // this.graph.on('edge:mouseenter', ({cell}) => {
        //   // alert(123)
        //   cell.addTools([
        //     {
        //       name: 'source-arrowhead',
        //     },
        //     {
        //       name: 'target-arrowhead',
        //       args: {
        //         attrs: {
        //           fill: 'red',
        //         },
        //       },
        //     },
        //     {
        //       name: 'segments',
        //       args: {snapRadius: 20, attrs: {fill: '#444'}}
        //     },
        //   ])
        // })
        //
        // this.graph.on('edge:mouseleave', ({cell}) => {
        //   cell.removeTools()
        // })
        await this.getDiagram(this.dataForm.id)
      },
      // showPorts(ports, show) {
      //   for (let i = 0, len = ports.length; i < len; i = i + 1) {
      //     ports[i].style.visibility = show ? 'visible' : 'hidden'
      //   }
      // },
      reset() {
        this.graph.drawBackground({color: '#fff'})
        const nodes = this.graph.getNodes()
        const edges = this.graph.getEdges()
        nodes.forEach((node) => {
          node.attr('body/stroke', '#5F95FF')
        })
        edges.forEach((edge) => {
          edge.attr('line/stroke', '#5F95FF')
          edge.prop('labels/0', {
            attrs: {
              body: {
                stroke: '#5F95FF',
              },
            },
          })
        })
      },
      deleteCompment() {
        const cells = this.graph.getSelectedCells()
        if (cells.length) {
          this.$confirm('是否删除该节点?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.$message({
              type: 'success',
              message: '删除成功!'
        console.log(cells, 'cells')
        if (cells.length === 1) {
          let node = cells[0]
          if (!node.isNode()) {
            this.$confirm('是否删除该连接线?', '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            }).then(() => {
              node.remove()
              this.$message({
                type: 'success',
                message: '删除成功!'
              })
            }).catch(() => {
              this.$message({
                type: 'info',
                message: '已取消删除'
              })
            })
            this.graph.removeCells(cells)
          }).catch(() => {
            this.$message({
              type: 'info',
              message: '已取消删除'
            // this.$message({message: '请选中节点', type: 'warning'})
            return false; // 取消操作
          }
          let nodeType = node.getData().nodeType
          let deleteType = 0
          if (nodeType === 'node' || nodeType === 'dashedBox') {
            deleteType = 1
          } else if ('parallel,switch,vote,bridge'.indexOf(nodeType) > -1) {
            deleteType = 2
          }
          let canDelete = false
          if (nodeType === 'start' || nodeType === 'end') {
            this.$message({message: '不允许删除起始和结束节点', type: 'warning'})
            return false; // 取消操作
          }
          if (deleteType > 0) {
            let startNode = null
            if (deleteType === 1) {
              startNode = node
            } else if (deleteType === 2) {
              startNode = this.graph.getCellById(node.getData().startNodeId)
            }
            let isSeriesNode = this.isSeriesNode(startNode, node)
            let isMultipleBrach = this.isMultipleBrach(node)
            if (isSeriesNode) {
              //串联
              let inLine = this.getInLinesOfNode(startNode)
              let outLine = this.getOutLinesOfNode(node)
              let inLineIsToLine = this.hasOtherLineToMyLine(inLine[0].id)
              let inNode = isSeriesNode.inNode
              let outNode = isSeriesNode.outNode
              console.log(inLine, outLine, 'inLine,outLine')
              console.log(inNode, outNode, 'inNode,outNode')
              //提示是否要删除
              this.$confirm('是否删除该节点?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
              }).then(() => {
                if (inLineIsToLine) {
                  inLine[0].target = {cell: outNode.id, port: 'left1'}
                } else {
                  outLine[0].source = {cell: inNode.id, port: 'right1'}
                }
                if (deleteType === 1) {
                  node.remove()
                } else {
                  this.deleteCombination(node)
                }
                this.$message({
                  type: 'success',
                  message: '删除成功!'
                })
              }).catch(() => {
                this.$message({
                  type: 'info',
                  message: '已取消删除'
                })
                return false
              })
            } else if (this.isMultipleBrach(node)) {
              //提示是否要删除
              this.$confirm('是否删除该节点?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
              }).then(() => {
                /*                  if (inLineIsToLine) {
                                    inLine[0].target = {cell: outNode.id, port: 'left1'}
                                  } else {
                                    outLine[0].source = {cell: inNode.id, port: 'right1'}
                                  }*/
                if (deleteType === 1)
                  node.remove()
                else
                  this.deleteCombination(node)
                this.$message({
                  type: 'success',
                  message: '删除成功!'
                })
              }).catch(() => {
                this.$message({
                  type: 'info',
                  message: '已取消删除'
                })
                return false
              })
            } else {
              //提示不能删除
              this.$message({message: '该条线路上只有该节点,无法删除', type: 'warning'})
              return false; // 取消操作
            }
          }
        } else {
          //提示不能删除
          this.$message({message: '只能选中一个节点', type: 'warning'})
          return false; // 取消操作
        }
      },
      async search() {
        await this.getDiagram();
      },
      async saveDiagram() {
        console.log(JSON.stringify(this.graph.toJSON()), 'graph.toJSON()')
        //   获取所有子节点
        this.getNodeArr()
        this.dataForm.content = JSON.stringify(this.graph.toJSON())
        this.dataForm.urlPref = window.SITE_CONFIG['apiURL']
        console.log(this.dataForm, 'dataFrom')
        await this.$http[this.dataForm.id === null ? 'post' : 'put'](`/taskReliability/ModelLine/`, this.dataForm).then(async res => {
          if (res.msg === 'success') {
            this.$emit('refreshDataList')
            this.$alert('保存成功', '提示', {
              confirmButtonText: '确定'
            })
          }
        })
      },
      getNodeArr() {
        const nodes = this.graph.getNodes()
        let nodeArr2 = []
        // 检查除当前节点之外的所有节点的包围框是否相交
        for (const node of nodes) {
          console.log(node, 'saveDiagram node')
          if (node.getData().nodeType == 'node' && node.getData().dataId) {
            nodeArr2.push(node.getData().dataId)
          }
        }
        this.dataForm.nodeArr = nodeArr2
      },
      async analyzeDiagram() {
        console.log(JSON.stringify(this.graph.toJSON()), 'graph.toJSON()')
        // 检查除当前节点之外的所有节点的包围框是否相交
        //   获取所有子节点
        this.getNodeArr()
        const nodes = this.graph.getNodes()
        for (const node of nodes) {
          if (node.getData().nodeType === 'dashedBox') {
            this.$message({message: '该模型中存在虚框,无法提交', type: 'warning'})
            return false;
          }
          if (node.getData().nodeType === 'vote') {
            if (node.getData().voteNum === null || node.getData().voteNum === '') {
              this.$message({message: '表决节点的表决数量未设置', type: 'warning'})
              return false;
            }
            const edges = this.graph.getIncomingEdges(node);
            if (node.getData().voteNum >= edges.length) {
              this.$message({message: '表决节点的表决数量必须小于该节点的进线数量', type: 'warning'})
              return false;
            }
          }
          if (node.getData().nodeType === 'switch') {
            if (node.getData().voteNum === null || node.getData().voteNum === '') {
              this.$message({message: '旁联节点的备份数量未设置', type: 'warning'})
              return false;
            }
            const edges = this.graph.getIncomingEdges(node);
            if (node.getData().voteNum >= edges.length) {
              this.$message({message: '旁联节点的备份数量必须小于该节点的进线数量', type: 'warning'})
              return false;
            }
          }
        }
        this.dataForm.content = JSON.stringify(this.graph.toJSON())
        this.dataForm.urlPref = window.SITE_CONFIG['apiURL']
        await this.$http['post'](`/taskReliability/ModelLine/analyze`, this.dataForm).then(async res => {
          if (res.msg === 'success') {
            this.$emit('refreshDataList')
            this.$alert('提交成功', '提示', {
              confirmButtonText: '确定'
            })
          }
        })
      },
      async layoutDiagram() {
        if (this.dataForm.autoLayout == 1) {
          console.log(JSON.stringify(this.graph.toJSON()), 'graph.toJSON()')
          this.dataForm.content = JSON.stringify(this.graph.toJSON())
          this.dataForm.urlPref = window.SITE_CONFIG['apiURL']
          await this.$http['post'](`/taskReliability/ModelLine/layout`, this.dataForm).then(async res => {
            if (res.msg === 'success') {
              // this.$emit('refreshDataList')
              // this.$alert('解析成功', '提示', {
              //   confirmButtonText: '确定'
              // })
              console.log(res.data, 'layoutDiagram res.data')
              this.dataForm.content = res.data.content
              console.log(this.dataForm.content, 'layoutDiagram dataForm.content')
              this.diagramJson = JSON.parse(this.dataForm.content)
              this.graph.fromJSON(this.diagramJson)
              this.isFirstLoad = false;
              // console.log(this.diagramJson.cells.length, 'this.diagramJson.cells.length')
              this.graph.positionContent('left')
            }
          })
        }
      })
// zoom
      this.graph.bindKey(['ctrl+1', 'meta+1'], () => {
        const zoom = this.graph.zoom()
        if (zoom < 1.5) {
          this.graph.zoom(0.1)
      },
      leftAlign() {
        const NODE = this.graph.getSelectedCells()
        let leftX = null
        for (let a of NODE) {
          if (leftX == null || a.getBBox().x < leftX) {
            leftX = a.getBBox().x
          }
        }
      })
      this.graph.bindKey(['ctrl+2', 'meta+2'], () => {
        const zoom = this.graph.zoom()
        if (zoom > 0.5) {
          this.graph.zoom(-0.1)
        for (let a of NODE) {
          let y = a.getBBox().y
          a.position(leftX, y)
          // console.log(leftX, ':', y, '  x:y')
        }
      })
      },
      topAlign() {
        const NODE = this.graph.getSelectedCells()
        let topY = null
        for (let a of NODE) {
          console.log(a.getBBox(), 'a.getBBox()')
          if (topY == null || a.getBBox().y < topY) {
            topY = a.getBBox().y
          }
        }
        for (let a of NODE) {
          let x = a.getBBox().x
          a.position(x, topY)
        }
      },
      centerAlign() {
        const NODE = this.graph.getSelectedCells()
        let rightX = null
        let leftX = null
        for (let a of NODE) {
          if (leftX == null || a.getBBox().x < leftX) {
            leftX = a.getBBox().x
          }
        }
        for (let a of NODE) {
          if (rightX == null || a.getBBox().x + a.getBBox().width > rightX) {
            rightX = a.getBBox().x + a.getBBox().width
          }
        }
      this.graph.on('blank:click', ({cell}) => {
        this.reset()
        // this.type.value = "grid"
        this.type = 'grid'
        // this.id = cell.id
      })
      // 监听节点添加事件
      this.graph.on('node:added', ({node}) => {
        const nodeId = node.id; // 获取节点的唯一 ID
        const nodeObj = node
        const intersectNodes = [];
        let centerX = leftX + (rightX - leftX) / 2
        for (let a of NODE) {
          let y = a.getBBox().y
          a.position(centerX - a.getBBox().width / 2, y)
        }
      },
      shuipingAlign() {
        const NODE = this.graph.getSelectedCells()
        let bottomY = null
        let topY = null
        for (let a of NODE) {
          if (topY == null || a.getBBox().y || 0 < topY) {
            topY = a.getBBox().y
          }
        }
        for (let a of NODE) {
          if (bottomY == null || a.getBBox().y + a.getBBox().height > bottomY) {
            bottomY = a.getBBox().y + a.getBBox().height
          }
        }
        let centerY = topY + (bottomY - topY) / 2
        for (let a of NODE) {
          let x = a.getBBox().x
          let centerHei = a.getBBox().height / 2
          a.position(x, centerY - centerHei)
        }
      },
      rightAlign() {
        const NODE = this.graph.getSelectedCells()
        let rightX = null
        for (let a of NODE) {
          if (rightX == null || a.getBBox().x + a.getBBox().width > rightX) {
            rightX = a.getBBox().x + a.getBBox().width
          }
        }
        for (let a of NODE) {
          let y = a.getBBox().y
          a.position(rightX - a.getBBox().width, y)
        }
      },
      bottomAlign() {
        const NODE = this.graph.getSelectedCells()
        let bottomY = null
        for (let a of NODE) {
          if (bottomY == null || (a.getBBox().y + a.getBBox().height) > bottomY) {
            bottomY = a.getBBox().y + a.getBBox().height
          }
        }
        for (let a of NODE) {
          let x = a.getBBox().x
          a.position(x, bottomY - a.getBBox().height)
        }
      },
      close() {
        if (this.timer) {
          window.clearInterval(this.timer)
        }
      },
      // 定义函数来检查两个包围框是否相交
      findIntersectsNode(node) {
        const nodes = this.graph.getNodes()
        let intersectNodes = []
        const bbox1 = node.getBBox();
        // 检查除当前节点之外的所有节点的包围框是否相交
        for (const otherNode of this.graph.getNodes()) {
        for (const otherNode of nodes) {
          if (otherNode === node) continue;
          const bbox1 = node.getBBox();
          const bbox2 = otherNode.getBBox();
          if (this.isIntersect(bbox1, bbox2)) {
          let nodeType = otherNode.getData().nodeType
          if (nodeType === "parallel" || nodeType === "switch" || nodeType === "vote" || nodeType === "dashedBox") {
            const bbox2 = otherNode.getBBox();
            if (bbox1.x < bbox2.x + bbox2.width &&
              bbox1.x + bbox1.width > bbox2.x &&
              bbox1.y < bbox2.y + bbox2.height &&
              bbox1.y + bbox1.height > bbox2.y) {
              intersectNodes.push(otherNode);
            }
          }
        }
        if (intersectNodes.length === 1) {
          //console.log('Intersecting nodes:', intersectNodes.map(n => n)); // 相交节点的对象
          return intersectNodes[0]
        } else {
          //提示用户只能拖到一个有效的节点上
          return null
        }
      },
      // 相交的节点
      addBranch(graphNode, dragNode) { // graphCell是画布上原有的节点。dragNode是当前拖拽的节点
        let graphNodeType = graphNode.getData().nodeType
        let dragNodeType = dragNode.getData().nodeType
        let offHeight = 50
        if (dragNodeType === 'node') {
          offHeight = 70
        } else if (dragNodeType === 'bridgeConnection') {
          offHeight = 175
        } else {
          offHeight = 70
        }
        let centerX = 0, centerY = 0;
        if (graphNodeType === 'dashedBox') { //虚框
          const edges = this.graph.getConnectedEdges(graphNode); // 获取画布上原有的节点所有进来的线
          let inEdges = edges.filter(edge => edge.target.cell === graphNode.id)
          let startNode = null
          let endNode = null
          if (inEdges.length === 1) {
            let startNodeId = inEdges[0].source.cell
            startNode = this.graph.getCellById(startNodeId)
          }
          let outEdges = edges.filter(edge => edge.source.cell === graphNode.id)
          if (outEdges.length === 1) {
            let endNodeId = outEdges[0].target.cell
            endNode = this.graph.getCellById(endNodeId)
          }
          if (startNode && endNode) {
            centerX = graphNode.position().x + graphNode.getBBox().width / 2
            centerY = graphNode.position().y + graphNode.getBBox().height / 2
            let result = this.addNodeAndConnect(graphNode, dragNode, centerX, centerY)
            let startPort = 'right1'
            let endPort = 'left1'
            if ((inEdges[0].target.port == 'top1' || outEdges[0].source.port == 'bottom1') && ('parallel,switch,vote,bridge'.indexOf(dragNodeType)) == -1) {
              startPort = 'bottom1'
              endPort = 'top1'
            }
            inEdges[0].target = {cell: result.newStartNode.id}
            outEdges[0].source = {cell: result.newEndNode.id}
            graphNode.remove()
            if (this.dataForm.autoLayout == 1) {
              if (!result.canPlace) {
                //调用自动排版
                this.layoutDiagram()
              }
            }
          }
        } else { //并行结构
          const graphNodeStartNodeId = graphNode.getData().startNodeId  // 获取画布上原有节点的开始ID
          const graphNodeStartNode = this.graph.getCellById(graphNodeStartNodeId) // 通过开始ID得到初始节点对象
          let graphNodeY = graphNode.position().y - graphNode.getBBox().height / 2 // 获取画布原有节点的y坐标
          let minY = graphNode.position().y
          let maxY = graphNode.position().y + graphNode.getBBox().height
          const edges = this.graph.getConnectedEdges(graphNode); // 获取画布上原有的节点所有进来的线
          // 获取连接线的路径数据
          let inEdges = edges.filter(edge => edge.target.cell === graphNode.id)
          //遍历这个组合里面所有节点, 修改minY,maxY
          let pointXY = {minY: minY, maxY: maxY}
          console.log(pointXY, 'old')
          this.getYRange(inEdges, graphNodeStartNode, pointXY)
          console.log(pointXY, 'new')
          let minX = graphNodeStartNode.position().x + graphNode.getBBox().width
          let maxX = graphNode.position().x - dragNode.getBBox().width / 2
          let centerX = minX + (maxX - minX) / 2
          let centerY = graphNodeY + graphNode.getBBox().height / 2 - pointXY.minY > pointXY.maxY - (graphNodeY + graphNode.getBBox().height / 2) ?
            pointXY.maxY + offHeight / 2 + 30 : pointXY.minY - offHeight / 2 - 30
          let result = this.addNodeAndConnect(null, dragNode, centerX, centerY)
          console.log(result, 'result111')
          this.graph.addEdge({
            source: {cell: graphNodeStartNode},
            target: {cell: result.newStartNode},
            router: {
              name: 'manhattan',
              args: {
                startDirections: ['top', 'bottom'], // 从下方开始
                endDirections: ['left'],      // 向左方结束
              },
            },
            connector: {name: 'rounded'},
            zIndex: -1
          })
          this.graph.addEdge({
            source: {cell: result.newEndNode},
            target: {cell: graphNode},
            router: {
              name: 'manhattan',
              args: {
                startDirections: ['right'], // 从下方开始
                endDirections: ['top', 'bottom'],      // 向左方结束
              },
            },
            connector: {name: 'rounded'},
            zIndex: -1
          })
          if (this.dataForm.autoLayout == 1) {
            if (!result.canPlace) {
              //调用自动排版
              this.layoutDiagram()
            }
          }
        }
      },
      addNodeAndConnect(targetNode, dragNode, centerX, centerY) { // graphCell是画布上原有的节点。dragNode是当前拖拽的节点
        let width = 100,
          height = 80,
          leftTopX = centerX,
          leftTopY = centerY
        let dragNodeType = dragNode.getData().nodeType
        if (dragNodeType === 'node') {
          width = 100
          height = 70
        } else if (dragNodeType === 'dashedBox') {
          width = 60
          height = 40
        } else if (dragNodeType === 'bridgeConnection') {
          width = 550
          height = 175
        } else {
          width = 270
          height = 70
        }
        leftTopX = centerX - width / 2
        leftTopY = centerY - height / 2
        let canPlace = true;
        if (!this.canPlace(targetNode, dragNode, {leftTopX, leftTopY, width, height})) {
          canPlace = false
        }
        if (dragNodeType === 'node' || dragNodeType === 'dashedBox') {
          dragNode.position(leftTopX, leftTopY)
          return {newStartNode: dragNode, newEndNode: dragNode, canPlace: canPlace}
        } else if (dragNodeType === 'bridgeConnection') {
          return {
            ...this.createBridgeConnection(leftTopX, leftTopY, dragNode),
            ...{canPlace: canPlace}
          }
        } else {
          return {
            ...this.createParallelBrach(leftTopX, centerY, dragNode),
            ...{canPlace: canPlace}
          }
        }
      },
      // 相交的边
      addNodeAndInsertEdge(graphEdge, dragNode) {
        const source = graphEdge.getSourceCell()
        const target = graphEdge.getTargetCell()
        let centerX = 0
        let centerY = 0
        if (!source.isNode() || !target.isNode()) {
          if (source.isNode()) {
            centerX = source.position().x + source.getBBox().width / 2
            centerY = dragNode.position().y + dragNode.getBBox().height / 2
          } else {
            centerX = target.position().x + target.getBBox().width / 2
            centerY = dragNode.position().y + dragNode.getBBox().height / 2
          }
        } else {
          centerX = dragNode.position().x + dragNode.getBBox().width / 2
          centerY = source.position().y + source.getBBox().height / 2
          if (target.getData().nodeType === 'node' || target.getData().nodeType === 'dashedBox') {
            centerY = target.position().y + target.getBBox().height / 2
          }
        }
        let startNodeId = graphEdge.source.cell
        let startNode = this.graph.getCellById(startNodeId)
        let endNodeId = graphEdge.target.cell
        let endNode = this.graph.getCellById(endNodeId)
        if (startNode && endNode) {
          let routerStart = ['right'];
          let routerEnd = ['left'];
          if (this.isTopBottom(graphEdge)) {
            routerStart = ['top', 'bottom'];
            routerEnd = ['top', 'bottom'];
          }
          let isRight = true;
          if (this.hasOtherLineToMyLine(graphEdge.id)) {
            let leftX = startNode.position().x + startNode.getBBox().width
            let rightX = endNode.position().x
            // let centerX = dragNode.position().x + dragNode.getBBox().width / 2
            if (centerX - leftX < rightX - centerX) {
              isRight = false
            }
          }
          if (isRight) {
            if (endNode.getData()) {
              if ("parallel,vote,bridge".indexOf(endNode.getData().nodeType) > -1) {
                isRight = false
              }
            }
          }
          let result = this.addNodeAndConnect(null, dragNode, centerX, centerY)
          if (isRight) {
            graphEdge.target = {cell: result.newStartNode.id}
            this.graph.addEdge({
              source: {cell: result.newEndNode},
              target: {cell: endNode},
              router: {
                name: 'manhattan',
                args: {
                  startDirections: routerStart, // 从下方开始
                  endDirections: routerEnd,      // 向左方结束
                },
              },
              connector: {name: 'rounded'},
              zIndex: -1
            })
          } else {
            this.graph.addEdge({
              source: {cell: startNode},
              target: {cell: result.newStartNode},
              router: {
                name: 'manhattan',
                args: {
                  startDirections: routerStart, // 从下方开始
                  endDirections: routerEnd,      // 向左方结束
                },
              },
              connector: {name: 'rounded'},
              zIndex: -1
            })
            graphEdge.source = {cell: result.newEndNode.id}
          }
          if (this.dataForm.autoLayout == 1) {
            if (!result.canPlace) {
              //调用自动排版
              this.layoutDiagram()
            }
          }
          // graphEdge.remove()
        }
      },
      findIntersectsEdge(graph, node) {
        const edges = graph.getEdges()
        const bbox = node.getBBox();
        const lines = [bbox.leftLine, bbox.rightLine, bbox.topLine, bbox.bottomLine];
        let res = [];
        edges.forEach((edge) => {
          const view = graph.findViewByCell(edge);
          lines.forEach((line) => {
            if (view) {
              if (view.path.intersectsWithLine(line)) {
                res.push(edge);
              }
            }
          })
        })
        const uniqueArr = res.filter((insEdge, index) =>
          res.findIndex(i => i.id === insEdge.id) === index);
        console.log(uniqueArr, 'uniqueArr')
        if (uniqueArr.length === 1) {
          return uniqueArr[0]
        } else {
          return false
        }
      },
      createParallelBrach(x, y, dragNode) {
        dragNode.position(x + 320, y - dragNode.size().height / 2)
        const connectNode = this.createConnectNode(x + 50, y)
        this.createBrach(dragNode, connectNode, x, y - 50)
        this.createBrach(dragNode, connectNode, x, y + 50)
        return {newStartNode: connectNode, newEndNode: dragNode}
      },
      createBrach(dragNode, connectNode, x, y) {
        const dashedBox = this.createDashedBox(x + 150, y)
        dragNode.setData({startNodeId: connectNode.id})
        this.graph.addEdge({
          source: {cell: connectNode},
          target: {cell: dashedBox},
          router: {
            name: 'manhattan',
            args: {
              startDirections: ['top', 'bottom'], // 从下方开始
              endDirections: ['left'],      // 向左方结束
            },
          },
          connector: {name: 'rounded'},
          zIndex: -1
        })
        this.graph.addEdge({
          source: {cell: dashedBox},
          target: {cell: dragNode},
          router: {
            name: 'manhattan',
            args: {
              startDirections: ['right'], // 从下方开始
              endDirections: ['top', 'bottom'],      // 向左方结束
            },
          },
          connector: {name: 'rounded'},
          zIndex: -1
        })
      },
      createBridgeConnection(x, y, dragNode) {
        console.log(x, y, 'leftX centerY')
        const leftTopDashedBox = this.createDashedBox(x + 40, y)
        const rightTopDashedBox = this.createDashedBox(x + 380, y)
        const leftConnectNode = this.createConnectNode(x, y + 87)
        const alignCenterDashedBox = this.createDashedBox(x + 209, y + 87)
        const leftBottomDashedBox = this.createDashedBox(x + 40, y + 160)
        const rightBottomDashedBox = this.createDashedBox(x + 380, y + 160)
        let edgeTop = this.graph.addEdge({
          source: {cell: leftTopDashedBox},
          target: {cell: rightTopDashedBox},
          router: {
            name: 'manhattan',
            args: {
              startDirections: ['right'], // 从下方开始
              endDirections: ['left'],      // 向左方结束
            },
          },
          connector: {name: 'rounded'},
          zIndex: -1
        })
        let edgeBottom = this.graph.addEdge({
          source: {cell: leftBottomDashedBox},
          target: {cell: rightBottomDashedBox},
          router: {
            name: 'manhattan',
            args: {
              startDirections: ['right'], // 从下方开始
              endDirections: ['left'],      // 向左方结束
            },
          },
          connector: {name: 'rounded'},
          zIndex: -1
        })
        const rightConnectNode = this.createBridgeNode(x + 530, y + 87, leftConnectNode.id, edgeTop.id, edgeBottom.id)
        rightConnectNode.setData({startNodeId: leftConnectNode.id})
        leftConnectNode.setData({endNodeId: rightConnectNode.id})
        /*        this.graph.addEdge({
                  source: {cell: startNode, port: 'right1'},
                  target: {cell: leftConnectNode, port: 'left1'},
                  router: {name: 'manhattan'},
                  connector: {name: 'rounded'},
                })
                this.graph.addEdge({
                  source: {cell: rightConnectNode, port: 'right1'},
                  target: {cell: endNode, port: 'left1'},
                  router: {name: 'manhattan'},
                  connector: {name: 'rounded'}
                })*/
        this.graph.addEdge({
          source: {cell: leftConnectNode},
          target: {cell: leftTopDashedBox},
          router: {
            name: 'manhattan',
            args: {
              startDirections: ['top', 'bottom'],
              endDirections: ['left'],
            },
          },
          connector: {name: 'rounded'},
          zIndex: -1
        })
        this.graph.addEdge({
          source: {cell: leftConnectNode},
          target: {cell: leftBottomDashedBox},
          router: {
            name: 'manhattan',
            args: {
              startDirections: ['top', 'bottom'], // 从下方开始
              endDirections: ['left'],      // 向左方结束
            },
          },
          connector: {name: 'rounded'},
          zIndex: -1
        })
        this.graph.addEdge({
          source: {cell: rightTopDashedBox},
          target: {cell: rightConnectNode},
          router: {
            name: 'manhattan',
            args: {
              startDirections: ['right'], // 从下方开始
              endDirections: ['top', 'bottom'],      // 向左方结束
            },
          },
          connector: {name: 'rounded'},
          zIndex: -1
        })
        this.graph.addEdge({
          source: {cell: rightBottomDashedBox},
          target: {cell: rightConnectNode},
          router: {
            name: 'manhattan',
            args: {
              startDirections: ['right'],
              endDirections: ['top', 'bottom'],
            },
          },
          connector: {name: 'rounded'},
          zIndex: -1
        })
        this.graph.addEdge({
          source: {cell: edgeTop},
          target: {cell: alignCenterDashedBox},
          router: {
            name: 'manhattan',
            args: {
              startDirections: ['top', 'bottom'], // 从下方开始
              endDirections: ['top', 'bottom'],      // 向左方结束
            },
          },
          connector: {name: 'rounded'},
          zIndex: -1
        })
        this.graph.addEdge({
          source: {cell: alignCenterDashedBox},
          target: {cell: edgeBottom},
          router: {
            name: 'manhattan',
            args: {
              startDirections: ['top', 'bottom'], // 从下方开始
              endDirections: ['top', 'bottom'],      // 向左方结束
            },
          },
          connector: {name: 'rounded'},
          zIndex: -1
        })
        dragNode.remove()
        return {newStartNode: leftConnectNode, newEndNode: rightConnectNode}
      },
      createDashedBox(x, y) {
        const dashId = getUUID().toString()
        let dashedBox = this.graph.addNode({
          shape: 'image',
          // imageUrl: require('/public/modelImg/' + item.imgPath + '.png'),
          width: 60,
          height: 40,
          id: dashId,
          data: {
            isSelfCreated: true,
            type: 'imageNodes',
            dataId: '',
            nodeType: 'dashedBox',
            nodeTypeExt: '',
            voteNum: ''
          },
          attrs: {
            image: {
              'xlink:href': '/modelImg/dashedBox.svg',
            },
            text: {
              text: '',
              fontSize: 14,
              refX: 0.5,
              refY: '100%',
              refY2: 4,
              textAnchor: 'middle',
              textVerticalAnchor: 'top',
            },
          },
          ports: {...this.ports},
        })
        dashedBox.position(x, y - dashedBox.size().height / 2)
        return dashedBox
      },
      createConnectNode(x, y) {
        const connectId = getUUID().toString()
        const dragNodeId = getUUID().toString()
        let connectNode = this.graph.addNode({
          shape: 'image',
          width: 10,
          height: 10,
          id: connectId,
          data: {
            isSelfCreated: true,
            type: 'imageNodes',
            endNodeId: dragNodeId,
            dataId: '',
            nodeType: 'connect',
            nodeTypeExt: '',
            voteNum: ''
          },
          attrs: {
            image: {
              'xlink:href': '/modelImg/connect.svg',
            },
            text: {
              text: '',
              fontSize: 14,
              refX: 0.5,
              refY: '100%',
              refY2: 4,
              textAnchor: 'middle',
              textVerticalAnchor: 'top',
            },
          },
          ports: {...this.ports},
        })
        connectNode.position(x, y - connectNode.size().height / 2)
        return connectNode
      },
      createBridgeNode(x, y, connectId, edgeTopId, edgeBottomId) {
        const dragNodeId = getUUID().toString()
        let bridgeNode = this.graph.addNode({
          shape: 'image',
          width: 30,
          height: 30,
          id: dragNodeId,
          data: {
            isSelfCreated: true,
            type: 'imageNodes',
            startNodeId: connectId,
            edgeTopId: edgeTopId,
            edgeBottomId: edgeBottomId,
            dataId: '',
            nodeType: 'bridge',
            nodeTypeExt: '',
            voteNum: ''
          },
          attrs: {
            image: {
              'xlink:href': '/modelImg/connect.svg',
            },
            text: {
              text: 'bridge',
              fontSize: 14,
              refX: 0.5,
              refY: '100%',
              refY2: 4,
              textAnchor: 'middle',
              textVerticalAnchor: 'top',
            },
          },
          ports: {...this.ports},
        })
        bridgeNode.position(x, y - bridgeNode.size().height / 2)
        return bridgeNode
      },
      getYRange(inEdges, startNode, pointXY) {
        for (let inEdge of inEdges) {
          let nodeId = inEdge.source.cell
          let node = this.graph.getCellById(nodeId)
          if (node.position().y < pointXY.minY) {
            pointXY.minY = node.position().y
          }
          if (node.position().y + node.getBBox().height > pointXY.maxY) {
            pointXY.maxY = node.position().y + node.getBBox().height
          }
          if (node.id === startNode.id) {
            continue
          }
          const edges = this.graph.getConnectedEdges(node); // 获取画布上原有的节点所有进来的线
          let inEdgesPrev = edges.filter(edge => edge.target.cell === node.id)
          this.getYRange(inEdgesPrev, startNode, pointXY)
        }
      },
      isSeriesNode(startNode, endNode) {
        let result = false
        let inNode = null
        let outNode = null
        let inEdges = this.getInLinesOfNode(startNode)
        console.log(inEdges, 'inEdges')
        if (inEdges.length === 1) {
          let isMyLineToOtherLine = this.isMyLineToOtherLine(inEdges[0])
          let hasOtherLineToMyLine = this.hasOtherLineToMyLine(inEdges[0].id)
          let inNodeId = inEdges[0].source.cell
          inNode = this.graph.getCellById(inNodeId)
          if (!isMyLineToOtherLine && !hasOtherLineToMyLine) {
            let inNodeType = inNode.getData().nodeType
            console.log(inNodeType, 'inNodeType')
            if ('node,dashedBox,parallel,switch,vote,bridge'.indexOf(inNodeType) > -1) {
              result = true
            }
          }
        }
        let outEdges = this.getOutLinesOfNode(endNode)
        console.log(outEdges, 'outEdges')
        if (outEdges.length === 1) {
          let isMyLineToOtherLine = this.isMyLineToOtherLine(outEdges[0])
          let hasOtherLineToMyLine = this.hasOtherLineToMyLine(outEdges[0].id)
          let outNodeId = outEdges[0].target.cell
          outNode = this.graph.getCellById(outNodeId)
          if (!isMyLineToOtherLine && !hasOtherLineToMyLine) {
            let outNodeType = outNode.getData().nodeType
            if ('node,connect,dashedBox'.indexOf(outNodeType) > -1) {
              result = true
            }
          }
        }
        console.log(result, 'result')
        if (result && inNode && outNode) {
          console.log(inNode, outNode, 'inNode, outNode')
          return {inNode, outNode}
        } else {
          return false
        }
      },
      hasOtherLineToMyLine(edgeId) {
        for (let edge of this.graph.getEdges()) {
          if (edge.source.cell === edgeId || edge.target.cell === edgeId)
            return true
        }
        return false
      },
      isMyLineToOtherLine(myEdge) {
        for (let edge of this.graph.getEdges()) {
          if (myEdge.source.cell === edge.id || myEdge.target.cell === edge.id)
            return true
        }
        return false
      },
      isTopBottom(edge) {
        if (this.hasTopBottom(edge.getRouter().args.startDirections) && this.hasTopBottom(edge.getRouter().args.endDirections)) {
          return true
        }
        return false
      },
      hasTopBottom(object) {
        let result = false
        for (let a of object) {
          if (a == "top" || a == "bottom") {
            result = true
            break
          }
        }
        return result
      },
      isMultipleBrach(node) {
        let outEdges = this.getOutLinesOfNode(node)
        let outNodeId = outEdges[0].target.cell
        if (this.isTopBottom(outEdges[0]))
          return false
        let outNode = this.graph.getCellById(outNodeId)
        if ('bridge,end'.indexOf(outNode.getData().nodeType) > -1) {
          return false
        }
        let inEdges = this.getInLinesOfNode(outNode)
        return inEdges.length > 1;
      },
      deleteCombination(node) {
        let startNode = this.graph.getCellById(node.getData().startNodeId)
        let allCombinationNodes = []
        console.log(startNode, 'startNode')
        this.getAllCombinationNodes(startNode.id, node, allCombinationNodes)
        console.log(allCombinationNodes, 'allCombinationNodes')
        this.graph.removeCells(allCombinationNodes)
      },
      getAllCombinationNodes(startNodeId, node, allCombinationNodes) {
        allCombinationNodes.push(node)
        if (node.id == startNodeId || node.isEdge()) {
          return
        }
        let inEdges = this.getInLinesOfNode(node) // 如果???
        for (let inEdge of inEdges) {
          let lineNode = this.getNodeOfConectLine(inEdge)
          if (lineNode) {
            this.getAllCombinationNodes(startNodeId, lineNode, allCombinationNodes)
          }
          let inNodeId = inEdge.source.cell
          let inNode = this.graph.getCellById(inNodeId)
          if (inNode.isEdge())
            continue
          this.getAllCombinationNodes(startNodeId, inNode, allCombinationNodes)
        }
      },
      getNodeOfConectLine(paramEdge) {
        for (let edge of this.graph.getEdges()) {
          let nodeId = null
          /*          if (edge.source.cell === paramEdge.id){
                      nodeId = edge.target.cell
                    }*/
          if (edge.target.cell === paramEdge.id) {
            nodeId = edge.source.cell
          }
          if (nodeId) {
            let node = this.graph.getCellById(nodeId)
            if (node.isNode())
              return node
          }
        }
        return null
      },
      getInLinesOfNode(node) {
        const edges = this.graph.getConnectedEdges(node); // 获取画布上原有的节点所有进来的线
        console.log(edges, '获取画布上开始节点所有的线 edges')
        return edges.filter(edge => edge.target.cell === node.id)
      },
      getOutLinesOfNode(node) {
        console.log(node, '获取画布上的结束节点 node')
        const edges = this.graph.getConnectedEdges(node); // 获取画布上原有的节点所有进来的线
        console.log(edges, '获取画布上的结束节点所有的线 edges')
        return edges.filter(edge => edge.source.cell === node.id)
      },
      canPlace(targetNode, dragNode, box2) {
        const nodes = this.graph.getNodes()
        let intersectNodes = []
        // 检查除当前节点之外的所有节点的包围框是否相交
        for (const otherNode of nodes) {
          if (otherNode === dragNode || otherNode === targetNode) continue;
          const bbox1 = otherNode.getBBox();
          if (bbox1.x < box2.leftTopX + box2.width &&
            bbox1.x + bbox1.width > box2.leftTopX &&
            bbox1.y < box2.leftTopY + box2.height &&
            bbox1.y + bbox1.height > box2.leftTopY) {
            intersectNodes.push(otherNode);
          }
        }
        if (intersectNodes.length > 0) {
          // console.log('Nodes intersect with node:', node.id);
          console.log('Intersecting nodes:', intersectNodes.map(n => n)); // 相交节点的对象
          intersectNodes.map(node => {
            this.addNodeAndConnect(node, nodeObj);
          })
        console.log(box2, 'box2')
        console.log(intersectNodes, 'intersectNodes')
        return intersectNodes.length <= 0;
      },
      undo() {
        if (this.graph.history.canUndo()) {
          this.graph.history.undo()
        }
      });
      this.graph.on('cell:click', ({cell}) => {
        // this.type.value = cell.isNode() ? "node" : "edge"
        this.type = cell.isNode() ? 'node' : 'edge'
        this.shape = cell.shape
        this.id = cell.id
        if (this.type === 'node') {
          this.nodeType = cell.getData().nodeType
          console.log(this.nodeType, cell.id, 'this.nodeType')
      },
      redo() {
        if (this.graph.history.canRedo()) {
          this.graph.history.redo()
        }
        console.log(this.shape, 'this.shape')
        // this.nodeOpt(this.id, this.globalGridAttr)
      })
      //单击边节点
      this.graph.on('edge:click', ({edge}) => {
        this.reset()
        edge.attr('line/stroke', 'orange')
        edge.prop('labels/0', {
          attrs: {
            body: {
              stroke: 'orange',
            },
          },
        })
      })
      // 单击node节点
      this.graph.on('node:click', ({node}) => {
      })
      // 控制连接桩显示/隐藏
      this.graph.on('node:delete', ({view, e}) => {
        e.stopPropagation()
        view.cell.remove()
      })
      this.graph.on('node:customevent', ({name, view, e}) => {
        if (name === 'node:delete') {
          e.stopPropagation()
          view.cell.remove()
        }
      })
      // 双击编辑
      this.graph.on('cell:dblclick', ({cell, e}) => {
        const isNode = cell.isNode()
        const name = cell.isNode() ? 'node-editor' : 'edge-editor'
        cell.removeTool(name)
        cell.addTools({
          name,
          args: {
            event: e,
            attrs: {
              backgroundColor: isNode ? '#EFF4FF' : '#FFF',
              text: {
                fontSize: 16,
                fill: '#262626',
              },
            },
          },
        })
      })
      this.graph.on('node:mouseenter', ({node}) => {
        const container = document.getElementById('containerImg')
        const ports = container.querySelectorAll(
            '.x6-port-body',
        )
        this.showPorts(ports, true)
      })
      this.graph.on('node:mouseleave', ({node}) => {
        // if (node.hasTool('button-remove')) {
        //   node.removeTool('button-remove')
        // }
        const container = document.getElementById('containerImg')
        const ports = container.querySelectorAll(
            '.x6-port-body',
        )
        this.showPorts(ports, false)
      })
      this.graph.on('edge:mouseenter', ({cell}) => {
        // alert(123)
        cell.addTools([
          {
            name: 'source-arrowhead',
          },
          {
            name: 'target-arrowhead',
            args: {
              attrs: {
                fill: 'red',
              },
            },
          },
          {
            name: 'segments',
            args: {snapRadius: 20, attrs: {fill: '#444'}}
          },
        ])
      })
      this.graph.on('edge:mouseleave', ({cell}) => {
        cell.removeTools()
      })
      await this.getDiagram(this.dataForm.id)
    },
    showPorts(ports, show) {
      for (let i = 0, len = ports.length; i < len; i = i + 1) {
        ports[i].style.visibility = show ? 'visible' : 'hidden'
      }
    },
    reset() {
      this.graph.drawBackground({color: '#fff'})
      const nodes = this.graph.getNodes()
      const edges = this.graph.getEdges()
      nodes.forEach((node) => {
        node.attr('body/stroke', '#5F95FF')
      })
      edges.forEach((edge) => {
        edge.attr('line/stroke', '#5F95FF')
        edge.prop('labels/0', {
          attrs: {
            body: {
              stroke: '#5F95FF',
            },
          },
        })
      })
    },
    async search() {
      await this.getDiagram();
    },
    async saveDiagram() {
      console.log(JSON.stringify(this.graph.toJSON()), 'graph.toJSON()')
      this.dataForm.content = JSON.stringify(this.graph.toJSON())
      this.dataForm.urlPref = window.SITE_CONFIG['apiURL']
      console.log(this.dataForm, 'dataFrom')
      await this.$http[this.dataForm.id === null ? 'post' : 'put'](`/taskReliability/ModelLine/`, this.dataForm).then(async res => {
        if (res.msg === 'success') {
          this.$alert('保存成功', '提示', {
            confirmButtonText: '确定'
          })
        }
      })
    },
    async analyzeDiagram() {
      console.log(JSON.stringify(this.graph.toJSON()), 'graph.toJSON()')
      this.dataForm.content = JSON.stringify(this.graph.toJSON())
      this.dataForm.urlPref = window.SITE_CONFIG['apiURL']
      await this.$http['post'](`/taskReliability/ModelLine/analyze`, this.dataForm).then(async res => {
        if (res.msg === 'success') {
          this.$alert('解析成功', '提示', {
            confirmButtonText: '确定'
          })
        }
      })
    },
    leftAlign() {
      const NODE = this.graph.getSelectedCells()
      let leftX = null
      for (let a of NODE) {
        if (leftX == null || a.getBBox().x < leftX) {
          leftX = a.getBBox().x
        }
      }
      for (let a of NODE) {
        let y = a.getBBox().y
        a.position(leftX, y)
        // console.log(leftX, ':', y, '  x:y')
      }
    },
    topAlign() {
      const NODE = this.graph.getSelectedCells()
      let topY = null
      for (let a of NODE) {
        console.log(a.getBBox(), 'a.getBBox()')
        if (topY == null || a.getBBox().y < topY) {
          topY = a.getBBox().y
        }
      }
      for (let a of NODE) {
        let x = a.getBBox().x
        a.position(x, topY)
        // console.log(leftX, ':', y, '  x:y')
      }
    },
    centerAlign() {
      const NODE = this.graph.getSelectedCells()
      let rightX = null
      let leftX = null
      for (let a of NODE) {
        if (leftX == null || a.getBBox().x < leftX) {
          leftX = a.getBBox().x
        }
      }
      for (let a of NODE) {
        if (rightX == null || a.getBBox().x + a.getBBox().width > rightX) {
          rightX = a.getBBox().x + a.getBBox().width
        }
      }
      let centerX = leftX + (rightX - leftX) / 2
      for (let a of NODE) {
        let y = a.getBBox().y
        a.position(centerX - a.getBBox().width / 2, y)
        // console.log(leftX, ':', y, '  x:y')
      }
    },
    shuipingAlign() {
      const NODE = this.graph.getSelectedCells()
      let bottomY = null
      let topY = null
      for (let a of NODE) {
        if (topY == null || a.getBBox().y || 0 < topY) {
          topY = a.getBBox().y
        }
      }
      for (let a of NODE) {
        if (bottomY == null || a.getBBox().y + a.getBBox().height > bottomY) {
          bottomY = a.getBBox().y + a.getBBox().height
        }
      }
      let centerY = topY + (bottomY - topY) / 2
      for (let a of NODE) {
        let x = a.getBBox().x
        let centerHei = a.getBBox().height / 2
        a.position(x, centerY - centerHei)
      }
    },
    rightAlign() {
      const NODE = this.graph.getSelectedCells()
      let rightX = null
      for (let a of NODE) {
        if (rightX == null || a.getBBox().x + a.getBBox().width > rightX) {
          rightX = a.getBBox().x + a.getBBox().width
        }
      }
      for (let a of NODE) {
        let y = a.getBBox().y
        a.position(rightX - a.getBBox().width, y)
      }
    },
    bottomAlign() {
      const NODE = this.graph.getSelectedCells()
      let bottomY = null
      for (let a of NODE) {
        if (bottomY == null || (a.getBBox().y + a.getBBox().height) > bottomY) {
          bottomY = a.getBBox().y + a.getBBox().height
        }
      }
      for (let a of NODE) {
        let x = a.getBBox().x
        a.position(x, bottomY - a.getBBox().height)
      }
    },
    close() {
      if (this.timer) {
        window.clearInterval(this.timer)
      }
    },
    // 定义函数来检查两个包围框是否相交
    isIntersect(bbox1, bbox2) {
      return (
          bbox1.x < bbox2.x + bbox2.width &&
          bbox1.x + bbox1.width > bbox2.x &&
          bbox1.y < bbox2.y + bbox2.height &&
          bbox1.y + bbox1.height > bbox2.y
      )
    },
    addNodeAndConnect(node, nodeObj) { // node是画布原有的节点。nodeObj是当前拖拽的节点
      const nodeType = node.getData().nodeType  // 获取节点类型
      const edges = this.graph.getConnectedEdges(node); // 获取与原节点相关联的所有连接线
      let TopSum = 0 // 在原节点上方
      let BottomSum = 0 // 在原节点下方
      const edgesSum = edges.length
      if (nodeType !== 'node') {
        if (edges.length === 0) {
          if (!this.nodeAdded) {
            // 添加节点的操作
            this.connectNode = this.graph.addNode({
              shape: 'image',
              // imageUrl: require('/public/modelImg/' + item.imgPath + '.png'),
              width: 30,
              height: 30,
              data: {
                type: 'imageNodes',
                dataId: '',
                nodeType: 'connect',
                nodeTypeExt: '',
                voteNum: ''
              },
              attrs: {
                image: {
                  'xlink:href': '/modelImg/connect.svg',
                },
                text: {
                  text: 'connect',
                  fontSize: 14,
                  refX: 0.5,
                  refY: '100%',
                  refY2: 4,
                  textAnchor: 'middle',
                  textVerticalAnchor: 'top',
                },
              },
              ports: {...this.ports},
            })
            // 设置标记为 true,表示已经添加过节点
            this.nodeAdded = true;
          }
          nodeObj.position(node.position().x - 240, node.position().y - (120 * edgesSum));
          this.connectNode.position(node.position().x - 480, node.position().y + (node.size().height - this.connectNode.size().height) / 2);
        } else if (edges.length === 1) {
          // 将节点移动到指定的位置
          nodeObj.position(node.position().x - 240, node.position().y - (120 * edgesSum));
        } else {
          for (const edge of edges) {
            const sourcePointY = edge.getSourcePoint().y; // 获取连接线的起始点y坐标
            const targetPointY = edge.getTargetPoint().y; // 获取连接线的结束点y坐标
            console.log('原节点Y坐标' + node.position().y, '连接线起始Y坐标' + sourcePointY)
            if (targetPointY > sourcePointY) {
              TopSum++
            } else if (targetPointY < sourcePointY) {
              BottomSum++
            }
          }
          console.log('在原节点上方的连接线数量:' + TopSum, '在原节点下方的连接线数量:' + BottomSum)
          if (TopSum > BottomSum) {
            nodeObj.position(node.position().x - 240, node.position().y + (120 + (120 * BottomSum)))
          } else {
            nodeObj.position(node.position().x - 240, node.position().y - (120 + (120 * TopSum)));
          }
        }
        this.graph.addEdge({
          source: {cell: nodeObj, port: 'right1'},
          target: {cell: node, port: 'left1'},
          router: {name: 'manhattan'},
          connector: {name: 'rounded'}
        })
        if (this.nodeAdded) {
          console.log(this.connectNode, 'connectNode')
          this.graph.addEdge({
            source: {cell: this.connectNode, port: 'right1'},
            target: {cell: nodeObj, port: 'left1'},
            router: {name: 'manhattan'},
            connector: {name: 'rounded'}
          })
        }
      } else {
          // 遍历所有连接线并删除与给定节点对象相关的连接线
        console.log(edges, '所有有关联的连接线 edge')
        if(edges.length === 0){
          this.graph.addEdge({
            source: {cell: node, port: 'right1'},
            target: {cell: nodeObj, port: 'left1'},
            router: {name: 'manhattan'},
            connector: {name: 'rounded'}
          })
           return nodeObj.position(node.position().x +node.getBBox().width+50, node.position().y);
        }else {
          for (const edge of edges) {
            console.log(edge, '所有有关联的连接线 edge')
            if (edge.source.cell === node.id) { // 如果连接线的起始节点等于当前画布目标节点的ID
              const sourceNode = this.graph.getCellById(edge.source.cell); // 获取连接线的源节点对象
              const targetNode = this.graph.getCellById(edge.target.cell) // 获取连接线的目标节点对象
              console.log(sourceNode, targetNode, 'targetNode 目标节点对象')
              // edge.remove(); // 从图中删除该连接线
              nodeObj.position(node.position().x +node.getBBox().width+50, node.position().y);
              // edge.source = {cell: node, port: 'right1'}
              edge.target = {cell: nodeObj, port: 'left1'}
              // targetNode.position(nodeObj.position().x +nodeObj.getBBox().width+50, node.position().y);
              // this.graph.addEdge({
              //   source: {cell: node, port: 'right1'},
              //   target: {cell: nodeObj, port: 'left1'},
              //   router: {name: 'manhattan'},
              //   connector: {name: 'rounded'}
              // })
              this.graph.addEdge({
                source: {cell: nodeObj, port: 'right1'},
                target: {cell: targetNode, port: 'left1'},
                router: {name: 'manhattan'},
                connector: {name: 'rounded'}
              })
            }else {
              this.graph.addEdge({
                source: {cell: node, port: 'right1'},
                target: {cell: nodeObj, port: 'left1'},
                router: {name: 'manhattan'},
                connector: {name: 'rounded'}
              })
              nodeObj.position(node.position().x +node.getBBox().width+50, node.position().y);
            }
          }
        }
      }
    },
  },
}
  }
</script>
<style>
#containerImg {
  display: flex;
  border: 1px solid #dfe3e8;
  height: 400px;
  width: 100% !important;
}
  #containerImg {
    display: flex;
    /*border: 1px solid #dfe3e8;*/
    height: 400px;
    width: 100% !important;
  }
.x6-graph-scroller.x6-graph-scroller-pannable {
  width: 100% !important;
}
  .x6-graph-scroller.x6-graph-scroller-pannable {
    width: 100% !important;
  }
#stencilImg {
  width: 100%;
  height: 100%;
  position: relative;
  border-right: 1px solid #dfe3e8;
}
  #stencilImg {
    width: 100%;
    height: 100%;
    position: relative;
    border-right: 1px solid #dfe3e8;
  }
.x6-widget-stencil {
  position: relative;
  height: 100%;
}
  .x6-widget-stencil {
    position: relative;
    height: 100%;
  }
#stencilImg .x6-graph-svg-viewport {
  height: 100%;
}
  #stencilImg .x6-graph-svg-viewport {
    height: 100%;
  }
.x6-widget-stencil-content {
  position: relative;
  height: calc(100% - 32px);
}
  .x6-widget-stencil-content {
    position: relative;
    height: calc(100% - 32px);
  }
#stencilImg .x6-widget-stencil.collapsable > .x6-widget-stencil-content {
  top: 0
}
  #stencilImg .x6-widget-stencil.collapsable > .x6-widget-stencil-content {
    top: 0
  }
  #containerImg .x6-graph-pagebreak>.x6-graph-pagebreak-horizontal {
    position: absolute;
    right: 0;
    left: 0;
    box-sizing: border-box;
    height: 0;
    border-top: none;
  }
  #containerImg .x6-graph-pagebreak>.x6-graph-pagebreak-vertical {
    position: absolute;
    top: 0;
    bottom: 0;
    box-sizing: border-box;
    width: 0;
    border-left: none;
  }
</style>