Loading...
This tutorial will guide you through the development of a G6 chart from scratch, and along the way, you will learn and understand the main concepts of G6.
We will use Vite to create a simple front-end application.
First, create an empty directory:
mkdir g6-tutorialcd g6-tutorial
Initialize the project:
npm init -y
Install G6:
npm install @antv/g6 --save
Vite is a new type of front-end build tool that is based on ESModule and can quickly start up projects.
Install Vite:
npm install vite --save-dev
Add a start script to the package.json:
{"scripts": {"dev": "vite"}}
Create the index.html and main.ts files with the following content:
index.html:
<!doctype html><html><head><title>@antv/g6 Tutorial</title></head><body><div id="container"></div><script type="module" src="main.ts"></script></body></html>
main.ts:
alert('Hello, G6!');
npm run dev
Open a web browser and visit the address output in the terminal (typically: http://127.0.0.1:5173/), and you will see a pop-up displaying "Hello, G6!".
Next, we will create a simple chart using G6.
G6 uses JSON-formatted data to describe the graph, which usually includes nodes and edges. We will use the following prepared data:
const data = {nodes: [{ id: 'node-1', style: { x: 50, y: 50 } },{ id: 'node-2', style: { x: 150, y: 50 } },],edges: [{ source: 'node-1', target: 'node-2' }],};
The data includes two nodes and one edge. The id attribute for nodes is mandatory, and the position of each node is set in the style. The source and target attributes of the edge represent the id of the starting node and the ending node, respectively.
Create an instance of the Graph, pass in a configuration object that includes the container and data, and then call the render method to draw the Graph:
import { Graph } from '@antv/g6';const graph = new Graph({container: 'container',data: {nodes: [{ id: 'node-1', style: { x: 50, y: 50 } },{ id: 'node-2', style: { x: 150, y: 50 } },],edges: [{ source: 'node-1', target: 'node-2' }],},});graph.render();
As shown below, you can see that the chart has been successfully drawn:
import { Graph } from '@antv/g6';const graph = new Graph({container: 'container',width: 200,height: 100,data: {nodes: [{ id: 'node-1', style: { x: 50, y: 50 } },{ id: 'node-2', style: { x: 150, y: 50 } },],edges: [{ source: 'node-1', target: 'node-2' }],},});graph.render();
Next, we will introduce how to configure the style and types of elements in the canvas.
G6 provides various mechanisms to configure element styles, which can be done in the data itself or within the chart instance. In the previous example, we configured the position of the nodes in the data. Next, we will configure the styles of nodes and edges in the graph configuration options:
import { Graph } from '@antv/g6';const graph = new Graph({container: 'container',data: {nodes: [{ id: 'node-1', style: { x: 50, y: 50 } },{ id: 'node-2', style: { x: 150, y: 50 } },],edges: [{ source: 'node-1', target: 'node-2' }],},node: {style: {fill: 'pink',},},edge: {style: {stroke: 'lightgreen',},},});graph.render();
As the code shows, we have configured the fill color of the nodes to be pink and the stroke color of the edges to be light green within the chart instance. You can see the effect in the example below:
import { Graph } from '@antv/g6';const graph = new Graph({container: 'container',width: 200,height: 100,data: {nodes: [{ id: 'node-1', style: { x: 50, y: 50 } },{ id: 'node-2', style: { x: 150, y: 50 } },],edges: [{ source: 'node-1', target: 'node-2' }],},node: {style: {fill: 'pink',},},edge: {style: {stroke: 'lightgreen',},},});graph.render();
The key parts are the node.style and edge.style options, which are used to configure the styles of nodes and edges, respectively.
In the subsequent code examples, we will only display the parts of the options. For the complete code of this project, please refer to the Complete Example.
Next, we will demonstrate more types of nodes by setting the node type:
{node: {type: (datum) => datum.id === 'node-1' ? 'circle' : 'rect',style: {fill: 'pink',size: 20}}}
In the code above, we set the type attribute of the node, which can be a string or a function. When type is a function, the argument of the function is the current node's data object, and the return value is the type of the node.
Similarly, each attribute under the
stylestyle of an element can also be a function, with the argument being the current element's data object.
You can even set the entire
styleproperty as a function, allowing you to dynamically set the element's style based on the data object.
The circular node (circle) is the default node type in G6. Here, we set the type of the first node to a circle and the type of the second node to a rectangle.
At the same time, we also set the size of the nodes to 20, so the first node is a circle with a radius of 10, and the second node is a square with a side length of 20.
If you want to set the size of the rectangular node to 20x10, you can set
sizeto an array[20, 10].
You can see the effect in the example below:
import { Graph } from '@antv/g6';const graph = new Graph({container: 'container',width: 200,height: 100,data: {nodes: [{ id: 'node-1', style: { x: 50, y: 50 } },{ id: 'node-2', style: { x: 150, y: 50 } },],edges: [{ source: 'node-1', target: 'node-2' }],},node: {type: (datum) => (datum.id === 'node-1' ? 'circle' : 'rect'),style: {fill: 'pink',size: 20,},},edge: {style: {stroke: 'lightgreen',},},});graph.render();
The chart provided in the previous example is static. Next, we will add some interactive behaviors.
G6 offers a variety of interactive behaviors. We will add a few commonly used Behaviors to allow users to drag, zoom the canvas, and drag nodes.
{behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'];}
Try dragging nodes and the canvas in the example below, and use the scroll wheel to zoom in and out on the canvas:
import { Graph } from '@antv/g6';const graph = new Graph({container: 'container',width: 300,height: 200,data: {nodes: [{ id: 'node-1', style: { x: 50, y: 50 } },{ id: 'node-2', style: { x: 150, y: 50 } },],edges: [{ source: 'node-1', target: 'node-2' }],},node: {type: (datum) => (datum.id === 'node-1' ? 'circle' : 'rect'),style: {fill: 'pink',size: 20,},},edge: {style: {stroke: 'lightgreen',},},behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'],});graph.render();
In the previous example, we manually set the positions of the nodes. However, this can become very difficult when there are many nodes.
Layout algorithms can automatically adjust the positions of nodes based on certain rules. G6 provides a variety of layout algorithms, such as tree layout, force-directed layout, and so on.
First, generate a set of data that does not include position information:
const data = {nodes: Array.from({ length: 10 }).map((_, i) => ({ id: `node-${i}` })),edges: Array.from({ length: 9 }).map((_, i) => ({ source: `node-0`, target: `node-${i + 1}` })),};
By default, if a node does not have position information, G6 will place the node at the top-left corner, that is, at the coordinates (0, 0).
Next, we will use the d3-force layout algorithm, which is a force-directed layout algorithm that can simulate the forces of attraction and repulsion between nodes, allowing the nodes to automatically adjust to suitable positions.
{layout: {type: 'd3-force',},}
View the example below, and you can see that the nodes have automatically adjusted to suitable positions:
import { Graph } from '@antv/g6';const graph = new Graph({container: 'container',data: {nodes: Array.from({ length: 10 }).map((_, i) => ({ id: `node-${i}` })),edges: Array.from({ length: 9 }).map((_, i) => ({ source: `node-0`, target: `node-${i + 1}` })),},node: {style: {size: 20,fill: 'pink',},},edge: {style: {stroke: 'lightgreen',},},behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'],layout: {type: 'd3-force',},});graph.render();
import { Graph } from '@antv/g6';const graph = new Graph({container: 'container',width: 200,height: 200,data: {nodes: Array.from({ length: 10 }).map((_, i) => ({ id: `node-${i}` })),edges: Array.from({ length: 9 }).map((_, i) => ({ source: `node-0`, target: `node-${i + 1}` })),},node: {style: {size: 20,fill: 'pink',},},edge: {style: {stroke: 'lightgreen',},},behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'],layout: {type: 'd3-force',},});graph.render();
Similarly, when there are many nodes, manually setting the color of each node can become difficult. G6 provides a palette mechanism that makes it easy to assign colors to elements.
Palettes typically assign colors to elements based on a specific field in the data, such as the type of node, the weight of an edge, etc.
Below, we add a category field in the data:
const data = {nodes: Array.from({ length: 10 }).map((_, i) => ({id: `node-${i}`,data: { category: i === 0 ? 'central' : 'around' },})),edges: Array.from({ length: 9 }).map((_, i) => ({ source: `node-0`, target: `node-${i + 1}` })),};
Then, use the tableau palette to set the colors for the nodes, where the field attribute specifies the field in the data, and the color attribute specifies the name of the palette.
{node: {palette: {field: 'category',color: 'tableau',}}}
It is important to note that the
fillstyle innode.styleshould be removed, as its priority is higher than the colors assigned by the palette.
import { Graph } from '@antv/g6';const graph = new Graph({container: 'container',width: 200,height: 200,data: {nodes: Array.from({ length: 10 }).map((_, i) => ({id: `node-${i}`,data: { category: i === 0 ? 'central' : 'around' },})),edges: Array.from({ length: 9 }).map((_, i) => ({ source: `node-0`, target: `node-${i + 1}` })),},node: {style: {size: 20,},palette: {field: 'category',color: 'tableau',},},edge: {style: {stroke: 'lightgreen',},},behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'],layout: {type: 'd3-force',},});graph.render();
The plugin mechanism is an important feature of G6, which allows you to extend the functionality of G6 through plugins. G6 provides a wealth of built-in plugins, such as tooltip, legend, etc., and also supports user-defined plugins.
Below, we will use the grid-line plugin to add grid lines to the canvas:
{plugins: ['grid-line'],}
You can see that grid lines have been added to the canvas:
import { Graph } from '@antv/g6';const graph = new Graph({container: 'container',width: 200,height: 200,data: {nodes: Array.from({ length: 10 }).map((_, i) => ({id: `node-${i}`,data: { category: i === 0 ? 'central' : 'around' },})),edges: Array.from({ length: 9 }).map((_, i) => ({ source: `node-0`, target: `node-${i + 1}` })),},node: {style: {size: 20,},palette: {field: 'category',color: 'tableau',},},edge: {style: {stroke: 'lightgreen',},},behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'],layout: {type: 'd3-force',},plugins: ['grid-line'],});graph.render();
The plugin configuration mentioned above used a shorthand form. Most plugins support the passing of additional parameters. For example, the grid-line plugin allows you to configure the follow property to specify whether the grid lines should follow the canvas when it is dragged.
{plugins: [{ type: 'grid-line', follow: true }];}
Try dragging the canvas in the example below, and you will see that the grid lines move along with the canvas:
import { Graph } from '@antv/g6';const graph = new Graph({container: 'container',width: 200,height: 200,data: {nodes: Array.from({ length: 10 }).map((_, i) => ({id: `node-${i}`,data: { category: i === 0 ? 'central' : 'around' },})),edges: Array.from({ length: 9 }).map((_, i) => ({ source: `node-0`, target: `node-${i + 1}` })),},node: {style: {size: 20,},palette: {field: 'category',color: 'tableau',},},edge: {style: {stroke: 'lightgreen',},},behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'],layout: {type: 'd3-force',},plugins: [{ type: 'grid-line', follow: true }],});graph.render();
In this tutorial, we created a G6 chart from scratch and became acquainted with the main concepts of G6. We learned how to create a simple chart, how to configure the style and types of elements, how to add interactive behaviors, how to use layout algorithms, how to use palettes, and how to use plugins.
For a more detailed introduction to the concepts of G6, you can refer to Core Concepts.
Detailed explanations of options such as elements, layouts, and plugins can be found in the API.