SOURCE

<template>
  <div class="ex-chart">
    <div ref="refContainer1"></div>
  </div>
</template>

<script setup>
import G6 from '@antv/g6';
import { ref, onMounted } from 'vue';

const tooltip = new G6.Tooltip({
  offsetX: 12,
  offsetY: 12,
  className: 'el-popper is-dark base-tooltip',
  shouldBegin: e => e.item.getModel().label.length > 6,
  getContent: e => {
    return e.item.getModel().label;
  },
  itemTypes: ['node'],
});

G6.registerNode(
  'round-rect',
  {
    drawShape: function drawShape(cfg, group) {
      const width = cfg.style.width;
      const height = cfg.style.height;
      const rect = group.addShape('rect', {
        capture: true,
        attrs: {
          x: 0,
          y: 0,
          width,
          height,
          radius: 2,
          fill: cfg.style.fill,
          stroke: '#e1e1e1',
          default: {
            fill: '#fff',
            stroke: '#e1e1e1',
          },
          active: {
            fill: cfg.style.stroke,
            stroke: cfg.style.stroke,
          },
          lineWidth: 1,
          fillOpacity: 1,
        },
        name: 'rect-shape',
      });
      group.addShape('rect', {
        attrs: {
          x: 0,
          y: 0,
          width: 3,
          height,
          radius: [2, 0, 0, 2],
          fill: cfg.style.stroke,
        },
        name: 'rect-shape',
      });
      group.addShape('text', {
        attrs: {
          text: cfg.label.slice(0, 6) + (cfg.label.length > 6 ? '......' : ''),
          x: 64,
          y: height * 0.5,
          fontWeight: 700,
          fill: '#333',
          default: {
            fill: '#333',
          },
          active: {
            fill: '#fff',
          },
          fontSize: 20,
          textAlign: 'left',
          textBaseline: 'middle',
        },
        name: 'text-shape',
      });
      group.addShape('image', {
        attrs: {
          x: 26,
          y: height * 0.5 - 10,
          default: {
            img: cfg.data.icon,
          },
          active: {
            img: cfg.data.icon2,
          },
          img: cfg.data.icon,
        },
        name: 'image-shape',
      });
      return rect;
    },
    getAnchorPoints: function getAnchorPoints() {
      return [
        [0, 0.5],
        [1, 0.5],
      ];
    },
  },
  'single-node'
);

const data1 = ref({
  nodes: [
    {
      id: 'node1',
      label: '三要素验真API三要素验真API',
      data: { customA: 'a', icon: '/1.png', icon2: '/favicon.png' },
    },
    {
      id: 'node2',
      label: '浙江移动系统',
      data: { customA: 'a', icon: '/1.png', icon2: '/favicon.png' },
    },
    {
      id: 'node3',
      label: '上研院系统',
      data: { customA: 'a', icon: '/1.png', icon2: '/favicon.png' },
    },
  ],
  edges: [
    {
      target: 'node1',
      source: 'node2',
    },
    {
      target: 'node1',
      source: 'node3',
    },
  ],
});

const updateGroupStyle = (item, type = 'default') => {
  const groupAttr = item.getKeyShape().attrs;
  const children = item.get('group').get('children');
  children[0].attr('fill', groupAttr[type].fill);
  children[0].attr('stroke', groupAttr[type].stroke);
  children[2].attr('fill', children[2].attrs[type].fill);
  children[3].attr('img', children[3].attrs[type].img);
};
const refContainer1 = ref(null);
const activeNode = ref(null);
onMounted(() => {
  const graph = new G6.Graph({
    container: refContainer1.value,
    autoResize: true,
    plugins: [tooltip],
    layout: {
      type: 'dagre',
      rankdir: 'LR',
      nodesep: 30,
      ranksep: 100,
    },
    modes: {
      default: ['drag-canvas'],
    },
    defaultNode: {
      type: 'round-rect',
      labelCfg: {
        position: 'center',
        style: {
          fontWeight: 700,
          fill: 'rgba(0,0,0,0)',
          fontSize: 20,
        },
      },
      style: {
        stroke: '#2367f1',
        fill: '#fff',
        width: 222,
        height: 56,
      },
    },
    defaultEdge: {
      type: 'polyline',
      style: {
        endArrow: {
          fill: '#e1e1e1',
          stroke: '#e1e1e1',
          path: G6.Arrow.triangle(5, 5, 0),
          d: 0,
        },
        offset: 50,
        stroke: '#e1e1e1',
      },
    },
  });
  graph.data(data1.value);
  graph.render();

  graph.on('node:click', evt => {
    if (activeNode.value) {
      updateGroupStyle(activeNode.value);
    }
    activeNode.value = evt.item;
    updateGroupStyle(evt.item, 'active');
  });
});
</script>

<style lang="scss">
.ex-chart {
  height: 400px;
  & > div {
    height: 100%;
  }
}
.x6-node {
  cursor: pointer;
  * {
    cursor: pointer;
  }
}
.x6-edge {
  cursor: default !important;
  * {
    cursor: default !important;
  }
}
</style>
console 命令行工具 X clear

                    
>
console