<!-- AntV G6 Graph Component -->
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import {  ElMessage } from "element-plus";
import {
  Clipboard,
  Graph,
  History,
  Keyboard,
  Selection,
  Shape,
  Snapline,
  Stencil,
  Transform
} from '@antv/x6'

// @ts-ignore
import insertCss from 'insert-css'
import { updateProjects} from "@/api/business/project";
import Createscenario from '@/views/component/scenario/createscenario.vue'
import ScenarioModel from '@/views/component/scenario/index.vue'
import img1 from '@/assets/x6/1.png'
import img2 from '@/assets/x6/2.png'
import img3 from '@/assets/x6/3.png'
import img4 from '@/assets/x6/4.png'
import img5 from '@/assets/x6/5.png'
import img6 from '@/assets/x6/6.png'
import img7 from '@/assets/x6/7.png'

import img11 from '@/assets/x6/11.png'
import img22 from '@/assets/x6/22.png'
import img33 from '@/assets/x6/33.png'
import img44 from '@/assets/x6/44.png'
import img55 from '@/assets/x6/55.png'
import img66 from '@/assets/x6/66.png'
import img77 from '@/assets/x6/77.png'

import line1 from '@/assets/x6/line1.png'
import line2 from '@/assets/x6/line2.png'
import line3 from '@/assets/x6/line3.png'
import line4 from '@/assets/x6/line4.png'
import line5 from '@/assets/x6/line5.png'
import line6 from '@/assets/x6/line6.png'
import AdddeviceModel from './adddevice.vue';
import EditdeviceModel from './editdevice.vue';
import MaterialModels from './materialmodel.vue';
import ChangesettingsModels from './changesettings.vue';

