Prechádzať zdrojové kódy

增加层级下钻的功能

yanglzh 11 mesiacov pred
rodič
commit
bdceb9450c
3 zmenil súbory, kde vykonal 276 pridanie a 257 odobranie
  1. 40 253
      src/views/home/AllLink.vue
  2. 232 0
      src/views/home/g6.js
  3. 4 4
      yarn.lock

+ 40 - 253
src/views/home/AllLink.vue

@@ -1,278 +1,65 @@
 <template>
-  <div class="chart" ref="chartRef"></div>
+  <div class="chart-wrapper">
+    <div class="chart" id="g6ChartWrapper"></div>
+    <button type="primary" size="small" class="btn" v-if="level === 2" @click="draw">返回上一级</button>
+  </div>
 </template>
 <script setup>
 import G6 from '@antv/g6';
+import { getG6Options, getMockData, getMockData2 } from './g6';
 import { onMounted, ref } from 'vue';
 
-const chartRef = ref()
+let graph = null
 
+const level = ref(1)
 onMounted(() => {
+  graph = new G6.Graph(getG6Options({
+    container: 'g6ChartWrapper'
+  }));
   draw()
 })
 
-const img = new Image();
-img.src = 'https://gw.alipayobjects.com/os/s/prod/antv/assets/image/logo-with-text-73b8a.svg';
-
-// img.onload = draw
-const imgs = ['C.svg', 'Elastic.svg', 'Hadoop.svg', 'Flink.svg', 'Hive.svg', 'jaeger.svg', 'python.svg', 'Docker2.svg', 'Prometheus.svg', 'java.svg']
-
-
-
-const nodes = imgs.map((img, i) => {
-  return {
-    id: String(i),
-    label: img.split(','),
-    type: 'image',
-    size: [40, 40],
-    img: '/imgs/' + img
-  }
-})
-
-const data = {
-  nodes,
-  // nodes: [
-  //   {
-  //     id: '0',
-  //     label: 'Zabbix server linux',
-  //     type: 'image',
-  //     size: [120, 60],
-  //     img: img.src
-  //   },
-  //   {
-  //     id: '1',
-  //     label: 'xybclinux',
-  //   },
-  //   {
-  //     id: '2',
-  //     label: 'Zabbix server tomcat',
-  //   },
-  //   {
-  //     id: '3',
-  //     label: 'Zabbix server mysql',
-  //   },
-  //   {
-  //     id: '4',
-  //     label: 'tomcat pilot',
-  //   },
-  //   {
-  //     id: '5',
-  //     label: 'xybcmysql',
-  //   },
-  //   {
-  //     id: '6',
-  //     label: 'Xybc',
-  //   },
-  //   {
-  //     id: '7',
-  //     label: 'linux pilot',
-  //   },
-  //   {
-  //     id: '8',
-  //     label: 'Zabbix server',
-  //   },
-  //   {
-  //     id: '9',
-  //     label: 'pilot alive',
-  //   },
-  // ],
-  edges: [
-    {
-      source: '0',
-      target: '2',
-    },
-    {
-      source: '0',
-      target: '3',
-    },
-    {
-      source: '2',
-      target: '5',
-    },
-    {
-      source: '2',
-      target: '4',
-    },
-    {
-      source: '4',
-      target: '7',
-    },
-    {
-      source: '5',
-      target: '8',
-    },
-    {
-      source: '8',
-      target: '9',
-    },
-    {
-      source: '1',
-      target: '6',
-    }
-  ],
-};
-
-const colors = [
-  '#BDD2FD',
-  '#BDEFDB',
-  '#C2C8D5',
-  '#FBE5A2',
-  '#F6C3B7',
-  '#B6E3F5',
-  '#D3C6EA',
-  '#FFD8B8',
-  '#AAD8D8',
-  '#FFD6E7',
-];
-const strokes = [
-  '#5B8FF9',
-  '#5AD8A6',
-  '#5D7092',
-  '#F6BD16',
-  '#E8684A',
-  '#6DC8EC',
-  '#9270CA',
-  '#FF9D4D',
-  '#269A99',
-  '#FF99C3',
-];
+function nodeClick(event) {
+  graph.off('node:click', nodeClick);
+  setTimeout(() => {
+    draw2()
+  }, 100);
+}
 
 function draw() {
-  // const nodes = data.nodes;
-  // const clusterMap = new Map();
-  // let clusterId = 0;
-  // nodes.forEach(function (node) {
-  //   // cluster
-  //   if (node.cluster && clusterMap.get(node.cluster) === undefined) {
-  //     clusterMap.set(node.cluster, clusterId);
-  //     clusterId++;
-  //   }
-  //   const cid = clusterMap.get(node.cluster);
-  //   if (!node.style) {
-  //     node.style = {};
-  //   }
-  //   node.style.fill = colors[cid % colors.length];
-  //   node.style.stroke = strokes[cid % strokes.length];
-  // });
+  level.value = 1
+  graph.data(getMockData());
+  graph.render();
 
-  const container = chartRef.value
-  const width = container.scrollWidth;
-  const height = container.scrollHeight || 500;
-  const toolbar = new G6.ToolBar({
-    position: { x: 10, y: 10 },
-  });
+  // 节点上的点击事件
+  graph.on('node:click', nodeClick);
+}
 
