g6 核心概念

image.png

// 建立 G6 圖實例
      const graph = new G6.Graph({
        container: 'mountNode', // 指定圖畫布的容器 id,與第 9 行的容器對應
        // 畫布寬高
        width: 800,
        height: 500,
      });
      // 讀取數據
      graph.data(data);
      // 渲染圖
     graph.render();
    //監聽
    graph.on()

Graph 對象的生命週期爲:初始化 —> 加載數據 —> 渲染 —> 更新 —> 銷燬。node

必要配置項

上面代碼中實例化 Graph 的部分使用了三個必要的配置項:git

  • container
  • widthheight

經常使用配置項

使用 canvas 或 svg 渲染
  • renderer
自適應畫布
  • fitView
  • fitViewPadding
  • fitCenter
全局元素配置
  • defaultNode
  • defaultEdge
  • nodeStateStyles
  • edgeStateStyles
佈局相關
  • layout
交互行爲相關
  • modes
動畫相關
  • animate
  • animateCfg
插件
  • plugins

圖形

每一個圖元素由圖形(Shape) 組成,且都會有本身的惟一關鍵圖形(keyShape)。web

圖形 Shape

各圖形 Shape 的通用方法

attr(name)

獲取實例的屬性值。算法

attr(name, value)

更新實例的單個繪圖屬性。canvas

attr({...})

批量更新實例繪圖屬性。api

KeyShape

image.png

image.png

表明元素的圖形數組

group

  • addGroup(cfgs)
  • addShape(type, cfgs)

變換dom

  • 獲取當前矩陣:getMatrix();
  • 設置矩陣:setMatrix(matrix) 或 attr('matrix', matrix);
  • 重置矩陣:resetMatrix()。

圖元素

圖的元素(Item)包含圖上的節點 Node 、邊 Edge 和 Combo 三大類。ide

  • 樣式屬性,經過 style 字段對象進行配置,和元素的關鍵圖形相關,例如 fillstroke
  • 其餘屬性,例如 idtype,不能在元素狀態改變是進行改變,可經過 graph.updateItem 進行手動更新。

節點svg

G6 的內置節點包括 circle,rect,ellipse,diamond,triangle,star,image,modelRect。這些內置節點的默認樣式分別以下圖所示。
image.png

定義方式

// 1  
defaultNode: {
    type: 'circle',
    // 其餘配置
  }

//2
graph.node((node) => {
  return {
    id: node.id,
    type: 'rect',
    style: {
      fill: 'blue',
    },
  };
});

graph.data(data);
graph.render();

//3
const data = {
  nodes: [
    {
      id: 'node_circle',
      x: 100,
      y: 100,
      type: 'circle',
      label: 'circle',
    },]
}

自定義

G6.registerNode(
  'nodeName',
  {
    options: {
      style: {},
      stateStyles: {
        hover: {},
        selected: {},
      },
    },
    /**
     * 繪製節點,包含文本
     * @param  {Object} cfg 節點的配置項
     * @param  {G.Group} group 圖形分組,節點中圖形對象的容器
     * @return {G.Shape} 返回一個繪製的圖形做爲 keyShape,經過 node.get('keyShape') 能夠獲取。
     * 關於 keyShape 可參考文檔 核心概念-節點/邊/Combo-圖形 Shape 與 keyShape
     */
    draw(cfg, group) {},
    /**
     * 繪製後的附加操做,默認沒有任何操做
     * @param  {Object} cfg 節點的配置項
     * @param  {G.Group} group 圖形分組,節點中圖形對象的容器
     */
    afterDraw(cfg, group) {},
    /**
     * 更新節點,包含文本
     * @override
     * @param  {Object} cfg 節點的配置項
     * @param  {Node} node 節點
     */
    update(cfg, node) {},
    /**
     * 更新節點後的操做,通常同 afterDraw 配合使用
     * @override
     * @param  {Object} cfg 節點的配置項
     * @param  {Node} node 節點
     */
    afterUpdate(cfg, node) {},
    /**
     * 響應節點的狀態變化。
     * 在須要使用動畫來響應狀態變化時須要被複寫,其餘樣式的響應參見下文說起的 [配置狀態樣式] 文檔
     * @param  {String} name 狀態名稱
     * @param  {Object} value 狀態值
     * @param  {Node} node 節點
     */
    setState(name, value, node) {},
    /**
     * 獲取錨點(相關邊的連入點)
     * @param  {Object} cfg 節點的配置項
     * @return {Array|null} 錨點(相關邊的連入點)的數組,若是爲 null,則沒有控制點
     */
    getAnchorPoints(cfg) {},
  },
  // 繼承內置節點類型的名字,例如基類 'single-node',或 'circle', 'rect' 等
  // 當不指定該參數則表明不繼承任何內置節點類型
  extendedNodeName,
);