import ConnectingwireModel from './connectingwire.vue';
const emit = defineEmits([ 'closeAntvx6']);
const props = defineProps({
  projectInfo: {
    required: false,
    type: Object,
    default: {}
  },
})
const isLock = ref(false) // 是否锁定
const deviceTypetype:any = ref('') // 设备类型
const isAdddevice = ref(false) // 是否添加设备
const isEditdevice = ref(false) // 是否编辑设备
const isMaterialModel = ref(false) // 是否物料信息
const projectInfo:any = ref(props.projectInfo) // 项目信息
const isScenario = ref(false) //是否展示历史模拟场景
const isDisplay = ref(true) // 是否显示
const isExpansionandcontraction = ref(false) // 是否显示展开收起按钮
// 为了协助代码演示
let graph: Graph
onMounted(() => {
  preWork()
  // #region 初始化画布 
  graph = new Graph({
    container: document.getElementById('graph-container') as HTMLElement,
    grid: true,
    mousewheel: {
      enabled: true,
      zoomAtMousePosition: true,
      modifiers: 'ctrl',
      minScale: 0.5,
      maxScale: 3,
    },
    connecting: {
      router: 'manhattan',
      connector: {
        name: 'rounded',
        args: {
          radius: 1,
        },
      },
      anchor: 'center',
      connectionPoint: 'anchor',
      allowBlank: false,
      snap: {
        radius: 20,
      },
      createEdge() {
        return new Shape.Edge({
          attrs: {
            line: {
              stroke: '#A2B1C3',
              strokeWidth: 2,
              strokeDasharray: 0,
              targetMarker: {
                name: 'block',
                width: 12,
                height: 8,
              },
              sourceMarker: null,
            },
          },
          zIndex: 0,
          interactive: {
            vertexMovable: true,
            vertexAddable: true,
            vertexDeletable: true,
            arrowheadMovable: true,
            edgeMovable: true,
          },
        })
      },
      validateConnection({ targetMagnet }) {
        return !!targetMagnet
      },
    },
    highlighting: {
      magnetAdsorbed: {
        name: 'stroke',
        args: {
          attrs: {
            fill: '#5F95FF',
            stroke: '#5F95FF',
          },
        },
      },
    },
    
    interacting: function (cellView) {
    // 获取当前节点的模型
      const cell = cellView.cell
      // 判断节点是否为 'rect' 形状
      if (cell.shape === 'rect') {
        // 如果是 'rect' 形状，则禁止节点移动
        return { nodeMovable: false }
      }
      // 其他形状的节点允许所有交互
      return true
    }
    // interacting: {
    //   nodeMovable: false, // 禁止所有节点移动
    // },
  })
  // #endregion

  // #region 使用插件
  graph
  .use(
      new Transform({
        resizing: false, // 通过拖拽边缘调整节点大小
        rotating: false, // 允许旋转节点
        // scaling 不是 Transform 插件的有效配置项，已移除
      }),
    )
    .use(
      new Selection({
        rubberband: true,
        showNodeSelectionBox: true,
      }),
    )
    .use(new Snapline())
    .use(new Keyboard())
    .use(new Clipboard())
    .use(new History())
  // #endregion

  // #region 初始化 stencil
  const stencil = new Stencil({
    title: '',
    target: graph,
    stencilGraphWidth: 300,
    stencilGraphHeight: 180,
    stencilGraphOptions: { panning: false },
    collapsable: false,
    groups: [
    //    {
    //   title: '基础流程图',
    //   name: 'group1',
    // },
      {
        collapsable: false,
        title: '设备',
        name: 'group2',
        graphHeight: 550,
        layoutOptions: {
          rowHeight: 120,
        },
      },
      // {
      //   collapsable: false,
      //   title: '管线',
      //   name: 'group3',
      //    graphHeight: 400,
      //   layoutOptions: {
      //     rowHeight: 120,
      //   },
      // },
    ],
    
    layoutOptions: {
      columns: 2,
      columnWidth: 140,
      rowHeight: 100,
    },
    getDragNode: (sourceNode:any) => {
      console.log('1111')
      let node:any = sourceNode
      if (node.data && node.data.lineStyle) {
      // 应用管线样式到连接线
      const lineStyle = node.data.lineStyle
      graph.options.connecting.createEdge = () => {
        return new Shape.Edge({
          attrs: {
            line: {
              stroke: '#A2B1C3',
              strokeWidth: 2,
              strokeDasharray: lineStyle.strokeDasharray,
              targetMarker: lineStyle.targetMarker,
              sourceMarker: lineStyle.sourceMarker
            }
          },
          zIndex: 0
        })
      }
      // 移除管线节点，因为它只是一个样式选择器
      setTimeout(() => {
        graph.removeNode(node)
      }, 100)
      return null
    }
      return sourceNode.clone({ deep: true })
    },
    // getDropNode: (draggingNode) => {
    //     return draggingNode.clone({ deep: true })
    //   },
  })

  graph.on('node:contextmenu', ({ e, node }) => {
      selectedNode.value = node
    e.preventDefault()
    // 显示自定义上下文菜单，包含箭头样式选项
    const pos = node.position?.() || { x: 0, y: 0 }
    showContextMenu(pos.x, pos.y)
  })

  function showContextMenu(x: number, y: number) {
    left.value = x + 260
    top.value = y - 50
    isMenuShow.value = true
  }
  graph.on('node:click', (row:any) => {

    let node:any = row.node
     nodeId.value = node.id
    if( node.store.data.shape == 'rect'){
     
      styleInfo.value = {
        name: node.store.data.attrs.label.text,
        color: node.store.data.attrs.body.stroke,
        line: node.store.data.attrs.body.strokeDasharray == ''?'实线':'虚线',
        width: node.store.data.attrs.body.strokeWidth,
        remark: node.store.data.remark
      }
    }
    row.e.preventDefault()
  })
  // 监听Stencil内部的Dnd事件

  document
    .getElementById('stencil')
    ?.appendChild(stencil.container as HTMLElement)

    // 监听Graph中节点创建事件
  graph.on('node:added', (args:any) => {
    console.log('节点已添加到画布', args)
    if(isLock.value == true){
      return
    }



    const { node } = args
    
    // 检查是否是管线节点
    if (node.data && node.data.lineStyle) {
      // 应用管线样式到连接线
      const lineStyle = node.data.lineStyle
      graph.options.connecting.createEdge = () => {
        return new Shape.Edge({
          attrs: {
            line: {
              stroke: '#A2B1C3',
              strokeWidth: 2,
              strokeDasharray: lineStyle.strokeDasharray,
              targetMarker: lineStyle.targetMarker,
              sourceMarker: lineStyle.sourceMarker
            }
          },
          zIndex: 0
        })
      }
      // 移除管线节点，因为它只是一个样式选择器
      setTimeout(() => {
        graph.removeNode(node)
      }, 100)
    } else {
      if(node.store && node.store.data && node.store.data.shape === 'rect'){
        nodeId.value = node.id
        styleInfo.value = {
            name: node.store.data.attrs.label.text,
            color: '#ff0000',
            line: '虚线',
            width: node.store.data.attrs.body.strokeWidth,
            remark: ''

        }
      node.store.data.remark = ''
        return
      }

      node.size(160, 160)
      // 去掉背景节点
      node.attr('body/fill', 'none')
      // 图片居中
      node.attr('image/refX', 0)
      node.attr('image/refY', 0)
      // node.attr('label/refX', 40)

      node.attr('image/width', 160)      // 修改宽度
      node.attr('image/height', 160)     // 修改高度


      nodeId.value = node.id
       if(node.store.data.attrs.text.text == '圆柱槽'){
        deviceTypetype.value = 'CylindricalTank'
        node.size(110, 140)
        const width = node.size().width
        node.attr('image/xlink:href', '/assets/11.png')    
        node.attr('image/width', 105)     
        node.attr('image/height', 135)   
        node.attr('label/refY', 140)
        node.attr('label/refX', width/2)
        node.attr('label/textAnchor', 'middle')
      }else if(node.store.data.attrs.text.text == '扁平槽'){
        deviceTypetype.value = 'FlatTank' 

        node.size(130, 60)
        const width = node.size().width
        node.attr('image/xlink:href', '/assets/22.png')    
        node.attr('image/width', 130)     
        node.attr('image/height', 60)   
        node.attr('label/refY', 65)
        node.attr('label/refX', width/2)
        node.attr('label/textAnchor', 'middle')


      }else if(node.store.data.attrs.text.text == '环形槽'){
        deviceTypetype.value = 'AnnularTank'

        node.size(90, 140)
        const width = node.size().width
        node.attr('image/xlink:href', '/assets/33.png')    
        node.attr('image/width', 90)     
        node.attr('image/height', 135)   
        node.attr('label/refY', 140)
        node.attr('label/refX', width/2)
        node.attr('label/textAnchor', 'middle')


      }else if(node.store.data.attrs.text.text == '管束槽'){
        deviceTypetype.value = 'TubeBundleTank'
        node.size(80, 140)
        const width = node.size().width
        node.attr('image/xlink:href', '/assets/44.png')    
        node.attr('image/width', 80)     
        node.attr('image/height', 135)   
        node.attr('label/refY', 140)
        node.attr('label/refX', width/2)
        node.attr('label/textAnchor', 'middle')
      }else if(node.store.data.attrs.text.text == '萃取柱'){
        deviceTypetype.value = 'ExtractionColumn'

        node.size(30, 140)
        const width = node.size().width
        node.attr('image/xlink:href', '/assets/55.png')    
        node.attr('image/width', 30)     
        node.attr('image/height', 135)   
        node.attr('label/refY', 140)
        node.attr('label/refX', width/2)
        node.attr('label/textAnchor', 'middle')


      }else if(node.store.data.attrs.text.text == '流化床'){
        deviceTypetype.value = 'FluidizedBed'
        node.size(60, 140)
        const width = node.size().width
        node.attr('image/xlink:href', '/assets/66.png')    
        node.attr('image/width', 60)     
        node.attr('image/height', 135)   
        node.attr('label/refY', 140)
        node.attr('label/refX', width/2)
        node.attr('label/textAnchor', 'middle')
      }else if(node.store.data.attrs.text.text == '锥底环形槽'){
        deviceTypetype.value = 'ACFTank'
        node.size(40, 140)
        const width = node.size().width
        node.attr('image/xlink:href', '/assets/77.png')    
        node.attr('image/width', 40)     
        node.attr('image/height', 135)   
        node.attr('label/refY', 140)
        node.attr('label/refX', width/2)
        node.attr('label/textAnchor', 'middle')
      }
      // 设置固定大小
    
      // 删除节点上的文字
      // node.attr('text/text', '')
      // node.attr('label/text', '')
      isAdddevice.value = true


    }

  })

 graph.on('edge:selected', ({ edge }) => {
  let edgeTemp :any = edge
  edge.addTools({
      name: 'button-remove',
      args: {
        x: 0,
        y: 0,
        offset: { x: 10, y: 10 },
      },
    })
     edge.addTools({
        name: 'vertices', // 指定使用 vertices 工具
        args: {
          // 可选配置参数
          snapRadius: 20,    // 移动时的吸附半径
          addable: true,     // 是否允许单击边添加顶点
          removable: true,   // 是否允许双击顶点删除
          attrs: {           // 自定义顶点的样式（小圆点）
            r: 6,
            fill:  edgeTemp.store.data.attrs.line.stroke,
          },
        },
      })


    
  });
  graph.on('edge:unselected', ({ edge }) => {
    edge.removeTools()
  })



  // #endregion

  // #region 快捷键与事件
  graph.bindKey(['meta+c', 'ctrl+c'], () => { 
    const cells = graph.getSelectedCells()
    if (cells.length) {
      graph.copy(cells)
    }
    return false
  })
  graph.bindKey(['meta+x', 'ctrl+x'], () => {
    const cells = graph.getSelectedCells()
    if (cells.length) {
      graph.cut(cells)
    }
    return false
  })
  graph.bindKey(['meta+v', 'ctrl+v'], () => {
    if (!graph.isClipboardEmpty()) {
      const cells = graph.paste({ offset: 32 })
      graph.cleanSelection()
      graph.select(cells)
    }
    return false
  })

  // undo redo
  graph.bindKey(['meta+z', 'ctrl+z'], () => {
    if (graph.canUndo()) {
      graph.undo()
    }
    return false
  })
  graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
    if (graph.canRedo()) {
      graph.redo()
    }
    return false
  })

  // select all
  graph.bindKey(['meta+a', 'ctrl+a'], () => {
    const nodes = graph.getNodes()
    if (nodes) {
      graph.select(nodes)
    }
  })
  graph.bindKey('delete', () => {
    const cells = graph.getSelectedCells()
    if (cells.length) {
      graph.removeCells(cells)
    }
  })

  // zoom
  graph.bindKey(['ctrl+1', 'meta+1'], () => {
    const zoom = graph.zoom()
    if (zoom < 1.5) {
      graph.zoom(0.1)
    }
  })
  graph.bindKey(['ctrl+2', 'meta+2'], () => {
    const zoom = graph.zoom()
    if (zoom > 0.5) {
      graph.zoom(-0.1)
    }
  })




  let startPoint:any = null // 矩形起点

