AntV/G6入門


官方教程

安裝

    npm install --save @antv/g6

使用 vue 作為模板

步驟

<template>
  <v-container>
    <!--步驟.1 容器 -->
    <div id="mountNode"></div>
  </v-container>
</template>

<script>
import G6 from "@antv/g6";
export default {
  name: "G6",
  async mounted() {
    /*
    ## 步驟.2 數據准備
    引入 G6 的數據源為 JSON 格式的對象。該對象中需要有節點(nodes)和邊(edges)字段,分別用數組表示:
     */

    // 初始化數據
    const initData = {
      // 點集
      nodes: [
        {
          id: "node1", // 節點的唯一標識
          x: 100, // 節點橫坐標
          y: 200, // 節點縱坐標
          label: "起始點", // 節點文本
        },
        {
          id: "node2",
          x: 300,
          y: 200,
          label: "目標點",
        },
      ],
      // 邊集
      edges: [
        // 表示一條從 node1 節點連接到 node2 節點的邊
        {
          source: "node1", // 起始點 id
          target: "node2", // 目標點 id
          label: "我是連線", // 邊的文本
        },
      ],
    };
    /*
    ## 步驟.3 圖實例化
    圖實例化時,至少需要為圖設置容器、寬、高:
     */
    const graph = new G6.Graph({
      container: "mountNode", // 指定掛載容器
      width: 800, // 圖的寬度
      height: 500, // 圖的高度
    });
    /*
    ## 步驟.4 圖的渲染
    數據的加載和圖的渲染是兩個步驟,可以分開進行。
     */

    graph.data(initData); // 加載數據

    graph.render(); // 渲染 調用 graph.render() 方法之后,G6 引擎會根據加載的數據進行圖的繪制。
  },
};
</script>

元素及其配置

