antv/g6 图谱封装配置(二)

news2025/5/24 15:59:01

继上次实现图谱后,后续发现如果要继续加入不同样式的图谱实现起来太过麻烦,因此考虑将配置项全部提取封装到js文件中,图谱组件只专注于实现各种不同的组件,其中主要封装的点就是各个节点的横坐标(x),纵坐标(y),以及节点宽(width),节点高(height),节点数组(nodes)和节点相连的边(edges),其他如颜色,字体大小等

封装效果如下:

mapData对象中保存每种金属对应的产业链,通过判断来选择取哪部分数据去显示对应的图谱,比如MapData['CU']即为显示铜的图谱,mapHeight为图谱的默认高度,mapPadding为图谱的父节点要显示的padding,因为图谱不一定需要占满显示,因此加了padding,desc为图谱的描述,nodes和edges为节点和边

实现效果如下:

其中mapData.js内容:

//有色金属
export const mapData = {
  CU: {
    //铜
    mapHeight: 450,
    mapPadding: 35,
    desc: '<span>铜产业链逻辑:</span>铜产业链分为上、中、下游。上游主要是采选、冶炼,中游是铜材加工,下游是终端消费。铜价主要受产业供需和宏观因素两个方面影响,但从研究分析上来讲产业可看供给,需求看宏观。宏观因素(核心):经济周期、政策周期、通胀/通缩;基本面因素:供需平衡表、库存周期、价差结构与区域溢价(短期)其他因素:商品大环境、资金面(博弈)、情绪面(事件、避险)',
    nodes: [
      {
        id: 'node1',
        x: 138,
        y: 135,
        width: 176,
        height: 60,
        label: '全球铜矿山产能',
        breedCode: 'CU',
        indexCode: 'OFFRDE0678557898',
        text: '全球铜矿山产能',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node2',
        x: 138,
        y: 209,
        width: 176,
        height: 60,
        label: '全球铜矿产能利用率',
        breedCode: 'CU',
        indexCode: 'ID00303168',
        text: '全球铜矿产能利用率',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node3',
        x: 394,
        y: 172,
        width: 134,
        height: 60,
        label: '全球铜矿供应',
        breedCode: 'CU',
        indexCode: 'OFFRDE0789849953',
        text: '全球铜矿供应',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node4',
        x: 394,
        y: 264,
        width: 134,
        height: 60,
        label: '加工费',
        breedCode: 'CU',
        indexCode: 'OFFRDE0407946063',
        text: '加工费',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node5',
        x: 394,
        y: 357,
        width: 134,
        height: 60,
        label: '国内铜矿供应',
        breedCode: 'CU',
        indexCode: 'OFFRDE0503146446',
        text: '国内铜矿供应',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node6',
        x: 591,
        y: 172,
        width: 158,
        height: 60,
        label: '精炼铜供应',
        breedCode: 'CU',
        indexCode: 'ID00407927',
        text: '精炼铜供应',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node7',
        x: 591,
        y: 234,
        width: 158,
        height: 40,
        label: '再生(废杂)铜供应',
        text: '各类政策因素',
        breedCode: 'JM',
        text: '再生(废杂)铜供应',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node8',
        x: 591,
        y: 286,
        width: 158,
        height: 40,
        label: '各类政策因素',
        text: '各类政策因素',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node9',
        x: 838,
        y: 31,
        width: 134,
        height: 60,
        label: '全球社会库存',
        text: '全球社会库存',
        breedCode: 'CU',
        indexCode: 'OFFRDE0416122129',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node10',
        x: 984,
        y: 31,
        width: 134,
        height: 60,
        label: 'LME铜库存',
        text: 'LME铜库存',
        breedCode: 'CU',
        indexCode: 'OFFRDE0099802675',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node11',
        x: 1130,
        y: 31,
        width: 134,
        height: 60,
        label: 'SHFE铜库存',
        text: 'SHFE铜库存',
        breedCode: 'CU',
        indexCode: 'OFFRDE0900823051',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node12',
        x: 1281,
        y: 31,
        width: 145,
        height: 60,
        label: 'COMEX铜库存',
        text: 'COMEX铜库存',
        breedCode: 'CU',
        indexCode: 'OFFRDE0470038275',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node13',
        x: 838,
        y: 136,
        width: 134,
        height: 60,
        label: '总库存变化',
        breedCode: 'CU',
        indexCode: 'OFFRDE0704512926',
        text: '总库存变化',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node14',
        x: 838,
        y: 234,
        width: 134,
        height: 60,
        label: '铜现货价',
        breedCode: 'CU',
        indexCode: 'ID00303957',
        text: '铜现货价',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node15',
        x: 838,
        y: 326,
        width: 134,
        height: 60,
        label: '比价与价差',
        text: '比价与价差',
        indexCode: 'FU00015882',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node16',
        x: 838,
        y: 418,
        width: 134,
        height: 60,
        label: '铜期货价',
        text: '铜期货价',
        indexCode: 'FU00015764',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node17',
        x: 1023,
        y: 136,
        width: 134,
        height: 60,
        label: '库存消费比',
        breedCode: 'CU',
        indexCode: 'OFFRDE0881777811',
        text: '库存消费比',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node18',
        x: 1023,
        y: 234,
        width: 134,
        height: 60,
        label: '表观需求',
        breedCode: 'CU',
        indexCode: 'ID01167294',
        text: '表观需求',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node19',
        x: 1023,
        y: 326,
        width: 134,
        height: 40,
        label: '贸易流向',
        text: '贸易流向',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node20',
        x: 1023,
        y: 418,
        width: 134,
        height: 40,
        label: '资金因素',
        text: '资金因素',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node21',
        x: 1257,
        y: 157,
        width: 134,
        height: 40,
        label: '房地产开工',
        text: '房地产开工',
        type: 'word-rect',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node22',
        x: 1257,
        y: 209,
        width: 134,
        height: 40,
        label: '汽车产销',
        text: '汽车产销',
        type: 'word-rect',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node23',
        x: 1257,
        y: 261,
        width: 134,
        height: 40,
        label: '基建投资',
        text: '基建投资',
        type: 'word-rect',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node24',
        x: 1257,
        y: 313,
        width: 134,
        height: 40,
        label: '家电等终端',
        text: '家电等终端',
        type: 'word-rect',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
    ],
    edges: [
      { source: 'node1', target: 'node3' },
      { source: 'node2', target: 'node3' },
      { source: 'node3', target: 'node4', type: 'hvh3' },
      { source: 'node4', target: 'node5', type: 'hvh3' },
      { source: 'node3', target: 'node6' },

      { source: 'node6', target: 'node14' },
      { source: 'node7', target: 'node14' },
      { source: 'node8', target: 'node14' },

      { source: 'node9', target: 'node13', type: 'hvh3' },
      {
        source: 'node10',
        target: 'node13',
        type: 'hvh3',
        sourceAnchor: 2,
        targetAnchor: 0,
      },
      {
        source: 'node11',
        target: 'node13',
        type: 'hvh3',
        sourceAnchor: 2,
        targetAnchor: 0,
      },
      {
        source: 'node12',
        target: 'node13',
        type: 'hvh3',
        sourceAnchor: 2,
        targetAnchor: 0,
      },

      { source: 'node13', target: 'node17' },
      { source: 'node13', target: 'node14', type: 'hvh3' },

      { source: 'node14', target: 'node18' },
      { source: 'node14', target: 'node15', type: 'hvh3' },

      { source: 'node15', target: 'node19' },
      { source: 'node15', target: 'node16', type: 'hvh3' },

      { source: 'node16', target: 'node20' },

      { source: 'node18', target: 'node21' },
      { source: 'node18', target: 'node22' },
      { source: 'node18', target: 'node23' },
      { source: 'node18', target: 'node24' },
    ],
  },
  AL: {
    //铝
    mapHeight: 229,
    mapPadding: 25,
    desc: '<span>铝产业链逻辑:</span>铝的产业链主要由铝土矿开采、氧化铝提炼、原铝生产和铝材加工四个环节组成。首先是铝土矿开采,再通过对铝土矿溶解、过滤、酸化和灼烧等工序提炼出氧化铝,然后通过电解熔融的方式制备电解铝。电解铝经过重熔提纯后可进一步加工成各种铝材、铝合金以及铝粉等。铝的上游产业链包括铝土矿开采、氧化铝提炼和原铝生产。原铝经过加工,制成铝加工材,应用于下游各行各业。',
    nodes: [
      {
        id: 'block1',
        x: 176,
        y: 120,
        width: 353,
        height: 218,
        type: 'block-rect',
        label: '上游',
      },
      {
        id: 'block2',
        x: 530,
        y: 120,
        width: 330,
        height: 218,
        type: 'block-rect',
        label: '中游',
      },
      {
        id: 'block3',
        x: 1020,
        y: 120,
        width: 626,
        height: 218,
        type: 'block-rect',
        label: '下游',
      },
      {
        id: 'node1',
        x: 80,
        y: 63,
        width: 134,
        height: 60,
        label: '铝土矿',
        breedCode: 'AL',
        indexCode: 'OFFRDE0116552998',
        text: '铝土矿',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node2',
        x: 80,
        y: 127,
        width: 134,
        height: 40,
        label: '煤炭',
        text: '煤炭',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node3',
        x: 80,
        y: 179,
        width: 134,
        height: 40,
        label: '石灰石和碱',
        text: '石灰石和碱',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node4',
        x: 274,
        y: 127,
        width: 134,
        height: 60,
        label: '氧化铝',
        breedCode: 'AL',
        indexCode: 'ID00188139',
        text: '氧化铝',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node5',
        x: 444,
        y: 75,
        width: 132,
        height: 40,
        label: '电力',
        text: '电力',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node6',
        x: 444,
        y: 127,
        width: 132,
        height: 40,
        label: '氧化铝',
        text: '氧化铝',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node7',
        x: 444,
        y: 185,
        width: 132,
        height: 52,
        label: '碳素阳极、氟化盐、冰晶石等',
        text: '碳素阳极、氟化盐、冰晶石等',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node8',
        x: 616,
        y: 127,
        width: 134,
        height: 60,
        label: '电解铝',
        breedCode: 'AL',
        indexCode: 'ID00188823',
        text: '电解铝',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node9',
        x: 795,
        y: 127,
        width: 134,
        height: 60,
        label: '铝合金锭',
        breedCode: 'AL',
        indexCode: 'ID01224399',
        text: '铝合金锭',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node10',
        x: 970,
        y: 63,
        width: 74,
        height: 40,
        label: '挤压材',
        text: '挤压材',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node11',
        x: 970,
        y: 127,
        width: 74,
        height: 40,
        label: '压制材',
        text: '压制材',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node12',
        x: 970,
        y: 191,
        width: 74,
        height: 40,
        label: '铸造材',
        text: '铸造材',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node13',
        x: 1106,
        y: 63,
        width: 116,
        height: 52,
        label: '管、棒、型、线等',
        text: '管、棒、型、线等',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node14',
        x: 1106,
        y: 127,
        width: 116,
        height: 52,
        label: '板、带、片、箔等',
        text: '板、带、片、箔等',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node15',
        x: 1106,
        y: 191,
        width: 116,
        height: 52,
        label: '汽车轮毂、发动机等',
        text: '汽车轮毂、发动机等',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node16',
        x: 1263,
        y: 63,
        width: 116,
        height: 52,
        label: '建筑、光伏、线缆',
        text: '建筑、光伏、线缆',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node17',
        x: 1263,
        y: 127,
        width: 116,
        height: 52,
        label: '包装、汽车、家电',
        text: '包装、汽车、家电',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node18',
        x: 1263,
        y: 191,
        width: 116,
        height: 52,
        label: '汽车、五金、电器电子',
        text: '汽车、五金、电器电子',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
    ],
    edges: [
      { source: 'node1', target: 'node4' },
      { source: 'node2', target: 'node4' },
      { source: 'node3', target: 'node4' },

      { source: 'node4', target: 'node6' },

      { source: 'node5', target: 'node8' },
      { source: 'node6', target: 'node8' },
      { source: 'node7', target: 'node8' },

      { source: 'node8', target: 'node9' },

      { source: 'node9', target: 'node10' },
      { source: 'node9', target: 'node11' },
      { source: 'node9', target: 'node12' },

      { source: 'node10', target: 'node13' },
      { source: 'node11', target: 'node14' },
      { source: 'node12', target: 'node15' },

      { source: 'node13', target: 'node16' },
      { source: 'node14', target: 'node17' },
      { source: 'node15', target: 'node18' },
    ],
  },
  AO: {
    //氧化铝,与铝一样
    mapHeight: 229,
    mapPadding: 25,
    desc: '<span>铝产业链逻辑:</span>铝的产业链主要由铝土矿开采、氧化铝提炼、原铝生产和铝材加工四个环节组成。首先是铝土矿开采,再通过对铝土矿溶解、过滤、酸化和灼烧等工序提炼出氧化铝,然后通过电解熔融的方式制备电解铝。电解铝经过重熔提纯后可进一步加工成各种铝材、铝合金以及铝粉等。铝的上游产业链包括铝土矿开采、氧化铝提炼和原铝生产。原铝经过加工,制成铝加工材,应用于下游各行各业。',
    nodes: [
      {
        id: 'block1',
        x: 176,
        y: 120,
        width: 353,
        height: 218,
        type: 'block-rect',
        label: '上游',
      },
      {
        id: 'block2',
        x: 530,
        y: 120,
        width: 330,
        height: 218,
        type: 'block-rect',
        label: '中游',
      },
      {
        id: 'block3',
        x: 1020,
        y: 120,
        width: 626,
        height: 218,
        type: 'block-rect',
        label: '下游',
      },
      {
        id: 'node1',
        x: 80,
        y: 63,
        width: 134,
        height: 60,
        label: '铝土矿',
        breedCode: 'AL',
        indexCode: 'OFFRDE0116552998',
        text: '铝土矿',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node2',
        x: 80,
        y: 127,
        width: 134,
        height: 40,
        label: '煤炭',
        text: '煤炭',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node3',
        x: 80,
        y: 179,
        width: 134,
        height: 40,
        label: '石灰石和碱',
        text: '石灰石和碱',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node4',
        x: 274,
        y: 127,
        width: 134,
        height: 60,
        label: '氧化铝',
        breedCode: 'AL',
        indexCode: 'ID00188139',
        text: '氧化铝',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node5',
        x: 444,
        y: 75,
        width: 132,
        height: 40,
        label: '电力',
        text: '电力',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node6',
        x: 444,
        y: 127,
        width: 132,
        height: 40,
        label: '氧化铝',
        text: '氧化铝',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node7',
        x: 444,
        y: 185,
        width: 132,
        height: 52,
        label: '碳素阳极、氟化盐、冰晶石等',
        text: '碳素阳极、氟化盐、冰晶石等',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node8',
        x: 616,
        y: 127,
        width: 134,
        height: 60,
        label: '电解铝',
        breedCode: 'AL',
        indexCode: 'ID00188823',
        text: '电解铝',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node9',
        x: 795,
        y: 127,
        width: 134,
        height: 60,
        label: '铝合金锭',
        breedCode: 'AL',
        indexCode: 'ID01224399',
        text: '铝合金锭',
        dataValue: '-',
        chg: '-',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
      },
      {
        id: 'node10',
        x: 970,
        y: 63,
        width: 74,
        height: 40,
        label: '挤压材',
        text: '挤压材',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node11',
        x: 970,
        y: 127,
        width: 74,
        height: 40,
        label: '压制材',
        text: '压制材',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node12',
        x: 970,
        y: 191,
        width: 74,
        height: 40,
        label: '铸造材',
        text: '铸造材',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node13',
        x: 1106,
        y: 63,
        width: 116,
        height: 52,
        label: '管、棒、型、线等',
        text: '管、棒、型、线等',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node14',
        x: 1106,
        y: 127,
        width: 116,
        height: 52,
        label: '板、带、片、箔等',
        text: '板、带、片、箔等',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node15',
        x: 1106,
        y: 191,
        width: 116,
        height: 52,
        label: '汽车轮毂、发动机等',
        text: '汽车轮毂、发动机等',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node16',
        x: 1263,
        y: 63,
        width: 116,
        height: 52,
        label: '建筑、光伏、线缆',
        text: '建筑、光伏、线缆',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node17',
        x: 1263,
        y: 127,
        width: 116,
        height: 52,
        label: '包装、汽车、家电',
        text: '包装、汽车、家电',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node18',
        x: 1263,
        y: 191,
        width: 116,
        height: 52,
        label: '汽车、五金、电器电子',
        text: '汽车、五金、电器电子',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
    ],
    edges: [
      { source: 'node1', target: 'node4' },
      { source: 'node2', target: 'node4' },
      { source: 'node3', target: 'node4' },

      { source: 'node4', target: 'node6' },

      { source: 'node5', target: 'node8' },
      { source: 'node6', target: 'node8' },
      { source: 'node7', target: 'node8' },

      { source: 'node8', target: 'node9' },

      { source: 'node9', target: 'node10' },
      { source: 'node9', target: 'node11' },
      { source: 'node9', target: 'node12' },

      { source: 'node10', target: 'node13' },
      { source: 'node11', target: 'node14' },
      { source: 'node12', target: 'node15' },

      { source: 'node13', target: 'node16' },
      { source: 'node14', target: 'node17' },
      { source: 'node15', target: 'node18' },
    ],
  },
  PB: {
    //铅
    mapHeight: 501,
    mapPadding: 100,
    desc: '',
    nodes: [
      {
        id: 'block1',
        x: 165,
        y: 255,
        width: 328,
        height: 490,
        type: 'block-rect',
        label: '原料端',
        labelCfg: { style: { width: 52, height: 20 } },
      },
      {
        id: 'block2',
        x: 475,
        y: 255,
        width: 270,
        height: 490,
        type: 'block-rect',
        label: '冶炼端',
        labelCfg: { style: { width: 52, height: 20 } },
      },
      {
        id: 'block3',
        x: 751,
        y: 255,
        width: 258,
        height: 490,
        type: 'block-rect',
        label: '初端下游产品',
        labelCfg: { style: { width: 88, height: 20 } },
      },
      {
        id: 'block4',
        x: 1037,
        y: 255,
        width: 290,
        height: 490,
        type: 'block-rect',
        label: '终端需求',
        labelCfg: { style: { width: 64, height: 20 } },
      },
      {
        id: 'node1',
        x: 50,
        y: 183,
        width: 74,
        height: 40,
        label: '铅原矿',
        text: '铅原矿',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node2',
        x: 164,
        y: 183,
        width: 74,
        height: 40,
        label: '铅精矿',
        text: '铅精矿',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node3',
        x: 279,
        y: 183,
        width: 74,
        height: 40,
        label: '粗铅',
        text: '粗铅',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node4',
        x: 432,
        y: 131,
        width: 74,
        height: 40,
        label: '阳极泥',
        text: '阳极泥',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node5',
        x: 554,
        y: 131,
        width: 88,
        height: 40,
        label: '金银锡锑',
        text: '金银锡锑',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node6',
        x: 554,
        y: 183,
        width: 88,
        height: 40,
        label: '原生铅',
        text: '原生铅',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node7',
        x: 778,
        y: 104,
        width: 156,
        height: 40,
        label: '其他',
        text: '其他',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node8',
        x: 778,
        y: 156,
        width: 156,
        height: 40,
        label: '蓄电池企业 (>85%)',
        text: '蓄电池企业 (>85%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
      },
      {
        id: 'node9',
        x: 778,
        y: 312,
        width: 156,
        height: 40,
        label: '氧化铅',
        text: '氧化铅',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node10',
        x: 778,
        y: 364,
        width: 156,
        height: 40,
        label: '铅合金',
        text: '铅合金',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node11',
        x: 778,
        y: 416,
        width: 156,
        height: 40,
        label: '铅材',
        text: '铅材',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node12',
        x: 1044,
        y: 52,
        width: 172,
        height: 40,
        label: '汽车启动',
        text: '汽车启动',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node13',
        x: 1044,
        y: 104,
        width: 172,
        height: 40,
        label: '电动车',
        text: '电动车',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node14',
        x: 1044,
        y: 156,
        width: 172,
        height: 40,
        label: '通信基站',
        text: '通信基站',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node15',
        x: 1044,
        y: 208,
        width: 172,
        height: 40,
        label: '电力',
        text: '电力',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node16',
        x: 1044,
        y: 260,
        width: 172,
        height: 40,
        label: '其他',
        text: '其他',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node17',
        x: 1044,
        y: 312,
        width: 172,
        height: 40,
        label: '铝盐、稳定剂、助溶剂',
        text: '铝盐、稳定剂、助溶剂',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node18',
        x: 1044,
        y: 364,
        width: 172,
        height: 40,
        label: '轴承、焊料、铅弹',
        text: '轴承、焊料、铅弹',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node19',
        x: 1044,
        y: 416,
        width: 172,
        height: 40,
        label: '铅板、铅管、电缆护套',
        text: '铅板、铅管、电缆护套',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node20',
        x: 778,
        y: 468,
        width: 156,
        height: 40,
        label: '回收',
        text: '回收',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FFF4F4 1:#FFE1E1',
        strock: '#F8C3C3',
      },
      {
        id: 'node21',
        x: 49,
        y: 312,
        width: 74,
        height: 40,
        label: '铅废料',
        text: '铅废料',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FFF4F4 1:#FFE1E1',
        strock: '#F8C3C3',
      },
      {
        id: 'node22',
        x: 279,
        y: 312,
        width: 74,
        height: 40,
        label: '还原铅',
        text: '还原铅',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FFF4F4 1:#FFE1E1',
        strock: '#F8C3C3',
      },
      {
        id: 'node23',
        x: 554,
        y: 312,
        width: 88,
        height: 40,
        label: '再生铅',
        text: '再生铅',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FFF4F4 1:#FFE1E1',
        strock: '#F8C3C3',
      },
    ],
    edges: [
      { source: 'node1', target: 'node2' },
      { source: 'node2', target: 'node3' },
      { source: 'node3', target: 'node4' },
      {
        source: 'node3',
        target: 'node6',
        label: '火法',
        subLabel: '电解',
        labelCfg: { style: { fontSize: 12, fill: '#245A9A' } },
        subLabelCfg: { style: { fontSize: 12, fill: '#245A9A' } },
      },
      { source: 'node4', target: 'node5' },

      { source: 'node6', target: 'node7' },
      { source: 'node6', target: 'node8' },

      {
        source: 'node6',
        target: 'node9',
        sourceAnchor: 1,
        targetAnchor: 3,
      },
      {
        source: 'node6',
        target: 'node10',
        sourceAnchor: 1,
        targetAnchor: 3,
      },
      {
        source: 'node6',
        target: 'node11',
        sourceAnchor: 1,
        targetAnchor: 3,
      },

      { source: 'node8', target: 'node12' },
      { source: 'node8', target: 'node13' },
      { source: 'node8', target: 'node14' },
      { source: 'node8', target: 'node15' },
      { source: 'node8', target: 'node16' },

      { source: 'node9', target: 'node17' },
      { source: 'node10', target: 'node18' },
      { source: 'node11', target: 'node19' },

      {
        source: 'node12',
        target: 'node20',
        sourceAnchor: 1,
        targetAnchor: 1,
        type: 'hvh_custom',
        direction: 'left',
        path: [
          [1150, 52],
          [1150, 234],
          [1170, 234],
          [1170, 468],
        ],
      },

      {
        source: 'node19',
        target: 'node20',
        sourceAnchor: 1,
        targetAnchor: 1,
        type: 'hvh_custom',
        path: [
          [1150, 416],
          [1150, 234],
          [1170, 234],
          [1170, 468],
        ],
      },

      {
        source: 'node20',
        target: 'node21',
        sourceAnchor: 3,
        targetAnchor: 2,
        type: 'hvh2',
        corner: true,
      },
      {
        source: 'node21',
        target: 'node22',
        label: '火法',
        subLabel: '湿法',
        labelCfg: { style: { fontSize: 12, fill: '#245A9A' } },
        subLabelCfg: { style: { fontSize: 12, fill: '#245A9A' } },
      },
      { source: 'node22', target: 'node23' },
    ],
  },
  ZN: {
    //锌
    mapHeight: 323,
    mapPadding: 0,
    desc: '<span>锌产业链逻辑:</span>锌生产过程以及实际的行业结构来看,行业价值链主要有三个主体:矿山、锌冶炼商、锌消费企业。矿山负责勘查和开采锌精矿,并将锌精矿出售给下游的锌冶炼企业,锌冶炼企业根据锌消费市场的需求冶炼出符合市场需要的精炼锌以及相关的副产品,锌的最终消费企业从锌冶炼企业购买所需的锌产品。价值链的分析主要侧重在各环节成本、收入的分析,由于矿山的收入基本等于冶炼商原料采购的成本,因此锌精矿的定价机制是研究各环节盈利能力的关键所在。由于锌精矿以加工费(TC/RC)的方式核算,因此锌金属价格和加工费(TC/RC)的高低是影响矿山和冶炼商收入的主要因素。',
    nodes: [
      {
        id: 'block1',
        x: 878.5,
        y: 54,
        width: 411,
        height: 108,
        type: 'block-rect',
        label: '',
      },
      {
        id: 'block2',
        x: 1155.5,
        y: 265,
        width: 425,
        height: 108,
        type: 'block-rect',
        label: '',
      },
      {
        id: 'block3',
        x: 696,
        y: 265,
        width: 454,
        height: 108,
        type: 'custom-node',
        label: '',
        strock: '#BCD0EE',
        shadowColor: 'rgba(54,78,128,0.1)',
        pieceList: [
          {
            type: 'rect',
            x: -227,
            y: -54,
            width: 26,
            height: 108,
            fill: '#4580D9',
            stroke: '',
            lineWidth: 0,
            radius: [4, 0, 0, 4],
            label: '一吨锌锭成本',
          },
          {
            type: 'text',
            x: -220,
            y: -40,
            label: '一',
            fontSize: 12,
            align: 'left',
            fill: '#fff',
            weight: 400
          },
          {
            type: 'text',
            x: -220,
            y: -24,
            label: '吨',
            fontSize: 12,
            align: 'left',
            fill: '#fff',
            weight: 400
          },
          {
            type: 'text',
            x: -220,
            y: -8,
            label: '锌',
            fontSize: 12,
            align: 'left',
            fill: '#fff',
            weight: 400
          },
          {
            type: 'text',
            x: -220,
            y: 8,
            label: '锭',
            fontSize: 12,
            align: 'left',
            fill: '#fff',
            weight: 400
          },
          {
            type: 'text',
            x: -220,
            y: 24,
            label: '成',
            fontSize: 12,
            align: 'left',
            fill: '#fff',
            weight: 400
          },
          {
            type: 'text',
            x: -220,
            y: 40,
            label: '本',
            fontSize: 12,
            align: 'left',
            fill: '#fff',
            weight: 400
          },
          {
            type: 'text',
            x: -191,
            y: -35,
            label: '原料成本:70%-80%、加工成本:20%-30%',
            fontSize: 12,
            align: 'left',
            fill: '#D91212',
            weight: 400
          },
          {
            type: 'text',
            x: -191,
            y: -11,
            label: '锌精矿:1.042吨   用电量:3500-3700kwh  硫酸:300-400kg',
            fontSize: 12,
            align: 'left',
            fill: '#333',
            weight: 400
          },
          {
            type: 'text',
            x: -191,
            y: 11,
            label: '锌辅料:250元   人工费:300-500元   锌粉:(55-65kg)*40%',
            fontSize: 12,
            align: 'left',
            fill: '#333',
            weight: 400
          },
          {
            type: 'text',
            x: -191,
            y: 33,
            label: '其他成本:(20-30%) ',
            fontSize: 12,
            align: 'left',
            fill: '#333',
            weight: 400
          },
        ]

      },
      {
        id: 'node1',
        x: 37,
        y: 89,
        width: 74,
        height: 40,
        label: '锌矿石',
        text: '锌矿石',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node2',
        x: 152,
        y: 89,
        width: 74,
        height: 40,
        label: '锌精矿',
        text: '锌精矿',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node3',
        x: 290,
        y: 89,
        width: 88,
        height: 40,
        label: '加工酸浸',
        text: '加工酸浸',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node4',
        x: 290,
        y: 159,
        width: 88,
        height: 40,
        label: '焙烧',
        text: '焙烧',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node5',
        x: 290,
        y: 230,
        width: 88,
        height: 40,
        label: '常压酸浸',
        text: '常压酸浸',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node6',
        x: 412,
        y: 159,
        width: 74,
        height: 40,
        label: '浸出液',
        text: '浸出液',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node7',
        x: 527,
        y: 159,
        width: 74,
        height: 40,
        label: '净化',
        text: '净化',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node8',
        x: 642,
        y: 159,
        width: 74,
        height: 40,
        label: '电积',
        text: '电积',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node9',
        x: 757,
        y: 159,
        width: 74,
        height: 40,
        label: '电解锌',
        text: '电解锌',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node10',
        x: 879,
        y: 159,
        width: 88,
        height: 40,
        label: '初级消费',
        text: '初级消费',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node11',
        x: 1155,
        y: 159,
        width: 88,
        height: 40,
        label: '终端消费',
        text: '终端消费',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node12',
        x: 754.5,
        y: 28,
        width: 147,
        height: 40,
        label: '镀锌 (30%)',
        text: '镀锌 (30%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node13',
        x: 754.5,
        y: 80,
        width: 147,
        height: 40,
        label: '压铸锌合金 (30%)',
        text: '压铸锌合金 (30%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node14',
        x: 899.5,
        y: 28,
        width: 119,
        height: 40,
        label: '黄铜 (22%)',
        text: '黄铜 (22%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node15',
        x: 899.5,
        y: 80,
        width: 119,
        height: 40,
        label: '氧化锌 (22%)',
        text: '氧化锌 (22%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node16',
        x: 1023.5,
        y: 28,
        width: 105,
        height: 40,
        label: '电池 (22%)',
        text: '电池 (22%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node17',
        x: 1023.5,
        y: 80,
        width: 105,
        height: 40,
        label: '其它 (22%)',
        text: '其它 (22%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node18',
        x: 1038.5,
        y: 239,
        width: 175,
        height: 40,
        label: '房地产及建筑业 (30%)',
        text: '房地产及建筑业 (30%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node19',
        x: 1038.5,
        y: 291,
        width: 175,
        height: 40,
        label: '基础设施建设 (22%)',
        text: '基础设施建设 (22%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node20',
        x: 1190.5,
        y: 239,
        width: 105,
        height: 40,
        label: '锌合金 (22%)',
        text: '锌合金 (22%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node21',
        x: 1190.5,
        y: 291,
        width: 105,
        height: 40,
        label: '汽车 (22%)',
        text: '汽车 (22%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node22',
        x: 1307.5,
        y: 239,
        width: 105,
        height: 40,
        label: '化工 (22%)',
        text: '化工 (22%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node23',
        x: 1307.5,
        y: 291,
        width: 105,
        height: 40,
        label: '其它 (22%)',
        text: '其它 (22%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        no_compute: true,
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
    ],
    edges: [
      { source: 'node1', target: 'node2' },
      { source: 'node2', target: 'node3' },
      { source: 'node2', target: 'node4' },
      {
        source: 'node3',
        target: 'node6',
        sourceAnchor: 1,
        targetAnchor: 0,
        type: 'hvh3',
        corner: true,
      },
      { source: 'node4', target: 'node5', type: 'hvh3' },
      { source: 'node4', target: 'node6' },
      {
        source: 'node5',
        target: 'node6',
        sourceAnchor: 1,
        targetAnchor: 2,
        type: 'hvh2',
        corner: true,
      },

      { source: 'node6', target: 'node7' },
      { source: 'node7', target: 'node8' },
      { source: 'node8', target: 'node9' },
      { source: 'node9', target: 'node10' },
      { source: 'node10', target: 'node11' },

      { source: 'node10', target: 'block1', type: 'hvh2' },
      { source: 'node11', target: 'block2', type: 'hvh3' },
    ],
  },
  NI: {//镍
    mapHeight: 362,
    mapPadding: 40,
    desc: '<span>镍产业链逻辑:</span>镍按照生产原料的不同可分为原生镍和再生镍,原生镍的生产原料来自于 镍矿,再生镍的生产原料来自于含镍废料。按照镍金属的含量,原生镍可以分为 四大产品系列,分别是电解镍、含镍生铁、镍铁、其它(镍盐、通用镍等)。',
    nodes: [
      {
        id: 'block1',
        x: 152.5,
        y: 184,
        width: 305,
        height: 350,
        type: 'block-rect',
        label: '上游',
        labelCfg: { style: { width: 42, height: 20 } },
      },
      {
        id: 'block2',
        x: 644.5,
        y: 184,
        width: 657,
        height: 350,
        type: 'block-rect',
        label: '中游',
        labelCfg: { style: { width: 40, height: 20 } },
      },
      {
        id: 'block3',
        x: 1145.5,
        y: 184,
        width: 323,
        height: 350,
        type: 'block-rect',
        label: '下游',
        labelCfg: { style: { width: 40, height: 20 } },
      },
      {
        id: 'block4',
        x: 56,
        y: 115,
        width: 88,
        height: 56,
        type: 'custom-node',
        label: '',
        strock: '#BCD0EE',
        shadowColor: 'rgba(54,78,128,0.1)',
        fill: 'rgba(255,255,255,0.9)',
        pieceList: [
          {
            type: 'text',
            x: 0,
            y: -11,
            label: '自有矿 (19%)',
            fontSize: 12,
            align: 'center',
            fill: '#333',
            weight: 400
          },
          {
            type: 'text',
            x: 0,
            y: 11,
            label: '进口矿 (81%)',
            fontSize: 12,
            align: 'center',
            fill: '#333',
            weight: 400
          },
        ]
      },
      {
        id: 'block5',
        x: 868,
        y: 330,
        width: 177,
        height: 34,
        type: 'custom-node',
        label: '',
        strock: '#BCD0EE',
        shadowColor: 'rgba(54,78,128,0.1)',
        fill: 'rgba(255,255,255,0.9)',
        pieceList: [
          {
            type: 'text',
            x: 0,
            y: 0,
            label: '进口 (30%)  国内产量 (70%)',
            fontSize: 12,
            align: 'center',
            fill: '#333',
            weight: 400
          },
        ]
      },
      {
        id: 'node1',
        x: 56,
        y: 195,
        width: 74,
        height: 40,
        label: '镍矿',
        text: '镍矿',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node2',
        x: 229,
        y: 127,
        width: 128,
        height: 50,
        label: '硫化锂矿',
        text: '硫化锂矿',
        subLabel: '(全球产量占36%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node3',
        x: 229,
        y: 261,
        width: 128,
        height: 54,
        label: '氧化锂矿',
        text: '氧化锂矿',
        subLabel: '(全球产量占64%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node4',
        x: 389,
        y: 127,
        width: 102,
        height: 50,
        label: '采矿',
        text: '采矿',
        subLabel: '(含镍1.5%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node5',
        x: 389,
        y: 261,
        width: 102,
        height: 50,
        label: '采矿',
        text: '采矿',
        subLabel: '(含镍1%-2%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node6',
        x: 546,
        y: 127,
        width: 102,
        height: 50,
        label: '镍精矿',
        text: '镍精矿',
        subLabel: '(含镍7-10%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node7',
        x: 703,
        y: 127,
        width: 102,
        height: 50,
        label: '高冰镍',
        text: '高冰镍',
        subLabel: '(含镍70%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node8',
        x: 868,
        y: 94,
        width: 114,
        height: 50,
        label: '镍盐',
        text: '镍盐',
        subLabel: '(含镍22%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node9',
        x: 868,
        y: 156,
        width: 114,
        height: 50,
        label: '电解镍',
        text: '电解镍',
        subLabel: '(含镍99.96%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node10',
        x: 868,
        y: 261,
        width: 114,
        height: 40,
        label: '镍铁',
        text: '镍铁',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
      },
      {
        id: 'node11',
        x: 1040,
        y: 156,
        width: 74,
        height: 40,
        label: '原生镍',
        text: '原生镍',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
      },
      {
        id: 'node12',
        x: 1217,
        y: 52,
        width: 156,
        height: 40,
        label: '不锈钢 (84%)',
        text: '不锈钢 (84%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
        no_compute: true,
      },
      {
        id: 'node13',
        x: 1217,
        y: 104,
        width: 156,
        height: 40,
        label: '电池 (4%)',
        text: '电池 (4%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
        no_compute: true,
      },
      {
        id: 'node14',
        x: 1217,
        y: 156,
        width: 156,
        height: 40,
        label: '电镀 (4%)',
        text: '电镀 (4%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
        no_compute: true,
      },
      {
        id: 'node15',
        x: 1217,
        y: 208,
        width: 156,
        height: 40,
        label: '镍造和镍合金 (5%)',
        text: '镍造和镍合金 (5%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
        no_compute: true,
      },
      {
        id: 'node16',
        x: 1217,
        y: 260,
        width: 156,
        height: 40,
        label: '其他 (2%)',
        text: '其他 (2%)',
        anchorPoints: [
          [0.5, 0], // 上
          [1, 0.5], // 右
          [0.5, 1], // 下
          [0, 0.5], // 左
        ],
        type: 'word-rect',
        fill: 'l(90) 0:#FBFCFF 1:#E9EDF3',
        strock: '#D4DBE7',
        no_compute: true,
      },
    ],
    edges: [
      { source: 'node1', target: 'block4', type: 'hvh2',lineDash: [2,2]},// 自定义虚线模式 
      { source: 'node1', target: 'node2' },
      { source: 'node1', target: 'node3' },

      { source: 'node2', target: 'node4' },
      { source: 'node3', target: 'node5' },
      {
        source: 'node4', target: 'node6', label: '选矿',
        subLabel: '',
        labelCfg: { style: { fontSize: 12, fill: '#245A9A' } },
        subLabelCfg: { style: { fontSize: 12, fill: '#245A9A' } },
      },
      {
        source: 'node4', target: 'node9', sourceAnchor: 2,
        type: 'hvh_custom',
        direction: 'top',
        path: [
          [389, 201],
          [868, 201],
        ],
        targetAnchor: 2, label: '湿法',
        subLabel: '',
        labelCfg: { style: { fontSize: 12, fill: '#245A9A' }, startPoint: { x: 389, y: 201 }, endPoint: { x: 868, y: 201 } },//自定义节点传文本所在边的起始点和终点
        subLabelCfg: { style: { fontSize: 12, fill: '#245A9A' } },
      },
      {
        source: 'node5', target: 'node10', label: '火法',
        subLabel: '',
        labelCfg: { style: { fontSize: 12, fill: '#245A9A' } },
        subLabelCfg: { style: { fontSize: 12, fill: '#245A9A' } },
      },
      {
        source: 'node6', target: 'node7', label: '湿法',
        subLabel: '',
        labelCfg: { style: { fontSize: 12, fill: '#245A9A' } },
        subLabelCfg: { style: { fontSize: 12, fill: '#245A9A' } },
      },
      { source: 'node7', target: 'node8' },
      { source: 'node7', target: 'node9' },

      { source: 'node8', target: 'node11' },
      { source: 'node9', target: 'node11' },
      { source: 'node10', target: 'node11' },
      { source: 'node10', target: 'block5', type: 'hvh3',lineDash: [2,2] },

      {
        source: 'node11', target: 'node12', sourceAnchor: 1,
        targetAnchor: 3,
      },
      { source: 'node11', target: 'node13' },
      { source: 'node11', target: 'node14' },
      { source: 'node11', target: 'node15' },
      {
        source: 'node11', target: 'node16', sourceAnchor: 1,
        targetAnchor: 3,
      },

    ]
  }
}
//默认黑色品种
export const defaultData = {
  mapHeight: 366,
  mapPadding: 0,
  desc: '',
  nodes: [
    {
      id: 'block1',
      x: 487,
      y: 117,
      width: 972,
      height: 232,
      type: 'block-rect',
      label: '长流程',
    },
    {
      id: 'block2',
      x: 670,
      y: 304,
      width: 604,
      height: 122,
      type: 'block-rect',
      label: '短流程',
    },
    {
      id: 'node1',
      x: 78,
      y: 42,
      label: '焦煤',
      breedCode: 'JM',
      indexCode: 'FU00008663',
      text: '焦煤',
      dataValue: '8302',
      chg: '0.16',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    {
      id: 'node2',
      x: 244,
      y: 42,
      label: '焦炭',
      breedCode: 'J',
      indexCode: 'FU00010732',
      text: '焦炭',
      dataValue: '8302',
      chg: '0.16',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    {
      id: 'node3',
      x: 244,
      y: 115,
      label: '铁矿石',
      breedCode: 'I',
      indexCode: 'FU00005559',
      text: '铁矿石',
      dataValue: '8302',
      chg: '-0.82',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    {
      id: 'node4',
      x: 466,
      y: 81,
      label: '高炉炼铁',
      dataValue: '8302',
      chg: '0.16',
      type: 'breed-rect',
      anchorPoints: [
        [0.5, 0], // 上
        [1, 0.5], // 右
        [0.5, 1], // 下
        [0, 0.5], // 左
      ],
    },
    {
      id: 'node5',
      x: 394,
      y: 189,
      label: '硅铁',
      breedCode: 'SF',
      indexCode: 'FU00000314',
      text: '硅铁',
      dataValue: '8302',
      chg: '0',
      anchorPoints: [
        [0, 0],
        [0.5, 0],
      ],
    },
    {
      id: 'node6',
      x: 540,
      y: 189,
      label: '硅锰',
      breedCode: 'SM',
      indexCode: 'FU00000202',
      text: '硅锰',
      dataValue: '8302',
      chg: '-0.16',
      anchorPoints: [
        [0, 0.5],
        [0.5, 0],
      ],
    },
    {
      id: 'node7',
      x: 669,
      y: 81,
      dataValue: '8302',
      chg: '0.16',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
      codes: [
        {
          label: '产能利用率',
          chg: '88.54',
          desc: '历史低位',
          indexCode: 'ID00183114',
          text: '高炉炼铁-产能利用率',
        },
        {
          label: '开工率',
          chg: '88.54',
          desc: '历史低位',
          indexCode: 'ID00183109',
          text: '高炉炼铁-开工率',
        },
        {
          label: '钢厂盈利率',
          chg: '88.54',
          desc: '历史低位',
          indexCode: 'ID00183126',
          text: '高炉炼铁-钢厂盈利率',
        },
      ],
      type: 'rate-rect',
    },
    {
      id: 'node8',
      x: 886,
      y: 81,
      label: '生铁产量',
      indexCode: 'ID00184088',
      text: '生铁产量',
      dataValue: '6669.9',
      chg: '2.3',
      type: 'ratio-rect',
      desc: '高于近一年平均增速',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    {
      id: 'node9',
      x: 466,
      y: 284,
      label: '废钢',
      indexCode: 'OFFRDE0554363373',
      text: '废钢',
      dataValue: '8302',
      chg: '0.16',
      type: 'breed-rect',
      desc1: '相对高位',
      desc2: '利好',
      desc3: '独立电炉企业',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    {
      id: 'node10',
      x: 660,
      y: 284,
      label: '电炉炼钢',
      dataValue: '8302',
      chg: '0.16',
      type: 'breed-rect',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    {
      id: 'node11',
      x: 854,
      y: 284,
      label: '',
      codes: [
        {
          label: '产能利用率',
          chg: '88.54',
          desc: '历史低位',
          indexCode: 'ID01302473',
          text: '电炉炼钢-产能利用率',
        },
        {
          label: '电炉炼钢利润',
          chg: '88.54',
          desc: '历史低位',
          indexCode: 'ID01040556',
          text: '电炉炼钢-电炉炼钢利率',
        },
      ],
      type: 'rate-rect',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    {
      id: 'node12',
      x: 1100,
      y: 188,
      label: '粗钢',
      indexCode: 'ID00182958',
      text: '粗钢',
      dataValue: '6669.9',
      chg: '3.3',
      type: 'ratio-rect',
      desc: '高于近一年平均增速',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    {
      id: 'node13',
      x: 1307,
      y: 42,
      label: '螺纹钢',
      breedCode: 'RB',
      indexCode: 'FU00001454',
      text: '螺纹钢',
      dataValue: '8302',
      chg: '0.16',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    {
      id: 'node14',
      x: 1307,
      y: 115,
      label: '线材',
      breedCode: 'WR',
      indexCode: 'FU00005821',
      noClick: true, //是否节点可点击
      text: '线材',
      dataValue: '8302',
      chg: '0.16',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    {
      id: 'node15',
      x: 1307,
      y: 188,
      label: '热轧板卷',
      breedCode: 'HC',
      indexCode: 'FU00002440',
      text: '热轧板卷',
      dataValue: '8302',
      chg: '0.16',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    {
      id: 'node16',
      x: 1307,
      y: 261,
      label: '不锈钢',
      breedCode: 'SS',
      indexCode: 'FU00000075',
      text: '不锈钢',
      dataValue: '8302',
      chg: '0.16',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
    {
      id: 'node17',
      x: 1307,
      y: 324,
      label: '其他',
      dataValue: '8302',
      chg: '0.16',
      type: 'breed-rect',
      anchorPoints: [
        [0, 0.5],
        [1, 0.5],
      ],
    },
  ],
  edges: [
    { source: 'node1', target: 'node2' },
    { source: 'node2', target: 'node4' },
    { source: 'node3', target: 'node4' },
    { source: 'node5', target: 'node4', type: 'hvh2' },
    { source: 'node6', target: 'node4', type: 'hvh2' },
    { source: 'node4', target: 'node7', disableArrow: true },
    { source: 'node7', target: 'node8' },
    { source: 'node9', target: 'node10' },
    { source: 'node10', target: 'node11', disableArrow: true },
    { source: 'node8', target: 'node12' },
    { source: 'node11', target: 'node12' },
    { source: 'node12', target: 'node13' },
    { source: 'node12', target: 'node14' },
    { source: 'node12', target: 'node15' },
    { source: 'node12', target: 'node16' },
    { source: 'node12', target: 'node17' },
  ],
}

 图谱组件link-map.vue:

<template>
  <div class="link-map">
    <div class="link-title">{{ breedName + props.elementName }}</div>
    <div class="link-desc" v-if="desc !== ''" v-html="desc"></div>
    <gl-spin :spinning="mapLoading">
      <div
        id="mountNode"
        :style="{
          height: mapHeight + 'px',
          padding: isBlank ? '' : `0 ${mapPadding}px`,
          maxHeight: maxHeight + 'px',
        }"
      ></div>
    </gl-spin>
  </div>
</template>
<script setup>
import { onMounted, getCurrentInstance } from 'vue'
import { formatNumValue } from '@/utils/index'
import G6 from '@antv/g6/dist/g6.min'
import { mapData, defaultData } from './mapData'
import { map } from 'lodash'
const { proxy } = getCurrentInstance()
const route = useRoute()
const props = defineProps({
  secCode: {
    type: String,
    default: '',
  },
  elementName: {
    type: String,
    default: '',
  },
  elementCode: {
    type: String,
    default: '',
  },
})
const emit = defineEmits(['breed-select'])
const nodes = ref([])
const edges = ref([])
const mapLoading = ref(false)
const graph2 = ref(null)
const color_breed = ref(['CU', 'AL', 'PB', 'ZN', 'SN', 'NI', 'LC', 'SI', 'AO']) //铜、铝、铅、锌、锡、镍、碳酸锂、工业硅、氧化铝
const mapHeight = ref(
  mapData[window.breedCode]
    ? mapData[window.breedCode].mapHeight
    : defaultData.mapHeight
)
const maxHeight = ref(
  mapData[window.breedCode]
    ? mapData[window.breedCode].mapHeight
    : defaultData.mapHeight
)
const isBlank = ref(color_breed.value.includes(window.breedCode) ? false : true) //是否黑色品种
const mapPadding = ref(
  mapData[window.breedCode]
    ? mapData[window.breedCode].mapPadding
    : defaultData.mapPadding
)
const breedName = ref(window.breedName)
const isDragging = ref(false)
const desc = ref('')

const tong_nodes = ref([
  {
    id: 'node1',
    x: 138,
    y: 136,
    width: 176,
    height: 61,
    label: '全球铜矿山产能',
    breedCode: 'JM',
    indexCode: 'OFFRDE0678557898',
    text: '全球铜矿山产能',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node2',
    x: 138,
    y: 209,
    width: 176,
    height: 61,
    label: '全球铜矿产能利用率',
    breedCode: 'JM',
    indexCode: 'ID00303168',
    text: '全球铜矿产能利用率',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node3',
    x: 394,
    y: 172,
    width: 134,
    height: 61,
    label: '全球铜矿供应',
    breedCode: 'JM',
    indexCode: 'OFFRDE0789849953',
    text: '全球铜矿供应',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node4',
    x: 394,
    y: 264,
    width: 134,
    height: 61,
    label: '加工费',
    breedCode: 'JM',
    indexCode: 'OFFRDE0407946063',
    text: '加工费',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node5',
    x: 394,
    y: 357,
    width: 134,
    height: 61,
    label: '国内铜矿供应',
    breedCode: 'JM',
    indexCode: 'OFFRDE0503146446',
    text: '国内铜矿供应',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node6',
    x: 591,
    y: 172,
    width: 158,
    height: 61,
    label: '精炼铜供应',
    breedCode: 'JM',
    indexCode: 'ID00407927',
    text: '精炼铜供应',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node7',
    x: 591,
    y: 234,
    width: 158,
    height: 39,
    label: '再生(废杂)铜供应',
    text: '各类政策因素',
    breedCode: 'JM',
    text: '再生(废杂)铜供应',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
    type: 'word-rect',
  },
  {
    id: 'node8',
    x: 591,
    y: 286,
    width: 158,
    height: 39,
    label: '各类政策因素',
    text: '各类政策因素',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
    type: 'word-rect',
  },
  {
    id: 'node9',
    x: 838,
    y: 31,
    width: 134,
    height: 61,
    label: '全球社会库存',
    text: '全球社会库存',
    breedCode: 'JM',
    indexCode: 'OFFRDE0416122129',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node10',
    x: 984,
    y: 31,
    width: 134,
    height: 61,
    label: 'LME铜库存',
    text: 'LME铜库存',
    breedCode: 'JM',
    indexCode: 'OFFRDE0099802675',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node11',
    x: 1130,
    y: 31,
    width: 134,
    height: 61,
    label: 'SHFE铜库存',
    text: 'SHFE铜库存',
    breedCode: 'JM',
    indexCode: 'OFFRDE0900823051',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node12',
    x: 1281,
    y: 31,
    width: 145,
    height: 61,
    label: 'COMEX铜库存',
    text: 'COMEX铜库存',
    breedCode: 'JM',
    indexCode: 'OFFRDE0470038275',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node13',
    x: 838,
    y: 136,
    width: 134,
    height: 61,
    label: '总库存变化',
    breedCode: 'JM',
    indexCode: 'OFFRDE0704512926',
    text: '总库存变化',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node14',
    x: 838,
    y: 234,
    width: 134,
    height: 61,
    label: '铜现货价',
    breedCode: 'JM',
    indexCode: 'ID00303957',
    text: '铜现货价',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node15',
    x: 838,
    y: 326,
    width: 134,
    height: 61,
    label: '比价与价差',
    text: '比价与价差',
    indexCode: 'FU00015882',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node16',
    x: 838,
    y: 418,
    width: 134,
    height: 61,
    label: '铜期货价',
    text: '铜期货价',
    indexCode: 'FU00015764',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node17',
    x: 1023,
    y: 136,
    width: 134,
    height: 61,
    label: '库存消费比',
    breedCode: 'JM',
    indexCode: 'OFFRDE0881777811',
    text: '库存消费比',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node18',
    x: 1023,
    y: 234,
    width: 134,
    height: 61,
    label: '表观需求',
    breedCode: 'JM',
    indexCode: 'ID01167294',
    text: '表观需求',
    dataValue: '-',
    chg: '-',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node19',
    x: 1023,
    y: 326,
    width: 134,
    height: 39,
    label: '贸易流向',
    text: '贸易流向',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
    type: 'word-rect',
  },
  {
    id: 'node20',
    x: 1023,
    y: 418,
    width: 134,
    height: 39,
    label: '资金因素',
    text: '资金因素',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
    type: 'word-rect',
  },
  {
    id: 'node21',
    x: 1257,
    y: 157,
    width: 134,
    height: 39,
    label: '房地产开工',
    text: '房地产开工',
    type: 'word-rect',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node22',
    x: 1257,
    y: 209,
    width: 134,
    height: 39,
    label: '汽车产销',
    text: '汽车产销',
    type: 'word-rect',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node23',
    x: 1257,
    y: 261,
    width: 134,
    height: 39,
    label: '基建投资',
    text: '基建投资',
    type: 'word-rect',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
  {
    id: 'node24',
    x: 1257,
    y: 313,
    width: 134,
    height: 39,
    label: '家电等终端',
    text: '家电等终端',
    type: 'word-rect',
    anchorPoints: [
      [0.5, 0], // 上
      [1, 0.5], // 右
      [0.5, 1], // 下
      [0, 0.5], // 左
    ],
  },
])
const tong_edges = ref([
  { source: 'node1', target: 'node3' },
  { source: 'node2', target: 'node3' },
  { source: 'node3', target: 'node4', type: 'hvh3' },
  { source: 'node4', target: 'node5', type: 'hvh3' },
  { source: 'node3', target: 'node6' },

  { source: 'node6', target: 'node14' },
  { source: 'node7', target: 'node14' },
  { source: 'node8', target: 'node14' },

  { source: 'node9', target: 'node13', type: 'hvh3' },
  {
    source: 'node10',
    target: 'node13',
    type: 'hvh3',
    sourceAnchor: 2,
    targetAnchor: 0,
  },
  {
    source: 'node11',
    target: 'node13',
    type: 'hvh3',
    sourceAnchor: 2,
    targetAnchor: 0,
  },
  {
    source: 'node12',
    target: 'node13',
    type: 'hvh3',
    sourceAnchor: 2,
    targetAnchor: 0,
  },

  { source: 'node13', target: 'node17' },
  { source: 'node13', target: 'node14', type: 'hvh3' },

  { source: 'node14', target: 'node18' },
  { source: 'node14', target: 'node15', type: 'hvh3' },

  { source: 'node15', target: 'node19' },
  { source: 'node15', target: 'node16', type: 'hvh3' },

  { source: 'node16', target: 'node20' },

  { source: 'node18', target: 'node21' },
  { source: 'node18', target: 'node22' },
  { source: 'node18', target: 'node23' },
  { source: 'node18', target: 'node24' },
])
const getSvg = (type, iconColor) => {
  // 动态生成SVG内容
  const generateSVG1 = (iconColor) => {
    return `
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
        <title>Icon/涨</title>
        <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
            <g id="Q2_5_4期限分析_供给分析_最小宽度1180" transform="translate(-388.000000, -226.000000)">
                <g id="价格" transform="translate(164.000000, 102.000000)">
                    <g id="编组-13" transform="translate(46.000000, 116.000000)">
                        <g id="产业链/期货/涨备份-3" transform="translate(70.000000, 0.000000)">
                            <g id="Icon/涨" transform="translate(108.000000, 8.000000)">
                                <rect id="矩形" x="0" y="0" width="14" height="14"/>
                                <path d="M13.234199,3.55970481 C13.5098844,3.54382543 13.7462444,3.75443985 13.7621238,4.03012528 C13.7633238,4.05095907 13.7632183,4.07184754 13.761808,4.09266815 L13.5387743,7.38534552 C13.5201122,7.66085657 13.2816378,7.86907379 13.0061267,7.8504117 C12.8875582,7.84238031 12.775727,7.7923795 12.6906807,7.70937277 L11.522514,6.56902231 C11.5039313,6.59161598 11.4837258,6.61329794 11.4619021,6.63390921 L7.52440214,10.3526592 C7.19748321,10.661416 6.66840549,10.5862535 6.44041171,10.1986641 L4.67251566,7.193375 L1.15091069,10.1604378 C0.879839379,10.3887084 0.486186576,10.3759255 0.230649525,10.1444346 L0.164577825,10.075895 C-0.0844446196,9.78018087 -0.0465935113,9.33858461 0.249120641,9.08956216 L4.40537064,5.58956216 C4.73689384,5.31038473 5.23987001,5.39651159 5.45961961,5.77008591 L7.20126566,8.731625 L10.5006292,5.61609079 L10.525,5.59589343 L9.5175239,4.6123147 C9.3199065,4.41943657 9.31606456,4.10287739 9.5089427,3.90525999 C9.59608394,3.81597757 9.71345538,3.76249833 9.83800849,3.75532412 L13.234199,3.55970481 Z" id="形状结合" fill="${iconColor}" fill-rule="nonzero"/>
                            </g>
                        </g>
                    </g>
                </g>
            </g>
        </g>
    </svg>
      `
  }
  // 下跌
  const generateSVG2 = (iconColor) => {
    return `
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
          <title>Icon/跌</title>
          <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
              <g id="Q2_5_4期限分析_供给分析_最小宽度1180" transform="translate(-547.000000, -226.000000)">
                  <g id="价格" transform="translate(164.000000, 102.000000)">
                      <g id="编组-13" transform="translate(46.000000, 116.000000)">
                          <g id="产业链/期货/跌备份-4" transform="translate(229.000000, 0.000000)">
                              <g id="Icon/跌" transform="translate(108.000000, 8.000000)">
                                  <rect id="矩形" x="0" y="0" width="14" height="14"/>
                                  <path d="M13.234199,3.50481138 C13.5098844,3.48893201 13.7462444,3.69954643 13.7621238,3.97523186 C13.7633238,3.99606564 13.7632183,4.01695412 13.761808,4.03777472 L13.5387743,7.3304521 C13.5201122,7.60596314 13.2816378,7.81418036 13.0061267,7.79551827 C12.8875582,7.78748688 12.775727,7.73748607 12.6906807,7.65447934 L11.522514,6.51412888 C11.5039313,6.53672256 11.4837258,6.55840451 11.4619021,6.57901578 L7.52440214,10.2977658 C7.19748321,10.6065225 6.66840549,10.5313601 6.44041171,10.1437707 L4.67251566,7.13848157 L1.15091069,10.1055444 C0.879839379,10.333815 0.486186576,10.3210321 0.230649525,10.0895412 L0.164577825,10.0210016 C-0.0844446196,9.72528744 -0.0465935113,9.28369118 0.249120641,9.03466874 L4.40537064,5.53466874 C4.73689384,5.25549131 5.23987001,5.34161816 5.45961961,5.71519249 L7.20126566,8.67673157 L10.5006292,5.56119737 L10.525,5.541 L9.5175239,4.55742128 C9.3199065,4.36454314 9.31606456,4.04798397 9.5089427,3.85036657 C9.59608394,3.76108415 9.71345538,3.70760491 9.83800849,3.70043069 L13.234199,3.50481138 Z" id="形状结合" fill="${iconColor}" fill-rule="nonzero" transform="translate(6.883798, 6.994464) scale(1, -1) translate(-6.883798, -6.994464) "/>
                              </g>
                          </g>
                      </g>
                  </g>
              </g>
          </g>
      </svg>
      `
  }
  // 持平
  const generateSVG3 = (iconColor) => {
    return `
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="14px" viewBox="0 0 14 14" version="1.1">
          <title>Icon/跌</title>
          <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
              <g id="Q2_5_4期限分析_供给分析_最小宽度1180" transform="translate(-706.000000, -226.000000)">
                  <g id="价格" transform="translate(164.000000, 102.000000)">
                      <g id="编组-13" transform="translate(46.000000, 116.000000)">
                          <g id="产业链/期货/跌备份-3" transform="translate(388.000000, 0.000000)">
                              <g id="Icon/跌" transform="translate(108.000000, 8.000000)">
                                  <rect id="矩形" x="0" y="0" width="14" height="14"/>
                                  <path d="M2.8,6 L11.2,6 C11.6418278,6 12,6.3581722 12,6.8 C12,7.2418278 11.6418278,7.6 11.2,7.6 L2.8,7.6 C2.3581722,7.6 2,7.2418278 2,6.8 C2,6.3581722 2.3581722,6 2.8,6 Z" id="矩形" fill="${iconColor}"/>
                              </g>
                          </g>
                      </g>
                  </g>
              </g>
          </g>
      </svg>
      `
  }

  return (
    'data:image/svg+xml;charset=utf-8,' +
    encodeURIComponent(
      type > 0
        ? generateSVG1(iconColor)
        : type === 0
        ? generateSVG3(iconColor)
        : generateSVG2(iconColor)
    )
  )
}
const linkData = ref({
  link1: {
    indexCode: 'FU00008663',
    text: '焦煤',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link2: {
    indexCode: 'FU00010732',
    text: '焦炭',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link3: {
    indexCode: 'FU00005559',
    text: '铁矿石',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link4: {
    indexCode: 'FU00000314',
    text: '硅铁',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link5: {
    indexCode: 'FU00000202',
    text: '硅锰',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link6: {
    indexCode: 'ID00183114',
    text: '高炉炼铁-产能利用率',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link7: {
    indexCode: 'ID00183109',
    text: '高炉炼铁-开工率',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link8: {
    indexCode: 'ID00183126',
    text: '高炉炼铁-钢厂盈利率',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link9: {
    indexCode: 'ID00184088',
    text: '生铁产量',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link10: {
    indexCode: 'OFFRDE0554363373',
    text: '废钢',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link11: {
    indexCode: 'ID01302473',
    text: '电炉炼钢-产能利用率',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link12: {
    indexCode: 'ID01040556',
    text: '电炉炼钢-电炉炼钢利率',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link13: {
    indexCode: 'ID00182958',
    text: '粗钢',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link14: {
    indexCode: 'FU00001454',
    text: '螺纹钢',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link15: {
    indexCode: 'FU00005821',
    text: '线材',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link16: {
    indexCode: 'FU00002440',
    text: '热轧板卷',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
  link17: {
    indexCode: 'FU00000075',
    text: '不锈钢',
    dataValue: '',
    dataChg: '',
    desc: '',
  },
})
//查询指定品种下链路图数据
const loadGraphData = (menuCode) => {
  mapLoading.value = true
  proxy.$request
    .get(
      `/futures-api/api/futures/data/chain?breedCode=${window.breedCode}&elementCode=${props.elementCode}`
    )
    .then((res) => {
      console.log('品种下链路图数据', res)
      mapLoading.value = false
      if (res.data) {
        const data = res.data
        // if (!isBlank.value) {
        //   console.log('显示铜产业链')
        //   edges.value = tong_edges.value
        //   nodes.value = tong_nodes.value
        // }
        console.log('nodes.value', nodes.value)
        nodes.value.forEach((val) => {
          if (val.indexCode) {
            let list = data.filter((item) => item.indexCode == val.indexCode)
            if (list.length > 0) {
              val.dataValue = list[0].dataValue
              val.chg = list[0].dataChg
              val.desc = list[0].desc
              val.unit = list[0].unit
              val.sumYoy = list[0].sumYoy
              if (val.indexCode == 'OFFRDE0554363373') {
                let descList = list[0].desc.replace(';<br>', '').split(' ')
                val.desc1 = descList[0]
                val.desc2 = descList[1]
                val.desc3 = descList[2]
              }
            }
          } else if (val.codes) {
            val.codes.forEach((ele) => {
              if (ele.indexCode) {
                let list = data.filter(
                  (item) => item.indexCode == ele.indexCode
                )
                if (list.length > 0) {
                  ele.dataValue = list[0].dataValue
                  ele.chg = list[0].dataChg
                  ele.desc = list[0].desc
                  ele.unit = list[0].unit
                }
              }
            })
          }
        })
        nextTick(() => {
          initGrah()
        })
      }
    })
}
const initGrah = () => {
  //创建模块节点
  G6.registerNode('block-rect', {
    draw(cfg, group) {
      // 主矩形配置
      const width = cfg.width
      const height = cfg.height
      const fill = '#FAFCFF'
      const stroke = '#4376CE'

      // 创建主矩形
      const mainRect = group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: -height / 2,
          width,
          height,
          stroke,
          fill,
          lineDash: [2, 2], // 激活状态用实线,非激活用虚线
          lineWidth: 1,
          radius: [4, 4, 4, 4],
          padding: 0,
          zIndex: -99,
        },
        name: 'main-rect',
      })
      if (cfg.label == '长流程') {
        group.addShape('rect', {
          attrs: {
            x: -width / 2 + 12,
            y: height / 2 - 10,
            width: 52,
            height: 20,
            fill: '#4580D9',
            stroke: '',
            lineWidth: 0,
            radius: [2, 2, 2, 2],
            zIndex: -99,
          },
          name: 'top-rect',
        })
        group.addShape('text', {
          attrs: {
            x: -width / 2 + 37,
            y: height / 2 + 6,
            text: '长流程',
            textAlign: 'center',
            fill: '#fff',
            fontSize: 12,
            zIndex: -99,
          },
          name: 'text1',
        })
      }
      if (cfg.label == '短流程') {
        group.addShape('rect', {
          attrs: {
            x: -width / 2 - 26,
            y: -10,
            width: 52,
            height: 20,
            fill: '#4580D9',
            stroke: '',
            lineWidth: 0,
            radius: [2, 2, 2, 2],
            zIndex: -99,
          },
          name: 'top-rect',
        })
        group.addShape('text', {
          attrs: {
            x: -width / 2,
            y: 7,
            text: '短流程',
            textAlign: 'center',
            fill: '#fff',
            fontSize: 12,
            zIndex: -99,
          },
          name: 'text1',
        })
      }
      let list = [
        '上游',
        '中游',
        '下游',
        '原料端',
        '冶炼端',
        '初端下游产品',
        '终端需求',
      ]
      if (list.includes(cfg.label)) {
        group.addShape('rect', {
          attrs: {
            x: -(cfg.labelCfg?.style?.width / 2 || 20),
            y: -height / 2 - (cfg.labelCfg?.style?.height / 2 || 10),
            width: cfg.labelCfg?.style?.width || 40,
            height: cfg.labelCfg?.style?.height || 20,
            fill: '#4580D9',
            stroke: '#4580D9',
            lineWidth: 1,
            radius: [2, 2, 2, 2],
            zIndex: -99,
          },
          name: 'top-rect',
        })
        group.addShape('text', {
          attrs: {
            x: 0,
            y: -height / 2 + 6,
            text: cfg.label,
            textAlign: 'center',
            fill: '#fff',
            fontSize: 12,
            zIndex: -99,
          },
          name: 'text1',
        })
      }

      return mainRect
    },
  })
  //创建上下分割节点
  G6.registerNode('split-rect', {
    draw(cfg, group) {
      // 主矩形配置
      const width = 135
      const height = 60
      const fill = cfg.chg > 0 ? '#FBEAEC' : cfg.chg < 0 ? '#DFF5EB' : '#F1F2FA'
      const stroke =
        cfg.chg > 0 ? '#F8DDE0' : cfg.chg < 0 ? '#B8DDCC' : '#D7DCEA'

      // 创建主矩形
      const mainRect = group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: -height / 2,
          width,
          height,
          fill,
          stroke,
          lineWidth: 1,
          radius: [4, 4, 4, 4],
          padding: 12,
        },
        name: 'main-rect',
      })

      // 添加分割线(水平中线)
      group.addShape('line', {
        attrs: {
          x1: -width / 2 + 12,
          y1: 0,
          x2: width / 2 - 12,
          y2: 0,
          stroke: cfg.chg > 0 ? '#E6C5C6' : cfg.chg < 0 ? '#ACD5C3' : '#D3D9E8',
          lineWidth: 1,
          cursor: cfg.text !== '线材' ? 'pointer' : '',
        },
        name: 'divider-line',
      })

      // 添加上半部分小矩形
      group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: -height / 2,
          width: width,
          height: 30,
          fill: '',
          stroke: '#666',
          lineWidth: 0,
          radius: [4, 4, 0, 0],
          cursor: cfg.text !== '线材' ? 'pointer' : '',
        },
        name: 'top-rect',
      })

      // 添加下半部分小矩形
      group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: 0, // 从分割线下方开始
          width: width,
          height: 30,
          fill: '',
          stroke: '',
          lineWidth: 0,
          radius: [0, 0, 4, 4],
          cursor: cfg.text !== '线材' ? 'pointer' : '',
        },
        name: 'bottom-rect',
      })
      if (cfg.label) {
        group.addShape('text', {
          attrs: {
            text: cfg.label,
            x: -width / 2 + 12,
            y: -8,
            textAlign: 'left',
            fill: '#333',
            fontSize: 12,
            fontWeight: 600,
            cursor: cfg.text !== '线材' ? 'pointer' : '',
          },
          name: 'text1',
        })

        // 添加SVG图像
        group.addShape('image', {
          attrs: {
            x: width / 2 - 24,
            y: -22,
            width: 14,
            height: 14,
            img:
              cfg.chg > 0
                ? getSvg(1, '#D91212')
                : cfg.chg < 0
                ? getSvg(-1, '#12A96E')
                : getSvg(0, '#999'),
            cursor: cfg.text !== '线材' ? 'pointer' : '',
          },
          name: 'img-1',
        })
        group.addShape('text', {
          attrs: {
            text: formatNumValue(cfg.dataValue),
            x: -width / 2 + 12,
            y: 22,
            textAlign: 'left',
            fill: cfg.chg > 0 ? '#D91212' : cfg.chg < 0 ? '#12A96E' : '#666',
            fontSize: 12,
            fontWeight: 600,
            cursor: cfg.text !== '线材' ? 'pointer' : '',
          },
          name: 'text3',
        })
        group.addShape('text', {
          attrs: {
            text: (cfg.chg > 0 ? '+' : cfg.chg < 0 ? '' : '') + cfg.chg + '%',
            x: width / 2 - 12,
            y: 22,
            textAlign: 'right',
            fill: cfg.chg > 0 ? '#D91212' : cfg.chg < 0 ? '#12A96E' : '#666',
            fontSize: 12,
            fontWeight: 600,
            cursor: cfg.text !== '线材' ? 'pointer' : '',
          },
          name: 'text4',
        })
      }

      return mainRect
    },
    // 响应状态变化
    setState(name, value, item) {
      // console.log('name', name, value, item)
      let cfg = item._cfg.model
      if (name === 'highlight') {
        const group = item.getContainer()
        const main_rect = group.find((ele) => ele.get('name') === 'main-rect')
        main_rect.attr(
          'stroke',
          value
            ? cfg.chg > 0
              ? '#D12323'
              : cfg.chg < 0
              ? '#12A96E'
              : '#8E92A1'
            : cfg.chg > 0
            ? '#F8DDE0'
            : cfg.chg < 0
            ? '#B8DDCC'
            : '#D7DCEA'
        )
        main_rect.attr('cursor', 'pointer')
        main_rect.attr('lineWidth', value ? 2 : 1)
        const top_rect = group.find((ele) => ele.get('name') === 'top-rect')
        // 改变背景色
        top_rect.attr(
          'fill',
          value
            ? cfg.chg > 0
              ? '#D12323'
              : cfg.chg < 0
              ? '#12A96E'
              : '#8E92A1'
            : ''
        )
        const bottom_rect = group.find(
          (ele) => ele.get('name') === 'bottom-rect'
        )
        // 改变背景色
        bottom_rect.attr(
          'fill',
          value
            ? cfg.chg > 0
              ? '#FFF6F7'
              : cfg.chg < 0
              ? '#E9FBF3'
              : '#F8F9FE'
            : ''
        )
        const text1 = group.find((ele) => ele.get('name') === 'text1')
        text1.attr('fill', value ? '#FFF' : '#333')
        const img_1 = group.find((ele) => ele.get('name') === 'img-1')
        img_1.attr(
          'img',
          value
            ? cfg.chg > 0
              ? getSvg(1, '#fff')
              : cfg.chg < 0
              ? getSvg(-1, '#fff')
              : getSvg(0, '#fff')
            : cfg.chg > 0
            ? getSvg(1, '#D91212')
            : cfg.chg < 0
            ? getSvg(-1, '#12A96E')
            : getSvg(0, '#999')
        )
      }
      if (name === 'hover' && cfg.text != '线材') {
        const group = item.getContainer()
        const main_rect = group.find((ele) => ele.get('name') === 'main-rect')
        main_rect.attr(
          'stroke',
          value || item.getStates().includes('highlight')
            ? cfg.chg > 0
              ? '#D12323'
              : cfg.chg < 0
              ? '#12A96E'
              : '#8E92A1'
            : cfg.chg > 0
            ? '#F8DDE0'
            : cfg.chg < 0
            ? '#B8DDCC'
            : '#D7DCEA'
        )
        main_rect.attr('cursor', 'pointer')
      }
    },
    getAnchorPoints() {
      return [
        [0.5, 0],
        [1, 0.5],
        [0.5, 1],
        [0, 0.5], // 四边中点
      ]
    },
  })
  //创建品种文本节点
  G6.registerNode('breed-rect', {
    draw(cfg, group) {
      // 主矩形配置
      const width = cfg.width ? cfg.width : cfg.label == '其他' ? 134 : 120
      const height = cfg.height ? cfg.height : 40
      const fill = '#FFF'
      const stroke = '#C3CDE8'

      // 创建主矩形
      const mainRect = group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: -height / 2,
          width,
          height,
          fill,
          stroke,
          lineWidth: 1,
          radius: [4, 4, 4, 4],
          padding: 0,
          shadowOffsetX: 0,
          shadowOffsetY: 2,
          shadowBlur: 6,
          spread: 2,
          shadowColor: 'rgba(149,157,174,0.1)',
        },
        name: 'main-rect',
      })
      if (cfg.label) {
        group.addShape('text', {
          attrs: {
            text: cfg.label,
            x: 0,
            y: 7,
            textAlign: 'center',
            fill: '#333',
            fontSize: 14,
            fontWeight: 600,
          },
          name: 'text1',
        })
        if (cfg.label == '废钢') {
          group.addShape('text', {
            attrs: {
              text: `螺废差:${cfg.dataValue}`,
              x: -width / 2,
              y: 46,
              textAlign: 'left',
              fill: '#333',
              fontSize: 12,
            },
            name: 'text2',
          })
          group.addShape('text', {
            attrs: {
              text: `(${cfg.desc1})`,
              x: -width / 2 + (4 * 12 + (cfg.dataValue.length + '') * 6) + 8,
              y: 46,
              textAlign: 'left',
              fill: '#D91212',
              fontSize: 12,
            },
            name: 'text2-desc1',
          })
          group.addShape('text', {
            attrs: {
              text: `${cfg.desc2}:`,
              x: -width / 2,
              y: 68,
              textAlign: 'left',
              fill: '#D91212',
              fontSize: 12,
            },
            name: 'text2-desc2',
          })
          group.addShape('text', {
            attrs: {
              text: `${cfg.desc3}`,
              x: -width / 2 + cfg.desc2.length * 12 + 8,
              y: 68,
              textAlign: 'left',
              fill: '#333',
              fontSize: 12,
            },
            name: 'text2-desc3',
          })
        }
      }
      return mainRect
    },
    setState(name, value, item) {
      if (name === 'hover') {
        const group = item.getContainer()
        const main_rect = group.find((ele) => ele.get('name') === 'main-rect')
        main_rect.attr(
          'shadowColor',
          value ? 'rgba(149,157,174,0.2)' : 'rgba(149,157,174,0.1)'
        )
      }
    },
  })
  //创建文本利率节点
  G6.registerNode('rate-rect', {
    draw(cfg, group) {
      // 主矩形配置
      const width = cfg.codes && cfg.codes.length > 2 ? 204 : 212
      const height = 12 + cfg.codes.length * 22
      const fill = '#FFF'
      const stroke = '#fff'

      // 创建主矩形
      const mainRect = group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: -height / 2,
          width,
          height,
          fill,
          stroke,
          lineWidth: 0,
          radius: [4, 4, 4, 4],
          padding: 0,
          shadowOffsetX: 0,
          shadowOffsetY: 2,
          shadowBlur: 6,
          spread: 2,
          shadowColor: 'rgba(54,78,128,0.1)',
        },
        name: 'main-rect',
      })
      if (cfg.codes) {
        cfg.codes.forEach((item, index) => {
          group.addShape('text', {
            attrs: {
              text: `${item.label}: ${item.chg}%`,
              x: -width / 2 + 12,
              y: -height / 2 + 24 + 22 * index,
              textAlign: 'left',
              fill: '#333',
              fontSize: 12,
            },
            name: `text-${index + 1}`,
          })
          group.addShape('text', {
            attrs: {
              text: `(${item.desc})`,
              x:
                -width / 2 +
                12 +
                ((item.label.length + 1) * 12 +
                  ((item.chg + '').length + 1) * 6) +
                12,
              y: -height / 2 + 24 + 22 * index,
              textAlign: 'left',
              fill: '#D91212',
              fontSize: 12,
            },
            name: `text-${index + 1}-desc`,
          })
        })
      }
      return mainRect
    },
  })
  //创建产量同比节点
  G6.registerNode('ratio-rect', {
    draw(cfg, group) {
      // 主矩形配置
      const width = 147
      const height = 86
      const fill = '#FFF'
      const stroke = '#C3CDE8'

      // 创建主矩形
      const mainRect = group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: -height / 2,
          width,
          height,
          fill,
          stroke,
          lineWidth: 1,
          radius: [4, 4, 4, 4],
          padding: 0,
          shadowOffsetX: 0,
          shadowOffsetY: 2,
          shadowBlur: 6,
          spread: 2,
          shadowColor: 'rgba(149,157,174,0.1)',
        },
        name: 'main-rect',
      })
      group.addShape('text', {
        attrs: {
          text: cfg.label,
          x: 0,
          y: -height / 2 + 24,
          textAlign: 'center',
          fill: '#333',
          fontSize: 14,
          fontWeight: 600,
        },
        name: 'text1',
      })
      group.addShape('line', {
        attrs: {
          x1: -width / 2 + 12,
          y1: -14,
          x2: width / 2 - 12,
          y2: -14,
          stroke: '#DDE3F2',
          lineWidth: 1,
        },
        name: 'divider-line',
      })
      group.addShape('text', {
        attrs: {
          text: `${cfg.dataValue}`,
          x: 16,
          y: -height / 2 + 55,
          textAlign: 'right',
          fill: '#333',
          fontSize: 16,
          fontWeight: 600,
        },
        name: 'text2',
      })
      group.addShape('text', {
        attrs: {
          text: `${cfg.unit}`,
          x: 20,
          y: -height / 2 + 53,
          textAlign: 'left',
          fill: '#666',
          fontSize: 12,
        },
        name: 'text2',
      })
      group.addShape('text', {
        attrs: {
          text: `累计同比${
            cfg.sumYoy > 0 ? '上涨' : cfg.sumYoy < 0 ? '下降' : '持平'
          }`,
          x: -width / 2 + 12,
          y: -height / 2 + 75,
          textAlign: 'left',
          fill: '#666',
          fontSize: 12,
        },
        name: 'text3',
      })
      group.addShape('text', {
        attrs: {
          text: `${Math.abs(cfg.sumYoy).toFixed(2)}%`,
          x: width / 2 - 14,
          y: -height / 2 + 76,
          textAlign: 'right',
          fill:
            cfg.sumYoy > 0 ? '#D91212' : cfg.sumYoy < 0 ? '#12A96E' : '#666666',
          fontSize: 14,
          fontWeight: 600,
        },
        name: 'text3-chg',
      })
      group.addShape('text', {
        attrs: {
          text: `${cfg.desc}`,
          x: 0,
          y: -height / 2 + 85 + 22,
          textAlign: 'center',
          fill: '#D91212',
          fontSize: 12,
        },
        name: 'text4',
      })
      return mainRect
    },
    setState(name, value, item) {
      if (name === 'hover') {
        const group = item.getContainer()
        const main_rect = group.find((ele) => ele.get('name') === 'main-rect')
        main_rect.attr(
          'shadowColor',
          value ? 'rgba(149,157,174,0.2)' : 'rgba(149,157,174,0.1)'
        )
      }
    },
  })
  //创建产量价格节点
  G6.registerNode('product-rect', {
    draw(cfg, group) {
      // 主矩形配置
      const width = cfg.width ? cfg.width : 134
      const height = cfg.height ? cfg.height : 60
      const fill = cfg.chg > 0 ? '#FBEAEC' : cfg.chg < 0 ? '#DFF5EB' : '#F1F2FA'
      const stroke =
        cfg.chg > 0 ? '#F8DDE0' : cfg.chg < 0 ? '#B8DDCC' : '#D7DCEA'

      // 创建主矩形
      const mainRect = group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: -height / 2,
          width,
          height,
          fill,
          stroke,
          lineWidth: 1,
          radius: [4, 4, 4, 4],
          padding: 12,
        },
        name: 'main-rect',
      })

      // 添加分割线(水平中线)
      group.addShape('line', {
        attrs: {
          x1: -width / 2 + 12,
          y1: 0,
          x2: width / 2 - 12,
          y2: 0,
          stroke: cfg.chg > 0 ? '#E6C5C6' : cfg.chg < 0 ? '#ACD5C3' : '#D3D9E8',
          lineWidth: 1,
        },
        name: 'divider-line',
      })

      // 添加上半部分小矩形
      group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: -height / 2,
          width: width,
          height: 30,
          fill: '',
          stroke: '#666',
          lineWidth: 0,
          radius: [4, 4, 0, 0],
        },
        name: 'top-rect',
      })

      // 添加下半部分小矩形
      group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: 0, // 从分割线下方开始
          width: width,
          height: 30,
          fill: '',
          stroke: '',
          lineWidth: 0,
          radius: [0, 0, 4, 4],
        },
        name: 'bottom-rect',
      })
      if (cfg.label) {
        group.addShape('text', {
          attrs: {
            text: cfg.label,
            x: -width / 2 + 12,
            y: -8,
            textAlign: 'left',
            fill: '#333',
            fontSize: 12,
            fontWeight: 600,
          },
          name: 'text1',
        })

        // 添加SVG图像
        group.addShape('image', {
          attrs: {
            x: width / 2 - 24,
            y: -22,
            width: 14,
            height: 14,
            img:
              cfg.chg > 0
                ? getSvg(1, '#D91212')
                : cfg.chg < 0
                ? getSvg(-1, '#12A96E')
                : getSvg(0, '#999'),
            cursor: cfg.text !== '线材' ? 'pointer' : '',
          },
          name: 'img-1',
        })
        group.addShape('text', {
          attrs: {
            text: formatNumValue(cfg.dataValue),
            x: -width / 2 + 12,
            y: 22,
            textAlign: 'left',
            fill: cfg.chg > 0 ? '#D91212' : cfg.chg < 0 ? '#12A96E' : '#666',
            fontSize: 12,
            fontWeight: 600,
          },
          name: 'text3',
        })
        group.addShape('text', {
          attrs: {
            text:
              (cfg.chg > 0 ? '+' : cfg.chg < 0 ? '' : '') +
              cfg.chg +
              (cfg.chg && cfg.chg != '-' ? '%' : ''),
            x: width / 2 - 12,
            y: 22,
            textAlign: 'right',
            fill: cfg.chg > 0 ? '#D91212' : cfg.chg < 0 ? '#12A96E' : '#666',
            fontSize: 12,
            fontWeight: 600,
          },
          name: 'text4',
        })
      }

      return mainRect
    },
  })
  //创建文本节点
  G6.registerNode('word-rect', {
    draw(cfg, group) {
      // 主矩形配置
      const width = cfg.width ? cfg.width : 120
      const height = cfg.height ? cfg.height : 40
      let fill = cfg.fill ? cfg.fill : 'l(90) 0:#F5F9FF 1:#E0EDFF'
      const stroke = cfg.strock ? cfg.strock : '#BCD0EE'
      // 创建主矩形
      const mainRect = group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: -height / 2,
          width,
          height,
          fill: fill,
          stroke,
          lineWidth: 1,
          radius: [4, 4, 4, 4],
          padding: 0,
          shadowOffsetX: 0,
          shadowOffsetY: 2,
          shadowBlur: 6,
          spread: 2,
          shadowColor: 'rgba(149,157,174,0.1)',
        },
        name: 'main-rect',
      })
      //no_compute,是否不需要计算换行
      //如果文本长度大于矩形宽度,则进行换行
      if (cfg.label.length * 16 > cfg.width && !cfg.no_compute) {
        let startLength = Math.floor((cfg.width - 20) / 16)
        let lines = Math.ceil(cfg.label.length / startLength)
        let startTop = (cfg.height - 16 * lines + 2 * (lines - 1)) / 2
        for (let i = 0; i < lines; i++) {
          group.addShape('text', {
            attrs: {
              x: 0,
              y: -height / 2 + 6 + startTop + i * 18,
              text: cfg.label.substring(i * startLength, (i + 1) * startLength),
              fontSize: 14,
              textAlign: 'center',
              textBaseline: 'middle',
              fill: '#333',
              fontSize: 14,
              fontWeight: 600,
            },
            name: 'text-shape',
          })
        }
      } else {
        group.addShape('text', {
          attrs: {
            text: cfg.label,
            x: 0,
            y: cfg.subLabel ? -2 : 8,
            textAlign: 'center',
            fill: '#333',
            fontSize: 14,
            fontWeight: 600,
          },
          name: 'text1',
        })
        if (cfg.subLabel) {
          group.addShape('text', {
            attrs: {
              text: cfg.subLabel,
              x: 0,
              y: 17,
              textAlign: 'center',
              fill: cfg.subLabel?.style?.fill || '#666',
              fontSize: cfg.subLabel?.style?.fontSize || 12,
              fontWeight: cfg.subLabel?.style?.weight || 400,
            },
            name: 'text2',
          })
        }
      }

      return mainRect
    },
    setState(name, value, item) {
      if (name === 'hover') {
        const group = item.getContainer()
        const main_rect = group.find((ele) => ele.get('name') === 'main-rect')
        main_rect.attr(
          'shadowColor',
          value ? 'rgba(149,157,174,0.2)' : 'rgba(149,157,174,0.1)'
        )
      }
    },
  })
  //创建自定义节点
  G6.registerNode('custom-node', {
    draw(cfg, group) {
      // 主矩形配置
      const width = cfg.width
      const height = cfg.height
      const fill = cfg.fill || '#fff'
      const stroke = cfg.strock
      // 创建主矩形
      const mainRect = group.addShape('rect', {
        attrs: {
          x: -width / 2,
          y: -height / 2,
          width,
          height,
          fill: fill,
          stroke,
          lineWidth: cfg.lineWidth || 1,
          radius: cfg.radius || [4, 4, 4, 4],
          padding: 0,
          shadowOffsetX: 0,
          shadowOffsetY: 2,
          shadowBlur: 6,
          spread: 2,
          shadowColor: cfg.shadowColor || 'rgba(149,157,174,0.1)',
        },
        name: 'main-rect',
      })
      cfg.pieceList &&
        cfg.pieceList.forEach((e, i) => {
          if (e.type == 'rect') {
            group.addShape('rect', {
              attrs: {
                x: e.x,
                y: e.y,
                width: e.width,
                height: e.height,
                fill: e.fill || '#fff',
                stroke: e.strock || '#fff',
                lineWidth: e.lineWidth || 0,
                radius: e.radius,
              },
              name: 'top-rect' + i,
            })
          }
          if (e.type == 'text') {
            group.addShape('text', {
              attrs: {
                x: e.x,
                y: e.y,
                text: e.label,
                fontSize: e.fontSize,
                textAlign: e.align,
                textBaseline: 'middle',
                fill: e.fill,
                fontWeight: e.weight,
              },
              name: 'text-shape',
            })
          }
        })

      return mainRect
    },
    setState(name, value, item) {
      if (name === 'hover') {
        const group = item.getContainer()
        const main_rect = group.find((ele) => ele.get('name') === 'main-rect')
        main_rect.attr(
          'shadowColor',
          value ? 'rgba(149,157,174,0.2)' : 'rgba(149,157,174,0.1)'
        )
      }
    },
  })
  //从左往右的箭头
  G6.registerEdge('hvh', {
    draw(cfg, group) {
      const startPoint = cfg.startPoint
      const endPoint = cfg.endPoint
      const shape = group.addShape('path', {
        attrs: {
          stroke: '#8993AA',
          path: [
            ['M', startPoint.x, startPoint.y],
            ['L', endPoint.x / 2 + (1 / 2) * startPoint.x, startPoint.y], // 二分之一处
            ['L', endPoint.x / 2 + (1 / 2) * startPoint.x, endPoint.y], // 二分之一处
            ['L', endPoint.x, endPoint.y],
          ],
          lineWidth: 1,
          lineDash: cfg.lineDash ? cfg.lineDash : '', // 自定义虚线模式
          zIndex: 10, // 确保边在顶部
          // startArrow: {
          //   path: "M 10,0 L -10,-10 L -10,10 Z",
          //   d: 10,
          // },
          // endArrow: {
          //   path: "M 10,0 L -10,-10 L -10,10 Z",
          //   d: 5,
          // },
          // endArrow: {
          //   path: G6.Arrow.triangle(10, 12, 25), // 三角形箭头
          //   fill: "#333", // 填充颜色
          //   stroke: "#333", // 边框颜色
          // },
        },
      })
      // 计算箭头方向
      const angle = Math.atan2(
        endPoint.y - startPoint.y,
        endPoint.x - startPoint.x
      )
      // 自定义箭头路径生成方法
      function getArrowPath(x, y, angle) {
        const length = 9 // 箭头长度
        const width = 4 // 箭头宽度

        // 计算箭头三个点的坐标
        const x1 = x - length * Math.cos(angle)
        const y1 = y - length * Math.sin(angle)

        const x2 = x1 - width * Math.cos(angle + Math.PI / 2)
        const y2 = y1 - width * Math.sin(angle + Math.PI / 2)

        const x3 = x1 - width * Math.cos(angle - Math.PI / 2)
        const y3 = y1 - width * Math.sin(angle - Math.PI / 2)

        return [['M', x, y], ['L', x2, y2], ['L', x3, y3], ['Z']]
      }
      //是否不需要显示箭头
      if (!cfg.disableArrow) {
        // 在终点绘制自定义箭头
        group.addShape('path', {
          attrs: {
            path: getArrowPath(endPoint.x, endPoint.y, 0),
            fill: '#8993AA',
            stroke: '#8993AA',
            lineWidth: 1,
          },
        })
      }
      // //在边上画循环点
      const circle = group.addShape('ellipse', {
        attrs: {
          x: cfg.startPoint.x,
          y: cfg.startPoint.y,
          fill: 'l(0) 0:rgba(102,212,255,0.7) 1:#1A56FF',
          rx: 4,
          ry: 1,
          shadowColor: '#1A56FF',
          shadowBlur: 4,
          shadowOffsetY: 1,
        },
        name: 'circle-shape',
      })
      const time =
        (Math.abs(cfg.endPoint.x - cfg.startPoint.x) +
          Math.abs(cfg.endPoint.y - cfg.startPoint.y)) /
        0.05
      circle.show()
      circle.animate(
        (ratio) => {
          const tmpPoint = shape.getPoint(ratio)
          const pos = G6.Util.getLabelPosition(shape, ratio)
          let matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]
          matrix = G6.Util.transform(matrix, [
            ['t', -tmpPoint.x, -tmpPoint.y],
            ['r', pos.angle],
            ['t', tmpPoint.x, tmpPoint.y],
          ])
          return {
            x: tmpPoint.x,
            y: tmpPoint.y,
            matrix,
          }
        },
        {
          repeat: true,
          duration: time,
          easing: 'easeLinear',
          delay: 0,
        }
      )

      // 计算边的中点
      const midX = (startPoint.x + endPoint.x) / 2
      const midY = (startPoint.y + endPoint.y) / 2
      // 计算边的角度(用于文本旋转)
      const angle2 = Math.atan2(
        endPoint.y - startPoint.y,
        endPoint.x - startPoint.x
      )

      // 添加上方文本
      if (cfg.label) {
        group.addShape('text', {
          attrs: {
            x: midX,
            y: midY - 6, // 上方偏移
            text: cfg.label,
            fill: cfg.labelCfg?.style?.fill || '#333',
            fontSize: cfg.labelCfg?.style?.fontSize || 12,
            textAlign: 'center',
            textBaseline: 'bottom',
            rotate: angle2,
          },
        })
      }

      // 添加下方文本
      if (cfg.subLabel) {
        group.addShape('text', {
          attrs: {
            x: midX,
            y: midY + 6, // 下方偏移
            text: cfg.subLabel,
            fill: cfg.subLabelCfg?.style?.fill || '#666',
            fontSize: cfg.subLabelCfg?.style?.fontSize || 12,
            textAlign: 'center',
            textBaseline: 'top',
            rotate: angle2,
          },
        })
      }
      return shape
    },
  })
  //从下往上的边
  G6.registerEdge('hvh2', {
    draw(cfg, group) {
      const startPoint = cfg.startPoint
      const endPoint = cfg.endPoint
      //默认显示2个拐角
      let shape = null
      if (cfg.corner) {
        //只显示一个拐角
        shape = group.addShape('path', {
          attrs: {
            stroke: '#8993AA',
            path: [
              ['M', startPoint.x, startPoint.y],
              ['L', endPoint.x, startPoint.y],
              ['L', endPoint.x, endPoint.y],
            ],
            lineWidth: 1,
            lineDash: cfg.lineDash ? cfg.lineDash : '', // 自定义虚线模式
            zIndex: 10, // 确保边在顶部
          },
        })
      } else {
        shape = group.addShape('path', {
          attrs: {
            stroke: '#8993AA',
            path: [
              ['M', startPoint.x, startPoint.y],
              [
                'L',
                startPoint.x,
                (2 / 3) * startPoint.y + (1 / 3) * endPoint.y,
              ], // 三分之一处
              ['L', endPoint.x, (2 / 3) * startPoint.y + (1 / 3) * endPoint.y], // 三分之二处
              ['L', endPoint.x, endPoint.y],
            ],
            lineWidth: 1,
            lineDash: cfg.lineDash ? cfg.lineDash : '', // 自定义虚线模式
            zIndex: 10, // 确保边在顶部
          },
        })
      }
      // 计算箭头方向
      const angle = Math.atan2(
        endPoint.y - startPoint.y,
        endPoint.x - startPoint.x
      )
      // 自定义箭头路径生成方法
      function getArrowPath(x, y, angle) {
        const length = 9 // 箭头长度
        const width = 4 // 箭头宽度

        // 计算箭头三个点的坐标
        const x1 = x
        const y1 = y

        const x2 = x1 - width
        const y2 = y1 + length

        const x3 = x1 + width
        const y3 = y1 + length

        return [['M', x, y], ['L', x2, y2], ['L', x3, y3], ['Z']]
      }
      // 在终点绘制自定义箭头
      group.addShape('path', {
        attrs: {
          path: getArrowPath(endPoint.x, endPoint.y, 0),
          fill: '#8993AA',
          stroke: '#8993AA',
          lineWidth: 1,
        },
      })

      // //在边上画循环点
      const circle = group.addShape('ellipse', {
        attrs: {
          x: cfg.startPoint.x,
          y: cfg.startPoint.y,
          fill: 'l(0) 0:rgba(102,212,255,0.7) 1:#1A56FF',
          rx: 4,
          ry: 1,
          shadowColor: '#1A56FF',
          shadowBlur: 4,
          shadowOffsetY: 1,
        },
        name: 'circle-shape',
      })
      const time =
        (Math.abs(cfg.endPoint.x - cfg.startPoint.x) +
          Math.abs(cfg.endPoint.y - cfg.startPoint.y)) /
        0.05
      circle.show()
      circle.animate(
        (ratio) => {
          const tmpPoint = shape.getPoint(ratio)
          const pos = G6.Util.getLabelPosition(shape, ratio)
          let matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]
          matrix = G6.Util.transform(matrix, [
            ['t', -tmpPoint.x, -tmpPoint.y],
            ['r', pos.angle],
            ['t', tmpPoint.x, tmpPoint.y],
          ])
          return {
            x: tmpPoint.x,
            y: tmpPoint.y,
            matrix,
          }
        },
        {
          repeat: true,
          duration: time,
          easing: 'easeLinear',
          delay: 0,
        }
      )

      return shape
    },
  })
  //从上往下的边
  G6.registerEdge('hvh3', {
    draw(cfg, group) {
      const startPoint = cfg.startPoint
      const endPoint = cfg.endPoint
      //默认显示2个拐角
      let shape = null
      if (cfg.corner) {
        //只显示一个拐角
        shape = group.addShape('path', {
          attrs: {
            stroke: '#8993AA',
            path: [
              ['M', startPoint.x, startPoint.y],
              ['L', endPoint.x, startPoint.y],
              ['L', endPoint.x, endPoint.y],
            ],
            lineWidth: 1,
            lineDash: cfg.lineDash ? cfg.lineDash : '', // 自定义虚线模式
          },
        })
      } else {
        shape = group.addShape('path', {
          attrs: {
            stroke: '#8993AA',
            path: [
              ['M', startPoint.x, startPoint.y],
              [
                'L',
                startPoint.x,
                (2 / 3) * startPoint.y + (1 / 3) * endPoint.y,
              ], // 三分之一处
              ['L', endPoint.x, (2 / 3) * startPoint.y + (1 / 3) * endPoint.y], // 三分之二处
              ['L', endPoint.x, endPoint.y],
            ],
            lineWidth: 1,
            lineDash: cfg.lineDash ? cfg.lineDash : '', // 自定义虚线模式
          },
        })
      }
      // 计算箭头方向
      const angle = Math.atan2(
        endPoint.y - startPoint.y,
        endPoint.x - startPoint.x
      )
      // 自定义箭头路径生成方法
      function getArrowPath(x, y, angle) {
        const length = 9 // 箭头长度
        const width = 4 // 箭头宽度

        // 计算箭头三个点的坐标
        const x1 = x
        const y1 = y

        const x2 = x1 - width
        const y2 = y1 - length

        const x3 = x1 + width
        const y3 = y1 - length

        return [['M', x, y], ['L', x2, y2], ['L', x3, y3], ['Z']]
      }
      // 在终点绘制自定义箭头
      group.addShape('path', {
        attrs: {
          path: getArrowPath(endPoint.x, endPoint.y, 0),
          fill: '#8993AA',
          stroke: '#8993AA',
          lineWidth: 1,
        },
      })

      // //在边上画循环点
      const circle = group.addShape('ellipse', {
        attrs: {
          x: cfg.startPoint.x,
          y: cfg.startPoint.y,
          fill: 'l(0) 0:rgba(102,212,255,0.7) 1:#1A56FF',
          rx: 4,
          ry: 1,
          shadowColor: '#1A56FF',
          shadowBlur: 4,
          shadowOffsetY: 1,
        },
        name: 'circle-shape',
      })
      const time =
        (Math.abs(cfg.endPoint.x - cfg.startPoint.x) +
          Math.abs(cfg.endPoint.y - cfg.startPoint.y)) /
        0.05
      circle.show()
      circle.animate(
        (ratio) => {
          const tmpPoint = shape.getPoint(ratio)
          const pos = G6.Util.getLabelPosition(shape, ratio)
          let matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]
          matrix = G6.Util.transform(matrix, [
            ['t', -tmpPoint.x, -tmpPoint.y],
            ['r', pos.angle],
            ['t', tmpPoint.x, tmpPoint.y],
          ])
          return {
            x: tmpPoint.x,
            y: tmpPoint.y,
            matrix,
          }
        },
        {
          repeat: true,
          duration: time < 1000 ? 1000 : time,
          easing: 'easeLinear',
          delay: 0,
        }
      )

      return shape
    },
  })
  //从右往左的边
  G6.registerEdge('hvh4', {
    draw(cfg, group) {
      const startPoint = cfg.startPoint
      const endPoint = cfg.endPoint
      const shape = group.addShape('path', {
        attrs: {
          stroke: '#8993AA',
          path: [
            ['M', startPoint.x, startPoint.y],
            ['L', startPoint.x - 20, startPoint.y], // 三分之一处
            [
              'L',
              startPoint.x - 20,
              (1 / 3) * startPoint.y + (2 / 3) * endPoint.y,
            ], // 三分之二处
            ['L', endPoint.x, (1 / 3) * startPoint.y + (2 / 3) * endPoint.y], // 三分之二处
            ['L', endPoint.x, endPoint.y],
          ],
          lineWidth: 1,
          lineDash: cfg.lineDash ? cfg.lineDash : '', // 自定义虚线模式
        },
      })
      // 计算箭头方向
      const angle = Math.atan2(
        endPoint.y - startPoint.y,
        endPoint.x - startPoint.x
      )
      // 自定义箭头路径生成方法
      function getArrowPath(x, y, angle) {
        const length = 9 // 箭头长度
        const width = 4 // 箭头宽度

        // 计算箭头三个点的坐标
        const x1 = x
        const y1 = y

        const x2 = x1 - width
        const y2 = y1 - length

        const x3 = x1 + width
        const y3 = y1 - length

        return [['M', x, y], ['L', x2, y2], ['L', x3, y3], ['Z']]
      }
      // 在终点绘制自定义箭头
      group.addShape('path', {
        attrs: {
          path: getArrowPath(endPoint.x, endPoint.y, 0),
          fill: '#8993AA',
          stroke: '#8993AA',
          lineWidth: 1,
        },
      })

      // //在边上画循环点
      const circle = group.addShape('ellipse', {
        attrs: {
          x: cfg.startPoint.x,
          y: cfg.startPoint.y,
          fill: 'l(0) 0:rgba(102,212,255,0.7) 1:#1A56FF',
          rx: 4,
          ry: 1,
          shadowColor: '#1A56FF',
          shadowBlur: 4,
          shadowOffsetY: 1,
        },
        name: 'circle-shape',
      })
      const time =
        (Math.abs(cfg.endPoint.x - cfg.startPoint.x) +
          Math.abs(cfg.endPoint.y - cfg.startPoint.y)) /
        0.05
      circle.show()
      circle.animate(
        (ratio) => {
          const tmpPoint = shape.getPoint(ratio)
          const pos = G6.Util.getLabelPosition(shape, ratio)
          let matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]
          matrix = G6.Util.transform(matrix, [
            ['t', -tmpPoint.x, -tmpPoint.y],
            ['r', pos.angle],
            ['t', tmpPoint.x, tmpPoint.y],
          ])
          return {
            x: tmpPoint.x,
            y: tmpPoint.y,
            matrix,
          }
        },
        {
          repeat: true,
          duration: time,
          easing: 'easeLinear',
          delay: 0,
        }
      )

      return shape
    },
  })
  //自定义边
  G6.registerEdge('hvh_custom', {
    draw(cfg, group) {
      const startPoint = cfg.startPoint
      const endPoint = cfg.endPoint
      let path = []
      //默认连接起始点和终端,中间的线段通过传入的数组连接
      path.push(['M', startPoint.x, startPoint.y])
      for (let i = 0; i < cfg.path.length; i++) {
        path.push(['L', cfg.path[i][0], cfg.path[i][1]])
      }
      path.push(['L', endPoint.x, endPoint.y])
      const shape = group.addShape('path', {
        attrs: {
          stroke: '#8993AA',
          path: path,
          lineWidth: 1,
          lineDash: cfg.lineDash ? cfg.lineDash : '', // 自定义虚线模式
        },
      })
      // 自定义箭头路径生成方法
      function getArrowPath(x, y, direction) {
        const length = 9 // 箭头长度
        const width = 4 // 箭头宽度

        // 计算箭头三个点的坐标
        const x1 = x
        const y1 = y
        let x2, y2, x3, y3
        if (direction == 'top') {
          x2 = x1 - width
          y2 = y1 + length

          x3 = x1 + width
          y3 = y1 + length
        } else if (direction == 'right') {
          x2 = x1 - length
          y2 = y1 - width

          x3 = x1 - length
          y3 = y1 + width
        } else if (direction == 'bottom') {
          x2 = x1 - width
          y2 = y1 - length

          x3 = x1 + width
          y3 = y1 - length
        } else {
          //默认箭头往左
          x2 = x1 + length
          y2 = y1 - width

          x3 = x1 + length
          y3 = y1 + width
        }

        return [['M', x, y], ['L', x2, y2], ['L', x3, y3], ['Z']]
      }
      // 在终点绘制自定义箭头
      group.addShape('path', {
        attrs: {
          path: getArrowPath(endPoint.x, endPoint.y, cfg.direction),
          fill: '#8993AA',
          stroke: '#8993AA',
          lineWidth: 1,
        },
      })

      // //在边上画循环点
      const circle = group.addShape('ellipse', {
        attrs: {
          x: cfg.startPoint.x,
          y: cfg.startPoint.y,
          fill: 'l(0) 0:rgba(102,212,255,0.7) 1:#1A56FF',
          rx: 4,
          ry: 1,
          shadowColor: '#1A56FF',
          shadowBlur: 4,
          shadowOffsetY: 1,
        },
        name: 'circle-shape',
      })
      const time =
        (Math.abs(cfg.endPoint.x - cfg.startPoint.x) +
          Math.abs(cfg.endPoint.y - cfg.startPoint.y)) /
        0.05
      circle.show()
      circle.animate(
        (ratio) => {
          const tmpPoint = shape.getPoint(ratio)
          const pos = G6.Util.getLabelPosition(shape, ratio)
          let matrix = [1, 0, 0, 0, 1, 0, 0, 0, 1]
          matrix = G6.Util.transform(matrix, [
            ['t', -tmpPoint.x, -tmpPoint.y],
            ['r', pos.angle],
            ['t', tmpPoint.x, tmpPoint.y],
          ])
          return {
            x: tmpPoint.x,
            y: tmpPoint.y,
            matrix,
          }
        },
        {
          repeat: true,
          duration: time,
          easing: 'easeLinear',
          delay: 0,
        }
      )

      // 计算边的中点
      let midX = (startPoint.x + endPoint.x) / 2
      let midY = (startPoint.y + endPoint.y) / 2
      //自定义边传入的起始点及结束点
      if (cfg.labelCfg && cfg.labelCfg.startPoint && cfg.labelCfg.endPoint) {
        midX = (cfg.labelCfg.startPoint.x + cfg.labelCfg.endPoint.x) / 2
        midY = (cfg.labelCfg.startPoint.y + cfg.labelCfg.endPoint.y) / 2
      }
      // 计算边的角度(用于文本旋转)
      const angle2 = Math.atan2(
        endPoint.y - startPoint.y,
        endPoint.x - startPoint.x
      )

      // 添加上方文本
      if (cfg.label) {
        group.addShape('text', {
          attrs: {
            x: midX,
            y: midY - 6, // 上方偏移
            text: cfg.label,
            fill: cfg.labelCfg?.style?.fill || '#333',
            fontSize: cfg.labelCfg?.style?.fontSize || 12,
            textAlign: 'center',
            textBaseline: 'bottom',
            rotate: angle2,
          },
        })
      }

      // 添加下方文本
      if (cfg.subLabel) {
        group.addShape('text', {
          attrs: {
            x: midX,
            y: midY + 6, // 下方偏移
            text: cfg.subLabel,
            fill: cfg.subLabelCfg?.style?.fill || '#666',
            fontSize: cfg.subLabelCfg?.style?.fontSize || 12,
            textAlign: 'center',
            textBaseline: 'top',
            rotate: angle2,
          },
        })
      }

      return shape
    },
  })

  const graph = new G6.Graph({
    container: 'mountNode',
    width: 1380,
    height: mapHeight.value,
    minZoom: 0.4,
    maxZoom: 1,
    modes: {
      default: [
        'click-select',
        { type: 'drag-canvas', enableOptimize: true },
        {
          type: 'zoom-canvas',
          optimizeZoom: true,
          shouldUpdate: () => false,
          onWheel: (e) => {
            e.preventDefault()
            const currentZoom = graph.getZoom()
            let ratio =
              e.wheelDelta > 0
                ? Math.min(currentZoom + 0.1, 1)
                : Math.max(currentZoom - 0.1, 0.4)
            graph.zoomTo(ratio, {
              x: graph.getWidth() / 2,
              y: graph.getHeight() / 2,
            })
            if (e.wheelDelta > 0 && ratio >= graph.getMaxZoom()) {
              graph.moveTo(0, 0)
            }
          },
        },
      ],
    },
    // defaultNode: {
    //   type: 'split-rect',
    //   size: [120, 80],
    //   style: { fill: '#FBEAEC', stroke: '#F8DDE0' },
    //   label: '',
    // },
    defaultNode: {
      type: 'product-rect',
      size: [120, 80],
      style: { fill: '#FBEAEC', stroke: '#F8DDE0' },
      label: '',
    },
    defaultEdge: {
      type: 'hvh',
      zIndex: 2,
    },
  })

  graph.data({
    edges: edges.value,
    nodes: nodes.value,
  })

  graph.render()

  nextTick(() => {
    const edgeGroup = graph.get('edgeGroup')
    edgeGroup.toFront()
    graph.paint()
  })

  // 提取公共方法
  function resetNodeStates() {
    graph.getNodes().forEach((node) => {
      if (node.getStates().includes('highlight')) {
        node.clearStates('highlight')
      }
    })
  }

  function handleNodeClick(evt) {
    console.log('handleNodeClick')
    const { item } = evt
    const model = item.getModel()
    if (item._cfg.currentShape === 'split-rect' && !item._cfg.model.noClick) {
      resetNodeStates()
      item.setState('highlight', true)
      if (item._cfg.model?.breedCode) {
        emit('breed-select', item._cfg.model.breedCode)
      }
    }
  }

  function handleNodeHover(ev, state) {
    const { item } = ev
    if (
      ['split-rect', 'breed-rect', 'ratio-rect', 'word-rect'].includes(
        item._cfg.currentShape
      )
    ) {
      graph.setItemState(item, 'hover', state)
    }
  }

  graph.on('node:click', handleNodeClick)

  graph.on('node:mouseenter', (ev) => {
    graph.setAutoPaint(false)
    handleNodeHover(ev, true)
    graph.paint()
    graph.setAutoPaint(true)
  })

  graph.on('node:mouseleave', (ev) => {
    handleNodeHover(ev, false)
  })

  let startX = 0
  let startY = 0

  graph.on('node:mousedown', (e) => {
    if (e.item._cfg.currentShape === 'block-rect') {
      isDragging.value = true
      startX = e.canvasX
      startY = e.canvasY
    }
  })

  graph.on('node:mousemove', (e) => {
    if (isDragging.value) {
      const dx = e.canvasX - startX
      const dy = e.canvasY - startY
      graph.translate(dx, dy, false, { duration: 500, easing: 'easeLinear' })
      startX = e.canvasX
      startY = e.canvasY
    }
  })

  graph.on('node:mouseup', () => {
    console.log('node:mouseup')
    isDragging.value = false
    //document.removeEventListener('mousemove', initDrag)
  })

  graph.on('canvas:mousemove', () => {
    isDragging.value = false
    //document.removeEventListener('mousemove', initDrag)
  })

  graph.on('canvas:mouseup', () => {
    isDragging.value = false
    //document.removeEventListener('mousemove', initDrag)
  })

  graph.on('viewportchange', () => {
    graph.refresh()
    graph.paint()
  })
  //默认选中品种
  graph.getNodes().forEach((node) => {
    // console.log('node', node._cfg.model.label)
    if (node._cfg.model.breedCode == window.breedCode) {
      node.setState('highlight', true)
    }
  })
  graph2.value = graph
  nextTick(() => {
    mapResize()
  })
}
const mapResize = () => {
  console.log('mapResize')
  nextTick(() => {
    let parentWidth = document.querySelector('.supply-analysis').clientWidth
    let width = parentWidth
    let autoHeight =
      ((!isBlank.value
        ? mapData[window.breedCode].mapHeight
        : defaultData.mapHeight) *
        width) /
      1426
    mapHeight.value = autoHeight
    mapPadding.value =
      ((!isBlank.value
        ? mapData[window.breedCode].mapPadding
        : defaultData.mapPadding) *
        width) /
      1376
    console.log('缩小比例', width / 1426)
    let ratio = document.getElementById('mountNode').clientWidth / 1376
    console.log('ratio', ratio)
    graph2.value &&
      graph2.value.zoomTo(ratio, {
        x: graph2.value.getWidth() / 2,
        y: graph2.value.getHeight() / 2,
      })
    graph2.value && graph2.value.moveTo(0, 0)
  })
}
//在移动节点过程中有时会丢失鼠标状态,因此通过页面监听鼠标移动事件获取鼠标状态
const initDrag = (e) => {
  //console.log('initDrag', e)
  if (e) {
    if (e.which == 0) {
      isDragging.value = false
    }
  }
}
onMounted(() => {
  console.log('mapData', mapData)
  if (!isBlank.value) {
    //console.log('显示铜产业链')
    edges.value = mapData[window.breedCode].edges
    nodes.value = mapData[window.breedCode].nodes
    mapHeight.value = mapData[window.breedCode].mapHeight
    mapPadding.value = mapData[window.breedCode].mapPadding
    desc.value = mapData[window.breedCode].desc
  } else {
    edges.value = defaultData.edges
    nodes.value = defaultData.nodes
    mapHeight.value = defaultData.mapHeight
    mapPadding.value = defaultData.mapPadding
  }
  const { menuCode } = route.query
  menuCode && loadGraphData(menuCode)
  //通用模块监听事件
  proxy.$bus.on('echartResize', mapResize)
  document.addEventListener('mousemove', initDrag)
})
onBeforeUnmount(() => {
  proxy.$bus.off('echartResize', mapResize)
  document.removeEventListener('mousemove', initDrag)
})
</script>
<style lang="less" scoped>
.link-map {
  padding: 12px;
  .link-title {
    font-weight: 600;
    font-size: 16px;
    color: #333333;
    line-height: 24px;
    text-align: center;
    margin-bottom: 12px;
  }
  .link-desc {
    font-size: 12px;
    margin-top: -4px;
    margin-bottom: 12px;
    :deep(span:nth-child(1)) {
      color: #245a9a;
    }
  }
}
#mountNode {
  width: 100%;
  height: 449px;
  // border: 1px solid #efefef;
  position: relative;
  overflow: hidden;
  max-width: 1376px;
  margin: 0 auto;
  //max-height: 379.299px;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2384716.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenCV CUDA模块图像过滤------用于创建一个最小值盒式滤波器(Minimum Box Filter)函数createBoxMinFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 该函数创建的是一个 最小值滤波器&#xff08;Minimum Filter&#xff09;&#xff0c;它对图像中每个像素邻域内的像素值取最小值。常用于&…