// 监听鼠标按下事件：记录起点
graph.on('blank:mousedown', (e) => {
  startPoint = { x: e.x, y: e.y }
})

// 监听鼠标松开事件：绘制矩形
graph.on('blank:mouseup', (e) => {
  console.log('鼠标松开事件', e)
  if (!startPoint) return

  if(isBoundary.value == false){
    return
  }


  const endPoint = { x: e.x, y: e.y }
  if(Math.abs(endPoint.x - startPoint.x) <20 && Math.abs(endPoint.y - startPoint.y) <20){
    return
  }
  const width = Math.abs(endPoint.x - startPoint.x)
  const height = Math.abs(endPoint.y - startPoint.y)
  const x = Math.min(startPoint.x, endPoint.x)
  const y = Math.min(startPoint.y, endPoint.y)

  // 添加矩形节点（设置 zIndex 为 -1 确保在最底层）
  graph.addNode({
    shape: 'rect',
    x,
    y,
    width,
    height,
    zIndex: -1, // 关键：置于底层
    // interactive: false, // 禁用所有交互
    // selectable: false, // 明确禁止选中
    draggable: false, // 明确禁止移动
     interacting: {
      nodeMovable: false, // 禁止所有节点移动
    },
    attrs: {
      body: {
        fill: 'transparent', 
        stroke: '#ff0000',
        strokeWidth: 1,
        strokeDasharray: '5 5', // 设置虚线样式
      },
      label: {
        text: '系统边界',
        refX: '50%',
        refY: -15,
        textAnchor: 'middle',
        dominantBaseline: 'middle',  // 文本自身的垂直居中
        fontSize: 15,
        fill: '#333333'
      }
    },
  })

  startPoint = null // 重置起点
})


  // 控制连接桩显示/隐藏
  const showPorts = (ports: NodeListOf<SVGElement>, show: boolean) => {
    for (let i = 0, len = ports.length; i < len; i += 1) {
      ports[i].style.visibility = show ? 'visible' : 'hidden'
    }
  }
  graph.on('node:mouseenter', () => {
    const container = document.getElementById('graph-container') as HTMLElement
    const ports = container.querySelectorAll(
      '.x6-port-body',
    ) as NodeListOf<SVGElement>
    showPorts(ports, true)
  })
  graph.on('node:mouseleave', () => {
    const container = document.getElementById('graph-container') as HTMLElement
    const ports = container.querySelectorAll(
      '.x6-port-body',
    ) as NodeListOf<SVGElement>
    showPorts(ports, false)
  })
  // #endregion

  // #region 初始化图形
  const ports = {
    groups: {
      top: {
        position: 'top',
        attrs: {
          circle: {
            r: 8,
            magnet: true,
            stroke: '#5F95FF',
            strokeWidth: 1,
            fill: '#fff',
            style: {
              visibility: 'hidden',
            },
          },
        },
      },
      right: {
        position: 'right',
        attrs: {
          circle: {
            r: 8,
            magnet: true,
            stroke: '#5F95FF',
            strokeWidth: 1,
            fill: '#fff',
            style: {
              visibility: 'hidden',
            },
          },
        },
      },
      bottom: {
        position: 'bottom',
        attrs: {
          circle: {
            r: 8,
            magnet: true,
            stroke: '#5F95FF',
            strokeWidth: 1,
            fill: '#fff',
            style: {
              visibility: 'hidden',
            },
          },
        },
      },
      left: {
        position: 'left',
        attrs: {
          circle: {
            r: 8,
            magnet: true,
            stroke: '#5F95FF',
            strokeWidth: 1,
            fill: '#fff',
            style: {
              visibility: 'hidden',
            },
          },
        },
      },
    },
    items: [
      {
        group: 'top',
      },
      {
        group: 'right',
      },
      {
        group: 'bottom',
      },
      {
        group: 'left',
      },
    ],
  }
  Graph.registerNode(
    'custom-image',
    {
      inherit: 'rect',
      width: 130,
      height: 100,
      markup: [
        {
          tagName: 'rect',
          selector: 'body',
        },
        {
          tagName: 'image',
        },
        {
          tagName: 'text',
          selector: 'label',
        },
      ],
      attrs: {
        body: {
          stroke: 'transparent',
          fill: '#f8f8f8',
        },
        image: {
          width: 62,
          height:84,
          refX: 35,
          refY: 0,
        },
        label: {
          refX: 45,
          refY: 80,
          textAnchor: 'start',
          textVerticalAnchor: 'top',
          fontSize: 14,
          fill: '#000',
        },
      },
      ports: { ...ports },
    },
    true,
  )

  const imageShapes = [
    {
      label: '圆柱槽',
      image: '/assets/1.png',
    },
    {
      label: '扁平槽',
      image: '/assets/2.png',
    },
    {
      label: '环形槽',
      image: '/assets/3.png',
    },
    {
      label: '管束槽',
      image: '/assets/4.png',
    },
    {
      label: '萃取柱',
      image: '/assets/5.png',
    },
    {
      label: '流化床',
      image: '/assets/6.png',
    },{
      label: '锥底环形槽',
      image: '/assets/7.png',
    },
  ]
  const imageNodes = imageShapes.map((item) =>
    graph.createNode({
      shape: 'custom-image',
      label: item.label,
      attrs: {
        image: {
          'xlink:href': item.image,
        },
      },
    }),
  )
  stencil.load(imageNodes, 'group2')
  
  // 创建管线节点
  const lineShapes = [
    {
      label: '实线',
      image: line1,
      targetMarker: null,
      sourceMarker: null,
      strokeDasharray: 0
    },
    {
      label: '单箭头实线',
      image: line2,
      targetMarker: {
        name: 'block',
        width: 12,
        height: 8
      },
      sourceMarker: null,
      strokeDasharray: 0
    },
    {
      label: '双箭头实线',
      image: line3,
      targetMarker: {
        name: 'block',
        width: 12,
        height: 8
      },
      sourceMarker: {
        name: 'block',
        width: 12,
        height: 8
      },
      strokeDasharray: 0
    },
    {
      label: '虚线',
      image: line4,
      targetMarker: null,
      sourceMarker: null,
      strokeDasharray: 5
    },
    {
      label: '单箭头虚线',
      image: line5,
      targetMarker: {
        name: 'block',
        width: 12,
        height: 8
      },
      sourceMarker: null,
      strokeDasharray: 5
    },
    {
      label: '双箭头虚线',
      image: line6,
      targetMarker: {
        name: 'block',
        width: 12,
        height: 8
      },
      sourceMarker: {
        name: 'block',
        width: 12,
        height: 8
      },
      strokeDasharray: 5
    }
  ]
  
  const lineNodes = lineShapes.map((item) => {
    // 创建一个节点来显示管线样式
    const node = graph.createNode({
      shape: 'custom-image',
      label: item.label,
      width: 130,
      height: 100,
      attrs: {
        image: {
          'xlink:href': item.image,
          width: 31,
          height: 31,
          refX: 50,
          refY: 20
        },
        body: {
          stroke: 'transparent',
          fill: '#f8f8f8'
        },
        label: {
          text: item.label,
          refX: 60,
          refY: 65,
          textAnchor: 'middle',
          fontSize: 12,
          fill: '#666'
        }
      },
      data: {
        lineStyle: {
          strokeDasharray: item.strokeDasharray,
          targetMarker: item.targetMarker,
          sourceMarker: item.sourceMarker
        }
      }
    })
    
    return node
  })
  
  stencil.load(lineNodes, 'group3')
    if (!graph || !projectInfo.value || !projectInfo.value.topology) return;
    graph.clearCells();
    const topology:any = JSON.parse(projectInfo.value.topology)
    if(!topology.designData)return
    graph.fromJSON(topology.designData);
  // #endregion
})