<script>
export default {
  name: "G6",
  async mounted() {
    const response = await fetch(
      "https://gw.alipayobjects.com/os/basement_prod/6cae02ab-4c29-44b2-b1fd-4005688febcb.json"
    );
    const initData = await response.json();
    // 將請求返回的數據遍歷 設置每個節點的樣式
    const nodes = initData.nodes;
    nodes.forEach((node) => {
      if (!node.style) {
        node.style = {};
      }
      switch (
        node.class // 根據節點數據中的 class 屬性配置圖形
      ) {
        case "c0": {
          node.type = "circle"; // class = 'c0' 時節點圖形為 circle
          break;
        }
        case "c1": {
          node.type = "rect"; // class = 'c1' 時節點圖形為 rect
          node.size = [35, 20]; // class = 'c1' 時節點大小
          break;
        }
        case "c2": {
          node.type = "ellipse"; // class = 'c2' 時節點圖形為 ellipse
          node.size = [35, 20]; // class = 'c2' 時節點大小
          break;
        }
      }
    });
    // 遍歷邊數據  設置每個邊的樣式
    const edges = initData.edges;
    edges.forEach((edge) => {
      if (!edge.style) {
        // 邊的樣式會覆蓋全局樣式 所以需要把全局樣式挪到這里
        edge.style = {
          stroke: "grey", // 邊描邊顏色
          opacity: 0.6, // 邊透明度
        };
      }
      edge.style.lineWidth = edge.weight; // 邊的粗細映射邊數據中的 weight 屬性數值
    });
    // 初始化數據
    // const initData = {
    //   // 點集 (節點集合)
    //   nodes: [
    //     /*
    //     元素的屬性
    //     不論是節點還是邊,它們的屬性分為兩種:

    //     樣式屬性 style:對應 Canvas 中的各種樣式,在元素狀態 State 發生變化時,可以被改變;
    //     其他屬性:例如圖形類型( type)、id(id )一類在元素狀態 State 發生變化時不能被改變的屬性。
    //     例如,G6 設定 hover 或 click 節點,造成節點狀態的改變,只能自動改變節點的樣式屬性(如 fill、stroke 等),其他屬性(如 type  等)不能被改變。如果需要改變其他屬性,要通過  graph.updateItem 手動配置。樣式屬性是一個名為  style  的對象, style 字段與其他屬性並行。
    //      */
    //     // 以節點元素為例,其屬性的數據結構如下:
    //     {
    //       id: "node0", // 元素的 id
    //       x: 0, // 節點橫坐標
    //       y: 0, // 節點縱坐標
    //       type: "rect", // 元素的圖形
    //       size: 40, // 元素的大小
    //       label: "node0", // 標簽文字
    //       visible: true, // 控制初次渲染顯示與隱藏,若為 false,代表隱藏。默認不隱藏
    //       // 標簽配置屬性
    //       labelCfg: {
    //         positions: "left", // 標簽的屬性,標簽在元素中的位置
    //         // 包裹標簽樣式屬性的字段 style 與標簽其他屬性在數據結構上並行
    //         style: {
    //           fontSize: 12, // 標簽的樣式屬性,文字字體大小
    //           // ...            // 標簽的其他樣式屬性
    //         },
    //       },
    //       // ...,               // 其他屬性
    //       // 包裹樣式屬性的字段 style 與其他屬性在數據結構上並行
    //       style: {
    //         fill: "#000", // 樣式屬性,元素的填充色
    //         stroke: "#888", // 樣式屬性,元素的描邊色
    //         // ...              // 其他樣式屬性
    //       },
    //     },
    //     {
    //       id: "node1", // 節點的唯一標識
    //       x: 100, // 節點橫坐標
    //       y: 200, // 節點縱坐標
    //       label: "起始點", // 節點文本
    //     },
    //     {
    //       id: "node2",
    //       x: 300,
    //       y: 200,
    //       label: "目標點",
    //     },
    //   ],
    //   // 邊集
    //   edges: [
    //     /*
    //     邊元素的屬性數據結構與節點元素相似,只是其他屬性中多了 source 和 target 字段,代表起始和終止節點的 id。
    //      */
    //     // 表示一條從 node0 節點連接到 node1 節點的邊
    //     {
    //       source: "node0", // 起始點 id
    //       target: "node1", // 目標點 id
    //       label: "我是連線", // 邊的文本
    //     },
    //     // 表示一條從 node1 節點連接到 node2 節點的邊
    //     {
    //       source: "node1", // 起始點 id
    //       target: "node2", // 目標點 id
    //       label: "我是連線", // 邊的文本
    //     },
    //   ],
    // };
    const graph = new G6.Graph({
      fitView: true, // 設置是否將圖適配到畫布中
      fitViewPadding: [0, 0, 0, 10], // 畫布上四周的留白寬度。
      animate: true, // 是否啟用圖的動畫。
      // 圖上行為模式的集合。由於比較復雜,按需參見:G6 中的 Mode 教程。
      modes: {
        default: [
          // 拖拽節點
          "drag-node",
          // 拖拽整個畫布
          "drag-canvas",
        ],
      },
      // 節點默認的屬性,包括節點的一般屬性和樣式屬性(style)
      defaultNode: {
        size: 30, // 節點大小
        /*
          type node節點圖形類型
          G6 支持以下圖形:
          - circle:圓;
          - rect:矩形;
          - ellipse:橢圓;
          - polygon:多邊形;
          - image:圖片;
          - marker:標記;
          - path:路徑;
          - text:文本;
          - dom(svg):DOM(圖渲染方式 renderer 為 'svg' 時可用)。
         */
        // type: "circle",
        // color: "#ff00ff",
        // 節點樣式配置 文檔 https://g6.antv.vision/zh/docs/api/shapeProperties#%E9%80%9A%E7%94%A8%E5%B1%9E%E6%80%A7
        style: {
          //////////////////////////////////////////////////////////////////////
          //通用屬性
          //////////////////////////////////////////////////////////////////////
          // 圖形名稱標識,G6 3.3 版本以上必須配置。
          name: "bitbw",
          // 設置用於填充繪畫的顏色(RGB 或 16 進制)、漸變或模式,對應 Canvas 屬性 fillStyle 。取值示例:rgb(18, 150, 231),#c193af,l(0) 0:#ffffff 0.5:#7ec2f3 1:#1890ff, r(0.5, 0.5, 0.1) 0:#ffffff 1:#1890ff。
          fill: "steelblue",
          // 節點描邊色
          stroke: "#666",
          // 邊寬度
          lineWidth: 6,
          // 描邊虛線,Number[] 類型中數組元素分別代表實、虛長度。
          lineDash: [1, 1],
          // 設置用於陰影的顏色。
          shadowColor: "#000000",
          // 設置用於陰影的模糊級別,數值越大,越模糊。 (擴散范圍)
          shadowBlur: 20,
          // 設置陰影距形狀的水平距離。(x 軸偏移量)
          shadowOffsetX: 10,
          // 設置陰影距形狀的垂直距離。(Y 軸偏移量)
          shadowOffsetY: 10,
          // 設置繪圖的當前 alpha 或透明值,范圍 [0, 1],對應 Canvas 屬性 globalAlpha。
          opacity: 0.3,
          // 設置填充的 alpha 或透明值,優先級高於 opacity,范圍 [0, 1]。
          fillOpacity: 0.9,
          // 設置描邊的 alpha 或透明值,優先級高於 opacity,范圍 [0, 1]。
          strokeOpacity: 0.9,
          // 鼠標在該節點上時的鼠標樣式,CSS 的 cursor 選項都支持。
          cursor: "help",
          //////////////////////////////////////////////////////////////////////
          // 各個圖形屬性  見文檔
          //////////////////////////////////////////////////////////////////////
        },
        // 節點上的標簽文本配置
        labelCfg: {
          // 節點上的標簽文本樣式配置
          style: {
            fill: "#fff", // 節點標簽文字顏色
          },
        },
      },
      // 邊默認的屬性,包括邊的一般屬性和樣式屬性(style)
      defaultEdge: {
        type: "polyline",
        color: "#ffff00",
        // ...                 // 邊的其他配置
        // 邊樣式配置
        style: {
          opacity: 0.6, // 邊透明度
          stroke: "grey", // 邊描邊顏色
        },
        // 邊上的標簽文本配置
        labelCfg: {
          autoRotate: true, // 邊上的標簽文本根據邊的方向旋轉
        },
      },
      // 邊在除默認狀態外,其他狀態下的樣式屬性(style)。例如鼠標放置(hover)、選中(select)等狀態
      nodeStateStyles: {
        hover: {},
        select: {},
      },
      container: "mountNode", // 指定掛載容器
      width: 1000, // 圖的寬度
      height: 1000, // 圖的高度
    });

    graph.data(initData); // 加載數據

    graph.render(); // 渲染 調用 graph.render() 方法之后,G6 引擎會根據加載的數據進行圖的繪制。
  },
};
</script>

