1 快速上手
1.1 在專案中使用 npm 包引入
Step 1: 使用命令列在專案目錄下執行以下命令
npm install --save @antv/g6
Step 2: 在需要用的 G6 的 JS 檔案中匯入
import G6 from '@antv/g6';
1.2 在 HTML 中使用 CDN 引入
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g6-{$version}/build/g6.js"></script>
注意
- 在
{$version}
中填寫版本號,例如3.2.0
; - 最新版為 3.2.0,可以在 npm 檢視最新版本;
- 詳情參考 Github 分支:https://github.com/antvis/g6/tree/master 。
2 快速試用
建立一個 G6 的關係圖僅需要下面幾個步驟:
- 建立關係圖的 HTML 容器;
- 資料準備;
- 建立關係圖;
- 配置資料來源,渲染。
Step 1: 建立容器
<div id="mountNode"></div>
Step 2: 資料準備
引入 G6 的資料來源為 JSON 格式的物件。該物件中需要有節點(nodes)和邊(edges)欄位,分別用陣列表示:
const data = {
// 點集
nodes: [
{
id: 'node1', // String,該節點存在則必須,節點的唯一標識
x: 100, // Number,可選,節點位置的 x 值
y: 200, // Number,可選,節點位置的 y 值
},
{
id: 'node2', // String,該節點存在則必須,節點的唯一標識
x: 300, // Number,可選,節點位置的 x 值
y: 200, // Number,可選,節點位置的 y 值
},
],
// 邊集
edges: [
{
source: 'node1', // String,必須,起始點 id
target: 'node2', // String,必須,目標點 id
},
],
};
注意
nodes
陣列中包含節點物件,唯一的id
是每個節點物件中必要的屬性,x
、y
用於定位;edges
陣列中包含邊物件,source
和 target 是每條邊的必要屬性,分別代表了該邊的起始點id
與 目標點id
。- 點和邊的其他屬性參見連結:圖元素配置文件。
Step 3: 建立關係圖
建立關係圖(例項化)時,至少需要為圖設定容器、寬和高。
const graph = new G6.Graph({
container: 'mountNode', // String | HTMLElement,必須,在 Step 1 中建立的容器 id 或容器本身
width: 800, // Number,必須,圖的寬度
height: 500, // Number,必須,圖的高度
});
Step 4: 配置資料來源,渲染
建立關係圖(例項化)時,至少需要為圖設定容器、寬和高。
graph.data(data); // 讀取 Step 2 中的資料來源到圖上
graph.render(); // 渲染圖
最終的結果
3 配置
3.1 元素及其配置
圖的元素特指圖上的節點Node和邊Edge,不論是節點還是邊,它們的屬性分為兩種:
- 樣式屬性
style
:對應 Canvas 中的各種樣式,在元素狀態State 發生變化時,可以被改變; - 其他屬性:例如圖形(
shape
)、id(id
)一類在元素狀態State發生變化時不能被改變的屬性。
例如,G6 設定 hover 或 click 節點,造成節點狀態的改變,只能自動改變節點的樣式屬性(如fill
、stroke
等),其他屬性(如shape
等)不能被改變。如果需要改變其他屬性,要透過 graph.updateItem 手動配置。樣式屬性是一個名為style
的物件,style
欄位與其他屬性並行。
以節點元素為例,其屬性的資料結構如下:
{
id: 'node0', // 元素的 id
shape: 'circle', // 元素的圖形
size: 40, // 元素的大小
label: 'node0' // 標籤文字
labelCfg: { // 標籤配置屬性
positions: 'center',// 標籤的屬性,標籤在元素中的位置
style: { // 包裹標籤樣式屬性的欄位 style 與標籤其他屬性在資料結構上並行
fontSize: 12 // 標籤的樣式屬性,文字字型大小
}
}
// ..., // 其他屬性
style: { // 包裹樣式屬性的欄位 style 與其他屬性在資料結構上並行
fill: '#000', // 樣式屬性,元素的填充色
stroke: '#888', // 樣式屬性,元素的描邊色
// ... // 其他樣式屬性
}
}
邊元素的屬性資料結構與節點元素相似,只是其他屬性中多了 source 和 target 欄位,代表起始和終止節點的 id
全域性配置
適用場景:所有節點統一的屬性配置,所有邊統一的屬性配置。使用方式:使用圖的兩個配置項:
defaultNode:節點在預設狀態下的樣式屬性(style)和其他屬性;
defaultEdge:邊在預設狀態下的樣式屬性(style)和其他屬性。
defaultNode: {
size: 30, // 節點大小
// ... // 節點的其他配置
// 節點樣式配置
style: {
fill: 'steelblue', // 節點填充色
stroke: '#666', // 節點描邊色
lineWidth: 1, // 節點描邊粗細
},
// 節點上的標籤文字配置
labelCfg: {
// 節點上的標籤文字樣式配置
style: {
fill: '#fff', // 節點標籤文字顏色
},
},
},
// 邊在預設狀態下的樣式配置(style)和其他配置
defaultEdge: {
// ... // 邊的其他配置
// 邊樣式配置
style: {
opacity: 0.6, // 邊透明度
stroke: 'grey', // 邊描邊顏色
},
// 邊上的標籤文字配置
labelCfg: {
autoRotate: true, // 邊上的標籤文字根據邊的方向旋轉
},
},
3.2 使用圖佈局 Layout
當資料中沒有節點位置資訊,或者資料中的位置資訊不滿足需求時,需要藉助一些佈局演算法對圖進行佈局。G6 提供了 7 種一般圖的佈局和 4 種樹圖的佈局:
一般圖:
- Random Layout:隨機佈局;
- Force Layout:經典力導向佈局:
- Circular Layout:環形佈局;
- Radial Layout:輻射狀佈局;
- MDS Layout:高維資料降維演算法佈局;
- Fruchterman Layout:Fruchterman 佈局,一種力導佈局;
- Dagre Layout:層次佈局。
樹圖佈局:
- Dendrogram Layout:樹狀佈局(葉子節點佈局對齊到同一層);
- CompactBox Layout:緊湊樹佈局;
- Mindmap Layout:腦圖佈局;
- Intended Layout:縮排佈局。
const graph = new G6.Graph({
... // 其他配置項
layout: { // Object,可選,佈局的方法及其配置項,預設為 random 佈局。
type: 'force', // 指定為力導向佈局
preventOverlap: true, // 防止節點重疊
// nodeSize: 30, // 節點大小,用於演算法中防止節點重疊時的碰撞檢測。由於已經在上一節的元素配置中
linkDistance: 100, // 指定邊距離為100設定了每個節點的 size 屬性,則不需要在此設定 nodeSize。
center: [500, 300]
}
});
更多屬性(https://g6.antv.vision/zh/docs/api/graphLayout/guide)
3.3 圖的互動 Behavior
G6 中的互動行為。G6 內建了一系列互動行為,使用者可以直接使用。簡單地理解,就是可以一鍵開啟這些互動行為:
drag-canvas
:拖拽畫布;zoom-canvas
:縮放畫布。
更多詳見:互動行為 Behavior
const graph = new G6.Graph({
// ... // 其他配置項
modes: {
default: ['drag-canvas', 'zoom-canvas', 'drag-node'], // 允許拖拽畫布、放縮畫布、拖拽節點
},
});
- activate-relations
含義:當滑鼠移到某節點時,突出顯示該節點以及與其直接關聯的節點和連線;
引數:
- trigger: 'mouseenter'。可以是 mousenter,表示滑鼠移入時觸發;也可以是 click,滑鼠點選時觸發;
- activeState: 'active'。活躍節點狀態。當行為被觸發,需要被突出顯示的節點和邊都會附帶此狀態,預設值為 active;可以與 graph 例項的 nodeStyle 和 edgeStyle 結合實現豐富的視覺效果。
- inactiveState: 'inactive'。非活躍節點狀態。不需要被突出顯示的節點和邊都會附帶此狀態。預設值為 * * * inactive。可以與 graph 例項的 nodeStyle 和 edgeStyle 結合實現豐富的視覺效果;
- resetSelected:高亮相連節點時是否重置已經選中的節點,預設為 false,即選中的節點狀態不會被 activate-relations 覆蓋;
{
type: 'activate-relations',
activeState: 'actives',
inactiveState: 'inactives',
resetSelected: false
},
// 當前節點的多狀態樣式
nodeStateStyles: {
actives: {
opacity: 1,
lineWidth: 0
},
inactives: {
opacity: 0.2,
lineWidth: 0
}
},
edgeStateStyles: {
actives: {
opacity: 1
},
inactives: {
opacity: 0.2
}
}
(https://g6.antv.vision/zh/docs/manual/middle/states/defaultBehavior)
3.4 監聽和繫結事件
- 全域性事件
只要在畫布上範圍內發生均會被觸發,如 mousedown,mouseup,click,mouseenter,mouseleave 等。
graph.on('click', (ev) => {
const shape = ev.target;
const item = ev.item;
if (item) {
const type = item.getType();
}
});
- canvas 事件
只在 canvas 空白處被觸發,如 canvas:mousedown,canvas:click 等,以canvas:eventName 為事件名稱。
graph.on('canvas:click', (ev) => {
const shape = ev.target;
const item = ev.item;
if (item) {
const type = item.getType();
}
});
- 節點/邊/combo 上的事件
例如 node:mousedown,edge:click, combo:click 等,以 type:eventName 為事件名稱。
graph.on('node:click', (ev) => {
const node = ev.item; // 被點選的節點元素
const shape = ev.target; // 被點選的圖形,可根據該資訊作出不同響應,以達到區域性響應效果
// ... do sth
});
graph.on('edge:click', (ev) => {
const edge = ev.item; // 被點選的邊元素
const shape = ev.target; // 被點選的圖形,可根據該資訊作出不同響應,以達到區域性響應效果
// ... do sth
});
graph.on('combo:click', (ev) => {
const combo = ev.item; // 被點選 combo 元素
const shape = ev.target; // 被點選的圖形,可根據該資訊作出不同響應,以達到區域性響應效果
// ... do sth
});
- 圖形上的事件
指定圖形上的事件,如 circle-shape:mousedown,circle-shape:click 等,以 shapeName:eventName 為事件名稱。可用於繫結節點/邊/combo 中對區域性圖形做出響應的場景。效果類似上文 graph.on('node:click', fn) 中透過 target 資訊作出不同響應。
關於圖形的 name:
內建節點/邊/combo 上每個圖形的名稱在開發過程中可以透過 graph.on('node:click', (ev) => console.log(ev.target.get('name'))) 得知;
自定義節點/邊/combo 中透過 addShape 增加的圖形,可新增與 attrs 平級的 name 欄位指定任意(同元素中唯一)字串作為 name。請注意同個元素(節點/邊/combo)中不同圖形儘量給予不同的 name 值。
下面例子為圖中所有 name 為 circle-shape 的圖形繫結了 click 事件監聽:
graph.on('circle-shape:click', (ev) => {
const shape = ev.target; // 被點選的圖形
// ... do sth
});
- 時機事件
時機事件指渲染、視口變換、元素增刪改、資料變換等時機。所有時機事件詳見 G6 的時機事件列表。如:beforeadditem
,afteradditem
等:
- 節點/邊/Combo 狀態改變時的事件:
beforerefreshitem
與afterrefreshitem
; - 佈局時機:
beforelayout
與afterlayout
。
下面例子為 graph 繫結了渲染完成時機的監聽。時機事件中,afterrender、afterlayout 一類事件必須在 graph.render()
或 graph.read()
之前繫結,方可監聽到首次渲染、佈局完成後的相關事件。
graph.on('afterrender', (ev) => {
// ... do sth
});
- 自定義事件
G6 允許使用者自定義任意事件,可在任意位置透過 graph.emit(customEventName: string, event: IG6GraphEvent)
觸發一個事件,第一個引數為自定義事件名稱。在觸發前,透過 graph.on(customEventName: string, callback: Function)
進行監聽。例如:
graph.on('some-custom-event-name', (ev) => {
// ... do sth
});
graph.emit('some-custom-event-name', {
// some params
})
ps:當資料多樣化的時候,可以對不同的資料設定不同的節點或者邊的樣式
data.nodes.forEach((node) => {
node.style = {
fill: node.type === 'company'
? '#EE5555'
: node.type === 'director'
? '#0F8CFF'
: '#FFC510',
stroke: node.type === 'company'
? '#EE5555'
: node.type === 'director'
? '#0F8CFF'
: '#FFC510'
}
})
data.edges.forEach((edge) => {
edge.style = {
stroke: edge.typest === 0
? '#EE5555'
: edge.typest === 1
? '#0F8CFF'
: '#FFC510'
}
edge.label = edge.typest === 0
? '董事'
: edge.typest === 1
? '經理'
: edge.typest === 2
? '職員'
: null
edge.labelCfg = {
style: {
fill: edge.typest === 0
? '#EE5555'
: edge.typest === 1
? '#0F8CFF'
: '#FFC510'
}
}
})