function preWork() {
  // 这里协助演示的代码，在实际项目中根据实际情况进行调整
  const container = document.getElementById('container') as HTMLElement
  const stencilContainer = document.createElement('div')
  stencilContainer.id = 'stencil'
  const graphContainer = document.createElement('div')
  graphContainer.id = 'graph-container'
  container.appendChild(stencilContainer)
  container.appendChild(graphContainer)

  insertCss(`
    #container {
      display: flex;
      border: 1px solid #dfe3e8;
      width: 100vw;
      height: calc(100vh - 60px);
    }
    #stencil {
      width: 300px;
      height: 100%;
      position: relative;
      border-right: 1px solid #dfe3e8;
    }
    .x6-widget-stencil-content{
      top:0px !important;
    }
      .x6-widget-stencil-title{
      display: none;
      }
   .x6-container-editbox #graph-container {
      width: calc(100% - 180px);
      height: 100% !important;
      background-color: #f1f3fe;
    }
    .x6-widget-stencil  {
      background-color: #fff;
    }
    .x6-widget-stencil-title {
      background-color: #fff;
    }
    .x6-widget-stencil-group-title {
      background-color: #fff !important;
    }
    .x6-widget-transform {
      margin: -1px 0 0 -1px;
      padding: 0px;
      border: 1px solid #239edd;
    }
    .x6-widget-transform > div {
      border: 1px solid #239edd;
    }
    .x6-widget-transform > div:hover {
      background-color: #3dafe4;
    }
    .x6-widget-transform-active-handle {
      background-color: #3dafe4;
    }
    .x6-widget-transform-resize {
      border-radius: 0;
    }
    .x6-widget-selection-inner {
      border: 1px solid #239edd;
    }
    .x6-widget-selection-box {
      opacity: 0;
    }
  `)
}
const left = ref(0) 
const top = ref(0) 
const isMenuShow = ref(false) // 是否显示右键菜单
const selectedNode:any = ref(null)
function deleteNode() { // 删除节点
  graph.removeNode(selectedNode.value)
   isMenuShow.value = false
}



function copyNode() { // 复制节点
  if (selectedNode.value) {
    try {
      // 获取当前节点的位置
      const position = selectedNode.value.position()
      // 创建新节点，使用节点的原始数据
      const newNode = selectedNode.value.clone()
      // 设置新位置（偏移50px）
      newNode.position(position.x + 50, position.y + 50)
      deviceTypetype.value = newNode.store.data.deviceInfo.type
      // 添加到画布
      graph.addNode(newNode)
        // 
      // :deviceId="nodeId" :projectInfo="projectInfo"
      //     :deviceTypetype="deviceTypetype"
       isMenuShow.value = false 
    } catch (error) {
      console.error('节点复制失败:', error)
    }
  }
}


function closeAntvx6() {
  emit('closeAntvx6')
}