布局Layout

<script>
export default {
  name: "G6",
  async mounted() {
    /* 
    當數據中沒有節點位置信息,或者數據中的位置信息不滿足需求時,需要借助一些布局算法對圖進行布局。G6 提供了 9 種一般圖的布局和 4 種樹圖的布局:
    一般圖:

    Random Layout:隨機布局;
    Force Layout:經典力導向布局:

    力導向布局:一個布局網絡中,粒子與粒子之間具有引力和斥力,從初始的隨機無序的布局不斷演變,逐漸趨於平衡穩定的布局方式稱之為力導向布局。適用於描述事物間關系,比如人物關系、計算機網絡關系等。

    Circular Layout:環形布局;
    Radial Layout:輻射狀布局;
    MDS Layout:高維數據降維算法布局;
    Fruchterman Layout:Fruchterman 布局,一種力導布局;
    Dagre Layout:層次布局;
    Concentric Layout:同心圓布局,將重要(默認以度數為度量)的節點放置在布局中心;
    Grid Layout:格子布局,將節點有序(默認是數據順序)排列在格子上。
    樹圖布局:

    Dendrogram Layout:樹狀布局(葉子節點布局對齊到同一層);
    CompactBox Layout:緊湊樹布局;
    Mindmap Layout:腦圖布局;
    Indented Layout:縮進布局。
     */

    /* 
      配置布局
     */
    const graph = new G6.Graph({
      //////////////////////////////////////////////////////////////////////////
      // Object,可選,布局的方法及其配置項,默認為 random 布局。
      layout: {
        type: "force", // 指定為力導向布局
        preventOverlap: true, // 防止節點重疊
        linkDistance: 100, // 指定邊距離為100
        // nodeSize: 30, // 節點大小,用於算法中防止節點重疊時的碰撞檢測。由於已經在上一節的元素配置中設置了每個節點的 size 屬性,則不需要在此設置 nodeSize。
      },
      //////////////////////////////////////////////////////////////////////////
      animate: true, // 是否啟用圖的動畫。
      // 圖上行為模式的集合。由於比較復雜,按需參見:G6 中的 Mode 教程。
      modes: {
        default: [
          // 拖拽節點
          "drag-node",
          // 拖拽整個畫布
          "drag-canvas",
        ],
      },
      defaultNode: {
        size: 30,
        labelCfg: {
          style: {
            fill: "#fff",
          },
        },
      },
      defaultEdge: {
        labelCfg: {
          autoRotate: true,
        },
      },
      container: "mountNode", // 指定掛載容器
      width: 1000, // 圖的寬度
      height: 1000, // 圖的高度
    });

    const main = async () => {
      const response = await fetch(
        "https://gw.alipayobjects.com/os/basement_prod/6cae02ab-4c29-44b2-b1fd-4005688febcb.json"
      );
      const remoteData = await response.json();

      const nodes = remoteData.nodes;
      const edges = remoteData.edges;
      nodes.forEach((node) => {
        if (!node.style) {
          node.style = {};
        }
        node.style.lineWidth = 1;
        node.style.stroke = "#666";
        node.style.fill = "steelblue";
        switch (node.class) {
          case "c0": {
            node.type = "circle";
            break;
          }
          case "c1": {
            node.type = "rect";
            node.size = [35, 20];
            break;
          }
          case "c2": {
            node.type = "ellipse";
            node.size = [35, 20];
            break;
          }
        }
      });
      edges.forEach((edge) => {
        if (!edge.style) {
          edge.style = {};
        }
        edge.style.lineWidth = edge.weight;
        edge.style.opacity = 0.6;
        edge.style.stroke = "grey";
      });

      graph.data(remoteData);
      graph.render();
    };
    main();
  },
};
</script>