网络抓包命令tcpdump及分析工具wireshark使用

文章目录 环境文档用途详细信息 环境 系统平台&#xff1a;Linux x86-64 Red Hat Enterprise Linux 8,Linux x86-64 Red Hat Enterprise Linux 7,Linux x86-64 SLES 12,银河麒麟 &#xff08;鲲鹏&#xff09;,银河麒麟 &#xff08;X86_64&#xff09;,银河麒麟&#xff08;龙…

车载诊断架构 --- 车载诊断有那些内容(上)

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 钝感力的“钝”,不是木讷、迟钝,而是直面困境的韧劲和耐力,是面对外界噪音的通透淡然。 生活中有两种人,一种人格外在意别人的眼光;另一种人无论…

【Hadoop】大数据技术之 HDFS

目录 一、HDFS 概述 1.1 HDFS 产出背景及定义 1.2 HDFS 优缺点 1.3 HDFS 组成架构 1.4 HDFS 文件块大小 二、HDFS 的Shell 操作 三、HDFS 的读写流程&#xff08;面试重点&#xff09; 3.1 HDFS 写数据流程 3.2 HDFS 读数据流程 四、DataNode 4.1 DataNode 的工作机制…

聊一下CSS中的标准流,浮动流,文本流,文档流

在网络上关于CSS的文章中&#xff0c;有时候能听到“标准流”&#xff0c;“浮动流”&#xff0c;“定位流”等等词语&#xff0c;还有像“文档流”&#xff0c;“文本流”等词&#xff0c;这些流是什么意思&#xff1f;它们是CSS中的一些布局方案和特性。今天我们就来聊一下CS…