function revokeClick(){
  if (graph.canUndo()) {
     isLock.value = true
    graph.undo()
     setTimeout(() => {
      isLock.value = false
    }, 500);
  }
}
function removeClick(){
  if (graph.canRedo()) {
    isLock.value = true
    graph.redo()
    setTimeout(() => {
      isLock.value = false
    }, 500);
  }
}
function bigClick(){  // 放大画布
  graph.zoom(0.1)
}
function smallClick(){ // 缩小画布
  graph.zoom(-0.1)
}
function ConnectingwireClick(){ // 打开连接线弹窗
  isConnectingwire.value = true;
}
function dialogConnectingwire(){ // 关闭连接线弹窗
  isConnectingwire.value = false;
}
const connectingwireInfo:any = ref({
  label: "实线",
  strokeDasharray: "0",
  arrow: "1",
  strokeWidth: 2,
  color: "#a2b1c3",
})
const lineLine:any = ref( "#a2b1c3")
function closeConnectingwireModel(e:any){ // 关闭连接线弹窗
  if(e != false){
  connectingwireInfo.value = e
   lineLine.value = e.color
  let lineStyle:any = {
    strokeDasharray: 0,
    targetMarker: {},
    sourceMarker: {}
  }
    if(e.arrow == 0){
      lineStyle = {
        sourceMarker: null,
        strokeDasharray: e.strokeDasharray,
        targetMarker: null
      }
    }
    if(e.arrow == 1){
      lineStyle = {
        sourceMarker: null,
        strokeDasharray:e.strokeDasharray,
        targetMarker: {
          height: 8,
          name: "block",
          width: 12
        }
      }
    }
    if(e.arrow == 2){
      lineStyle = {
        sourceMarker: {
          height: 8,
          name: "block",
          width: 12
        },
        strokeDasharray:e.strokeDasharray,
        targetMarker: {
          height: 8,
          name: "block",
          width: 12
        }
      }
    }
    graph.options.connecting.createEdge = () => {
      return new Shape.Edge({
        attrs: {
          line: {
            stroke: lineLine.value,
            strokeWidth: e.strokeWidth,
            strokeDasharray: lineStyle.strokeDasharray,
            targetMarker: lineStyle.targetMarker,
            sourceMarker: lineStyle.sourceMarker
          }
        },
        zIndex: 0
      })
    }
  }
  isConnectingwire.value = false;
}
const nodeId = ref("")



function analysisAdd(){
   dialogVisible.value = true;
}
const dialogVisible = ref(false)
function closeCreatescenario(){ // 关闭新增模拟分析弹窗
  dialogVisible.value = false;
}
function simulationClick() { // 打开模拟分析
  isScenario.value = true;
}
//取消按钮
function handleClose() {
  isScenario.value = false;
}

function dialogAdddevice(){ // 打开新增设备弹窗
   graph.undo()
   isAdddevice.value = false;
}
const selectedDevice = ref({})
function closeAdddevice(e:any){ // 关闭新增设备弹窗
  selectedDevice.value = e
  let retrievedNode:any = graph.getCellById(nodeId.value)
   retrievedNode.attr('text/text', e.name)
   retrievedNode.attr('label/text', e.name)
   retrievedNode.store.data.deviceInfo = e
  saveDesign()
  isAdddevice.value = false;
}

const deviceInfo:any = ref({}) // 是否编辑设备

function EditdeviceClick(){ // 打开编辑设备弹窗
  deviceInfo.value = selectedNode.value.store.data.deviceInfo
  nodeId.value = selectedNode.value.id
  if(deviceInfo.value != null){
    deviceTypetype.value = deviceInfo.value.type
  }
  isEditdevice.value = true;
}
function closeEditdevice(e:any){ // 关闭编辑设备弹窗
  selectedDevice.value = e
  let retrievedNode:any = graph.getCellById(nodeId.value)
  retrievedNode.store.data.deviceInfo = e
   retrievedNode.attr('text/text', e.name)
   retrievedNode.attr('label/text', e.name)
  isEditdevice.value = false;
  saveDesign()
}

function dialogEditdevice(){ // 关闭设备弹窗
   isEditdevice.value = false;
}
const materialInfo:any = ref({}) // 是否物料信息
const selectedMaterial:any = ref({})


function MaterialModelClick(){ // 打开物料信息弹窗
   deviceInfo.value = selectedNode.value.store.data.deviceInfo
  materialInfo.value = {}
  if(selectedNode.value.store.data.materialInfo != null){
    materialInfo.value = selectedNode.value.store.data.materialInfo
  }
  
  nodeId.value = selectedNode.value.id
  if(materialInfo.value != null){
    deviceTypetype.value = materialInfo.value.type
  }
  isMaterialModel.value = true;
}
function dialogMaterialModel(){ // 关闭物料信息弹窗
  isMaterialModel.value = false;
}
function closeMaterialModel(e:any){ // 关闭物料信息弹窗
  if(e == false){
    isMaterialModel.value = false;
    return
  }

  selectedMaterial.value = e
  let retrievedNode:any = graph.getCellById(nodeId.value)
  retrievedNode.store.data.materialInfo = e
  saveDesign()
  isMaterialModel.value = false;
}

const isConnectingwire = ref(false) // 是否连接线
// const connectingwireData:any = ref([]) // 是否连接线数据

const isChangesettings = ref(false)
const changesettingsData:any = ref([]) // 是否变动设置
function dialogChangesettings(){ // 关闭变动设置弹窗
  isChangesettings.value = false;
}
function ChangesettingsClick(){ // 打开变动设置弹窗
  changesettingsData.value = []
  if(selectedNode.value.store.data.deviceInfo == null){
    ElMessage({
      type: "error",
      message: "请先添加设备信息",
    });
    return
  }
  if(selectedNode.value.store.data.materialInfo == null){
    ElMessage({
      type: "error",
      message: "请先添加物料信息",
    });
    return
  }
  deviceInfo.value = selectedNode.value.store.data.deviceInfo
  materialInfo.value = selectedNode.value.store.data.materialInfo

  if(selectedNode.value.store.data.changesettings != null){
    changesettingsData.value = selectedNode.value.store.data.changesettings
  }
  
  nodeId.value = selectedNode.value.id
  if(materialInfo.value != null){
    deviceTypetype.value = materialInfo.value.type
  }
  isChangesettings.value = true;
}

function closeChangesettingsModel(e:any){ // 关闭变动设置弹窗
  if(e == false){
    isChangesettings.value = false;
    return
  }
  selectedMaterial.value = e
  let retrievedNode:any = graph.getCellById(nodeId.value)
  retrievedNode.store.data.changesettings = e
  isChangesettings.value = false;
}

function setFormulaInit(formula:any) {
  // const formula = "【(圆柱槽B)*0.2+(环形槽A)*1.0+0.5】";
  // 匹配*号后、+或)前的数字（支持整数和小数）
  const regex = /([\*\/])(\d+\.?\d*)/g;
  const coefficients = [];
  let match;

  // 循环提取所有匹配项
  while ((match = regex.exec(formula)) !== null) {
    if(!isNaN(parseFloat(match[1]))){
       coefficients.push(parseFloat(match[1])); // 转为数字类型
    }else if(!isNaN(parseFloat(match[2]))){
      coefficients.push(parseFloat(match[2])); // 转为数字类型
    }
   
  }
    console.log(coefficients); // 输出: [0.2, 1.0]
  return coefficients

}