鏈接方式

image.png

// 接入點
    anchorPoints: [
        [0, 1],
        [0.5, 1],
      ],

jsx寫法

<[group|shape] [key]="value" style={{ [key]: value }}>
  <[more tag] /> ...
  <text>value</text>
</[group|shape]>

  • line:直線,不支持控制點;
  • polyline:折線,支持多個控制點;
  • arc:圓弧線;
  • quadratic:二階貝塞爾曲線;
  • cubic:三階貝塞爾曲線;
  • cubic-vertical:垂直方向的三階貝塞爾曲線,不考慮用戶從外部傳入的控制點;
  • cubic-horizontal:水平方向的三階貝塞爾曲線,不考慮用戶從外部傳入的控制點;
  • loop:自環。

定義方式: 與節點相似

箭頭:

//默認
style: {
  endArrow: true,
  startArrow: true
}
//內置 6種
endArrow: {
// 使用內置箭頭路徑函數,參數爲箭頭的 寬度、長度、偏移量(默認爲 0,與 d 對應)
path: G6.Arrow.triangle(10, 20, 25),
d: 25
}
// 自定義箭頭
// 只有內置箭頭和自定義箭頭能夠配置樣式
style: {
  endArrow: {
    path: 'M 0,0 L 20,10 L 20,-10 Z',
    d: 5,
    fill: '#f00',
    stroke: '#0f0',
    opacity: 0.5,
    lineWidth: 3,
    // ...
  },
}

自定義:同節點

combo

G6 的內置 Combo 包括 circle 和 rect 兩種類型

對於熟悉圖可視化類庫的用戶來講,節點分組是很是實用的一個功能

G6 已經存在一個節點分組 Node Group 功能,但它的機制沒法支持一些較複雜的功能,例如:帶有節點分組的圖佈局、自定義 Combo、嵌套節點分組的均勻 padding、節點與分組的邊、分組與分組的邊、空的節點分組等

image.png

{
  nodes: [
    {
      id: 'node1',
      comboId: 'comboA' // node1 屬於 comboA
    },
    {
      id: 'node2',
      comboId: 'comboB' // node2 屬於 comboB
    },
    {
      id: 'node3' // node3 不屬於任何 combo
    },
    // ...
  ],
  edges: [
    // ...
  ],
  combos: [
    { // 定義 comboA
      id: 'comboA',
      label: 'A',
      parentId: 'comboC'
    },
    { // 定義 comboB
      id: 'comboB',
      parentId: 'comboB'
    },
    { // 定義 comboC,這是一個空的 combo
      id: 'comboC'
    },
    // ...
  ]
}

其餘內容:相似與節點

高級樣式

背景