交互行為Behavior

<script>
export default {
  name: "G6",
  async mounted() {
    /* 
    交互行為 Behavior
    G6 中的交互行為。G6 內置了一系列交互行為,用戶可以直接使用。簡單地理解,就是可以一鍵開啟這些交互行為:

    drag-canvas:拖拽畫布;
    zoom-canvas:縮放畫布。

    交互管理 Mode
    Mode 是 G6 交互行為的管理機制,一個 mode 是多種行為 Behavior 的組合,允許用戶通過切換不同的模式進行交互行為的管理。由於該概念較為復雜,在本入門教程中,讀者不需要對該機制深入理解。如有需求,參見 交互模式 Mode。

    交互狀態 State
    狀態 State 是 G6 中的狀態機制。用戶可以為圖中的元素(節點/邊)設置不同的狀態及不同狀態下的樣式。在狀態發生變化時,G6 自動更新元素的樣式。例如,可以為節點設置狀態 'click' 為 true 或 false,並為節點設置 'click' 的樣式為加粗節點邊框。當 'click' 狀態被切換為 true 時,節點的邊框將會被加粗,'click' 狀態被切換為 false 時,節點的樣式恢復到默認。在下面的使用方法中,將會有具體例子。
     */

    const graph = new G6.Graph({
      //////////////////////////////////////////////////////////////////////////
      //  交互管理 Mode
      //////////////////////////////////////////////////////////////////////////
      modes: {
        // 默認模式
        default: [
          // 拖拽節點
          "drag-node",
          // 拖拽整個畫布
          "drag-canvas",
          // 放縮畫布
          "zoom-canvas",
        ],
        // 編輯模式
        edit: [],
      },
      //////////////////////////////////////////////////////////////////////////
      // 交互狀態 State
      //////////////////////////////////////////////////////////////////////////
      // 節點不同狀態下的樣式集合
      nodeStateStyles: {
        // 鼠標 hover 上節點,即 hover 狀態為 true 時的樣式
        hover: {
          fill: "lightsteelblue",
        },
        // 鼠標點擊節點,即 click 狀態為 true 時的樣式
        click: {
          stroke: "#000",
          lineWidth: 3,
        },
      },
      // 邊不同狀態下的樣式集合
      edgeStateStyles: {
        // 鼠標點擊邊,即 click 狀態為 true 時的樣式
        click: {
          stroke: "steelblue",
        },
      },
      //////////////////////////////////////////////////////////////////////////

      // Object,可選,布局的方法及其配置項,默認為 random 布局。
      layout: {
        type: "force", // 指定為力導向布局
        preventOverlap: true, // 防止節點重疊
        linkDistance: 100, // 指定邊距離為100
        // nodeSize: 30, // 節點大小,用於算法中防止節點重疊時的碰撞檢測。由於已經在上一節的元素配置中設置了每個節點的 size 屬性,則不需要在此設置 nodeSize。
      },
      animate: true, // 是否啟用圖的動畫。

      defaultNode: {
        size: 30,
        labelCfg: {
          style: {
            fill: "#fff",
          },
        },
      },
      defaultEdge: {
        labelCfg: {
          autoRotate: true,
        },
      },
      container: "mountNode", // 指定掛載容器
      width: 1000, // 圖的寬度
      height: 1000, // 圖的高度
    });
    /* 
    監聽事件並切換元素狀態
    G6 中所有元素監聽都掛載在圖實例上,如下代碼中的 graph 對象是 G6.Graph 的實例,graph.on()  函數監聽了某元素類型(node / edge)的某種事件(click / mouseenter / mouseleave / ... 所有事件參見:Event API)。
    // 在圖實例 graph 上監聽
    graph.on('元素類型:事件名', (e) => {
      // do something
    });
     */
    //////////////////////////////////////////////////////////////////////////
    // 監聽事件並切換元素狀態
    //////////////////////////////////////////////////////////////////////////
    // 鼠標進入節點
    graph.on("node:mouseenter", (e) => {
      const nodeItem = e.item; // 獲取鼠標進入的節點元素對象
      graph.setItemState(nodeItem, "hover", true); // 設置當前節點的 hover 狀態為 true
    });

    // 鼠標離開節點
    graph.on("node:mouseleave", (e) => {
      const nodeItem = e.item; // 獲取鼠標離開的節點元素對象
      graph.setItemState(nodeItem, "hover", false); // 設置當前節點的 hover 狀態為 false
    });

    // 點擊節點
    graph.on("node:click", (e) => {
      // 先將所有當前是 click 狀態的節點置為非 click 狀態
      const clickNodes = graph.findAllByState("node", "click");
      console.log("Bowen: mounted -> clickNodes", clickNodes)
      clickNodes.forEach((cn) => {
        graph.setItemState(cn, "click", false);
      });
      const nodeItem = e.item; // 獲取被點擊的節點元素對象
      graph.setItemState(nodeItem, "click", true); // 設置當前節點的 click 狀態為 true
    });

    // 點擊邊
    graph.on("edge:click", (e) => {
      // 先將所有當前是 click 狀態的邊置為非 click 狀態
      const clickEdges = graph.findAllByState("edge", "click");
      clickEdges.forEach((ce) => {
        graph.setItemState(ce, "click", false);
      });
      const edgeItem = e.item; // 獲取被點擊的邊元素對象
      graph.setItemState(edgeItem, "click", true); // 設置當前邊的 click 狀態為 true
    });

    const main = async () => {
      const response = await fetch(
        "https://gw.alipayobjects.com/os/basement_prod/6cae02ab-4c29-44b2-b1fd-4005688febcb.json"
      );
      const remoteData = await response.json();

      const nodes = remoteData.nodes;
      const edges = remoteData.edges;
      nodes.forEach((node) => {
        if (!node.style) {
          node.style = {};
        }
        node.style.lineWidth = 1;
        node.style.stroke = "#666";
        node.style.fill = "steelblue";
        switch (node.class) {
          case "c0": {
            node.type = "circle";
            break;
          }
          case "c1": {
            node.type = "rect";
            node.size = [35, 20];
            break;
          }
          case "c2": {
            node.type = "ellipse";
            node.size = [35, 20];
            break;
          }
        }
      });
      edges.forEach((edge) => {
        if (!edge.style) {
          edge.style = {};
        }
        edge.style.lineWidth = edge.weight;
        edge.style.opacity = 0.6;
        edge.style.stroke = "grey";
      });

      graph.data(remoteData);
      graph.render();
    };
    main();
  },
};
</script>