function getBias(formula:any){
  // 从后往前找最后一个+的位置
// 匹配最后一个+号后面的数字（支持整数、小数）
  if (formula.includes(' - ')){
    const parts = formula.split(' - ');
    // 处理以点开头的文件（如.gitignore）
     return parseFloat('-' + parts.pop().toLowerCase()) ;
  };
  if (formula.includes(' + ')){
    const parts = formula.split(' + ');
    // 处理以点开头的文件（如.gitignore）
    return parseFloat('+' + parts.pop().toLowerCase()) ;
  };
  return 0
  // 从最后一个点分割，取后面的部分


}

const styleInfo:any = ref({
  name: '',
  color: '#409EFF',
  line: '',
  width: '',
  remark: ''
})

function inputChange (e:any){
  let node:any =  graph.getCellById(nodeId.value)
  node.attr('label/text', e)
}
function lineChange(e:any){
  let node:any =  graph.getCellById(nodeId.value)
  if(e == '实线'){
    node.attr('body/strokeDasharray', '')
  }else{
    node.attr('body/strokeDasharray', '5 5')
  }
  
}
function widthChange(e:any){
  let node:any =  graph.getCellById(nodeId.value)
  node.attr('body/strokeWidth', e)
}

function colorChangs(e:any){
  let node:any =  graph.getCellById(nodeId.value)
  node.attr('body/stroke', e)
}

function remarkChange(e:any){
  let node:any =  graph.getCellById(nodeId.value)
  node.store.data.remark = e
}



function saveDesign() { // 保存设计
  try {
    // 获取画布内容并转换为JSON
    const designData:any = graph.toJSON()
    let cells:any = []
    if(designData !=null && designData.cells.length>0){
         cells = designData.cells
    }
    let  devices = []
    for(let i=0;i<cells.length;i++){
      if(cells[i].shape == 'custom-image'){
        let tempData:any = {}
        if(cells[i].changesettings && cells[i].changesettings.length > 0){
          for(let j=0;j<cells[i].changesettings.length;j++){
            if(cells[i].changesettings[j].formula != '' && cells[i].changesettings[j].formula != null){
              const key = cells[i].changesettings[j].name as string
              const unit = cells[i].changesettings[j].unit
              const name = cells[i].changesettings[j].name
              const delay= cells[i].changesettings[j].delay
              let tempSources = []

              for(let k=0;k<setFormulaInit(cells[i].changesettings[j].formula).length;k++){
         
                // name: '('+getName(key).name +')',
                // key: getName(key).key,
                // type: getName(key).type,
                // parentName : getName(key).type == 'device' ? '('+item.deviceName  +')' : '('+item.materialName +')',
                // parentId : getName(key).type == 'device' ? item.deviceId : item.materialId

                if(cells[i].changesettings[j].deviceMaterialData[k] == null){
                     return
                }
                
                tempSources.push({
                  entityType: cells[i].changesettings[j].deviceMaterialData[k].type, //圆柱槽B
                  entityId: cells[i].changesettings[j].deviceMaterialData[k].parentId  , //materialId :  cdeeca2e-1e0c-4bdd-b946-f347c104752c
                  property: cells[i].changesettings[j].deviceMaterialData[k].key, // 铀浓度（g/L）
                  coefficient: setFormulaInit(cells[i].changesettings[j].formula)[k], //0.2
                  delay: { enabled: true, time: cells[i].changesettings[j].deviceMaterialData[k].delay, unit: 's' } // 5
                })
              }
              tempData[key] = {
                name: tempData[key],
                type:'influence',
                unit:unit,
                base:0,
                bias: getBias(cells[i].changesettings[j].formula) || 0,
                sources:tempSources,
                expression:cells[i].changesettings[j].formula
              }
            }
           
          }
        }
        if(cells[i].deviceInfo != null){
          devices.push({
            deviceId:cells[i].id,
            name:cells[i].deviceInfo.name,
            type:cells[i].deviceInfo.type,
            properties:{},
            material: cells[i].materialInfo != null ? {
              materialId:cells[i].id,
              name:cells[i].materialInfo.name,
              properties:tempData
            }:{}
          })
        }
        
      }
    }
    console.log(devices)
    const topology = {
      projectId: projectInfo.value.projectId,
      name: projectInfo.value.name,
      devices:devices,
      pipelines:[],
      systemboundaries:[],
      globalDisplay:{
        device:{
          showProperties:[]
        },
        material:{
          showProperties:[]
        },
       
      },
      designData:cells
    }
    // 添加保存信息
    const saveData = {
      projectId: projectInfo.value.projectId,
      topology: JSON.stringify(topology)
    }
    updateProjects(saveData).then((res:any) => {
      if(res === true){
        ElMessage({
          type: "success",
          message: "保存成功",
        });
      }
    });
    // 返回保存的数据
    return saveData
  } catch (error) {
    console.error('保存设计失败:', error)
    return null
  }
}
const isBoundary = ref(false)
const boundaryClick = () => {
  isBoundary.value = !isBoundary.value
}
</script>
 