ATGM332D-F8N22单北斗多频定位导航模块

ATGM332D-F8N 系列模块是 12.216mm 尺寸的高性能单北斗多频定位导航模块。该系列模块产品基于中科微新一代 SOC 单北斗多频芯片 AT9880B&#xff0c;支持北斗二号和北斗三号的 B1I、B1C、B2I、B3I、B2a 和 B2b 频点信号。 主要特征 多频点单北斗接收机 支持北斗二号、北斗三号…

2024年热门AI趋势及回顾

人工智能的崛起 2024 年可能会被铭记为人工智能不再是一种技术新奇事物&#xff0c;而是成为现实的一年。微软、Salesforce 和 Intuit 等巨头将人工智能融入主流企业解决方案&#xff1b;从文案写作到数据分析&#xff0c;专门的人工智能应用程序和服务如雨后春笋般涌现&#…

3. OpenManus-RL中使用AgentGym建立强化学习环境

AgentGym概述 AgentGym是为评估和开发大模型agent而设计的支持多环境和多任务的框架。该框架统一采用ReAct格式&#xff0c;提供多样化的交互环境和任务&#xff0c;支持实时反馈和并发操作。 What is Ai Agent&#xff08;基于大模型的智能体&#xff09;? 首先是人造实体&…

C++性能测试工具——sysprof的使用