-  // 浮动上之后显示提示框
-  const tooltip = new G6.Tooltip({
-    offsetX: 10,
-    offsetY: 10,
-    // 允许出现 tooltip 的 item 类型
-    // itemTypes: ['node', 'edge'],
-    itemTypes: ['node'],
-    // 自定义 tooltip 内容
-    getContent: (e) => {
-      const outDiv = document.createElement('div');
-      outDiv.style.width = 'fit-content';
-      //outDiv.style.padding = '0px 0px 20px 0px';
-      outDiv.innerHTML = `<ul>
-        <li>节点ID: ${e.item.getModel().id}</li>
-        <li>节点名称: ${e.item.getModel().label || e.item.getModel().id}</li>
-      </ul>`
-      return outDiv;
-    },
-  });
 
-  const graph = new G6.Graph({
-    container,
-    width,
-    height,
-    modes: {
-      default: ['drag-canvas', 'drag-node', 'activate-relations'],
-    },
-    plugins: [tooltip, toolbar],
-    fitView: 'autoZoom',
-    layout: {
-      type: 'radial',
-      unitRadius: 70,
-      preventOverlap: true,
-      strictRadial: false,
-    },
-    animate: true,
-    defaultNode: {
-      size: 30,
-      style: {
-        fill: '#fa8c16',
-        stroke: '#000',
-        lineWidth: 1
-      },
-      labelCfg: {
-        style: {
-          fill: '#fff',
-          fontSize: 10,
-          // background: {
-          //   fill: '#ffffff',
-          //   stroke: '#9EC9FF',
-          //   padding: [2, 2, 2, 2],
-          //   radius: 2,
-          // },
-        },
-        position: 'bottom',
-      },
-    },
-    defaultEdge: {
-      style: {
-        endArrow: {
-          path: 'M 0,0 L 8,4 L 8,-4 Z',
-          fill: '#fff',
-        },
-      },
-    },
-    nodeStateStyles: {
-      active: {
-        opacity: 1,
-      },
-      inactive: {
-        opacity: 0.4,
-        fill: '#000',
-      },
-    },
-    edgeStateStyles: {
-      active: {
-        opacity: 1,
-      },
-      inactive: {
-        opacity: 0.4,
-      },
-    },
-  });
-  graph.data(data);
+function draw2() {
+  level.value = 2
+  graph.clear();
+  // graph.destroy();
+  graph.data(getMockData2());
   graph.render();
-
-  // graph.on('node:mouseenter', (e) => {
-  //   graph.setItemState(e.item, 'active', true);
-  // });
-  // graph.on('node:mouseleave', (e) => {
-  //   graph.setItemState(e.item, 'active', false);
-  // });
-  // graph.on('edge:mouseenter', (e) => {
-  //   graph.setItemState(e.item, 'active', true);
-  // });
-  // graph.on('edge:mouseleave', (e) => {
-  //   graph.setItemState(e.item, 'active', false);
-  // });
-
-  if (typeof window !== 'undefined')
-    window.onresize = () => {
-      if (!graph || graph.get('destroyed')) return;
-      if (!container || !container.scrollWidth || !container.scrollHeight) return;
-      graph.changeSize(container.scrollWidth, container.scrollHeight);
-    };
 }
 
 </script>
 <style lang="scss" scoped>