<template>
  <div class="app-layout" @click="isMenuShow = false">
    <div class="antvx6-header">
      <div class="header-left-box">
        <div class="return-icon-box" @click="closeAntvx6"  title="返回工作台">
          <img src="@/assets/x6/return.png" alt="图标" style="cursor: pointer;">
        </div>
        <div class="project-name">{{ projectInfo.name }}</div>
        <div class="return-icon-box" @click="analysisAdd"  title="新增模拟分析">
          <img src="@/assets/x6/add.png" alt="图标" style="cursor: pointer;">
        </div>
        <div class="return-icon-box" @click="simulationClick" title="历史模拟分析">
          <img src="@/assets/x6/history.png" alt="图标"  style="cursor: pointer;">
        </div>
      </div>
      <div class="header-content-box">
        <div class="operation-icon-box" @click="revokeClick">
          <img src="@/assets/x6/revoke.png">
          <div class="operation-icon-text">撤销</div>
        </div>
        <div class="operation-icon-box" @click="removeClick">
          <img src="@/assets/x6/redo.png">
          <div class="operation-icon-text">重做</div>
        </div>
        <div class="operation-icon-box" @click="bigClick">
          <img src="@/assets/x6/magnify.png">
          <div class="operation-icon-text">放大</div>
        </div>
        <div class="operation-icon-box"  @click="smallClick">
          <img src="@/assets/x6/reduce.png">
          <div class="operation-icon-text">缩小</div>
        </div>
        <div class="operation-icon-box"  @click="isDisplay = !isDisplay">
          <img v-if="isDisplay" src="@/assets/x6/display.png">
          <img v-else src="@/assets/x6/hide.png">
          <div class="operation-icon-text">显示</div>
        </div>

        <div class="operation-icon-box" style="width: 60px;" @click="boundaryClick">
          <img v-if="!isBoundary" src="@/assets/x6/display.png">
          <img v-else src="@/assets/x6/hide.png">
          <div v-if="!isBoundary" class="operation-icon-text">绘制边界</div>
          <div v-else class="operation-icon-text">停止绘制</div>
        </div>

        <div class="operation-icon-box" @click="ConnectingwireClick">
          <img src="@/assets/x6/line.png" style="margin: 5px  0;">
          <div class="operation-icon-text">连接线</div>
        </div>
        
        <div class="operation-icon-box" @click="saveDesign">
          <img src="@/assets/x6/save.png">
          <div class="operation-icon-text">保存</div>
        </div>
      </div>
      <div class="header-left-box"></div>
    </div>
    <div id="container" style="position: relative;">
      <div class="context-menu" v-if="isMenuShow" :style="{left: left +'px', top: top+'px'}">
          <img src="@/assets/x6/info.png" alt="图标" title="设备信息" style="cursor: pointer;" @click="EditdeviceClick">
          <img src="@/assets/x6/material.png" alt="图标" title="物料信息"  style="cursor: pointer;" @click="MaterialModelClick">
          <img src="@/assets/x6/change.png" alt="图标" title="变动设置"  style="cursor: pointer;" @click="ChangesettingsClick">
          <img src="@/assets/x6/copy.png" alt="图标" title="复制"  style="cursor: pointer;" @click="copyNode">
          <img src="@/assets/x6/del.png" alt="图标" title="删除"  style="cursor: pointer;"
          @click="deleteNode">
      </div>

      <div class="line-style-box">
        <!-- <div class="DisplaySettingsButton">显示设置</div> -->
         <div class="expansionandcontraction-box" v-if="isExpansionandcontraction == false" @click="isExpansionandcontraction = true">
          <img src="@/assets/x6/expansionandcontraction-left.png">
        </div>
        <div v-if="isExpansionandcontraction == true" style="display: flex;align-items: center;">
          <div class="expansionandcontraction-box" @click="isExpansionandcontraction = false">
            <img src="@/assets/x6/expansionandcontraction-right.png">
          </div>
          <div class="style-content-box">
            <div class="style-content-box-title">样式</div>
            <div class="style-content-box-display">
              <div class="style-content-box-key">名称</div>
               <el-input v-model="styleInfo.name" style="width:200px" placeholder="" @input="inputChange"></el-input>
            </div>
            <div class="style-content-box-display">
              <div class="style-content-box-key">线形</div>
              <el-select v-model="styleInfo.line" style="width:200px" @change="lineChange">
                <el-option  label="实线" value="实线" />
                <el-option  label="虚线" value="虚线" />
              </el-select>
            
            </div>
            <div class="style-content-box-display">
              <div class="style-content-box-key">线宽</div>
               <el-select v-model="styleInfo.width" style="width:200px" @change="widthChange">
               
                 <el-option  label="1" value="1" />
                <el-option  label="2" value="2" />
                <el-option  label="3" value="3" />
                <el-option  label="4" value="4" />
                <el-option  label="5" value="5" />
                <el-option  label="6" value="6" />
                <el-option  label="7" value="7" />
                <el-option  label="8" value="8" />
                <el-option  label="9" value="9" />
                <el-option  label="10" value="10" />
              </el-select>
            </div>
            <div class="style-content-box-display">
              <div class="style-content-box-key">边线颜色</div>
               <el-color-picker v-model="styleInfo.color" @change="colorChangs"></el-color-picker>
            </div>
            <div class="style-content-box-display" style="align-items: self-start;">
              <div class="style-content-box-key" style="padding-top: 5px;">描述信息</div>
               <el-input type="textarea" :rows="4" v-model="styleInfo.remark" style="width:200px" @input="remarkChange"></el-input>
            </div>
          </div>
        </div>
        
      </div>
    </div>
    <Createscenario v-if="dialogVisible" :projectInfo="projectInfo" @closeCreatescenario ="closeCreatescenario"/>
    <el-dialog v-model="isScenario" :close-on-click-modal="false"
      :modal="false" draggable :before-close="handleClose" title="历史模拟分析"
        append-to-body width="1142px">
      <ScenarioModel v-if="isScenario"  :projectInfo="projectInfo" ref="Scenario" />
    </el-dialog>
    <el-dialog v-model="isAdddevice" :close-on-click-modal="false"
      :modal="false" draggable :before-close="dialogAdddevice" title="添加设备"
        append-to-body width="1050px">
         <AdddeviceModel v-if="isAdddevice == true" :deviceId="nodeId" :projectInfo="projectInfo"
          :deviceTypetype="deviceTypetype" ref="Adddevice" @closeAdddevice="closeAdddevice"/>
    </el-dialog>

    <el-dialog v-model="isEditdevice" :close-on-click-modal="false" :modal="false" draggable :before-close="dialogEditdevice" title="设备信息"  append-to-body width="1050px">
      <EditdeviceModel v-if="isEditdevice == true" :deviceId="nodeId" :deviceInfo="deviceInfo"
        :deviceTypetype="deviceTypetype" ref="Editdevice" @closeEditdevice="closeEditdevice"/>
    </el-dialog>

    <el-dialog v-model="isMaterialModel" :close-on-click-modal="false" :modal="false" draggable :before-close="dialogMaterialModel" title="物料信息"  append-to-body width="1014px">
      <MaterialModels v-if="isMaterialModel == true" :materialId="nodeId" :projectInfo="projectInfo"
      :materialInfo="materialInfo" :deviceInfo="deviceInfo"  :deviceTypetype="deviceTypetype" ref="MaterialModel" @closeMaterialModel="closeMaterialModel"/>
    </el-dialog>


    <el-dialog v-model="isChangesettings" :close-on-click-modal="false" :modal="false" draggable :before-close="dialogChangesettings" title="变动设置"  append-to-body width="1014px">
      <ChangesettingsModels v-if="isChangesettings == true" :materialId="nodeId" :projectInfo="projectInfo" :changesettingsData="changesettingsData"
      :materialInfo="materialInfo" :deviceInfo="deviceInfo" ref="ChangesettingsModel" @closeChangesettingsModel="closeChangesettingsModel"/>
    </el-dialog>


    <el-dialog v-model="isConnectingwire" :close-on-click-modal="false" :modal="false" draggable :before-close="dialogConnectingwire" title="连接线"  append-to-body width="1014px">
      <div style="height: calc(100vh - 200px); overflow: auto;">
        <ConnectingwireModel v-if="isConnectingwire == true"  :connectingwireInfo="connectingwireInfo"
        @closeConnectingwireModel="closeConnectingwireModel"/>
      </div>
    </el-dialog>





  </div>