一、sysprof sysprof相对于前面的一些性能测试工具来说&#xff0c;要简单不少。特别是其图形界面的操作&#xff0c;非常容易上手&#xff0c;它还支持分析文件的保存和导入功能&#xff0c;这是一个非常不错的功能。做为一款系统性能测试工具&#xff0c;它支持多种硬件平台…

树莓派内核源码的下载,配置,编译和替换

共享文件夹的创建 ubuntu创建共享文件夹可以实现和本地windows跨系统文件共享 下面是创建步骤 先在windows准备一个文件夹来当做共享文件夹 树莓派内核源码下载 1.在树莓派终端输入以下指令查看内核版本 uname -r我这里是已经编译替换过后的版本 2.选择树莓派对应的版本号下…

CentOS停止维护了,解决yum不能安装软件的问题

最近在使用CentOS的yum命令安装软件时&#xff0c;出现了如下错误&#xff1a; 原因&#xff1a; 这是因为CentOS在2024 年 6 月 30 日停止维护了&#xff0c;同时也移除了相关的软件镜像仓库&#xff0c;导致网站地址访问不了&#xff0c;从而下载不了软件。 解决方法&#xf…

过压保护电路设计和计算

设备供电电压因各种原因变得过高会烧坏设备,因此可以在前级加过压保护电路。 稳压二极管+PMOS 电路分析 1、当输入电压 Vin < 5.1V 时:(下图以输入电压 Vin = 5V 举例) D1是5.1V稳压管,此时输入电压Vin才5V,小于5.1V,所以稳压管D1未进入稳压状态,不导通。 5.1V稳…