defaultNode: {
    position: 'left',
    style: {
      background: {
        fill: '#ffffff',
        stroke: 'green',
        padding: [3, 2, 3, 2],
        radius: 2,
        lineWidth: 3,
      },
    },

三種方式更新文本樣式

// 1. 實例化默認
  defaultNode: {
    type: 'node',
    labelCfg: {
      style: {
        fill: '#fff',
        fontSize: 14,
      },
    },
  },
// 2.數據指定
const data = {
  nodes: [
    {
      id: 'node1',
      label: 'node1',
      labelCfg: {
        style: {
          fill: '#fff',
          fontSize: 12,
        },
      },
    },
  ],
};
// 3.update/updateItem

graph.updateItem(node, {
  // 節點的樣式
  style: {
    stroke: 'blue',
  },
  // 節點上文本的樣式
  labelCfg: {
    style: {
      fill: '#fff',
      fontSize: 12,
    },
  },
});

漸變色/紋理

image.png

操做

更新樣式

更新節點邊: 三種方式

層級

全部節點會繪製在全部邊的上層

先繪製圖形在後繪製圖形後邊

toFront()toBack()

顯示/隱藏

show()/hide()

多條邊

image.png

自定義邊 edgeType

鎖定/解鎖

lock()unlock()hasLocked()

不可拖動

不可縮放

圖佈局

通常佈局

樹圖

佈局切換

  • updateLayout(params):佈局方法或參數的切換;
graph.updateLayout({
          type: 'force', // 佈局名稱
          preventOverlap: true, // 佈局參數,是否容許重疊
          nodeSize: 40, // 佈局參數,節點大小,用於判斷節點是否重疊
          linkDistance: 100, // 佈局參數,邊長
        });

*   `changeData()`:數據的切換。

        graph.changeData(data2);

子圖

子圖佈局獨立與全局佈局的思路,與 graph 不掛鉤,直接使用實例化佈局方法的方式,灌入子圖數據,經過佈局將位置寫到相應數據中。這種機制還可供外部的全局佈局使用,即便不用 G6 渲染,也能夠計算節點佈局後的位置

// 實例化佈局
const subgraphLayout = new G6.Layout['force']({
  center: [500, 450],
});

// 初始化佈局,灌入子圖數據
subgraphLayout.init({
  nodes: subGraphNodes,
  edges: subGraphEdges,
});

// 執行佈局
subgraphLayout.execute();

// 圖實例根據數據更新節點位置
graph.positionsAnimate();

webworker

在大規模圖可視化中,佈局算法每每須要較大的計算量。

workerEnabled: true, // 開啓 Web-Worker
  • 樹圖不支持 Web-Worker 機制;
  • 子圖佈局機制暫不支持 Web-Worker 機制。
  • 使用會形成交互延時須要注意

自定義佈局

getDefaultCfg() {
    return {};
  },
  /**
   * 初始化
   * @param {object} data 數據
   */
  init(data) {},
  /**
   * 執行佈局
   */
  execute() {},
  /**
   * 根據傳入的數據進行佈局
   * @param {object} data 數據
   */
  layout(data) {},
  /**
   * 更新佈局配置,但不執行佈局
   * @param {object} cfg 須要更新的配置項
   */
  updateCfg(cfg) {},
  /**
   * 銷燬
   */
  destroy() {},
});

佈局預測

import { GraphLayoutPredict } from '@antv/vis-predict-engine'

const { predictLayout, confidence } = await GraphLayoutPredict.predict(data);
const graph = new G6.Graph({
  // 省略其餘配置
    layout: {
    type: predictLayout
  }
})

交互與事件

監聽/綁定

  • 畫布、圖形層次的事件,mousedownmouseupclickmouseentermouseleave 等;
  • 節點/邊 上的事件,node:mousedownedge:click 等,以 type:eventName 爲事件名稱;
  • 時機事件:

    • 節點/邊增刪改時的事件, 例如:beforeadditemafteradditem  等;
    • 節點/邊狀態改變時的事件:beforerefreshitemafterrefreshitem
    • 佈局時機:beforelayoutafterlayout
graph.on('click', (ev) => {
  const shape = ev.target;
  const item = ev.item;
  if (item) {
    const type = item.getType();
  }
});

graph.on('node:click', (ev) => {
  const shape = ev.target;
  const node = ev.item;
});

內置 behavior

ehavior 是 G6 提供的定義圖上交互事件的機制。

G6 目前共提供瞭如下 14 個內置的 Behavior。