</template>
 
<style>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.app-layout {
  position: fixed;
  z-index: 10;
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
  font-family: 'Segoe UI', sans-serif;
}

.toolbar {
  padding: 10px;
  background-color: #f5f5f5;
  border-bottom: 1px solid #e0e0e0;
  display: flex;
  gap: 20px;
  flex-wrap: wrap;
}

.style-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-right: 20px;
}

.style-group h4 {
  margin: 0 0 5px 0;
  font-size: 14px;
  color: #333;
  font-weight: 600;
}

.toolbar button {
  padding: 8px 16px;
  border: 1px solid #d9d9d9;
  border-radius: 4px;
  background-color: #fff;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.3s;
  white-space: nowrap;
}

.toolbar button:hover {
  border-color: #1890ff;
  color: #1890ff;
}

.toolbar button:active {
  background-color: #f0f0f0;
}

/* Sidebar Styles */
.sidebar {
  width: 200px;
  background-color: #ffffff;
  border-right: 1px solid #e0e0e0;
  overflow-y: auto;
  padding: 16px;
  box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
}

.sidebar-section {
  margin-bottom: 24px;
}

.sidebar-section h3 {
  font-size: 14px;
  font-weight: 600;
  color: #333;
  margin-bottom: 12px;
  padding-bottom: 8px;
  border-bottom: 1px solid #f0f0f0;
}

.device-item {
  display: flex;
  align-items: center;
  padding: 10px;
  margin-bottom: 8px;
  background-color: #fafafa;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  cursor: grab;
  transition: all 0.2s ease;
}

.device-item:hover {
  background-color: #f0f5ff;
  border-color: #1890ff;
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(24, 144, 255, 0.2);
}

.device-item:active {
  cursor: grabbing;
}

.device-icon {
  font-size: 24px;
  margin-right: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
}

.device-name {
  font-size: 13px;
  color: #333;
  font-weight: 500;
}

/* Graph Container Styles */
.graph-container {
  flex: 1;
  position: relative;
  background-color: #fafafa;
  overflow: hidden;
  width: 100%;
  height: 100%;

}

/* Drag and drop visual feedback */
.graph-container.drag-over {
  background-color: #e6f7ff;
  border: 2px dashed #1890ff;
}

.context-menu {
  position: absolute;
  z-index: 100;
  background-color: #fff;
  border: 1px solid #dfe3e8;
  border-radius: 4px;
  box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.15);
  width: 240px;
  height: 40px;
  display: flex;
  justify-content: space-around;
  align-items: center;
}
</style>
<style>
.x6-widget-stencil-content {
  top: 0px !important;
}

.antvx6-header {
  width: 100%;
  height: 60px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px;
  background-color: #ffffff;
  border-bottom: 1px solid #e0e0e0;
}

.header-left-box {
  width: 400px;
  height: 60px;
  display: flex;
  align-items: center;
}

.header-content-box {
  display: flex;
  align-items: center;
}

.return-icon-box {
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  margin-right: 10px;
}

.return-icon-box:hover {
  background-color: #eeeeee;
  border-radius: 4px;
}

.antvx6-header .project-name {
  font-family: 'Arial Negreta', 'Arial Normal', 'Arial';
  font-weight: 700;
  font-style: normal;
  font-size: 16px;
  color: #333333;
  margin-right: 10px;
}

.antvx6-header .operation-icon-box {
  width: 46px;
  height: 46px;
  display: flex;
  align-content: center;
  justify-content: center;
  flex-wrap: wrap;
  cursor: pointer;
  margin-right: 20px;
  font-family: '微软雅黑';
  font-weight: 400;
  font-style: normal;
  font-size: 12px;
  color: #4B4B4B;
  padding-top: 5px;
}

.antvx6-header .operation-icon-box:hover {
  background-color: #eeeeee;
  border-radius: 4px;
}

.operation-icon-text {
  width: 100%;
  text-align: center;
  padding-top: 5px;
}
.line-style-box{
  position: absolute;
  right: 0;
  height: 100%;
  /* width: 100px; */
  /* background-color: #d9d9d9; */
  z-index: 10;
  display: flex;
  align-items: center;
}
.expansionandcontraction-box{
  width:15px;
  height: 64px;
  background-color: #ffffff;
  border: 1px solid #cfcfcf;

  border-radius: 10px 0 0 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.style-content-box{
  width: 300px;
  height: calc(100vh - 60px);
  border: 1px solid #cfcfcf;
  border-top: none;
  border-right: none;
  background: #fff;
}
.style-content-box-title{
  width: 100%;
  height: 40px;
  line-height: 40px;
  text-align: left;
  font-size: 14px;
  font-family: 'Arial Negreta', 'Arial Normal', 'Arial';
  font-weight: 700;
  font-style: normal;
  font-size: 14px;
  color: #282828;
  background-color: rgba(255, 255, 255, 1);
  box-sizing: border-box;
  border-bottom:1px solid rgba(238, 238, 238, 1);
  padding-left: 15px;
}

.DisplaySettingsButton{
  position: absolute;
  left: -100px;
  top: 20px;
  width: 100px;
  height: 40px;
  line-height: 40px;
  text-align: center;
  font-size: 14px;
  font-family: 'Arial Negreta', 'Arial Normal', 'Arial';
  font-weight: 400;
  font-style: normal;
  font-size: 14px;
  color: #282828;
  background-color: rgba(255, 255, 255, 1);
  border: none;
  border-radius: 4px;
  box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.1);
  cursor: pointer;
}

.x6-graph-grid {
  background-image: none !important;
}
.style-content-box-display{
  display: flex;
  align-items: center;
  padding-top: 20px;
  
}
.style-content-box-key{
  width: 80px;
  text-align: right;
  font-family: '微软雅黑';
  font-weight: 400;
  font-style: normal;
  font-size: 14px;
  color: #808080;
  padding-right: 10px;
}

.x6-widget-stencil .x6-node.x6-node-immovable{
  cursor: pointer;
}
</style>