20250523-BUG:无法加载“GameLib/Framework.h“头文件(已解决)

BUG&#xff1a;无法加载"GameLib/Framework.h"头文件&#xff08;已解决&#xff09; 最近在打开新的C项目时报了这个错&#xff0c;我是按照以下步骤来排除的BUG&#xff0c;希望对您有所帮助~ 检查【C/C】-【附加包含目录】中的路径有无问题&#xff0c;一般需要加…

OpenCv高阶(8.0)——答题卡识别自动判分

文章目录 前言一、代码分析及流程讲解&#xff08;一&#xff09;初始化模块正确答案映射字典&#xff08;题目序号: 正确选项索引&#xff09;图像显示工具函数 &#xff08;二&#xff09;轮廓处理工具模块&#xff08;三&#xff09;几何变换核心模块 二、主处理流程图像读取…

Python语法特点与编码规范

注释 单行注释 把#号当做注释符号 多行注释 python中并没有规定多行注释标记&#xff0c;通常使用单引号作为多行注释 中文注释 规定文件所用编码&#xff0c;当时是为解决python2不支持中文的问题 #codingutf-8代码缩进 python采用代码缩进和冒号区分代码层次&#xff0c…

反本能---如何对抗你的习以为常

目录 一、概述 二、自我提升 &#xff08;一&#xff09;我们为什么总想拖延 &#xff08;二&#xff09;如何有效应对拖延 &#xff08;三&#xff09;如何更好的自我控制 &#xff08;四&#xff09;为啥付出了没有回报 &#xff08;五&#xff09;如何提高学习效率 三…