-.chart {
+.chart-wrapper {
   width: 100%;
   height: 100%;
+  position: relative;
+
+  .chart {
+    width: 100%;
+    height: 100%;
+  }
+
+  .btn {
+    position: absolute;
+    right: 0;
+    top: 0;
+  }
 }
 </style>

+ 232 - 0
src/views/home/g6.js

@@ -0,0 +1,232 @@
+import G6 from '@antv/g6'
+
+const toolbar = new G6.ToolBar({
+  position: { x: 10, y: 10 }
+})
+
+// 浮动上之后显示提示框
+const tooltip = new G6.Tooltip({
+  offsetX: 10,
+  offsetY: 10,
+  // 允许出现 tooltip 的 item 类型
+  // itemTypes: ['node', 'edge'],
+  itemTypes: ['node'],
+  // 自定义 tooltip 内容
+  getContent: (e) => {
+    const outDiv = document.createElement('div')
+    outDiv.style.width = 'fit-content'
+    //outDiv.style.padding = '0px 0px 20px 0px';
+    outDiv.innerHTML = `<ul>
+        <li>节点ID: ${e.item.getModel().id}</li>
+        <li>节点名称: ${e.item.getModel().label || e.item.getModel().id}</li>
+      </ul>`
+    return outDiv
+  }
+})
+
+export function getG6Options({ container = 'container' }) {
+  return {
+    container,
+    // width,
+    // height,
+    modes: {
+      default: ['drag-canvas', 'drag-node', 'activate-relations']
+    },
+    plugins: [tooltip, toolbar],
+    fitView: 'autoZoom',
+    layout: {
+      type: 'radial',
+      unitRadius: 70,
+      preventOverlap: true,
+      strictRadial: false
+    },
+    animate: true,
+    defaultNode: {
+      size: 30,
+      style: {
+        fill: '#fa8c16',
+        stroke: '#000',
+        lineWidth: 1
+      },
+      labelCfg: {
+        style: {
+          fill: '#fff',
+          fontSize: 10
+          // background: {
+          //   fill: '#ffffff',
+          //   stroke: '#9EC9FF',
+          //   padding: [2, 2, 2, 2],
+          //   radius: 2,
+          // },
+        },
+        position: 'bottom'
+      }
+    },
+    defaultEdge: {
+      style: {
+        endArrow: {
+          path: 'M 0,0 L 8,4 L 8,-4 Z',
+          fill: '#fff'
+        }
+      }
+    },
+    nodeStateStyles: {
+      active: {
+        opacity: 1
+      },
+      inactive: {
+        opacity: 0.4,
+        fill: '#000'
+      }
+    },
+    edgeStateStyles: {
+      active: {
+        opacity: 1
+      },
+      inactive: {
+        opacity: 0.4
+      }
+    }
+  }
+}
+
+// 更新数据
+// graph.on('circle-shape:click', (evt) => {
+//   const { item } = evt;
+//   graph.updateItem(item, {
+//     label: '点击了局部',
+//     labelCfg: {
+//       style: {
+//         fill: '#003a8c',
+//         fontSize: 16,
+//       },
+//     },
+//   });
+// });
+
+// window.onresize = () => {
+//   if (!graph || graph.get('destroyed')) return
+//   if (!container || !container.scrollWidth || !container.scrollHeight) return
+//   graph.changeSize(container.scrollWidth, container.scrollHeight)
+// }
+
+export function getMockData() {
+  const img = new Image()
+  img.src = 'https://gw.alipayobjects.com/os/s/prod/antv/assets/image/logo-with-text-73b8a.svg'
+
+  // img.onload = draw
+  const imgs = ['C.svg', 'Elastic.svg', 'Hadoop.svg', 'Flink.svg', 'Hive.svg', 'jaeger.svg', 'python.svg', 'Docker2.svg', 'Prometheus.svg', 'java.svg']
+
+  const nodes = imgs.map((img, i) => {
+    return {
+      id: String(i),
+      label: img.split(','),
+      type: 'image',
+      size: [40, 40],
+      img: '/imgs/' + img
+    }
+  })
+
+  return {
+    nodes,
+    // nodes: [
+    //   {
+    //     id: '0',
+    //     label: 'Zabbix server linux',
+    //     type: 'image',
+    //     size: [120, 60],
+    //     img: img.src
+    //   },
+    // ],
+    edges: [
+      {
+        source: '0',
+        target: '2'
+      },
+      {
+        source: '0',
+        target: '3'
+      },
+      {
+        source: '2',
+        target: '5'
+      },
+      {
+        source: '2',
+        target: '4'
+      },
+      {
+        source: '4',
+        target: '7'
+      },
+      {
+        source: '5',
+        target: '8'
+      },
+      {
+        source: '8',
+        target: '9'
+      },
+      {
+        source: '1',
+        target: '6'
+      }
+    ]
+  }
+}
+
+export function getMockData2() {
+  const img = new Image()
+  img.src = 'https://gw.alipayobjects.com/os/s/prod/antv/assets/image/logo-with-text-73b8a.svg'
+
+  const imgs = ['C.svg', 'Elastic.svg', 'Hadoop.svg', 'Flink.svg', 'Hive.svg', 'jaeger.svg', 'python.svg', 'Docker2.svg', 'Prometheus.svg', 'java.svg']
+
+  const nodes = imgs.map((img, i) => {
+    return {
+      id: String(i),
+      label: img.split(','),
+      type: 'image',
+      size: [40, 40],
+      img: '/imgs/' + img
+    }
+  })
+
+  return {
+    nodes,
+    // nodes: [
+    //   {
+    //     id: '0',
+    //     label: 'Zabbix server linux',
+    //     type: 'image',
+    //     size: [120, 60],
+    //     img: img.src
+    //   },
+    // ],
+    edges: [
+      {
+        source: '0',
+        target: '1'
+      },
+      {
+        source: '0',
+        target: '2'
+      },
+      {
+        source: '0',
+        target: '3'
+      },
+      {
+        source: '0',
+        target: '4'
+      },
+      {
+        source: '0',
+        target: '5'
+      },
+      {
+        source: '0',
+        target: '6'
+      }
+    ]
+  }
+}

+ 4 - 4
yarn.lock

@@ -1206,10 +1206,10 @@ echarts@^5.2.1:
     tslib "2.3.0"
     zrender "5.4.0"
 
-element-plus@^2.2.27:
-  version "2.2.30"
-  resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.2.30.tgz#b594efcbd6969f3f88130aa1edf50c98139d6e73"
-  integrity sha512-HYSnmf2VMGa0gmw03evxevodPy3WimbAd4sfenOAhNs7Wl8IdT+YJjQyGAQjgEjRvhmujN4O/CZqhuEffRyOZg==
+element-plus@2.2.27:
+  version "2.2.27"
+  resolved "https://registry.yarnpkg.com/element-plus/-/element-plus-2.2.27.tgz#a5ddfe018597436e7c4bef6abd2108d72f765ea8"
+  integrity sha512-P04HDOZBYDdvlYuleuCZRULzAc5xJVOBfLDK9xWxVo0vyo8ntdaXS5sTU+/76vrNzuO3FhLn9kvrsbiJEVa1jg==
   dependencies:
     "@ctrl/tinycolor" "^3.4.1"
     "@element-plus/icons-vue" "^2.0.6"