本文將進行 Tutorial 案例的簡單繪製和配置。通過本文,你將知道創建一般圖時一些常用的配置項及其作用。
基礎繪製
創建容器
需要在 HTML 中創建一個用於容納 G6 繪製的圖的容器,通常爲 div 標籤。G6 在繪製時會在該容器下追加 canvas 標籤,然後將圖繪製在其中。
<body>
<div id="mountNode"></div>
<!-- 引入 G6 -->
<!-- ... -->
</body>
數據準備
引入 G6 的數據源爲 JSON 格式的對象。該對象中需要有節點(nodes)和邊(edges)字段,分別用數組表示:
<script>
// console.log(G6.Global.version);
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: '我是連線', // 邊的文本
},
],
};
</script>
⚠️ 注意:
- nodes 數組中包含節點對象,唯一的 id 是每個節點對象中必要的屬性,x、 y 用於定位;
- edges 數組中包含邊對象,source 和 target 是每條邊的必要屬性,分別代表了該邊的起始點 id 與 目標點 id。
圖實例化
圖實例化時,至少需要爲圖設置容器、寬、高:
<script>
// const initData = { ... }
const graph = new G6.Graph({
container: 'mountNode', // 指定掛載容器
width: 800, // 圖的寬度
height: 500, // 圖的高度
});
</script>
圖的渲染
數據的加載和圖的渲染是兩個步驟,可以分開進行。
<script>
// const initData = { ... }
// const graph = ...
graph.data(initData); // 加載數據
graph.render(); // 渲染
</script>
繪製結果
調用 graph.render() 方法之後,G6 引擎會根據加載的數據進行圖的繪製。結果如下:
真實數據加載
上文中,我們使用了僅含有兩個節點和一條邊的數據,直接將數據定義放在了代碼中。而真實場景的數據通常是遠程接口請求加載的。爲了方便,我們已經給讀者準備好了一份 JSON 數據文件,地址如下:
https://gw.alipayobjects.com/os/basement_prod/6cae02ab-4c29-44b2-b1fd-4005688febcb.json
加載遠程數據
修改 index.html,通過 fetch 函數異步加載遠程的數據源,並傳入 G6 的圖實例中:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>02.繪製 Tutorial 案例</title>
</head>
<body>
<div id="mountNode"></div>
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g6-3.3.1/dist/g6.min.js"></script>
<script>
const graph = new G6.Graph({
container: 'mountNode', // 指定掛載容器
width: 800, // 圖的寬度
height: 500, // 圖的高度
});
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();
graph.data(remoteData); // 加載遠程數據
graph.render(); // 渲染
};
main();
</script>
</body>
</html>
fetch 函數允許我們發起網絡請求,加載數據,而其異步的過程可以通過 async/await 進行更合理的控制。這裏我們爲了方便起見,將主要邏輯放在了 main 函數裏面。
運行後,我們得到了下圖結果:
乍看之下,圖像有點奇怪,實際上數據已經正確的加載了進來。由於數據量比較大,節點和邊都非常的多,顯得內容比較雜亂。另外由於畫布大小的限制,實際的圖被畫布截斷了,目前只能看見部分內容,這個問題後文會繼續解決。
請看下面摘取自 tutorial-data.json 的部分數據,我們發現數據中節點定義了位置信息 x 與 y,並且很多節點的 x 和 y 不在圖的寬高(width: 800, height: 600)範圍內:
{
"nodes": [
{ "id": "0", "label": "n0", "class": "c0", "x": 1000, "y": -100 },
{ "id": "1", "label": "n1", "class": "c0", "x": 300, "y": -10 }
//...
],
"edges": [
//...
]
}
由於 G6 在讀取數據時,發現了數據中帶有位置信息(x 和 y),就會按照該位置信息進行繪製,這是爲了滿足按照原始數據繪製的需求設計的。但爲優化超出屏幕到問題,G6 提供了圖的兩個相關配置項:
- fitView:設置是否將圖適配到畫布中;
- fitViewPadding:畫布上四周的留白寬度。
我們將實例化圖的代碼更改爲如下形式:
const graph = new G6.Graph({
container: 'mountNode', // 指定掛載容器
width: 800, // 圖的寬度
height: 500, // 圖的高度
fitView: true,
fitViewPadding: [20, 40, 50, 20],
});
上述代碼將會生成如下圖:
可以看到,圖像已經可以自動適配畫布的大小,完整的顯示了出來。
常用配置
本文使用到的配置以及後續 Tutorial 將會使用到到常用配置如下:
配置項 | 類型 | 選項 / 示例 | 默認 | 說明 |
---|---|---|---|---|
fitView | Boolean | true / false | false | 是否將圖適配到畫布大小,可以防止超出畫布或留白太多。 |
fitViewPadding | Number / Array | 20 / [ 20, 40, 50, 20 ] | 0 | 畫布上的四周留白寬度。 |
animate | Boolean | true / false | false | 是否啓用圖的動畫。 |
modes | Object | { default: [ 'drag-node', 'drag-canvas' ] } | null | 圖上行爲模式的集合。由於比較複雜,按需參見:G6 中的 Mode 教程。 |
defaultNode | Object | { type: 'circle', color: '#000', style: { ...... } } | null | 節點默認的屬性,包括節點的一般屬性和樣式屬性(style)。 |
defaultEdge | Object | { type: 'polyline', color: '#000', style: { ...... } } | null | 邊默認的屬性,包括邊的一般屬性和樣式屬性(style)。 |
nodeStateStyles | Object | { hover: { ...... }, select: { ...... } } | null | 節點在除默認狀態外,其他狀態下的樣式屬性(style)。例如鼠標放置(hover)、選中(select)等狀態。 |
edgeStateStyles | Object | { hover: { ...... }, select: { ...... } } | null | 邊在除默認狀態外,其他狀態下的樣式屬性(style)。例如鼠標放置(hover)、選中(select)等狀態。 |