(15)关于窗体的右键菜单的学习与使用,这关系到了信号与事件 event

&#xff08;1&#xff09;起因来源于 4.11 的老师讲的例题&#xff0c;标准的&#xff0c;规范的使用右键菜单的代码及参考资料如下&#xff1a; &#xff08;2&#xff09; 接着脱离上面的那个复杂的环境&#xff0c;用简单的例子测试一下 &#xff1a; 说明老师讲的都是对…

Ubuntu Desktop 24.04 常用软件安装步骤

文章目录 Ubuntu Desktop 24.04 常用软件安装步骤Snipaste F1快捷截图&#xff08;超方便 | 我6台电脑每台都用&#xff09;搜狗输入法快速浏览工具 | 空格键快速预览文件壁纸工具 | varietySSH 工具 | Termius 终端分屏工具 | TmuxCaffeine | 避免息屏小工具 一些设置将启动台…

Linux iSCSI存储共享实验指南

实验介绍 1、在Linux平台上通过iSCSI协议实现IP-SAN存储共享 2、掌握存储导出(export)和存储导入(import)的配置方法 3、学习iSCSI存储的发现、连接、断开和管理操作 1、实验环境 两台同网段的Linux虚拟机&#xff08;无需物理交换机&#xff09; 操作系统&#xff1a;Lin…

git入门之HEAD介绍

目录 前言一、HEAD 的含义与作用二、游离状态的触发场景及特征1. 触发条件2. 游离状态的特征 三、游离状态的常见使用情况1. 临时查看历史代码2. 保留游离状态的提交 四、注意事项与最佳实践1. 风险防范2. 状态检测技巧 总结 前言 本文介绍Git核心概念HEAD的定义&#xff0c;作…