drag-combo
collapse-expand-combo
drag-canvas
zoom-canvas
drag-node
click-select
tooltip
edge-tooltip
activate-relations
brush-select
lasso-select
collapse-expand
create-edge
shortcuts-call

自定義交互 Behavior

在交互行爲上, G6 主要考慮了三個場景:

  • 展現關係數據;
  • 可視化建模;
  • 圖分析。

在這些場景中只要用戶可能沒法一眼看清楚全部須要的信息,都須要進行交互,例如:

  • 圖太大,須要縮放;
  • 單個節點上展現的信息太少,須要經過 tooltip 顯示詳情;
  • 對節點進行增刪改查。
交互模式 Mode
  • default 模式中包含點擊選中節點行爲和拖拽畫布行爲;
  • edit 模式中包含點擊節點彈出編輯框行爲和拖拽節點行爲。
modes: {
    // 支持的 behavior
    default: ['drag-canvas', 'zoom-canvas'],
    edit: ['click-select'],
  },

// 解綁目前圖模式的全部事件監聽;
// 生成新的 Behavior ,進行事件初始化;
// 綁定新的行爲對應的事件監聽。
graph.setMode('edit');

graph.addBehaviors
graph.removeBehaviors

狀態State

判斷是否該使用 state 的原則很簡單,從交互和業務兩個層面來看:

  • 某個交互動做要改變節點或邊的樣式及屬性;
  • 呈現給用戶的內容會根據數據改變(如 1 表明成功,0 表明失敗)。

知足上述條件其一,則應該使用 state。

在 G6 中,有兩種方式配置不一樣狀態的樣式:

  • 在實例化 Graph 時,經過 nodeStateStylesedgeStateStyles 對象定義;
  • 在節點/邊數據中,在 stateStyles 對象中定義狀態;
  • 設置狀態:setItemState
  • 取消狀態:clearItemStates
  • 更新狀態:updateItem
graph.setItemState(item, stateName, stateValue) 

graph.clearItemStates(item, 'selected');
// 實例化
 nodeStateStyles: {

  },

//數據
  stateStyles: {
      },

//updataItem
stateStyles: {
    // 修改 hover 狀態下的樣式
    hover: {
      opacity: 0.1,
      // 修改 name 爲 'node-label' 的子圖形 hover 狀態下的樣式
      'node-text': {
        stroke: 'blue',
      },
    },
  },

//優先級
item.hasState('active');

插件**

// 實例化 Image Minimap 插件
const imageMinimap = new G6.ImageMinimap({
  width: 200,
  graphImg: 'https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*eD7nT6tmYgAAAAAAAAAAAABkARQnAQ'
});
const graph = new G6.Graph({
  //... 其餘配置項
  plugins: [imageMinimap], // 配置 imageMinimap 插件
});

圖算法

計算nodes,edges x/y

動畫

全局

//全局
 animate: true, // Boolean,切換佈局時是否使用動畫過分,默認爲 false
graph.updateLayout(cfg) 佈局的變化
graph.changeData() 數據的變化

元素

  • 節點上圖形的動畫
  • 增長帶有動畫的背景圖形
  • 節點上部分圖形的旋轉動畫
  • 圓點在沿着線運動
  • 虛線運動的效果
  • 線從無到有的效果
//開始
 shape.animate(
        (ratio) => {
          // 每一幀的操做,入參 ratio:這一幀的比例值(Number)。返回值:這一幀須要變化的參數集(Object)。
          // 先變大、再變小
          const diff = ratio <= 0.5 ? ratio * 10 : (1 - ratio) * 10;
          let radius = cfg.size;
          if (isNaN(radius)) radius = radius[0];
          // 返回這一幀須要變化的參數集,這裏只包含了半徑
          return {
            r: radius / 2 + diff,
          };
        },
        {
          // 動畫重複
          repeat: true,
          duration: 3000,
          easing: 'easeCubic',
        },
      ); // 一次動畫持續的時長爲 3000,動畫效果爲 'easeCubic'
          
//結束
shape.stopAnimate();
相關文章
相關標籤/搜索