插件與交互工具

<script>
import G6 from "@antv/g6";
export default {
  name: "G6",
  async mounted() {
    /* 
    插件與工具
    為輔助用戶在圖上探索,G6 提供了一些輔助工具,其中一部分是插件工具,另一部分是交互工具。

    本文將為 Tutorial 案例 添加縮略圖插件、網格插件、節點提示框、邊提示框。

    插件
    使用插件時,有三個步驟:
      Step 1: 引入插件;
      Step 2: 實例化插件;
      Step 3: 在實例化圖時將插件的實例配置到圖上
    
    交互工具
    交互工具是指配置到圖上交互模式中的工具。使用交互工具時,有兩個步驟:
      Step 1: 在實例化圖時配置 modes;
      Step 2: 為交互工具定義樣式。
     */
    ////////////////////////////////////////////////////////////////////////////
    // 插件
    ////////////////////////////////////////////////////////////////////////////
    //Minimap 縮略圖 (Minimap) 是一種常見的用於快速預覽和探索圖的工具,可作為導航輔助用戶探索大規模圖。
    // 實例化 minimap 插件 (minimap 原理新建了一個 canvas 定位到主體畫布上)
    const minimap = new G6.Minimap({
      size: [100, 200],
      className: "minimap",
      type: "delegate",
    });
    //Image Minimap 用於優化 minimap 性能  前期展示用於替代 minimap 的 image
    // 實例化 Image Minimap 插件
    // const imageMinimap = new G6.ImageMinimap({
    //   width: 200,
    //   // 用於在 minimap 位置顯示的 image
    //   graphImg:
    //     "https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*eD7nT6tmYgAAAAAAAAAAAABkARQnAQ",
    // });
    // 實例化 grid 插件 grid 原理新建了一個非常大的 div 背景圖片為網格  定位到主體畫布上 並設置 z-index -1 )
    const grid = new G6.Grid();
    console.log("Bowen: mounted -> grid", grid);
    // 實例化圖
    const graph = new G6.Graph({
      plugins: [minimap, grid], // 將 grid 實例配置到圖上
      ////////////////////////////////////////////////////////////////////////////
      modes: {
        // 默認模式
        default: [
          // 拖拽節點
          "drag-node",
          // 拖拽整個畫布
          "drag-canvas",
          // 放縮畫布
          "zoom-canvas",
          ////////////////////////////////////////////////////////////////////////////
          // 交互工具
          ////////////////////////////////////////////////////////////////////////////
          {
            // 提示框 tooltip
            // 本質為一個 div 定位到畫布上, formatText返回的內容為div中內容 同時需要給 .g6-tooltip 樣式
            type: "tooltip",
            formatText(model) {
              // 提示框文本內容
              const text =
                "label: " + model.label + "<br/> class: " + model.class;
              return text;
            },
          },
        ],
        // 編輯模式
        edit: [],
      },
      // 節點不同狀態下的樣式集合
      nodeStateStyles: {
        // 鼠標 hover 上節點,即 hover 狀態為 true 時的樣式
        hover: {
          fill: "lightsteelblue",
        },
        // 鼠標點擊節點,即 click 狀態為 true 時的樣式
        click: {
          stroke: "#000",
          lineWidth: 3,
        },
      },
      // 邊不同狀態下的樣式集合
      edgeStateStyles: {
        // 鼠標點擊邊,即 click 狀態為 true 時的樣式
        click: {
          stroke: "steelblue",
        },
      },
      // Object,可選,布局的方法及其配置項,默認為 random 布局。
      layout: {
        type: "force", // 指定為力導向布局
        preventOverlap: true, // 防止節點重疊
        linkDistance: 100, // 指定邊距離為100
        // nodeSize: 30, // 節點大小,用於算法中防止節點重疊時的碰撞檢測。由於已經在上一節的元素配置中設置了每個節點的 size 屬性,則不需要在此設置 nodeSize。
      },
      animate: true, // 是否啟用圖的動畫。

      defaultNode: {
        size: 30,
        labelCfg: {
          style: {
            fill: "#fff",
          },
        },
      },
      defaultEdge: {
        labelCfg: {
          autoRotate: true,
        },
      },
      container: "mountNode", // 指定掛載容器
      width: 800, // 圖的寬度
      height: 500, // 圖的高度
    });
    // 鼠標進入節點
    graph.on("node:mouseenter", (e) => {
      const nodeItem = e.item; // 獲取鼠標進入的節點元素對象
      graph.setItemState(nodeItem, "hover", true); // 設置當前節點的 hover 狀態為 true
    });

    // 鼠標離開節點
    graph.on("node:mouseleave", (e) => {
      const nodeItem = e.item; // 獲取鼠標離開的節點元素對象
      graph.setItemState(nodeItem, "hover", false); // 設置當前節點的 hover 狀態為 false
    });

    // 點擊節點
    graph.on("node:click", (e) => {
      // 先將所有當前是 click 狀態的節點置為非 click 狀態
      const clickNodes = graph.findAllByState("node", "click");
      console.log("Bowen: mounted -> clickNodes", clickNodes);
      clickNodes.forEach((cn) => {
        graph.setItemState(cn, "click", false);
      });
      const nodeItem = e.item; // 獲取被點擊的節點元素對象
      graph.setItemState(nodeItem, "click", true); // 設置當前節點的 click 狀態為 true
    });

    // 點擊邊
    graph.on("edge:click", (e) => {
      // 先將所有當前是 click 狀態的邊置為非 click 狀態
      const clickEdges = graph.findAllByState("edge", "click");
      clickEdges.forEach((ce) => {
        graph.setItemState(ce, "click", false);
      });
      const edgeItem = e.item; // 獲取被點擊的邊元素對象
      graph.setItemState(edgeItem, "click", true); // 設置當前邊的 click 狀態為 true
    });

    const main = async () => {
      const response = await fetch(
        "https://gw.alipayobjects.com/os/basement_prod/6cae02ab-4c29-44b2-b1fd-4005688febcb.json"
      );
      const remoteData = await response.json();

      const nodes = remoteData.nodes;
      const edges = remoteData.edges;
      nodes.forEach((node) => {
        if (!node.style) {
          node.style = {};
        }
        node.style.lineWidth = 1;
        node.style.stroke = "#666";
        node.style.fill = "steelblue";
        switch (node.class) {
          case "c0": {
            node.type = "circle";
            break;
          }
          case "c1": {
            node.type = "rect";
            node.size = [35, 20];
            break;
          }
          case "c2": {
            node.type = "ellipse";
            node.size = [35, 20];
            break;
          }
        }
      });
      edges.forEach((edge) => {
        if (!edge.style) {
          edge.style = {};
        }
        edge.style.lineWidth = edge.weight;
        edge.style.opacity = 0.6;
        edge.style.stroke = "grey";
      });

      graph.data(remoteData);
      graph.render();
    };
    main();
  },
};
</script>
<style lang="scss">
/* 提示框的樣式 */
.g6-tooltip {
  border: 1px solid #e2e2e2;
  border-radius: 4px;
  font-size: 12px;
  color: #545454;
  background-color: rgba(255, 255, 255, 0.9);
  padding: 10px 8px;
  box-shadow: rgb(174, 174, 174) 0px 0px 10px;
}

// g6 主體位置
canvas {
  position: relative;
  z-index: 1;
}
// 網格位置
.g6-grid-container {
  z-index: 0 !important;
  *,
  ::before,
  ::after {
    // 覆蓋 vuetify  background-repeat: no-repeat;
    background-repeat: repeat;
  }
}
</style>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM