feat: add corresponding English docs (#5738)

* feat: add corresponding English docs
---------

Co-authored-by: whf01206399 <whf01206399@antgroup.com>
This commit is contained in:
Wang Hongfei 2024-05-16 10:13:08 +08:00 committed by GitHub
parent f4d530320f
commit 2f8365bfd6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
70 changed files with 4733 additions and 747 deletions

View File

@ -100,7 +100,7 @@ export class Legend extends BasePlugin<LegendOptions> {
* <zh/>
*
* <en/> Update the legend configuration
* @param options - <zh/> | <en/> Legend configuration item
* @param options - <zh/> | <en/> Legend options
* @internal
*/
public update(options: Partial<LegendOptions>) {

View File

@ -17,7 +17,7 @@ const PADDING = 10;
/**
* <zh/> Timebar
* <en/> The configuration item of the Timebar.
* <en/> The options of the Timebar.
*/
export interface TimebarOptions extends BasePluginOptions {
/**

View File

@ -9,7 +9,7 @@ import { BUILD_IN_SVG_ICON, TOOLBAR_CSS, parsePositionToStyle } from './util';
/**
* <zh/> Toolbar
*
* <en/> The configuration item of the Toolbar toolbar
* <en/> The options of the Toolbar toolbar
*/
export interface ToolbarOptions extends BasePluginOptions {
/**
@ -77,7 +77,7 @@ export class Toolbar extends BasePlugin<ToolbarOptions> {
* <zh/>
*
* <en/> Update the configuration of the toolbar
* @param options - <zh/> | <en/> The configuration item of the toolbar
* @param options - <zh/> | <en/> The options of the toolbar
* @internal
*/
public async update(options: Partial<ToolbarOptions>) {

View File

@ -33,7 +33,7 @@ export interface GraphOptions extends CanvasOptions, ViewportOptions {
* @remarks
* <zh/>
*
* <en/> When it is an animation configuration item, the animation will be enabled, and the animation configuration will be used as the basic configuration of the global animation
* <en/> When it is an animation options, the animation will be enabled, and the animation configuration will be used as the basic configuration of the global animation
*/
animation?: boolean | AnimationEffectTiming;
/**

View File

@ -1,4 +1,345 @@
---
title: contribute
order: 8
---
---
To contribute, you need to understand G6's code structure and development workflow. The code repository for G6 is located at: https://github.com/antvis/G6
If you want to fix a bug or add a new feature, you need to first fork a copy of the code to your repository, then make modifications in your repository, and finally submit a Pull Request (PR) to the G6 repository.
## Project Structure
<Tree>
<ul>
<li>
packages
<ul>
<li>
g6
<small>G6 Core Implementation</small>
<ul>
<li>
__tests__
<small>Testing and Development Environment</small>
<ul>
<li>
assets
<small>Test Static Resources</small>
</li>
<li>
dataset
<small>Test Dataset</small>
</li>
<li>
demos
<small>Test Demos</small>
</li>
<li>
snapshots
<small>Test Snapshots</small>
</li>
<li>
unit
<small>Test Cases</small>
</li>
<li>
utils
<small>Test Utility Functions</small>
</li>
</ul>
</li>
<li>
src
<ul>
<li>
animations
<small>Animation Executors and Built-in Animations</small>
</li>
<li>
behaviors
<small>Built-in Interactions</small>
</li>
<li>
constants
<small>Constants and Enumeration Values</small>
</li>
<li>
elements
<small>Built-in Elements</small>
<ul>
<li>
combos
<small>Built-in Combos</small>
</li>
<li>
edges
<small>Built-in Edges</small>
</li>
<li>
nodes
<small>Built-in Nodes</small>
</li>
<li>
shapes
<small>Composite Shapes</small>
</li>
</ul>
</li>
<li>
layouts
<small>Layout References and Encapsulation</small>
</li>
<li>
palettes
<small>Built-in Palettes</small>
</li>
<li>
plugins
<small>Built-in Plugins</small>
</li>
<li>
registry
<small>Registry Module</small>
</li>
<li>
runtime
<small>Graph and Core Controller</small>
</li>
<li>
spec
<small>Specification Type Definitions</small>
</li>
<li>
themes
<small>Built-in Themes</small>
</li>
<li>
transforms
<small>Built-in Data Transformations</small>
</li>
<li>
types
<small>Type Definitions</small>
</li>
<li>
utils
<small>Utility Functions</small>
</li>
<li>
exports.ts
<small>Export Items</small>
</li>
<li>
preset.ts
<small>Pre-operations</small>
</li>
</ul>
</li>
<li>
vite.config.js
<small>Development Environment Vite Configuration</small>
</li>
</ul>
</li>
<li>
g6-extension-3d/src
<small>3D Extension</small>
<ul>
<li>
behaviors
<small>3D Behaviors</small>
</li>
<li>
elements
<small>3D Elements</small>
</li>
<li>
plugins
<small>3D Plugins</small>
</li>
<li>
renderer.ts
<small>3D Renderer</small>
</li>
</ul>
</li>
<li>
g6-extension-react/src
<small>React Node Extension</small>
<ul>
<li>
elements
<small>React Elements</small>
</li>
<li>
graph
<small>React Graph Encapsulation</small>
</li>
</ul>
</li>
<li>
site
<small>Official Website and Documentation</small>
<ul>
<li>
docs
<small>Tutorials and API</small>
</li>
<li>
examples
<small>Graph Examples</small>
</li>
<li>
.dumirc.ts
<small>Configuration File</small>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</Tree>
## Development Process
1. Fork and Pull the Code
Fork the G6 repository on Github to your account, then clone it locally.
```bash
# Navigate to your workspace
cd /path/to/your/workspace
# Navigate to the G6 directory
git clone git@github.com:[your username]/G6.git
```
2. Install Dependencies
:::warning{title=Warning}
Please ensure your local environment meets the following requirements:
- [Node.js](https://nodejs.org/) version >= 18
- [pnpm](https://pnpm.io/) version >= 8
:::
```bash
# Enter the G6 code directory
cd G6
# Install Dependencies
pnpm install
```
3. Start the Development Environment
```bash
# Enter the g6 code directory.
cd ./packages/g6
# Start the development environment
pnpm dev
```
At this point, you can access G6's development environment and preview the examples by visiting http://127.0.0.1:8080 in your web browser.
4. Develop New Features or Fix Bugs
Switch to a development branch:
```bash
git checkout -b [branch name]
```
Make code modifications according to your needs and test locally.
5. Write Test Cases
In the `packages/g6/__tests__/unit` directory, write test cases to ensure your code behaves as expected.
Validate Your Code with Tests
```bash
pnpm test
```
6. Submit a Pull Request (PR)
```bash
# Stage changes
git add .
# Commit Changes
git commit -m "[commit type]: commit message"
# Push to Your Repository
git push
```
Submit a Pull Request (PR) to the G6 repository on GitHub.
## Testing and Coverage
G6 utilizes Jest for conducting unit tests, with the test cases situated in the `packages/g6/__tests__/unit` directory.
We require that all code submissions must pass tests to ensure code quality.
The coverage rate for the current PR (Pull Request) submission is advised not to fall below the coverage rate of the existing codebase, and it is <text style="color: red;">not to fall below 90%</text>.
## Code Standards
The G6 code adheres to the following standards:
- eslint:recommended
- @typescript-eslint/recommended
- jsdoc/recommended-error
## Commit Conventions
G6 adopts the [Conventional Commits](https://www.conventionalcommits.org/) specification, and the commit message format is as follows:
```
<type>[optional scope]: <description>
```
The type field can be one of the following:
- feat: A new feature
- fix: A bug fix
- docs: Documentation update
- style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.)
- refactor: Code change that neither fixes a bug nor adds a feature
- perf: A code change that improves performance
- test: Adding missing or correcting existing tests
- build: Changes that affect the build system or external dependencies
- ci: Changes to our CI configuration files and scripts
- chore: Other changes that don't modify src or test files
- revert: Reverts a previous commit
For example:
```
feat: add new feature
refactor(behavior): refactor drag-canvas behavior
```
Please ensure that your commit messages conform to the standards, and try to use English descriptions whenever possible. This helps us better manage the code.
## Pull Request (PR) Standards
After completing the above steps, you can submit a PR to the G6 repository. Please ensure that your PR adheres to the following standards:
- A single PR should address only one issue.
- The title of the PR should be concise and clear.
- The description of the PR should be clear and detailed. If the changes involve the user interface, please include screenshots.
- The PR must pass CI (Continuous Integration) checks.
## Code Review
After your PR is submitted, we will review your code. Please be patient and await the results of the review. If there are any areas that require modification, we will point them out within the PR.
## Release Process
We regularly release new versions. If your PR is for a non-urgent bug fix, it will be included in the next release. If your PR addresses an urgent bug fix, we will release a new version as soon as possible.

View File

@ -223,8 +223,6 @@ git clone git@github.com:[your username]/G6.git
- [Node.js](https://nodejs.org/) 版本 >= 18
- [pnpm](https://pnpm.io/) 版本 >= 8
部分 scripts 脚本执行依赖 ts-node执行前需要全局安装 ts-node。
:::
```bash

View File

@ -0,0 +1,38 @@
```js | ob { pin: false }
(() => {
const { register, Line, Graph } = window.g6;
class AntLine extends Line {
onCreate() {
this.shapeMap.key.animate([{ lineDashOffset: 20 }, { lineDashOffset: 0 }], {
duration: 500,
iterations: Infinity,
});
}
}
register('edge', 'ant-line', AntLine);
const container = createContainer({ width: 200, height: 50 });
const graph = new Graph({
container,
width: 200,
height: 50,
data: {
nodes: [
{ id: 'node-1', style: { x: 25, y: 25 } },
{ id: 'node-2', style: { x: 175, y: 25 } },
],
edges: [{ source: 'node-1', target: 'node-2', style: { lineDash: [10, 10] } }],
},
edge: {
type: 'ant-line',
},
});
graph.draw();
return container;
})();
```

View File

@ -0,0 +1,39 @@
```js | ob { pin: false }
(() => {
const { register, Circle, Graph } = window.g6;
class BreathingCircle extends Circle {
onCreate() {
this.shapeMap.halo.animate([{ lineWidth: 5 }, { lineWidth: 10 }], {
duration: 1000,
iterations: Infinity,
direction: 'alternate',
});
}
}
register('node', 'breathing-circle', BreathingCircle);
const container = createContainer({ width: 50, height: 50 });
const graph = new Graph({
container,
width: 50,
height: 50,
data: {
nodes: [{ id: 'node-1', style: { x: 25, y: 25 } }],
},
node: {
type: 'breathing-circle',
style: {
halo: true,
haloLineWidth: 5,
},
},
});
graph.draw();
return container;
})();
```

View File

@ -0,0 +1,18 @@
```js | ob { pin: false }
createGraph(
{
data: {
nodes: new Array(6).fill(0).map((_, i) => ({ id: `node-${i}`, data: { value: (i + 1) * 20 } })),
},
layout: { type: 'grid', cols: 6 },
node: {
palette: {
type: 'value',
field: 'value',
color: (value) => `rgb(${value * 255}, 0, 0)`,
},
},
},
{ width: 200, height: 50 },
);
```

View File

@ -0,0 +1,14 @@
```js | ob { pin: false }
createGraph(
{
data: {
nodes: new Array(30).fill(0).map((_, i) => ({ id: `node-${i}` })),
},
layout: { type: 'grid', cols: 10, rows: 3 },
node: {
palette: 'spectral',
},
},
{ width: 400, height: 100 },
);
```

View File

@ -0,0 +1,18 @@
```js | ob { pin: false }
createGraph(
{
data: {
nodes: new Array(6).fill(0).map((_, i) => ({ id: `node-${i}`, data: { category: ['A', 'B', 'C'][i % 3] } })),
},
layout: { type: 'grid', cols: 6 },
node: {
palette: {
type: 'group',
field: 'category',
color: 'tableau',
},
},
},
{ width: 200, height: 50 },
);
```

View File

@ -1,4 +1,209 @@
---
title: Animation
order: 8
---
---
## Overview
<image width="150px" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*NkILT56xXp4AAAAAAAAAAAAADmJ7AQ/original" />
Animation refers to the state changes of elements over a period of time, such as the position, size, and color of nodes. In G6, animations are often used to enhance user experience and improve the coherence and smoothness of the graph update process.
G6 provides a set of animation paradigms to describe element animations and has built-in some common animation effects. Users can achieve different animation effects by configuring animation parameters.
The implementation of an animation paradigm is as follows:
```typescript
[
{
fields: ['x', 'y'],
},
];
```
The aforementioned animation paradigm indicates that when the `x` and `y` attributes of an element change, an animation will be executed.
## Configure Animation
In G6, animation configuration is divided into global configuration and local configuration. Global configuration is mainly used to set whether animations are enabled globally, the duration of animations, and other parameters. Local configuration is primarily used to set the animation effects for elements.
### Disabled Global Animation
To disable global animations, you can pass the `animation` option when instantiating the `Graph`:
```typescript
{
animation: false,
}
```
### Configure Global Animation
If you want to enable animations and also configure the default duration for the animations, you can pass the `animation` option:
```typescript
{
animation: {
duration: 500,
},
}
```
### Configure Element Animation
For individual elements, you can configure animations at different stages. For example, if you want an element to have a fade-in and fade-out effect when it enters and exits, you can configure it as follows:
```typescript
{
node: {
animation: {
enter: 'fade',
exit: 'fade'
}
}
}
```
If you want to update the position of an element with a translation transition, you can configure it as follows:
```typescript
{
node: {
animation: {
update: 'translate',
}
}
}
```
If you wish to disable animations for an element, you can configure it as follows:
```typescript
{
node: {
animation: false,
}
}
```
## Animation Paradigm
The animation configuration mentioned in the previous section actually used the built-in animation paradigm. This section introduces how to customize the animation paradigm.
:::info{title=Tip}
Before writing an animation paradigm, it is necessary to understand the compositional structure of an element. For details, please refer to the [Element](/en/manual/core-concept/element#composition-node) section.
:::
The [Element](/en/manual/core-concept/element) section mentioned that elements in G6 are composed of one or more atomic graphics. Therefore, the animation of an element is essentially a combination of these atomic graphic animations.
Thus, the animation paradigm is an array that describes the animation effects of each atomic graphic within the element. For the element itself, it is also a special composite shape and thus has basic shape attributes such as `x`, `y`, etc.
Therefore, you can directly write an animation paradigm for the element itself:
```typescript
[
{
fields: ['x', 'y'],
},
];
```
## Custom Animation
If the built-in animations do not meet your requirements, you can create custom animations. For details, please refer to [Custom Animation](/en/manual/custom-extension/animation).
## Animation Priority
Animation priority refers to the precedence between global animation configuration and element-specific animation configuration. It can be summarized as follows:
| Global Animation Config | Local Animation Config | Whether to Execute Animation |
| ----------------------- | ---------------------- | ------------------------------------------------------------------------------------------------ |
| ✅ true | ✅ true | ✅ Execute animation with default configuration |
| ✅ true | ❌ false | ❌ Won't execute animation |
| ✅ true | ✅ Custom Animation | ✅ Execute animation with local animation configuration |
| ❌ false | ✅ true | ❌ Won't execute animation |
| ❌ false | ❌ false | ❌ Won't execute animation |
| ❌ false | ✅ Custom Animation | ❌ Won't execute animation |
| ✅ Custom Animation | ✅ true | ✅ Execute animation with global animation configuration |
| ✅ Custom Animation | ✅ Custom Animation | ✅ Execute animation, local animation configuration overrides the global animation configuration |
| ✅ Custom Animation | ❌ false | ❌ Won't execute animation |
## Persistent Animation
If you want elements to have persistent animations, such as the undulating effect of nodes or the ant line effect of edges, this can be achieved by customizing the elements. Below is an implementation of an edge with an Ant Line animation provided:
```typescript
import { Line } from '@antv/g6';
class AntLine extends Line {
onCreate() {
this.shapeMap.key.animate([{ lineDashOffset: -20 }, { lineDashOffset: 0 }], {
duration: 500,
iterations: Infinity,
});
}
}
```
The `onCreate` is a lifecycle hook used to execute animations when an element is created.
Configure the edge style in the options as follows:
```typescript
{
edge: {
type: 'ant-line',
style:{
lineDash: [10, 10]
}
}
}
```
<embed src="@/docs/manual/core-concept-common/animation/ant-line.md"></embed>
The `lineDash` is an array for `lineDashOffset`, and the AntLine effect is achieved by continuously varying the `lineDashOffset`.
Similarly, you can also create a breathing effect for nodes:
```typescript
import { Circle } from '@antv/g6';
class BreathingCircle extends Circle {
onCreate() {}
}
```
The `lineDashOffset` is the offset for `lineDash`, and the AntLine effect is achieved by continuously varying the `lineDashOffset`.
Similarly, you can also create a breathing effect for nodes:
```typescript
import { Circle } from '@antv/g6';
class BreathingCircle extends Circle {
onCreate() {
this.shapeMap.halo.animate([{ lineWidth: 5 }, { lineWidth: 10 }], {
duration: 1000,
iterations: Infinity,
direction: 'alternate',
});
}
}
```
Node Style Configuration:
```typescript
{
node: {
type: 'breathing-circle',
style: {
halo: true,
haloLineWidth: 5,
},
},
}
```
<embed src="@/docs/manual/core-concept-common/animation/breathing-circle.md"></embed>

View File

@ -91,7 +91,7 @@ G6 中动画配置分为全局配置和局部配置,全局配置主要用于
上一节中提到的动画配置实际上使用了内置的动画范式,本节介绍如何自定义动画范式。
:::info{title=提示}
在编写动画范式之前需要了解元素的组成结构,具体请参考[元素](/manual/core-concept/element#节点构成)一节
在编写动画范式之前需要了解元素的组成结构,具体请参考[元素](/manual/core-concept/element#节点构成)一节
:::
[元素](/manual/core-concept/element)一节中提到G6 中的元素是由一个或多个原子图形组合而成。因此元素的动画本质上是这些原子图形动画的组合。
@ -130,7 +130,7 @@ G6 中动画配置分为全局配置和局部配置,全局配置主要用于
## 持续动画
如果希望元素具有持续动画,例如节点的波动效果、边的线效果等,可以通过自定义元素方式实现,下面提供一个具有蚂蚁线(Ant Line)动画的边的实现:
如果希望元素具有持续动画,例如节点的波动效果、边的蚂蚁线效果等,可以通过自定义元素方式实现,下面提供一个具有蚂蚁线(Ant Line)动画的边的实现:
```typescript
import { Line } from '@antv/g6';
@ -152,7 +152,7 @@ class AntLine extends Line {
```typescript
{
edge: {
type: 'fly-line',
type: 'ant-line',
style:{
lineDash: [10, 10]
}
@ -160,43 +160,18 @@ class AntLine extends Line {
}
```
```js | ob { pin: false }
(() => {
const { register, Line, Graph } = window.g6;
<embed src="@/docs/manual/core-concept-common/animation/ant-line.md"></embed>
class AntLine extends Line {
onCreate() {
this.shapeMap.key.animate([{ lineDashOffset: 20 }, { lineDashOffset: 0 }], {
duration: 500,
iterations: Infinity,
});
}
}
其中 `lineDash``lineDashOffset` 的数组,通过不断变化 `lineDashOffset` 来实现飞线效果。
register('edge', 'fly-line', FlyLine);
同样的,还可以实现节点的呼吸效果:
const container = createContainer({ width: 200, height: 50 });
```typescript
import { Circle } from '@antv/g6';
const graph = new Graph({
container,
width: 200,
height: 50,
data: {
nodes: [
{ id: 'node-1', style: { x: 25, y: 25 } },
{ id: 'node-2', style: { x: 175, y: 25 } },
],
edges: [{ source: 'node-1', target: 'node-2', style: { lineDash: [10, 10] } }],
},
edge: {
type: 'fly-line',
},
});
graph.draw();
return container;
})();
class BreathingCircle extends Circle {
onCreate() {}
}
```
其中 `lineDashOffset``lineDash` 的偏移量,通过不断变化 `lineDashOffset` 来实现飞线效果。
@ -231,42 +206,4 @@ class BreathingCircle extends Circle {
}
```
```js | ob { pin: false }
(() => {
const { register, Circle, Graph } = window.g6;
class BreathingCircle extends Circle {
onCreate() {
this.shapeMap.halo.animate([{ lineWidth: 5 }, { lineWidth: 10 }], {
duration: 1000,
iterations: Infinity,
direction: 'alternate',
});
}
}
register('node', 'breathing-circle', BreathingCircle);
const container = createContainer({ width: 50, height: 50 });
const graph = new Graph({
container,
width: 50,
height: 50,
data: {
nodes: [{ id: 'node-1', style: { x: 25, y: 25 } }],
},
node: {
type: 'breathing-circle',
style: {
halo: true,
haloLineWidth: 5,
},
},
});
graph.draw();
return container;
})();
```
<embed src="@/docs/manual/core-concept-common/animation/breathing-circle.md"></embed>

View File

@ -1,4 +1,103 @@
---
title: Behavior
order: 5
---
---
## Overview
<image width="200px" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*sa3jRqp83K4AAAAAAAAAAAAADmJ7AQ/original" />
Behavior refers to a series of operational behaviors between the user and the canvas or elements, such as dragging, scaling, panning, and selecting. Interactions help users to more intuitively obtain information from the graph.
:::warning{title=Note}
In G6 5.x, the concept of "interaction mode" (Mode) has been removed. Users only need to manage the currently enabled behaviors.
:::
G6 provides a rich set of interactive features, and users can choose the appropriate interactive behaviors according to their needs, including:
- [Brush Select](/en/api/behaviors/brush-select): Box Selection
- [Click Select](/en/api/behaviors/click-element): Single Click Selection
- [Collapse Expand](/en/api/behaviors/collapse-expand): Expand and Collapse
- [Create Edge](/en/api/behaviors/create-edge): Create an Edge
- [Drag Canvas](/en/api/behaviors/drag-canvas): Drag the Canvas
- [Drag Element](/en/api/behaviors/drag-element): Drag an Element
- [Focus Element](/en/api/behaviors/focus-element): Focus on an Element
- [Hover Element](/en/api/behaviors/hover-element): Hover Over an Element
- [Lasso Select](/en/api/behaviors/lasso-select): Lasso Selection
- [Zoom Canvas](/en/api/behaviors/zoom-canvas): Zoom the Canvas
## Register Behavior
You can directly use the built-in behaviors. If you want to use other behaviors, you need to register them first:
```typescript
import { register, ExtensionCategory } from '@antv/g6';
import { CustomBehavior } from 'package-name/or/path-to-your-custom-behavior';
register(ExtensionCategory.BEHAVIOR, 'custom-behavior', CustomBehavior);
```
## Configure Behavior
You can directly configure the names of behavior types in the `behaviors` array, for example:
```typescript
{
behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element', 'click-select'],
}
```
It also supports passing configuration parameters in the form of an `object`, for example:
```typescript
{
behaviors: [
{
type: 'zoom-canvas',
sensitivity: 2,
},
],
}
```
> Different behaviors support different configuration parameters. For details, please refer to [behaviors](/en/api/behaviors/brush-select).
### Update Behavior
If you need to update behaviors after initialization, for example, to temporarily disable a certain behavior, you can use the [updateBehavior](/en/api/graph/method#graphupdatebehaviorbehavior) method:
```typescript
// Disable the `zoom-canvas` behavior.
graph.updateBehavior({
key: 'zoom-canvas',
enable: false,
});
```
:::warning{title=Note}
To use the `updateBehavior` method, you must configure the behavior as an `object` during initialization and provide a `key` value.
:::
You can also use the [setBehaviors](/en/api/graph/method#graphsetbehaviorsbehaviors) method to add, update, or remove current behavior behaviors at any time:
```typescript
// Add the `lasso-select` behavior
graph.setBehaviors((behaviors) => [...behaviors, 'lasso-select']);
// Update the `zoom-canvas` behavior (requires configure the behavior as an `object` with a `key` during initialization)
graph.setBehaviors((behaviors) =>
behaviors.map((behavior) => {
if (behavior.key === 'zoom-canvas') {
return { ...behavior, sensitivity: 2 };
}
return behavior;
}),
);
// Remove the `click-select` behavior
graph.setBehaviors((behaviors) => behaviors.filter((behavior) => behavior !== 'click-select'));
```
## Custom Behavior
If the built-in behaviors do not meet your requirements, you can create custom behaviors. For details, please refer to [Custom Behavior](/en/manual/custom-extension/behavior).

View File

@ -1,4 +1,66 @@
---
title: Data
order: 1
---
---
## Overview
G6 is a data-driven charting library, where data is one of the most important concepts. In G6, data is the core of the chart, and both display and interaction are based on data.
Common graph data formats include:CSV, [DOT](https://graphviz.org/doc/info/lang.html), GDF, GML, [GraphML](http://graphml.graphdrawing.org/), [GEXF](https://gexf.net/) etc。
G6 uses JSON format to describe the graph structure, which includes information about nodes and edges. Here is a simple JSON data example:
```json
{
"nodes": [{ "id": "node1" }, { "id": "node2" }],
"edges": [{ "source": "node1", "target": "node2" }]
}
```
Compared to the other formats mentioned above, the JSON format has a more intuitive and understandable data structure. It is also more flexible, allowing for easy expansion of node and edge attributes.
It is a data exchange format widely supported by computers, so you do not have to worry about data format compatibility issues.
## API
G6 provides a series of APIs to access and manipulate data, including:
- [getData](/en/api/graph/method#graphgetdata)
- [setData](/en/api/graph/method#graphsetdatadata)
- [updateData](/en/api/graph/method#graphupdatedatadata)
- [getNodeData](/en/api/graph/method#graphgetnodedata)
- [getEdgeData](/en/api/graph/method#graphgetedgedata)
- [getComboData](/en/api/graph/method#graphgetcombodata)
- [addData](/en/api/graph/method#graphadddatadata)
- [addNodeData](/en/api/graph/method#graphaddnodedatadata)
- [addEdgeData](/en/api/graph/method#graphaddedgedatadata)
- [addComboData](/en/api/graph/method#graphaddcombodatadata)
- [updateData](/en/api/graph/method#graphupdatedatadata)
- [updateNodeData](/en/api/graph/method#graphupdatenodedatadata)
- [updateEdgeData](/en/api/graph/method#graphupdateedgedatadata)
- [updateComboData](/en/api/graph/method#graphupdatecombodatadata)
- [removeData](/en/api/graph/method#graphremovedataids)
- [removeNodeData](/en/api/graph/method#graphremovenodedataids)
- [removeEdgeData](/en/api/graph/method#graphremoveedgedataids)
- [removeComboData](/en/api/graph/method#graphremovecombodataids)
Through different APIs, you can conveniently access and manipulate graph data, performing operations such as adding, deleting, modifying, and querying the graph.
## Use Remote Data
G6 does not provide functionality for data retrieval and parsing. For local JSON data, you can directly import and use it as follows:
```typescript
import data from './path/to/data.json' assert { type: 'json' };
```
For remote data, you can use `fetch` or other networking libraries to retrieve the data:
```typescript
fetch('https://path/to/data.json')
.then((res) => res.json())
.then((data) => {
// Use data
});
```

View File

@ -1,4 +1,350 @@
---
title: Element
order: 2
---
---
## Overview
In G6, graph elements include **Nodes (Node)**, **Edges (Edge)**, and **Combos (Combo)**, which are the basic building blocks of a graph.
An element is composed of one or more atomic graphics, which are the smallest graphic units in G6, including [rectangles](https://g.antv.antgroup.com/en/api/basic/rect), [circles](https://g.antv.antgroup.com/en/api/basic/circle), [text](https://g.antv.antgroup.com/en/api/basic/text), [paths](https://g.antv.antgroup.com/en/api/basic/path), and so on.
For example, a node can be composed of a rectangle and some text, and an edge can be composed of a path and some text.
<image width="300" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*2ZewT4T1p_4AAAAAAAAAAAAADmJ7AQ/original" />
G6 has a rich set of built-in graph element types and also supports user-defined graph elements, allowing users to define new types of graph elements according to their needs.
## Configure Element
Unlike G6 4.x, in G6 5.x, all configurations for a single graph element are laid out flat within the same object, with no nesting. Configurations for different parts of a node are distinguished using a prefix. For example, to set the fill color and label name of a node:
```typescript
{
node: {
style: {
fill: 'orange',
labelText: 'node',
},
},
};
```
The advantage of adopting this approach is that during the development process, it is easier to find the corresponding options. It also facilitates the merging of configurations. If you are using the `VSCode` editor, you can see all the configurable properties of an element and search based on keywords:
<image width="800" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*oY_uTK80sIoAAAAAAAAAAAAADmJ7AQ/original" />
## Node
Nodes are typically used to represent entities or abstract concepts in a graph, such as a person, a location, an organization, etc. Nodes can contain several attributes, such as the node's ID, name, type, etc.
<image width="300" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*TZt2S7Z0d-8AAAAAAAAAAAAADmJ7AQ/original" />
G6 provides the following built-in nodes:
- `Circle` for circular nodes
- `Diamond` for diamond-shaped nodes
- `Donut` for donut-shaped nodes
- `Rect` for rectangular nodes
- `Ellipse` for elliptical nodes
- `Hexagon` for hexagonal nodes
- `HTML` for HTML nodes
- `Image` for image nodes
- `Star` for star-shaped nodes
- `Triangle` for triangular nodes
You can use these nodes directly by configuring the `type`:
```typescript
// Specify the Node Type in the Data
const data = {
nodes: [{ id: 'node-1', type: 'circle' }],
};
// Specify the Node Type in the Node Configuration
{
node: {
type: 'circle',
}
}
```
Generally speaking, most nodes share the same style properties, such as using `size` to specify the node's dimensions. You can view the specific style properties for nodes at [Element - Node](/en/api/elements/nodes/base-node).
Some special nodes may have their own style properties. For example, the `HTML` node has an `innerHTML` property that is used to specify the HTML content of the node. The specific style properties can be found at [Node Style](/en/api/elements/nodes/html).
In addition to these, G6 officially provides some additional nodes that require installation before use:
`@antv/g6-extension-3d` provides 3D nodes:
<image width="300" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*ShNXTp0u3vkAAAAAAAAAAAAADmJ7AQ/original" />
- `Capsule` for capsule-shaped nodes
- `Cone` for conical nodes
- `Cube` for cubic nodes
- `Cylinder` for cylindrical nodes
- `Plane` for planar nodes
- `Sphere` for spherical nodes
- `Torus` for toroidal nodes
`@antv/g6-extension-react` provides nodes suitable for use with the React framework:
<image width="350" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*7jypQbkp00wAAAAAAAAAAAAADmJ7AQ/original" />
- `ReactNode` for React nodes
- `GNode` for nodes written with JSX syntax from `@antv/g`
### Composition of Node
The nodes provided in G6 are composed of the following parts:
<image width="250" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*Ot4bSbBx97EAAAAAAAAAAAAADmJ7AQ/original" />
- `key`: The main shape of the node, representing the primary form of the node, such as rectangles, circles, etc.
- `label`: The text label, typically used to display the name or description of the node.
- `icon`: The icon shape, usually used to display an icon for the node, which can be an image or a text icon.
- `badge`: A badge located at the top right corner of the node by default.
- `halo`: The halo effect displayed around the main shape.
- `port`: The connection point on the node, used for connecting edges.
### Register Node
You can directly use built-in nodes, but if you want to use other nodes or create custom nodes, you need to register them first:
```typescript
import { register, ExtensionCategory } from '@antv/g6';
import { CustomNode } from 'package-name/or/path-to-your-custom-node';
register(ExtensionCategory.NODE, 'custom-node', CustomNode);
```
### Configure Node
You can configure the node type and its style in the following ways:
1. Configure in the data:
```json
{
"nodes": [
{
"id": "node-1",
"type": "custom-node",
"style": {
// Node Style
}
}
]
}
```
2. Configure in the Node Style Mapping:
```typescript
{
node: {
type: 'custom-node',
style: {
// Node Style
}
}
}
```
### Custom Node
If the built-in node elements do not meet your requirements, you can customize node elements,For more details, please refer to [Custom Node](/en/manual/custom-extension/element#custom-node)。
## Edge
You can create edges between any two nodes or combos, and you may also create multiple edges between two nodes/combos to represent different relationships.
<image width="300" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*YKN7TasqOh4AAAAAAAAAAAAADmJ7AQ/original" />
G6 offers several built-in edge types:
- `Line` A straight line edge
- `Polyline` A polyline edge composed of straight line segments
- `Quadratic` An edge with a quadratic Bézier curve
- `Cubic` An edge with a cubic Bézier curve
- `CubicVertical` A cubic Bézier curve edge that is primarily vertical
- `CubicHorizontal` A cubic Bézier curve edge that is primarily horizontal
Configuring an edge is similar to configuring a node, where you can specify the `type` to use the desired edge style:
```typescript
// Specifying Edge Types in Data
const data = {
edges: [{ source: 'node-1', target: 'node-2', type: 'line' }],
};
// Specifying Edge Types in Edge Configuration
{
edge: {
type: 'line',
}
}
```
In G6, edges are directional by default, pointing from the source node to the target node, but the arrow can be hidden to represent undirected edges.
```typescript
{
edge: {
style: {
startArrow: false,
endArrow: false,
},
},
};
```
### Edge Composition
In G6, an edge is composed of the following parts:
<image height="100" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*cVHVQJKLOlgAAAAAAAAAAAAADmJ7AQ/original" />
- `key` : The primary shape of the edge, representing the main form of the edge, such as a straight line, polyline, etc.
- `label` : A text label, usually used to display the name or description of the edge
- `arrow` : A text label, usually used to display the name or description of the edge
- `halo` : A graphic that displays a halo effect around the main shape
### Register Edge
The registration method for edges is similar to that for nodes:
```typescript
import { register, ExtensionCategory } from '@antv/g6';
import { CustomEdge } from 'package-name/or/path-to-your-custom-edge';
register(ExtensionCategory.EDGE, 'custom-edge', CustomEdge);
```
### Configure Edge
You can configure the edge type and its style in the following ways:
1. Configure in the data:
```json
{
"edges": [
{
"source": "node-1",
"target": "node-2",
"type": "custom-edge",
"style": {
// edge style
}
}
]
}
```
2. In the edge style mapping:
```typescript
{
edge: {
type: 'custom-edge',
style: {
// edge style
}
}
}
```
### Custom Edge
If the built-in edge elements do not meet your requirements, you can customize edge elements. For details, please refer to [Custom Edge](/en/manual/custom-extension/element#custom-edge).
## Combo
Combo, fully named as Combination, is a special type of element in G6 that can contain nodes and sub-combos. It is often used to represent a set relationship, such as a department containing multiple employees, a city containing multiple districts, etc.
<image width="300" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*WJhpRJCcFLAAAAAAAAAAAAAADmJ7AQ/original" />
:::warning{title=note}
It is not recommended to use combos in **tree graph** because the layout method of combos does not match that of tree diagrams, which may lead to style confusion.
:::
G6 provides the following built-in combos:
- `Circle` for circular combos
- `Rect` for rectangular combos
You can use them by configuring the `type`:
```typescript
// Specify the combo Type in the Data
const data = {
combos: [{ id: 'combo-1', type: 'circle' }],
};
// In the combo configuration, specify the combo type:
{
combo: {
type: 'circle',
}
}
```
### Composition of Combo
The combos provided in G6 are composed of the following parts:
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*z-OxR4MAdUwAAAAAAAAAAAAADmJ7AQ/original" />
- `key`: The main shape of the combo, representing the primary form of the combo.
- `halo`: The graphic that displays the halo effect around the main shape.
- `label`: The text label, usually used to display the name or description of the combo.
### Register Combo
The registration method for Combo is similar to that for nodes:
```typescript
import { register, ExtensionCategory } from '@antv/g6';
import { CustomCombo } from 'package-name/or/path-to-your-custom-combo';
register(ExtensionCategory.COMBO, 'custom-combo', CustomCombo);
```
### Configure Combo
You can configure the combo type and its style in the following ways:
1. Configure in the data:
```json
{
"combos": [
{
"id": "combo-1",
"type": "custom-combo",
"style": {
// combo Style
}
}
]
}
```
2. Configure in the combo style mapping:
```typescript
{
combo: {
type: 'custom-combo',
style: {
// combo Style
}
}
}
```
### Custom Combo
If the built-in combo elements do not meet your needs, you can customize combo elements. For more details, please refer to [Custom Combo](/en/manual/custom-extension/element#custom-combo).

View File

@ -70,7 +70,7 @@ const data = {
}
```
通常来说,大多数节点具有相同的样式属性,例如都使用 `size` 来指定节点的大小。你可以在[Node - 节点](/api/elements/nodes/base-node)中查看节点的具体样式属性。
通常来说,大多数节点具有相同的样式属性,例如都使用 `size` 来指定节点的大小。你可以在[Element - 节点](/api/elements/nodes/base-node)中查看节点的具体样式属性。
某些特殊的节点可能会有自己的样式属性,例如 `HTML` 节点的 `innerHTML` 属性用于指定节点的 HTML 内容。具体的样式属性可以参考[节点样式](/api/elements/nodes/html)。

View File

@ -1,4 +1,77 @@
---
title: extension
order: 9
---
---
## Concept
Extension is an important concept in G6, it is a general term for all expandable parts in G6, including the following types:
- Animation
- Behavior
- Element
- Node
- Edge
- Combo
- Layout
- Palette
- Plugin
- Theme
- Transform
## Register Extension
G6 provides the `register` function for registering extensions, for example:
```typescript
import { register, ExtensionCategory } from '@antv/g6';
import { CustomNode } from './my-custom-node';
// # Registering Nodes
register(ExtensionCategory.NODE, 'custom-node', CustomNode);
```
The first parameter of the `register` function is the type of the extension, the second parameter is the name of the extension, and the third parameter is the implementation of the extension.
Different types of extensions **can** use the same extension name, but when registering extensions of the same type, only the first registration will take effect.
> For detailed parameter signatures, see: [API Documentation](/en/api/reference/g6/register)
```typescript
// ✅
register(ExtensionCategory.NODE, 'custom-name', CustomNode);
register(ExtensionCategory.COMBO, 'custom-name', CustomCombo);
// ❌
register(ExtensionCategory.NODE, 'custom-name', CustomNode);
register(ExtensionCategory.NODE, 'custom-name', CustomNode);
```
## Use Extension
The configuration location for different types of extensions varies, but all are used by specifying the name that was used during registration, for example:
- Using node extensions: `options.node.type`
- Using edge extensions: `options.edge.type`
- Using combo extensions: `options.combo.type`
- Using behavior extensions: `options.behaviors`
- Using layout extensions: `options.layout.type`
- Using plugin extensions: `options.plugins`
- Using theme extensions: `options.theme`
- Using data transform extensions: `options.transform`
- Using palette extensions: `options.node.palette`, `options.edge.palette`, etc.
- Using animation extensions: `options.node.animate`, `options.edge.animate`, etc.
## Get Extension
G6 provides the `getExtension` and `getExtensions` methods to obtain a single extension and all extensions of a specified type, respectively, for example:
```typescript
import { getExtension, getExtensions, ExtensionCategory } from '@antv/g6';
// To get the implementation of the node extension registered with the name 'custom-node'
getExtension(ExtensionCategory.NODE, 'custom-node');
// Retrieve all registered node extension implementations
getExtensions(ExtensionCategory.NODE);
```

View File

@ -8,11 +8,11 @@ order: 9
扩展 (Extension) 是 G6 中的一个重要概念,它是 G6 中所有可扩展部分的统称,包括以下几种:
- 动画 (Animation)
- 节点 (Node)
- 边 (Edge)
- 组合 (Combo)
- 交互 (Behavior)
- 元素 (Element)
- 节点 (Node)
- 边 (Edge)
- 组合 (Combo)
- 布局 (Layout)
- 色板 (Palette)
- 插件 (Plugin)

View File

@ -1,4 +1,76 @@
---
title: Graph
order: 0
---
---
## Overview
### Definition of Graph
In Chinese, the character "图" (Graph) can often be used to represent many different concepts, such as image,shape,and chart or diagram,etc.
In Graph Theory, a graph is a mathematical structure used to model pairwise relationships between objects, which we typically represent with nodes (or Vertex) and edges (or Link) to denote the objects and the relationships between them.
The "graph" in G6:
- Conceptually, it is the "graph" from Graph Theory, a data structure composed of nodes and edges.
- Visually, a "graph" is a figure composed of a set of graphical elements representing nodes and edges.
- In terms of code implementation, a "graph" is a class capable of transforming data into a graphical display.
### Types of Graph
Graph Theory categorizes graphs into many different types based on their structure and properties, such as:
- Directed Graph and Undirected Graph
- Weighted Graph and Unweighted Graph
- Simple Graph and Multigraph
- Cyclic Graph and Acyclic Graph
- Connected Graph and Disconnected Graph
- Complete Graph and Non-Complete Graph
- Sparse Graph and Dense Graph
- ...
In G6, we provide a universal graph representation capable of depicting the various types of graphs mentioned above, for example:
- Directed Graph and Undirected Graph: Defined by the start and end points of the edges.
- Weighted Graph and Unweighted Graph: Defined by the `weight` data on the edges.
- Simple Graph and Multigraph: Defined by the uniqueness of the edges.
- ...
### Use Scenarios
Graphs are a very versatile data structure that can be used to represent a variety of scenarios, such as:
- Social Networks
- Knowledge Graphs
- Traffic Networks
- Power Grids
In G6, we provide a rich expression capability for graphs that can meet the needs of different scenarios. We also offer a wealth of interactive and animated effects to make the graphs more vivid and intuitive.
## Use G6 Graph
To create a Graph with G6, you first need to import the `@antv/g6` library, and then instantiate the Graph class.
> For installation instructions, refer to: [Getting Started - Installation](/en/manual/getting-started/installation)
The Graph class accepts an instantiation argument object, known as **options** (Options, in visualization theory it is referred to as: `Specification`), which is used to configure the graph's data, element styles, layout, interactions, etc.
```typescript
import { Graph } from '@antv/g6';
const graph = new Graph({
container: 'container',
width: 800,
height: 600,
// ... other other options
});
```
:::warning{title=note}
The instantiation process only configures the basic information of the graph. To render the graph onto the page, you still need to call the `render` method.
:::
- To learn how to quickly create a graph, please refer to [Quick Start](/en/manual/getting-started/quick-start).
- For more detailed information about the configuration options, please refer to [Method](/en/api/graph/method).
- To gain an in-depth understanding of the concepts within the configuration options, please read the rest of the content in this section.

View File

@ -1,4 +1,168 @@
---
title: Layout
order: 4
---
---
## Overview
Graph layout refers to the process of arranging the elements in a graph according to certain rules, such as force-directed layouts based on the electrostatic model, sequential arrangement in grid layouts, and tree layouts based on hierarchical structures, etc.
<image width="300" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*WIhlToluHaEAAAAAAAAAAAAADmJ7AQ/original" />
## Layout Type
G6 provides a variety of layout algorithms, allowing users to select the appropriate layout algorithm based on their needs:
<!-- TODO to be verified if the links are correct -->
- [AntVDagreLayout](/en/api/layouts/antv-dagre-layout): A layout based on dagre customization
- [CircularLayout](/en/api/layouts/circular-layout): Circular layout
- [ComboCombinedLayout](/en/api/layouts/combo-combined-layout): A layout suitable for scenarios with combos
- [ConcentricLayout](/en/api/layouts/concentric-layout): Concentric circle layout
- [D3Force3DLayout](/en/api/layouts/d3-force-3-d-layout): A [3D force-directed](https://github.com/vasturiano/d3-force-3d) layout
- [D3ForceLayout](/en/api/layouts/d3-force-layout): A force-directed layout based on [D3](https://d3js.org/d3-force)
- [DagreLayout](/en/api/layouts/dagre-layout): A layout based on [dagre](https://github.com/dagrejs/dagre)
- [ForceAtlas2Layout](/en/api/layouts/force-atlas2-layout): A layout based on [ForceAtlas2](https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0098679)
- [ForceLayout](/en/api/layouts/force-layout): Force-directed layout
- [FruchtermanLayout](/en/api/layouts/fruchterman-layout): A layout based on [Fruchterman](https://www.sciencedirect.com/topics/computer-science/reingold-layout)
- [GridLayout](/en/api/layouts/grid-layout): Grid layout
- [MDSLayout](/en/api/layouts/mds-layout): A layout algorithm for high-dimensional data dimensionality reduction
- [RadialLayout](/en/api/layouts/radial-layout): Radial layout
- [RandomLayout](/en/api/layouts/random-layout): Random layout
- CompactBox Layout: Compact tree layout
- Dendrogram Layout: Dendrogram layout
- Mindmap Layout: Mind map layout
- Indented Layout: Indented tree layout
Among them, `CompactBox Layout`, `Dendrogram Layout`, `Mindmap Layout`, and `Indented Layout` are types of tree layouts, suitable for graphs with tree-like structures.
## Register Layout
You can directly use the built-in layouts, but if you want to use other layouts, you need to register them first:
```typescript
import { register, ExtensionCategory } from '@antv/g6';
import { CustomLayout } from 'package-name/or/path-to-your-custom-layout';
register(ExtensionCategory.LAYOUT, 'custom-layout', CustomLayout);
```
## Configure Layout
You can specify the graph's layout algorithm through the `layout` option, for example:
```typescript
{
layout: {
// Specify the layout algorithm to be used
type: 'force',
// Layout Algorithm Options
gravity: 10
// ...
}
}
```
You can also update the layout configuration after instantiating the graph using `graph.setLayout`.
## Layout Acceleration
G6 provides accelerated versions of some layout algorithms, including: executing layout algorithms in a Web Worker, providing [WASM](https://webassembly.org/) versions of layout algorithms, and GPU-accelerated layout algorithms. They can be used in the following ways:
### Executing Layout Algorithms in a Web Worker
All built-in layout algorithms in G6, except for tree layouts, support execution in a Web Worker. Simply set `enableWorker` to `true`:
```typescript
{
layout: {
type: 'force',
enableWorker: true,
// ...
}
}
```
### Use WASM Version Layout Algorithms
The layout algorithms that currently support WASM versions are: `Fruchterman Layout`, `ForceAtlas Layout`, `Force Layout`, `Dagre Layout`.
First, install `@antv/layout-wasm`:
```bash
npm install @antv/layout-wasm --save
```
Import and Register the Layout Algorithm:
```typescript
import { register, Graph, ExtensionCategory } from '@antv/g6';
import { FruchtermanLayout, initThreads, supportsThreads } from '@antv/layout-wasm';
register(ExtensionCategory.LAYOUT, 'fruchterman-wasm', FruchtermanLayout);
```
Initialize the Thread:
```typescript
const supported = await supportsThreads();
const threads = await initThreads(supported);
```
Initialize the Graph and Pass in Layout Configuration:
```typescript
const graph = new Graph({
// ... other configurations
layout: {
type: 'fruchterman-wasm',
threads,
// ... other configurations
},
});
```
### Use GPU-Accelerated Layout
The layout algorithms that currently support GPU acceleration are: `Fruchterman Layout` and `GForce Layout`.
First, install `@antv/layout-gpu`:
```bash
npm install @antv/layout-gpu --save
```
Import and Register the Layout Algorithm:
```typescript
import { register, Graph, ExtensionCategory } from '@antv/g6';
import { FruchtermanLayout } from '@antv/layout-gpu';
register(ExtensionCategory.LAYOUT, 'fruchterman-gpu', FruchtermanLayout);
```
Initialize the Graph and Pass in Layout Configuration:
```typescript
const graph = new Graph({
// ... other configurations
layout: {
type: 'fruchterman-gpu',
// ... other configurations
},
});
```
## Execute Layout
Usually, after calling `graph.render()`, G6 will automatically execute the layout algorithm.
If you need to manually execute the layout algorithm, G6 provides the following APIs:
- [layout](/en/api/graph/method#graphlayout): Execute the layout algorithm
- [setLayout](/en/api/graph/method#graphsetlayoutlayout): Set the layout algorithm
- [stopLayout](/en/api/graph/method#graphstoplayout): Stop the layout algorithm
## Custom Layout
If the built-in layout algorithms do not meet your requirements, you can create a custom layout algorithm. For details, please refer to [Custom Layout](/en/manual/custom-extension/layout).

View File

@ -159,9 +159,9 @@ const graph = new Graph({
如果需要手动执行布局算法G6 提供了以下 API
- [layout](/api/graph/method#layout):执行布局算法
- [setLayout](/api/graph/method#setLayout):设置布局算法
- [stopLayout](/api/graph/method#stopLayout):停止布局算法
- [layout](/api/graph/method#graphlayout):执行布局算法
- [setLayout](/api/graph/method#graphsetlayoutlayout):设置布局算法
- [stopLayout](/api/graph/method#graphstoplayout):停止布局算法
## 自定义布局

View File

@ -1,4 +1,186 @@
---
title: Palette
order: 7
---
---
## Overview
A palette refers to a set of predefined color collections that help users more conveniently select colors. In G6, a palette is a common option that allows users to configure the colors of elements such as nodes, edges, and links through the palette.
Palettes are divided into two types: `discrete palette` and `continuous palette`.
A discrete palette is an array of colors used to map discrete values within elements to different colors, such as the type of nodes, the relationship of edges, etc. Below is a simple example of a discrete palette:
```typescript
['#5B8FF9', '#61DDAA', '#F6BD16', '#F6903D', '#F08BB4'];
```
A continuous palette is an interpolator that takes a value between 0 and 1 and returns the corresponding color. It is used to map continuous values within elements to different colors, such as the degree of nodes, the weight of edges, etc. Below is a simple example of a continuous palette:
```typescript
(value: number) => `rgb(${value * 255}, 0, 0)`;
```
## Register Palette
You can directly use the built-in palettes, but if you want to use other palettes, you need to register them first:
```typescript
import { register, ExtensionCategory } from '@antv/g6';
import { CustomPalette } from 'package-name/or/path-to-your-custom-palette';
register(ExtensionCategory.PALETTE, 'custom-palette', CustomPalette);
```
:::warning{title=note}
During the process of registering a palette, there is no distinction made between discrete and continuous palettes. It is necessary to ensure the consistency between the palette type and the data type when using the palette.
:::
### Built-in Palettes
Currently, G6 has 5 sets of commonly used discrete palettes that users can directly utilize:
- spectral
<div style="display: flex; width: 600px; height: 20px;"><style>div{flex-grow:1}</style><div style="background: rgb(158, 1, 66);"></div><div style="background: rgb(213, 62, 79);"></div><div style="background: rgb(244, 109, 67);"></div><div style="background: rgb(253, 174, 97);"></div><div style="background: rgb(254, 224, 139);"></div><div style="background: rgb(255, 255, 191);"></div><div style="background: rgb(230, 245, 152);"></div><div style="background: rgb(171, 221, 164);"></div><div style="background: rgb(102, 194, 165);"></div><div style="background: rgb(50, 136, 189);"></div><div style="background: rgb(94, 79, 162);"></div></div>
- tableau
<div style="display: flex; width: 600px; height: 20px;"><style>div{flex-grow:1}</style><div style="background: rgb(78, 121, 167);"></div><div style="background: rgb(242, 142, 44);"></div><div style="background: rgb(225, 87, 89);"></div><div style="background: rgb(118, 183, 178);"></div><div style="background: rgb(89, 161, 79);"></div><div style="background: rgb(237, 201, 73);"></div><div style="background: rgb(175, 122, 161);"></div><div style="background: rgb(255, 157, 167);"></div><div style="background: rgb(156, 117, 95);"></div><div style="background: rgb(186, 176, 171);"></div></div>
- oranges
<div style="display: flex; width: 600px; height: 20px;"><style>div{flex-grow:1}</style><div style="background: rgb(255, 245, 235);"></div><div style="background: rgb(254, 230, 206);"></div><div style="background: rgb(253, 208, 162);"></div><div style="background: rgb(253, 174, 107);"></div><div style="background: rgb(253, 141, 60);"></div><div style="background: rgb(241, 105, 19);"></div><div style="background: rgb(217, 72, 1);"></div><div style="background: rgb(166, 54, 3);"></div><div style="background: rgb(127, 39, 4);"></div></div>
- greens
<div style="display: flex; width: 600px; height: 20px;"><style>div{flex-grow:1}</style><div style="background: rgb(247, 252, 245);"></div><div style="background: rgb(229, 245, 224);"></div><div style="background: rgb(199, 233, 192);"></div><div style="background: rgb(161, 217, 155);"></div><div style="background: rgb(116, 196, 118);"></div><div style="background: rgb(65, 171, 93);"></div><div style="background: rgb(35, 139, 69);"></div><div style="background: rgb(0, 109, 44);"></div><div style="background: rgb(0, 68, 27);"></div></div>
- blues
<div style="display: flex; width: 600px; height: 20px;"><style>div{flex-grow:1}</style><div style="background: rgb(247, 251, 255);"></div><div style="background: rgb(222, 235, 247);"></div><div style="background: rgb(198, 219, 239);"></div><div style="background: rgb(158, 202, 225);"></div><div style="background: rgb(107, 174, 214);"></div><div style="background: rgb(66, 146, 198);"></div><div style="background: rgb(33, 113, 181);"></div><div style="background: rgb(8, 81, 156);"></div><div style="background: rgb(8, 48, 107);"></div></div>
## Configure Palette
Currently, the configuration of palettes is mainly focused on elements, taking nodes as an example:
### Discrete Palette
1. Default Configuration: By directly setting the value of `palette` to the name of the palette, each node will be assigned a different color by default
```typescript
{
node: {
palette: 'spectral', // spectral is the Palette Name
}
}
```
<embed src="@/docs/manual/core-concept-common/palette/default-config.md"></embed>
> When the number of elements exceeds the number of colors in the palette, the colors in the palette will be reused in a cyclic manner.
2. Standard Configuration: The attributes for configuring a discrete palette include: `type: 'group'`, `field`, `color`, `invert`.
Among them, `type: 'group'` explicitly specifies that the current palette type is a discrete palette; `field` designates the field for grouping in the element data; `color` is the name of the palette; `invert` indicates whether to invert the palette.
Given a set of example data:
```json
{
"nodes": [
{ "id": "node-1", "data": { "category": "A" } },
{ "id": "node-2", "data": { "category": "B" } },
{ "id": "node-3", "data": { "category": "C" } },
{ "id": "node-4", "data": { "category": "A" } },
{ "id": "node-5", "data": { "category": "B" } },
{ "id": "node-6", "data": { "category": "C" } }
]
}
```
In the data, `node-1` and `node-4` belong to category A, `node-2` and `node-5` belong to category B, `node-3` and `node-6` belong to category C.
Configure the color of the nodes in such a way that nodes of the same category have the same color:
```typescript
{
node: {
palette: {
type: 'group', // Specify the palette type as a categorical palette.
field: 'category', // Specify the grouping field in the data.
color: 'tableau', // Use a Tableau-like palette.
}
}
}
```
<embed src="@/docs/manual/core-concept-common/palette/standard-config.md"></embed>
### Continuous Palette
A continuous palette only supports standard configuration methods, with configuration properties including: `type: 'value'`, `field`, `color`, `invert`.
Given a set of example data:
```json
{
"nodes": [
{ "id": "node-1", "data": { "value": 0 } },
{ "id": "node-2", "data": { "value": 20 } },
{ "id": "node-3", "data": { "value": 40 } },
{ "id": "node-4", "data": { "value": 60 } },
{ "id": "node-5", "data": { "value": 80 } },
{ "id": "node-6", "data": { "value": 100 } }
]
}
```
Now, create an interpolator that maps the maximum value to red (`rgb(255, 0, 0)`) and the minimum value to black (`rgb(0, 0, 0)`):
```typescript
(value) => `rgb(${value * 255}, 0, 0)`;
```
Configure the following so that the color of the nodes is mapped to different colors based on the value of the `value` field in the data:
```typescript
{
node: {
palette: {
type: 'value', // Specify the palette type as a continuous palette
field: 'value', // Specify the numerical field in the data
color: (value) => `rgb(${value * 255}, 0, 0)`, // Use an interpolator
}
}
}
```
<embed src="@/docs/manual/core-concept-common/palette/continuous-palette.md"></embed>
:::warning{title=note}
The built-in continuous palette does not support specifying a value range. If there is a need for more complex color mapping, it can be customized within the style mapping.
:::
## Custom Palette
If the built-in palette does not meet your requirements, you can customize the palette. For details, please refer to [Custom Palette](/en/manual/custom-extension/palette).
## Priority
The palette generates styles based on the type of element. For nodes and combos, the color is mapped to the `fill` attribute; for edges, the color is mapped to the `stroke` attribute.
If both a palette and a style mapping are configured, the style mapping will override the palette colors. In the following example, the color of the nodes is always red:
```typescript
{
node: {
style: {
fill: 'red',
},
palette: 'spectral',
}
}
```

View File

@ -76,20 +76,7 @@ register(ExtensionCategory.PALETTE, 'custom-palette', CustomPalette);
}
```
```js | ob { pin: false }
createGraph(
{
data: {
nodes: new Array(30).fill(0).map((_, i) => ({ id: `node-${i}` })),
},
layout: { type: 'grid', cols: 10, rows: 3 },
node: {
palette: 'spectral',
},
},
{ width: 400, height: 100 },
);
```
<embed src="@/docs/manual/core-concept-common/palette/default-config.md"></embed>
> 当元素数量超过色板颜色数量时,会循环使用色板中的颜色
@ -128,24 +115,7 @@ createGraph(
}
```
```js | ob { pin: false }
createGraph(
{
data: {
nodes: new Array(6).fill(0).map((_, i) => ({ id: `node-${i}`, data: { category: ['A', 'B', 'C'][i % 3] } })),
},
layout: { type: 'grid', cols: 6 },
node: {
palette: {
type: 'group',
field: 'category',
color: 'tableau',
},
},
},
{ width: 200, height: 50 },
);
```
<embed src="@/docs/manual/core-concept-common/palette/standard-config.md"></embed>
### 连续色板
@ -186,24 +156,7 @@ createGraph(
}
```
```js | ob { pin: false }
createGraph(
{
data: {
nodes: new Array(6).fill(0).map((_, i) => ({ id: `node-${i}`, data: { value: (i + 1) * 20 } })),
},
layout: { type: 'grid', cols: 6 },
node: {
palette: {
type: 'value',
field: 'value',
color: (value) => `rgb(${value * 255}, 0, 0)`,
},
},
},
{ width: 200, height: 50 },
);
```
<embed src="@/docs/manual/core-concept-common/palette/continuous-palette.md"></embed>
:::warning{title=注意}
内置连续色板不支持指定值域范围,如果有更复杂的颜色映射需求,可以在样式映射中自定义

View File

@ -1,4 +1,100 @@
---
title: Plugin
order: 6
---
---
## Overview
A plugin is the most flexible extension mechanism in G6, allowing users to extend G6's functionality through plugins. For example, you can mount additional graphical components on the canvas or implement features like undo and redo.
Most customization requirements can be met through plugins. G6 comes with some commonly used plugins, such as: [Tooltip](/en/api/plugins/tooltip), [Grid](/en/api/plugins/grid), [History](/en/api/plugins/history).
> For a list of built-in plugins, please refer to: [Plugin](/en/api/plugins/bubble-sets)
## Register Plugin
You can use built-in plugins directly. If you want to use other plugins, you need to register them first:
```typescript
import { register, ExtensionCategory } from '@antv/g6';
import { CustomPlugin } from 'package-name/or/path-to-your-custom-plugin';
register(ExtensionCategory.PLUGIN, 'custom-plugin', CustomPlugin);
```
## Configure Plugin
To enable and configure plugins, you need to pass the `plugins` option when instantiating the `Graph`. This option is an array that includes the plugins that need to be enabled:
```typescript
{
plugins: ['grid', 'tooltip', 'contextmenu'],
}
```
Some plugins support property configuration in the form of an `object`, for example:
```typescript
{
plugins: [
{
type: 'bubble-sets',
members: ['node-1'],
},
];
}
```
### Update Plugin
After the `Graph` is instantiated, you can adjust the plugins using the [setPlugins](/en/api/graph/method#graphsetpluginsplugins) method:
```typescript
// add minimap plugin
graph.setPlugins((plugins) => [...plugins, 'minimap']);
// remove tooltip plugin
graph.setPlugins((plugins) => plugins.filter((plugin) => plugin !== 'tooltip'));
```
G6 Graph also provides the [updatePlugin](/en/api/graph/method#graphupdatepluginplugin) method for more conveniently updating plugin configurations:
```typescript
graph.updatePlugin({
key: 'grid',
follow: true,
});
```
:::warning{title=note}
To use the `updatePlugin` method, you must configure the plugin as an `object` during initialization and pass in a `key` value.
:::
### Uninstall Plugin
The [setPlugins](/en/api/graph/method#graphsetpluginsplugins) method can also be used to uninstall plugins by setting the plugin configuration list to an empty array:
```typescript
// Uninstall all plugins
graph.setPlugins([]);
```
## Invoking Plugin Methods
Some plugins provide API methods that can be invoked by users. For example, the `history` plugin provides `undo` and `redo` methods, which users can call to perform undo and redo operations.
To invoke these methods, you first need to obtain the plugin instance, which can be acquired through the `getPluginInstance` method:
```js
const history = graph.getPluginInstance('history');
```
:::warning{title=note}
The `graph.getPluginInstance` method takes the plugin `key` value as a parameter. Therefore, to obtain a plugin instance, you must configure the corresponding plugin as an `object` and pass in the `key` value.
:::
## Custom Plugin
If the built-in plugins do not meet your requirements, you can create custom plugins. For details, please refer to [Custom Plugin](/en/manual/custom-extension/plugin).

View File

@ -1,4 +1,148 @@
---
title: State
order: 3
---
---
## Overview
<image width="500px" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*yVbORYybrDQAAAAAAAAAAAAADmJ7AQ/original" />
Status (State) refers to the condition of an <u>element</u>, such as **selected**, **hovered**, **active**, etc. States allow elements to display different styles in different conditions, helping users to more intuitively understand the information in the graph.
## State Type
In G6, the types of states are represented as an array of strings (`string[]`), meaning that an element can be in multiple states at the same time. For example, a node can be in both the **selected** and **hovered** states.
The predefined states in G6 include:
- `selected`: Selected state
- `active`: Active state
- `highlight`: Highlighted state
- `inactive`: Inactive state
- `disable`: Disabled state
:::warning{title=note}
- **Default State** is the initial state of an element. When an element has no states, it is in the default state.
- The preset states are not mandatory; they are merely common types of states. Users can define more state types according to their own needs.
:::
## Set Element State
### State Style
Currently, G6 supports configuring state styles within style mappings, for example:
```typescript
{
node: {
style: {/** Default State Style */},
selected: {/** Selected State Style */},
[State name]: {/** State Style */}
},
edge: {
style: {/** Default State Style */},
selected: {/** Selected State Style */},
[State name]: {/** State Style */}
},
combo: {
style: {/** Default State Style */},
selected: {/** Selected State Style */},
[State name]: {/** State Style */}
}
}
```
### Toggle State
Before rendering, you can configure the state of elements in the data:
```typescript
const data = {
nodes: [
{
id: 'node-1',
states: ['selected'],
},
{
id: 'node-2',
states: ['disabled'],
},
],
edges: [
{
source: 'node-1',
target: 'node-2',
states: ['highlight'],
},
],
};
```
Or, after rendering, you can toggle the state of elements through the API:
```typescript
// Set node 'node-1' to the selected state
graph.setElementState('node-1', 'selected');
// Set node 'node-2' to both the selected and disabled states
graph.setElementState('node-2', ['selected', 'disabled']);
// Set both 'node-1' and 'node-2' to the highlighted state
graph.setElementState({
'node-1': ['highlight'],
'node-2': ['highlight'],
});
```
### Get State
G6 provides multiple APIs for retrieving states, or for determining whether an element is in a certain state:
```typescript
// Retrieve all states of 'node-1'.
graph.getElementState('node-1');
```
> When an element is only in the **default state**, the `getElementState` method returns an empty array `[]`.
```typescript
// Retrieve all selected nodes.
graph.getElementDataByState('node', 'selected');
```
### Remove State
To remove the state of an element, you can also use the `setElementState` method to achieve this:
```typescript
// Remove all states from `node-1` (restore to the default state)
graph.setElementState('node-1', []);
```
## State Priority
When an element is in multiple states, the priority of the states is determined by the order of the state values. For example, if a node's state value is: `['selected', 'highlight']`, then the final state style will be:
> <i>Final style = Default state style + Selected state style + Highlight state style</i>
The style of the latter state will override the style of the former state.
## Custom State
To customize states, simply add them to the style mapping, for example:
```typescript
{
node: {
// Custom state name: 'custom-state'
'custom-state': {/** Custom State Style */}
},
}
```
Toggle State:
```typescript
graph.setElementState('node-1', 'custom-state');
```

View File

@ -0,0 +1,31 @@
```js | ob { pin: false }
(() => {
const container = createContainer({ width: 200, height: 50 });
const graph = new window.g6.Graph({
width: 200,
height: 50,
container,
data: {
nodes: [{ id: 'node-1', style: { x: 25, y: 25, size: 20 } }],
},
node: {
animation: {
update: [
{
fields: ['x', 'y'],
},
{ fields: ['r'], shape: 'key' },
],
},
},
});
graph.draw().then(() => {
graph.updateNodeData([{ id: 'node-1', style: { x: 175, size: 40 } }]);
graph.draw();
});
return container;
})();
```

View File

@ -0,0 +1,31 @@
```js | ob { pin: false }
(() => {
const container = createContainer({ width: 200, height: 50 });
const graph = new window.g6.Graph({
width: 200,
height: 50,
container,
data: {
nodes: [{ id: 'node-1', style: { x: 25, y: 25, size: 20 } }],
},
node: {
animation: {
update: [
{
fields: ['x', 'y'],
},
{ fields: ['r', 'fill'], shape: 'key' },
],
},
},
});
graph.draw().then(() => {
graph.updateNodeData([{ id: 'node-1', style: { x: 175, size: 40, fill: 'pink' } }]);
graph.draw();
});
return container;
})();
```

View File

@ -0,0 +1,31 @@
```js | ob { pin: false }
(() => {
const container = createContainer({ width: 50, height: 50 });
const graph = new window.g6.Graph({
width: 50,
height: 50,
container,
data: {
nodes: [{ id: 'node-1', style: { x: 25, y: 25, size: 20 } }],
},
node: {
animation: {
update: [
{
fields: ['r'],
shape: 'key',
},
],
},
},
});
graph.draw().then(() => {
graph.updateNodeData([{ id: 'node-1', style: { size: 40 } }]);
graph.draw();
});
return container;
})();
```

View File

@ -0,0 +1,42 @@
```js | ob { pin: false }
(async () => {
const { BaseBehavior, CanvasEvent, register, ExtensionCategory, Graph } = window.g6;
class ClickAddNode extends BaseBehavior {
constructor(context, options) {
super(context, options);
const { graph } = this.context;
graph.on(`canvas:${CanvasEvent.CLICK}`, (event) => {
const { layerX, layerY } = event.nativeEvent;
graph.addNodeData([
{
id: 'node-' + Date.now(),
style: { x: layerX, y: layerY },
},
]);
graph.draw();
});
}
}
register(ExtensionCategory.BEHAVIOR, 'click-add-node', ClickAddNode);
const container = createContainer({ width: 300, height: 300 });
container.style.border = '1px solid #ccc';
const graph = new Graph({
container,
width: 300,
height: 300,
data: {
nodes: [],
},
behaviors: ['click-add-node'],
});
await graph.render();
return container;
})();
```

View File

@ -0,0 +1,69 @@
```js | ob { pin: false }
(async () => {
const { Graph, BaseLayout, register, ExtensionCategory } = window.g6;
class TickTockLayout extends BaseLayout {
id = 'tick-tock-layout';
async execute(data, options) {
const { onTick } = { ...this.options, ...options };
this.tickCount = 0;
this.data = data;
this.promise = new Promise((resolve) => {
this.resolve = resolve;
});
this.timer = window.setInterval(() => {
onTick(this.simulateTick());
if (this.tickCount === 10) this.stop();
}, 200);
await this.promise;
return this.simulateTick();
}
simulateTick = () => {
const x = this.tickCount++ % 2 === 0 ? 50 : 150;
return {
nodes: (this?.data?.nodes || []).map((node, index) => ({
id: node.id,
style: { x, y: (index + 1) * 30 },
})),
};
};
tick = () => {
return this.simulateTick();
};
stop = () => {
clearInterval(this.timer);
this.resolve?.();
};
}
register(ExtensionCategory.LAYOUT, 'tick-tock', TickTockLayout);
const container = createContainer({ width: 200, height: 200 });
const graph = new Graph({
container,
width: 200,
height: 200,
animation: true,
data: {
nodes: [{ id: 'node-1' }, { id: 'node-2' }, { id: 'node-3' }, { id: 'node-4' }, { id: 'node-5' }],
},
layout: {
type: 'tick-tock',
},
});
graph.render();
return container;
})();
```

View File

@ -0,0 +1,42 @@
```js | ob { pin: false }
(async () => {
const { Graph, BaseLayout, register, ExtensionCategory } = window.g6;
class DiagonalLayout extends BaseLayout {
id = 'diagonal-layout';
async execute(data) {
const { nodes = [] } = data;
return {
nodes: nodes.map((node, index) => ({
id: node.id,
style: {
x: 50 * index + 25,
y: 50 * index + 25,
},
})),
};
}
}
register(ExtensionCategory.LAYOUT, 'diagonal', DiagonalLayout);
const container = createContainer({ width: 200, height: 200 });
const graph = new Graph({
container,
width: 200,
height: 200,
data: {
nodes: [{ id: 'node-1' }, { id: 'node-2' }, { id: 'node-3' }, { id: 'node-4' }],
},
layout: {
type: 'diagonal',
},
});
await graph.render();
return container;
})();
```

View File

@ -0,0 +1,42 @@
```js | ob { pin: false }
(() => {
const { BasePlugin, Graph, register, ExtensionCategory } = window.g6;
class RemoteDataSource extends BasePlugin {
constructor(context, options) {
super(context, options);
this.loadData();
}
async loadData() {
// mock remote data
const data = {
nodes: [
{ id: 'node-1', style: { x: 25, y: 50 } },
{ id: 'node-2', style: { x: 175, y: 50 } },
],
edges: [{ source: 'node-1', target: 'node-2' }],
};
const { graph } = this.context;
graph.setData(data);
await graph.render();
}
}
register(ExtensionCategory.PLUGIN, 'remote-data-source', RemoteDataSource);
const container = window.createContainer({ width: 200, height: 100 });
const graph = new Graph({
container,
width: 200,
height: 100,
plugins: ['remote-data-source'],
});
graph.render();
return container;
})();
```

View File

@ -1,4 +1,116 @@
---
title: Custom Animation
order: 6
---
---
## Overview
## Implement Animation
For circular node (Circle) elements, the main shape is a circle. Now, let's create an animation for it so that when the size of the node changes, it transitions with a scaling animation:
```typescript
[
{
fields: ['r'],
shape: 'key',
},
];
```
Now let's create a graph instance and update the element size to trigger the update animation:
```typescript
const graph = new Graph({
container: 'container',
width: 50,
height: 50,
data: {
nodes: [{ id: 'node-1', style: { x: 25, y: 25, size: 20 } }],
},
node: {
animation: {
update: [{ fields: ['r'], shape: 'key' }],
},
},
});
graph.draw().then(() => {
graph.updateNodeData([{ id: 'node-1', style: { size: 40 } }]);
graph.draw();
});
```
> ⬇️ Move the pointer to the graph below and click the play button on the left to replay
<embed src="@/docs/manual/custom-extension-common/animation/implement-animation.md"></embed>
#### Principle Analysis
When animating an element, the element converts its animation frame parameters into animation frame parameters for its individual sub-graphics and executes the corresponding animations.
In the example above, by updating the node size, an animation was performed on the node, and its animation frame parameters were:
```json
[{ "size": 20 }, { "size": 40 }]
```
After obtaining the attribute, the node element converts it into animation frame parameters for the main shape (circle):
```json
[{ "r": 10 }, { "r": 20 }]
```
Therefore, what is ultimately happening here is that a transition animation is being performed on the circle, changing its radius from 10 to 20.
#### Composite Animation
By directly combining the position change animation with the size change animation into a single animation paradigm, you can obtain a composite animation paradigm:
```typescript
[
{
fields: ['x', 'y'],
},
{
fields: ['r'],
shape: 'key',
},
];
```
And update both the position and size of the node simultaneously:
```typescript
graph.updateNodeData([{ id: 'node-1', style: { x: 175, size: 40 } }]);
graph.draw();
```
> ⬇️ Move the pointer to the graph below and click the play button on the left to replay
<embed src="@/docs/manual/custom-extension-common/animation/composite-animation-1.md"></embed>
Add color transition:
```typescript
[
{
fields: ['x', 'y'],
},
{
fields: ['r', 'fill'],
shape: 'key',
},
];
```
Execute node update:
```typescript
graph.updateNodeData([{ id: 'node-1', style: { x: 175, size: 40, fill: 'pink' } }]);
graph.draw();
```
> ⬇️ Move the pointer to the graph below and click the play button on the left to replay
<embed src="@/docs/manual/custom-extension-common/animation/composite-animation-2.md"></embed>

View File

@ -43,37 +43,7 @@ graph.draw().then(() => {
> ⬇️ 指针移动至下方图中,并点击左侧播放按钮进行重新播放
```js | ob { pin: false }
(() => {
const container = createContainer({ width: 50, height: 50 });
const graph = new window.g6.Graph({
width: 50,
height: 50,
container,
data: {
nodes: [{ id: 'node-1', style: { x: 25, y: 25, size: 20 } }],
},
node: {
animation: {
update: [
{
fields: ['r'],
shape: 'key',
},
],
},
},
});
graph.draw().then(() => {
graph.updateNodeData([{ id: 'node-1', style: { size: 40 } }]);
graph.draw();
});
return container;
})();
```
<embed src="@/docs/manual/custom-extension-common/animation/implement-animation.md"></embed>
#### 原理分析
@ -118,37 +88,7 @@ graph.draw();
> ⬇️ 指针移动至下方图中,并点击左侧播放按钮进行重新播放
```js | ob { pin: false }
(() => {
const container = createContainer({ width: 200, height: 50 });
const graph = new window.g6.Graph({
width: 200,
height: 50,
container,
data: {
nodes: [{ id: 'node-1', style: { x: 25, y: 25, size: 20 } }],
},
node: {
animation: {
update: [
{
fields: ['x', 'y'],
},
{ fields: ['r'], shape: 'key' },
],
},
},
});
graph.draw().then(() => {
graph.updateNodeData([{ id: 'node-1', style: { x: 175, size: 40 } }]);
graph.draw();
});
return container;
})();
```
<embed src="@/docs/manual/custom-extension-common/animation/composite-animation-1.md"></embed>
加入颜色过渡:
@ -173,34 +113,4 @@ graph.draw();
> ⬇️ 指针移动至下方图中,并点击左侧播放按钮进行重新播放
```js | ob { pin: false }
(() => {
const container = createContainer({ width: 200, height: 50 });
const graph = new window.g6.Graph({
width: 200,
height: 50,
container,
data: {
nodes: [{ id: 'node-1', style: { x: 25, y: 25, size: 20 } }],
},
node: {
animation: {
update: [
{
fields: ['x', 'y'],
},
{ fields: ['r', 'fill'], shape: 'key' },
],
},
},
});
graph.draw().then(() => {
graph.updateNodeData([{ id: 'node-1', style: { x: 175, size: 40, fill: 'pink' } }]);
graph.draw();
});
return container;
})();
```
<embed src="@/docs/manual/custom-extension-common/animation/composite-animation-2.md"></embed>

View File

@ -1,4 +1,62 @@
---
title: Custom Behavior
order: 2
---
---
## Overview
The execution logic for behaviors typically involves: 1. Listening for user behavior events, 2. Updating the canvas or performing other operations based on the events. For example, the `DragCanvas` behavior listens for pointer drag events and updates the position of the camera based on the distance dragged.
behaviors and plugins are both derived from G6's internal `BaseExtension` base class, so the implementation methods for behaviors and plugins are essentially the same. However, based on the concept of visualization, behaviors are usually used to handle user behavior events, while plugins are typically used to handle canvas rendering logic, rendering of additional components, etc.
## Implement Behavior
The implementation of an behavior is quite flexible, and you can implement your behavior in the style you prefer.
Below is a simple implementation of a custom behavior that adds a node to the canvas when the user clicks on it:
```typescript
import { BaseBehavior, CanvasEvent } from '@antv/g6';
import type { BaseBehaviorOptions, RuntimeContext, IPointerEvent } from '@antv/g6';
interface ClickAddNodeOptions extends BaseBehaviorOptions {}
class ClickAddNode extends BaseBehavior<ClickAddNodeOptions> {
constructor(context: RuntimeContext, options: ClickAddNodeOptions) {
super(context, options);
const { graph } = this.context;
graph.on(`canvas:${CanvasEvent.CLICK}`, (event: IPointerEvent) => {
const { layerX, layerY } = event.nativeEvent as PointerEvent;
graph.addNodeData([
{
id: 'node-' + Date.now(),
style: { x: layerX, y: layerY },
},
]);
graph.draw();
});
}
}
```
In the example code, we implemented an behavior called `ClickAddNode` based on `BaseBehavior`. This behavior adds an event listener to the Graph in its constructor. When the user clicks on the canvas, a node will be added at the clicked position.
> Click on an empty space in the canvas below to add a node
<embed src="@/docs/manual/custom-extension-common/behavior/implement-behaviors.md"></embed>
:::info{title=info}
The above example is the simplest implementation of an behavior. In actual development, you will also need to handle the destruction of event listeners, enabling and disabling behaviors, and other logic.
In addition, there may be event conflicts between multiple behaviors, and you will need to carefully manage these conflicts.
:::
## Register Behavior
You can register behaviors through the registration method provided by G6. For more details, see [Register Behavior](/en/manual/core-concept/behavior#register-behavior).
## Configure Behavior
You can pass the name of the behavior type or a configuration parameters object in the `behaviors`. For more details, see [Configure Behavior](/en/manual/core-concept/behavior#configure-behavior)

View File

@ -44,48 +44,7 @@ class ClickAddNode extends BaseBehavior<ClickAddNodeOptions> {
> 点击下面画布中的空白位置以添加一个节点
```js | ob { pin: false }
(async () => {
const { BaseBehavior, CanvasEvent, register, ExtensionCategory, Graph } = window.g6;
class ClickAddNode extends BaseBehavior {
constructor(context, options) {
super(context, options);
const { graph } = this.context;
graph.on(`canvas:${CanvasEvent.CLICK}`, (event) => {
const { layerX, layerY } = event.nativeEvent;
graph.addNodeData([
{
id: 'node-' + Date.now(),
style: { x: layerX, y: layerY },
},
]);
graph.draw();
});
}
}
register(ExtensionCategory.BEHAVIOR, 'click-add-node', ClickAddNode);
const container = createContainer({ width: 300, height: 300 });
container.style.border = '1px solid #ccc';
const graph = new Graph({
container,
width: 300,
height: 300,
data: {
nodes: [],
},
behaviors: ['click-add-node'],
});
await graph.render();
return container;
})();
```
<embed src="@/docs/manual/custom-extension-common/behavior/implement-behaviors.md"></embed>
:::info{title=提示}
上述示例是一个最简单的交互实现,实际开发过程中,你还需要处理监听事件的销毁、交互的启用与禁用等逻辑。

View File

@ -1,4 +1,295 @@
---
title: Custom Element
order: 0
---
---
## Overview
When the built-in elements of G6 do not meet the requirements, you can expand the G6 element library by customizing elements. Custom elements are an important feature of G6, allowing users to extend based on existing elements through secondary inheritance and encapsulation, or to develop new elements based on [G Graphics](https://g.antv.antgroup.com/en/api/basic/display-object).
## Element Base Class
Before starting to customize an element, you need to understand some important properties and methods of the G6 element base class:
### Properties
#### shapeMap
> Record<string, DisplayObject>
The mapping table of all graphics under the current element
#### animateMap
> Record<string, IAnimation>
The mapping table of all animations under the current element
### Methods
#### upsert(key, Ctor, style, container)
Create or update graphics, and automatically destroy the graphics when the element is destroyed
```typescript
upsert(key: string, Ctor: { new (...args: any[]): DisplayObject }, style: Record<string, any>, container: DisplayObject);
```
| Parameter | Type | Description |
| --------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| key | string | The key of the graphic, that is, the corresponding key in `shapeMap`. Built-in keys include `'key'`, `'label'`, `'halo'`, `'icon'`, `'port'`, `'badge'` |
| Ctor | { new (...args: any[]): DisplayObject } | The constructor for the graphic class |
| style | Record<string, any> | The style of the graphic |
| container | DisplayObject | The container where the graphic is mounted |
#### render(style, container)
Draw the content of the element
```typescript
render(style: Record<string, any>, container: Group): void;
```
| Parameter | Type | Description |
| --------- | ------------------- | ------------- |
| style | Record<string, any> | Element style |
| container | Group | Container |
### Hook
The element provides the following hook functions, which can be overridden as needed:
- `onCreate`: Triggered after the element is created and the entrance animation is complete.
- `onUpdate`: Triggered after the element is updated and the update animation is complete.
- `onDestroy`: Triggered after the element completes the exit animation and is destroyed.
### Element Convention
- **Use Conventional Attributes**
The currently agreed-upon element attributes include:
1. `size`: The size of the element
- **Use the `getXxxStyle` and `drawXxxShape` pairing method for graphic drawing**
`getXxxStyle` is used to obtain the graphic style, and `drawXxxShape` is used for drawing the graphic. Graphics created in this way support automatic animation execution.
- **The Graph context can be accessed via `attributes.context`**
## Custom Node
### Implement Node
**Inherit from Existing Nodes**
To inherit from an existing node, you can either inherit from the base class for all nodes, `BaseNode`, or inherit from an existing node, such as `Circle`.
Below is an example of inheriting from `BaseNode` to implement a circular node:
```typescript
import { BaseNode } from '@antv/g6';
import { Circle } from '@antv/g';
import type { Group } from '@antv/g';
import type { BaseNodeStyleProps } from '@antv/g6';
interface ExtendBaseNode extends BaseNodeStyleProps {
// Custom Properties
radius: number;
}
class ExtendBaseNode extends BaseNode {
protected getKeyStyle(attributes: Required<ExtendBaseNode>) {
return { ...super.getKeyStyle(attributes), r: attributes.radius };
}
// Override Methods
protected drawKeyShape(attributes: Required<ExtendBaseNode>, container: Group) {
// Custom Drawing Logic, Create a G.Circle
return this.upsert('key', Circle, this.getKeyStyle(attributes), container);
}
}
```
Below is an example that inherits from `Circle`, adding a text segment to the circular node:
```typescript
import { Circle, subStyleProps } from '@antv/g6';
import { Text } from '@antv/g';
import type { Group } from '@antv/g';
import type { CircleStyleProps } from '@antv/g6';
interface ExtendCircleStyleProps extends CircleStyleProps {
// Custom Properties
paragraph: string;
}
class ExtendCircle extends Circle {
protected getTextStyle(attributes: Required<ExtendCircleStyleProps>) {
// Obtain style properties that start with 'paragraph', such as 'paragraphFontSize'
const paragraphStyle = subStyleProps(attributes, 'paragraph');
return { ...paragraphStyle, text: attributes.paragraph };
}
protected drawTextShape(attributes: Required<ExtendCircleStyleProps>, container: Group) {
// Custom drawing logic, create a G.Text
return this.upsert('text', Text, this.getTextStyle(attributes), container);
}
protected render(attrs: Required<ExtendCircleStyleProps>, container: Group) {
super.render(attrs, container);
// Invoke custom drawing logic
this.drawTextShape(attrs, container);
}
}
```
**New Development**
If you want to develop a new node based on the G graph, you can directly inherit from `G.Shape`.
:::warning{title=note}
To adopt a new development approach, you need to fully understand the implementation logic of G6 elements and manage the lifecycle, animations, and other aspects of the elements yourself.
The customization process is relatively complex, so it is recommended to first consider extending existing nodes.
:::
Here is a simple example of inheriting from` G.Shape` to implement a circular node:
<details>
<summary>Example</summary>
```typescript
import { CustomElement, Circle } from '@antv/g';
import type { BaseStyleProps, DisplayObjectConfig } from '@antv/g';
interface CustomCircleStyleProps extends BaseStyleProps {
radius: number;
}
class CustomCircle extends CustomElement {
constructor(options: DisplayObjectConfig<CustomCircleStyleProps>) {
super(options);
this.render();
}
protected render() {
const { radius } = this.attributes;
const circle = new Circle({
style: {
...this.attributes,
x: 0,
y: 0,
r: radius,
},
});
this.appendChild(circle);
}
}
```
To implement graphical animation, you need to override the `animate` method to perform the animation operations on the `CustomCircle` onto the `Circle` graphic:
```typescript
import type {} from '@antv/g';
class CustomCircle extends CustomElement {
// ...Other logic.
// Overriding the `animate` method.
// Here, the animation of the `r` attribute on the `circle` is implemented
animate(keyframes: Keyframe[], options?: number | KeyframeAnimationOptions): IAnimation | null {
const circle = this.children[0] as Circle;
const circleKeyframes = keyframes.map(({ radius }) => ({ r: radius }));
circle.animate(circleKeyframes, options);
}
}
```
</details>
### Register Node
You can register by using the `register` method provided by G6.For more details[Register Node](/en/manual/core-concept/element#注册节点)
### Configure Node
Custom nodes can be used and configured in `data` or `node style mapping`.For more details,[Configure Node](/en/manual/core-concept/element#配置节点)
## Customize Edge
### Implement Edge
Customizing edges is similar to customizing nodes. You can either inherit existing edges or develop a completely new edge based on the G graph.
Here is an example of implementing a custom straight-line edge by inheriting from `BaseEdge`:
```typescript
import { BaseEdge } from '@antv/g6';
import { Line } from '@antv/g';
import type { BaseNodeStyleProps } from '@antv/g6';
class ExtendBaseEdge extends BaseEdge {
// Override the getKeyStyle method
protected getKeyStyle(attributes: Required<BaseNodeStyleProps>) {
const { sourceNode, targetNode } = attributes;
const [x1, y1] = sourceNode.getPosition();
const [x2, y2] = targetNode.getPosition();
return { ...super.getKeyStyle(attributes), x1, y1, x2, y2 };
}
// Override the drawKeyShape method
protected drawKeyShape(attributes: Required<BaseNodeStyleProps>, container: Group) {
return this.upsert('key', Line, this.getKeyStyle(attributes), container);
}
}
```
### Register Edge
You can register by using the `register` method provided by G6. For more details, see [Register Edge](/en/manual/core-concept/element#register-edge).
### Configure Edge
Custom edges can be used and configured in `data` or `edge style mapping`. For more details, see [Configure Edge](/en/manual/core-concept/element#configure-edge).
## Custom Combo
Combo in G6 inherit from `BaseNode`, but there are certain differences: Combo have two states, namely expanded (`Expanded`) and collapsed (`Collapsed`), and thus the implementation is also different.
### Implement Combo
The way to customize Combo is similar to customizing nodes. You can either inherit from existing Combo or develop entirely new Combo based on G Graphics.
Here is an example that inherits from `BaseCombo` to implement a custom rectangular combo:
```typescript
import { BaseCombo } from '@antv/g6';
import { Rect } from '@antv/g';
import type { BaseComboStyleProps } from '@antv/g6';
class ExtendBaseCombo extends BaseCombo {
protected getKeyStyle(attributes: Required<BaseComboStyleProps>) {
const [width, height] = this.getKeySize(attributes);
return { ...super.getKeyStyle(attributes), anchor: [0.5, 0.5], width, height };
}
// Implement the drawKeyShape method
protected drawKeyShape(attributes: Required<BaseComboStyleProps>, container: Group) {
return this.upsert('key', Rect, this.getKeyStyle(attributes), container);
}
}
```
### Register Combo
You can register by using the `register` method provided by G6. For more details, see [Register Combo](/en/manual/core-concept/element#register-combo)
### Configure Combo
Custom Combo can be used and configured in `data` or `combo style mapping`. For more details, see [Configure Combo](/en/manual/core-concept/element#configure-combo)

View File

@ -1,4 +1,133 @@
---
title: Custom Layout
order: 1
---
---
## Overview
In G6, layouts are divided into two types: 'iterative layout' and 'non-iterative layout'. An iterative layout refers to a layout algorithm that iterates multiple times until convergence, while a non-iterative layout refers to a layout algorithm that executes only once.
## Implement Layout
### Non-Iterative Layout
Implementing a non-iterative layout is relatively straightforward; you only need to implement the `execute` method in `BaseLayout`. Below is a simple implementation of a custom layout:
```typescript
import { BaseLayout } from '@antv/g6';
import type { GraphData } from '@antv/g6';
class DiagonalLayout extends BaseLayout {
id = 'diagonal-layout';
async execute(data: GraphData): Promise<GraphData> {
const { nodes = [] } = data;
return {
nodes: nodes.map((node, index) => ({
id: node.id,
style: {
x: 50 * index + 25,
y: 50 * index + 25,
},
})),
};
}
}
```
In the code above, we implemented a simple layout algorithm that arranges nodes along a diagonal line starting from the top-left corner.
<embed src="@/docs/manual/custom-extension-common/layout/non-iterative-layout.md"></embed>
:::info{title=info}
The `execute` method returns a GraphData object, which only needs to contain the basic information of the elements (such as id, source, target) and the properties added by the layout (such as x, y, control points of edges, etc.), and does not need to contain other unnecessary information.
If you only need to layout the nodes, you can return only the node information and do not need to return the edge information.
:::
### Iterative Layout
The implementation of an iterative layout also requires inheriting from `BaseLayout`, but in addition to `execute`, you also need to implement the `tick` and `stop` methods. The `tick` method is used to iterate the layout to a specified number of rounds, and the `stop` method is used to stop the layout iteration.
In addition, in iterative layouts, you need to call `options.onTick` each time the layout iterates to trigger the graph update.
```typescript
type onTick = (data: GraphData) => void;
```
Below is a simple implementation of an iterative layout:
```typescript
import { BaseLayout } from '@antv/g6';
import type { GraphData, BaseLayoutOptions } from '@antv/g6';
interface TickTockLayoutOptions extends BaseLayoutOptions {
onTick: (data: GraphData) => void;
}
class TickTockLayout extends BaseLayout<TickTockLayoutOptions> {
public id = 'custom-layout';
private tickCount = 0;
private data?: GraphData;
private timer?: number;
private resolve?: () => void;
private promise?: Promise<void>;
async execute(data: GraphData, options: TickTockLayoutOptions): Promise<GraphData> {
const { onTick } = { ...this.options, ...options };
this.tickCount = 0;
this.data = data;
this.promise = new Promise((resolve) => {
this.resolve = resolve;
});
this.timer = window.setInterval(() => {
onTick(this.simulateTick());
if (this.tickCount === 10) this.stop();
}, 200);
await this.promise;
return this.simulateTick();
}
simulateTick = () => {
const x = this.tickCount++ % 2 === 0 ? 50 : 150;
return {
nodes: (this?.data?.nodes || []).map((node, index) => ({
id: node.id,
style: { x, y: (index + 1) * 30 },
})),
};
};
tick = () => {
return this.simulateTick();
};
stop = () => {
clearInterval(this.timer);
this.resolve?.();
};
}
```
In this example, we have implemented a simple iterative layout algorithm that toggles the x-coordinate of the nodes between 50 and 150 every 200 milliseconds and arranges them in order along the y-axis according to the sequence of the nodes.
<embed src="@/docs/manual/custom-extension-common/layout/iterative-layout.md"></embed>
## Register Layout
You can register through the `register` method provided by G6. For more details, please refer to [Register Layout](/en/manual/core-concept/layout#register-layout)
## Configure Layout
The type and parameters of the layout can be configured in `options.layout`. For more details, please refer to [Configure Layout](/en/manual/core-concept/layout#configure-layout)

View File

@ -37,48 +37,7 @@ class DiagonalLayout extends BaseLayout {
在上面的代码中,我们实现了一个简单的布局算法,将节点从左上角沿对角线排列。
```js | ob { pin: false }
(async () => {
const { Graph, BaseLayout, register, ExtensionCategory } = window.g6;
class DiagonalLayout extends BaseLayout {
id = 'diagonal-layout';
async execute(data) {
const { nodes = [] } = data;
return {
nodes: nodes.map((node, index) => ({
id: node.id,
style: {
x: 50 * index + 25,
y: 50 * index + 25,
},
})),
};
}
}
register(ExtensionCategory.LAYOUT, 'diagonal', DiagonalLayout);
const container = createContainer({ width: 200, height: 200 });
const graph = new Graph({
container,
width: 200,
height: 200,
data: {
nodes: [{ id: 'node-1' }, { id: 'node-2' }, { id: 'node-3' }, { id: 'node-4' }],
},
layout: {
type: 'diagonal',
},
});
await graph.render();
return container;
})();
```
<embed src="@/docs/manual/custom-extension-common/layout/non-iterative-layout.md"></embed>
:::info{title=提示}
`execute` 方法返回的是一个 GraphData 对象,里面仅需要包含元素的基本信息(如 id、source、target以及布局新增的属性如 x、y、边的控制点等不需要包含其他无用的信息。
@ -162,75 +121,7 @@ class TickTockLayout extends BaseLayout<TickTockLayoutOptions> {
在这个例子中,我们实现了一个简单的迭代布局算法,每 200ms 将节点的 x 坐标在 50 和 150 之间切换,并按照节点顺序在 y 方向上排列。
```js | ob { pin: false }
(async () => {
const { Graph, BaseLayout, register, ExtensionCategory } = window.g6;
class TickTockLayout extends BaseLayout {
id = 'tick-tock-layout';
async execute(data, options) {
const { onTick } = { ...this.options, ...options };
this.tickCount = 0;
this.data = data;
this.promise = new Promise((resolve) => {
this.resolve = resolve;
});
this.timer = window.setInterval(() => {
onTick(this.simulateTick());
if (this.tickCount === 10) this.stop();
}, 200);
await this.promise;
return this.simulateTick();
}
simulateTick = () => {
const x = this.tickCount++ % 2 === 0 ? 50 : 150;
return {
nodes: (this?.data?.nodes || []).map((node, index) => ({
id: node.id,
style: { x, y: (index + 1) * 30 },
})),
};
};
tick = () => {
return this.simulateTick();
};
stop = () => {
clearInterval(this.timer);
this.resolve?.();
};
}
register(ExtensionCategory.LAYOUT, 'tick-tock', TickTockLayout);
const container = createContainer({ width: 200, height: 200 });
const graph = new Graph({
container,
width: 200,
height: 200,
animation: true,
data: {
nodes: [{ id: 'node-1' }, { id: 'node-2' }, { id: 'node-3' }, { id: 'node-4' }, { id: 'node-5' }],
},
layout: {
type: 'tick-tock',
},
});
graph.render();
return container;
})();
```
<embed src="@/docs/manual/custom-extension-common/layout/iterative-layout.md"></embed>
## 注册布局

View File

@ -1,4 +1,59 @@
---
title: Custom Palette
order: 5
---
---
## Overview
[Core Concepts - Palette](/en/manual/core-concept/palette) mentions that G6 supports discrete palettes and continuous palettes. A discrete palette is essentially an array of colors, while a continuous palette is a color interpolator.
Therefore, customizing a palette also adopts these two methods, and the following sections will introduce how to customize discrete and continuous palettes, respectively.
## Implement Palette
### Discrete Palette
You can simply define a string array that contains color values. Supported color values include: RGB color values, hexadecimal color values, and color names. Below is an example of a discrete palette:
```typescript
const hex = ['#FF0000', '#00FF00', '#0000FF'];
const color = ['red', 'green', 'blue'];
const rgb = ['rgb(255, 0, 0)', 'rgb(0, 255, 0)', 'rgb(0, 0, 255)'];
```
### Continuous Palette
A continuous palette requires the definition of a color interpolator. The interpolator is a function that accepts a numerical value as a parameter and returns a color value. Below is an example of a continuous palette:
```typescript
const color = (value: number) => `rgb(${value * 255}, 0, 0)`;
```
## Register Palette
You can register a palette using the `register` method provided by G6. For more details, please refer to [Register Palette](/en/manual/core-concept/palette#register-palette)
## Use Without Registration
In addition to registration, you can also bypass the registration mechanism and directly pass the palette value at the location where the palette is needed, for example:
```typescript
{
node: {
palette: {
type: 'group',
field: 'category',
color: ['#5B8FF9', '#61DDAA', '#F6BD16'], // Pass in a color array.
}
},
edge: {
palette: {
type: 'value',
field: 'value',
color: (value) => `rgb(${value * 255}, 0, 0)`, // Pass in an interpolator
}
}
}
```

View File

@ -1,4 +1,55 @@
---
title: Custom Plugin
order: 3
---
---
## Overview
Custom plugins can implement additional functionalities, such as adding extra components, rendering logic, etc.
## Implement Plugin
Similar to interactions, the implementation of plugins is also quite flexible, and you can implement your plugins in the style you prefer.
Below is an example of a simple custom plugin that automatically loads remote data during the graph instantiation process:
```typescript
import { BasePlugin } from '@antv/g6';
import type { BasePluginOptions, RuntimeContext } from '@antv/g6';
interface RemoteDataSourceOptions extends BasePluginOptions {}
class RemoteDataSource extends BasePlugin<RemoteDataSourceOptions> {
constructor(context: RuntimeContext, options: RemoteDataSourceOptions) {
super(context, options);
this.loadData();
}
private async loadData() {
// mock remote data
const data = {
nodes: [
{ id: 'node-1', x: 100, y: 100 },
{ id: 'node-2', x: 200, y: 200 },
],
edges: [{ source: 'node-1', target: 'node-2' }],
};
const { graph } = this.context;
graph.setData(data);
await graph.render();
}
}
```
In the example above, we have simulated the implementation of a data loading plugin. After using this plugin, there is no need to pass in data when instantiating the Graph; the plugin will automatically load remote data.
<embed src="@/docs/manual/custom-extension-common/plugin/implement-plugin.md"></embed>
## Register Plugin
You can register plugins using the `register` method provided by G6. For more details, please refer to [Register Plugin](/en/manual/core-concept/plugin#register-plugin)
## Configure Plugin
You can pass the name of the interaction type or a configuration parameters object in the `plugins` field. For more details, please refer to [Configure Plugins](/en/manual/core-concept/plugin#configure-plugin)

View File

@ -44,48 +44,7 @@ class RemoteDataSource extends BasePlugin<RemoteDataSourceOptions> {
在上面的例子中,我们模拟实现了一个数据加载插件,在使用该插件后,实例化 Graph 时不用再传入数据,该插件会自动加载远程数据。
```js | ob { pin: false }
(() => {
const { BasePlugin, Graph, register, ExtensionCategory } = window.g6;
class RemoteDataSource extends BasePlugin {
constructor(context, options) {
super(context, options);
this.loadData();
}
async loadData() {
// mock remote data
const data = {
nodes: [
{ id: 'node-1', style: { x: 25, y: 50 } },
{ id: 'node-2', style: { x: 175, y: 50 } },
],
edges: [{ source: 'node-1', target: 'node-2' }],
};
const { graph } = this.context;
graph.setData(data);
await graph.render();
}
}
register(ExtensionCategory.PLUGIN, 'remote-data-source', RemoteDataSource);
const container = window.createContainer({ width: 200, height: 100 });
const graph = new Graph({
container,
width: 200,
height: 100,
plugins: ['remote-data-source'],
});
graph.render();
return container;
})();
```
<embed src="@/docs/manual/custom-extension-common/plugin/implement-plugin.md"></embed>
## 注册插件

View File

@ -1,4 +1,97 @@
---
title: Custom Theme
order: 4
---
---
## Overview
In G6, the theme is a subset of Graph Options and includes configurations related to the canvas and element styles. A theme can help you quickly switch between different graph styles.
## Custom Theme
For element styles, the configurations within a theme are static and do not support the use of callback functions to dynamically calculate styles. Additionally, `type` is also not supported for configuration within a theme. A theme includes the following configurations:
- `background`: Canvas background color
- `node`: Node style
- `edge`: Edge style
- `combo`: Combo style
Below is a simple example of a theme configuration:
```typescript
const theme = {
background: '#fff',
node: {
style: {
fill: '#e1f3fe',
lineWidth: 0,
},
selected: {
style: {
fill: '#3b71d6',
lineWidth: 1,
},
},
},
edge: {
// ...
},
combo: {
// ...
},
};
```
❌ Incorrect Example
```typescript
const theme = {
node: {
// ❌ The theme does not support configuring element types
type: 'rect',
style: {
// ❌ The theme does not support callback functions
fill: (d) => d.style.color,
},
},
};
```
:::warning{title=Note}
For element state styles, please ensure that every property in the state style has a corresponding default style in the default style, otherwise it may result in the inability to clear the state style.
:::
## Register Theme
You can register a theme using the `register` method provided by G6. Here is an example:
```typescript
import { register, ExtensionCategory } from '@antv/g6';
register(ExtensionCategory.THEME, 'custom-theme', theme);
```
## Configure Theme
To enable and configure a theme, you need to pass the `theme` option when instantiating the `Graph`:
```typescript
{
theme: 'custom-theme',
}
```
### Switch Theme
After the `Graph` instance is created, you can switch themes by using the [setTheme](/en/api/graph/method#setTheme) method:
```typescript
graph.setTheme('dark');
```
Additionally, you can also obtain the current theme by using the `getTheme` method:
```typescript
graph.getTheme();
// => 'dark'
```

View File

@ -1,4 +1,10 @@
---
title: FAQ
order: 6
---
---
### What is the Difference Between Extension and Plugin?
`Extension` is a concept in G6 that collectively refers to all types of registrable content, including elements, behaviors, layouts, and plugins, among others.
`Plugin` represents a flexible extension mechanism provided by G6 and is a special type of `Extension`.

View File

@ -0,0 +1,48 @@
```ts
import { Graph, treeToGraphData } from '@antv/g6';
const data = {
id: 'root',
children: [
{ id: 'node1', children: [{ id: 'node1-1' }, { id: 'node1-2' }] },
{ id: 'node2', children: [{ id: 'node2-1' }, { id: 'node2-2' }] },
],
};
const graph = new Graph({
container: 'container',
layout: {
type: 'compact-box',
direction: 'TB',
},
data: treeToGraphData(data),
edge: {
type: 'cubic-vertical',
},
});
graph.render();
```
```js | ob { pin:false }
createGraph(
{
autoFit: 'view',
data: g6.treeToGraphData({
id: 'root',
children: [
{ id: 'node1', children: [{ id: 'node1-1' }, { id: 'node1-2' }] },
{ id: 'node2', children: [{ id: 'node2-1' }, { id: 'node2-2' }] },
],
}),
layout: {
type: 'compact-box',
direction: 'TB',
},
edge: {
type: 'cubic-vertical',
},
},
{ width: 200, height: 200 },
);
```

View File

@ -1,4 +1,132 @@
---
title: Feature
order: 1
---
---
## 🏖️ Brand New Design Paradigm for Graphs
G6 version 5.0 has redesigned the Options paradigm. While ensuring comprehensive capabilities, it optimizes the options structure to be more intuitive and easier to understand.
You only need to quickly grasp the basic [core concepts](/en/manual/core-concept/graph) to get started with G6 quickly and achieve graph visualization without delay.
**😰 The 4.0 Paradigm** had a complex nested structure and was less semantically capable
```typescript
{
defaultNode: {
size: 30,
style: {
fill: 'steelblue',
stroke: '#666',
lineWidth: 1
},
labelCfg: {
style: {
fill: '#fff',
}
}
},
nodeStateStyles: {
hover: {
fill: 'lightsteelblue'
}
},
modes: {
default: ['zoom-canvas', 'drag-canvas', 'drag-node'],
},
}
```
**😄 The 5.0 Paradigm** has a clear structure and is easy to understand
```typescript
{
node: {
style: {
size: 30,
fill: 'steelblue',
stroke: '#666',
lineWidth: 1
labelFill: '#fff',
},
state: {
hover: {
fill: 'lightsteelblue'
}
}
},
behaviors: ['zoom-canvas', 'drag-canvas', 'drag-node'],
}
```
## 🔨 Brand New API Design
G6 5.0 has redesigned its API, adopting a consistent naming convention.
## 🌲 Merging Graphs with Tree Graphs
Tree graphs are essentially a type of directed acyclic graph. G6 5.0 has integrated the design of graphs and tree graphs, reducing the cost of understanding and usage.
Now, you can directly use `Graph` to instantiate and draw tree graphs in G6, without the need to use `TreeGraph`. You simply need to specify the layout as a tree graph layout.
Additionally, G6 provides the `treeToGraphData` utility method to help you quickly convert tree graph data into graph data.
<embed src="@/docs/manual/feature-common/treeToGraphData.md"></embed>
## 🌆 Multi-Renderer Support
G6 5.0 employs the next-generation @antv/g rendering engine, which has been newly designed. It offers support for multiple renderers such as `Canvas`, `SVG`, and `WebGL`. Additionally, it supports the mixed use of different renderers on layered canvases.
```typescript
import { Renderer } from '@antv/g-webgl';
import { Graph } from '@antv/g6';
const graph = new Graph({
// ... other configurations
// Use the WebGL renderer
renderer: () => new Renderer(),
});
```
## 🚀 High-Performance Layouts
G6 5.0 has adopted a brand-new layout engine, with some layouts implemented in Rust, providing higher performance for layout calculations. Additionally, there is support for WebGPU acceleration in certain layouts.
> 🚀 To utilize high-performance layouts, you will need to install the `@antv/layout-wasm` package
```typescript
import { FruchtermanLayout } from '@antv/layout-gpu';
import { Graph, register, ExtensionCategory } from '@antv/g6';
register(ExtensionCategory.LAYOUT, 'fruchterman-gpu', FruchtermanLayout);
const graph = new Graph({
// ... other configurations
layout: {
type: 'fruchterman-gpu',
// ... Other Layout Configurations
},
});
```
## 🎨 Multiple Themes Mechanism
G6 5.0 comes with two built-in themes: light and dark, and allows for flexible customization based on the use case. For details, please refer to [Custom Theme](/en/manual/custom-extension/theme).
## 💻 Information Layering
Under Construction...
## 🌍 3D Large Graphs
Under Construction...
## 💪 Plugin Optimization and Enhancement
G6 5.0 has optimized and enhanced existing plugins, decoupling Graph from plugins, and providing richer capabilities while optimizing configurations.
Please visit [Plugin](/en/api/plugins/bubble-sets) to experience the capabilities of more plugins.
## 💼 Optimized Package Size
Thanks to the well-modularized design and extension registration mechanism of G6 5.0, modules that are not used will not be packaged into the final build file, reducing the package size.

View File

@ -71,54 +71,7 @@ G6 5.0 重新设计了 API采用了一致的命名规范
此外G6 提供了 `treeToGraphData` 工具方法,帮助你快速将树图数据转换为图数据。
```ts
import { Graph, treeToGraphData } from '@antv/g6';
const data = {
id: 'root',
children: [
{ id: 'node1', children: [{ id: 'node1-1' }, { id: 'node1-2' }] },
{ id: 'node2', children: [{ id: 'node2-1' }, { id: 'node2-2' }] },
],
};
const graph = new Graph({
container: 'container',
layout: {
type: 'compact-box',
direction: 'TB',
},
data: treeToGraphData(data),
edge: {
type: 'cubic-vertical',
},
});
graph.render();
```
```js | ob { pin:false }
createGraph(
{
autoFit: 'view',
data: g6.treeToGraphData({
id: 'root',
children: [
{ id: 'node1', children: [{ id: 'node1-1' }, { id: 'node1-2' }] },
{ id: 'node2', children: [{ id: 'node2-1' }, { id: 'node2-2' }] },
],
}),
layout: {
type: 'compact-box',
direction: 'TB',
},
edge: {
type: 'cubic-vertical',
},
},
{ width: 200, height: 200 },
);
```
<embed src="@/docs/manual/feature-common/treeToGraphData.md"></embed>
## 🌆 多渲染器支持

View File

@ -2,3 +2,33 @@
title: download-image
order: 2
---
G6 5.0 only provides an API for exporting the canvas as a Base64 image ([toDataURL](/en/api/graph/method#graphtodataurloptions)). If you need to download the image, you can use the following method:
```typescript
async function downloadImage() {
const dataURL = await graph.toDataURL();
const [head, content] = dataURL.split(',');
const contentType = head.match(/:(.*?);/)![1];
const bstr = atob(content);
let length = bstr.length;
const u8arr = new Uint8Array(length);
while (length--) {
u8arr[length] = bstr.charCodeAt(length);
}
const blob = new Blob([u8arr], { type: contentType });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'graph.png';
a.click();
}
```
:::warning{title=note}
The exported image may not contain the complete canvas content; the export range only includes the content within the Graph canvas. Some plugins use custom containers, canvases, etc., and this content will not appear in the exported image.
:::

View File

@ -3,4 +3,132 @@ title: Event
order: 0
---
Coming soon...
## Overview
The event system in G6 is encapsulated based on the event system of [G](https://g.antv.antgroup.com/en/api/event/intro), providing a wider range of event types and more convenient methods for event binding and unbinding.
## Event Types
The event types in G6 are mainly divided into the following categories:
1. Graph events
2. Canvas events
3. Element events
### Graph Events
Graph events refer to events associated with the entire graph instance, such as the graph's rendering completion event, the graph's update event, etc. The complete list of graph events can be found at [GraphEvent](/en/api/reference/g6/graphevent).
#### Listening to Graph Events
Listening to graph events is consistent with the default event listening method. For example, to listen to the graph's rendering completion event:
```typescript
import { Graph, GraphEvent } from '@antv/g6';
const graph = new Graph({
// ...
});
graph.on(GraphEvent.AFTER_RENDER, () => {
// event handler
});
```
### Canvas Events
Canvas events refer to events associated with the canvas, such as the canvas's click event, the canvas's drag event, etc. The complete list of canvas events can be found at [CanvasEvent](/en/api/reference/g6/canvasevent).
#### Listening to Canvas Events
Listening to canvas events requires the use of the form `canvas:${CanvasEvent}`, which means carrying the `canvas:` prefix. For example, to listen to the canvas's click event:
```typescript
import { Graph, CanvasEvent } from '@antv/g6';
const graph = new Graph({
// ...
});
graph.on(`canvas:${CanvasEvent.CLICK}`, (event) => {
// event handler
});
```
### Element Events
Element events primarily refer to events that are triggered on element objects, such as a node's drag event, an edge's click event, etc. Elements are categorized into three types: nodes (`node`), edges (`edge`), and combos (`combo`). The complete list of corresponding events can be found at: [NodeEvent](/en/api/reference/g6/nodeevent), [EdgeEvent](/en/api/reference/g6/edgeevent), [ComboEvent](/en/api/reference/g6/comboevent).
#### Listening to Element Events
Similar to canvas events, you need to listen to element events in the form of `node:${NodeEvent}`, `edge:${EdgeEvent}`, or `combo:${ComboEvent}`.
For example, to listen to a node's drag event and an edge's click event:
```ts
import { Graph, NodeEvent, EdgeEvent, ComboEvent } from '@antv/g6';
const graph = new Graph({
// ...
});
graph.on(`node:${NodeEvent.DRAG}`, (event) => {
// event handler
});
graph.on(`edge:${EdgeEvent.CLICK}`, (event) => {
// event handler
});
graph.on(`combo:${ComboEvent.CLICK}`, (event) => {
// event handler
});
```
## Event Listening and Unlistening
G6 provides the following APIs for event listening and unlistening:
### on
Add an event listener
```typescript
const handler = (event) => {
// event handler
};
graph.on('event_name', handler);
```
### off
Remove an event listener
```typescript
graph.off('event_name', handler);
```
When no arguments are passed, it will remove all event listeners:
```typescript
graph.off();
```
### once
Add a one-time event listener, which means the event listener will be automatically removed after the event is triggered
```typescript
graph.once('event_name', handler);
```
### emit
If you want to manually trigger an event, you can use the `emit` method:
```typescript
graph.emit('event_name', {
// event data
});
```

View File

@ -0,0 +1,29 @@
```js | ob { pin: false }
fetch('https://assets.antv.antgroup.com/g6/graph.json')
.then((res) => res.json())
.then((data) =>
createGraph(
{
data,
autoFit: 'view',
node: {
style: {
size: 10,
},
palette: {
field: 'group',
color: 'tableau',
},
},
layout: {
type: 'd3force',
manyBody: {},
x: {},
y: {},
},
behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'],
},
{ width: 500, height: 500 },
),
);
```

View File

@ -0,0 +1,27 @@
```js | ob { pin: false }
createGraph(
{
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'],
},
{ width: 300, height: 200 },
);
```

View File

@ -0,0 +1,14 @@
```js | ob { pin: false }
createGraph(
{
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' }],
},
},
{ width: 200, height: 100 },
);
```

View File

@ -0,0 +1,24 @@
```js | ob { pin: false }
createGraph(
{
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',
},
},
},
{ width: 200, height: 100 },
);
```

View File

@ -0,0 +1,26 @@
```js | ob { pin: false }
createGraph(
{
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',
},
},
},
{ width: 200, height: 100 },
);
```

View File

@ -0,0 +1,26 @@
```js | ob { pin: false }
createGraph(
{
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: 'd3force',
},
},
{ width: 200, height: 200 },
);
```

View File

@ -0,0 +1,32 @@
```js | ob { pin: false }
createGraph(
{
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: 'd3force',
},
},
{ width: 200, height: 200 },
);
```

View File

@ -0,0 +1,33 @@
```js | ob { pin: false }
createGraph(
{
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: 'd3force',
},
plugins: ['grid-line'],
},
{ width: 200, height: 200 },
);
```

View File

@ -0,0 +1,33 @@
```js | ob { pin: false }
createGraph(
{
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: 'd3force',
},
plugins: [{ type: 'grid-line', follow: true }],
},
{ width: 200, height: 200 },
);
```

View File

@ -1,4 +1,42 @@
---
title: Installation
order: 1
---
---
## npm
```bash
# npm
npm install @antv/g6@beta --save
# pnpm
pnpm add @antv/g6@5
# yarn
yarn add @antv/g6@5
```
Import G6 in the code:
```js
import { Graph } from '@antv/g6';
```
Visit [G6 npm Example](https://codesandbox.io/p/sandbox/using-g6-from-npm-d9spnr) to view the complete example code.
## CDN
`@antv/g6` Available on multiple CDNs:
- unpkg: https://unpkg.com/@antv/g6@beta/dist/g6.min.js
- jsDelivr: https://cdn.jsdelivr.net/npm/@antv/g6@beta/dist/g6.min.js
- npmmirror: https://registry.npmmirror.com/@antv/g6/beta/files/dist/g6.min.js
- cdnjs: https://cdnjs.cloudflare.com/ajax/libs/antv-g6/5.0.0-beta.34/g6.min.js
Import G6 using a `script` tag:
```html
<script src="https://unpkg.com/@antv/g6@beta/dist/g6.min.js"></script>
```
Visit [G6 CDN Example](https://codesandbox.io/p/sandbox/using-g6-from-cdn-xt9ty6) to view the complete example code.

View File

@ -1,4 +1,8 @@
---
title: angular
order: 2
---
---
Refer to the example below, you can use G6 in Angular, and you can also view the [Live Example](https://codesandbox.io/p/sandbox/g6-angular-2gv4rt?file=%2Fsrc%2Fapp%2Fapp.component.ts%3A11%2C1)。
<embed src="@/common/angular-snippet"></embed>

View File

@ -1,4 +1,8 @@
---
title: react
order: 0
---
---
Refer to the example below, you can use G6 in React, and you can also view the [Live Example](https://codesandbox.io/p/sandbox/g6-react-gpcc43) 。
<embed src="@/common/react-snippet"></embed>

View File

@ -1,4 +1,8 @@
---
title: vue
order: 1
---
---
Refer to the example below, you can use G6 in Vue, and you can also view the [Live Example](https://codesandbox.io/p/sandbox/g6-vue-xzf7pg)。
<embed src="@/common/vue-snippet"></embed>

View File

@ -2,3 +2,109 @@
title: Quick Start
order: 0
---
## Online Experience with G6
Visit [Chart Examples](/en/examples) to experience G6 online without any environment setup.
## Creating a Simple Graph
In this example, we will create a simple graph using G6 based on an HTML page.
Copy the following code into an HTML file and then open this file in a browser:
```html
<!-- Prepare a container -->
<div id="container" style="width: 500px; height: 500px"></div>
<!-- Import G6's JS file -->
<script src="https://unpkg.com/@antv/g6@beta/dist/g6.min.js"></script>
<script>
fetch('https://assets.antv.antgroup.com/g6/graph.json')
.then((res) => res.json())
.then((data) => {
const graph = new Graph({
container: 'container',
autoFit: 'view',
data,
node: {
style: {
size: 10,
},
palette: {
field: 'group',
color: 'tableau',
},
},
layout: {
type: 'd3force',
manyBody: {},
x: {},
y: {},
},
behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'],
});
graph.render();
});
</script>
```
You will get a graph as shown below:
<embed src="@/docs/manual/getting-started-common/quick-start/simple-graph.md"></embed>
Let's analyze the following code snippet:
1. First, we create a `div` element to serve as the container for the graph:
```html
<div id="container" style="width: 500px; height: 500px"></div>
```
2. Then, include the G6's JS file:
```html
<script src="https://unpkg.com/@antv/g6@beta/dist/g6.min.js"></script>
```
3. Use the `fetch` method to obtain the graph's data:
```js
fetch('https://assets.antv.antgroup.com/g6/graph.json').then((res) => res.json());
```
4. Finally, create an instance of the graph, pass in the configuration object, and call the `render` method to render the graph:
```js
const graph = new Graph({
container: 'container',
autoFit: 'view',
data,
node: {
style: {
size: 10,
},
palette: {
field: 'group',
color: 'tableau',
},
},
layout: {
type: 'd3force',
manyBody: {},
x: {},
y: {},
},
behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'],
});
graph.render();
```
If you are using frameworks such as React, Vue, Angular, etc., you can refer to:
- [Using G6 in React](./integration/react)
- [Using G6 in Vue](./integration/vue)
- [Using G6 in Angular](./integration/angular)

View File

@ -53,35 +53,7 @@ order: 0
会得到如下所示的图:
```js | ob { pin: false }
fetch('https://assets.antv.antgroup.com/g6/graph.json')
.then((res) => res.json())
.then((data) =>
createGraph(
{
data,
autoFit: 'view',
node: {
style: {
size: 10,
},
palette: {
field: 'group',
color: 'tableau',
},
},
layout: {
type: 'd3force',
manyBody: {},
x: {},
y: {},
},
behaviors: ['drag-canvas', 'zoom-canvas', 'drag-element'],
},
{ width: 500, height: 500 },
),
);
```
<embed src="@/docs/manual/getting-started-common/quick-start/simple-graph.md"></embed>
下面分析一下这段代码:

View File

@ -1,4 +1,353 @@
---
title: Step-by-step guide
order: 3
---
---
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.
## Create Application
We will use Vite to create a simple front-end application.
### Initialization
First, create an empty directory:
```bash
mkdir g6-tutorial
cd g6-tutorial
```
Initialize the project:
```bash
npm init -y
```
Install G6:
```bash
npm install @antv/g6@beta --save
```
Vite is a new type of front-end build tool that is based on ESModule and can quickly start up projects.
Install Vite:
```bash
npm install vite --save-dev
```
Add a start script to the `package.json`:
```json
{
"scripts": {
"dev": "vite"
}
}
```
### Create Files
Create the `index.html` and `main.ts` files with the following content:
**index.html**:
```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**
```typescript
alert('Hello, G6!');
```
### Start project
```bash
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!".
## Creating a Simple Graph
Next, we will create a simple chart using G6.
### Preparing the Data
G6 uses JSON-formatted data to describe the graph, which usually includes nodes and edges. We will use the following prepared data:
```js
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.
### Creating and Drawing the Graph
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:
```typescript
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:
<embed src="@/docs/manual/getting-started-common/step-by-step/create-chart.md"></embed>
### Element
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:
<!-- TODO -->
```js
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:
<embed src="@/docs/manual/getting-started-common/step-by-step/elements-1.md"></embed>
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](https://codesandbox.io/s/g6-tutorial).
Next, we will demonstrate more types of nodes by setting the node type:
```js
{
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 `style` style of an element can also be a function, with the argument being the current element's data object.
> You can even set the entire `style` property 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 `size` to an array `[20, 10]`.
You can see the effect in the example below:
<embed src="@/docs/manual/getting-started-common/step-by-step/elements-2.md"></embed>
### Behaviors
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.
```js
{
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:
<embed src="@/docs/manual/getting-started-common/step-by-step/behaviors.md"></embed>
### Layout
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:
```js
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 `d3force` 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.
```js
{
layout: {
type: 'd3force',
},
}
```
View the example below, and you can see that the nodes have automatically adjusted to suitable positions:
<details>
<summary>Complete Code</summary>
```js
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: 'd3force',
},
});
graph.render();
```
</details>
<embed src="@/docs/manual/getting-started-common/step-by-step/layout.md"></embed>
### Palette
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:
```js
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.
```js
{
node: {
palette: {
field: 'category',
color: 'tableau',
}
}
}
```
> It is important to note that the `fill` style in `node.style` should be removed, as its priority is higher than the colors assigned by the palette.
<embed src="@/docs/manual/getting-started-common/step-by-step/palette.md"></embed>
### Plugins
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:
```js
{
plugins: ['grid-line'],
}
```
You can see that grid lines have been added to the canvas:
<embed src="@/docs/manual/getting-started-common/step-by-step/plugins-1.md"></embed>
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.
```js
{
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:
<embed src="@/docs/manual/getting-started-common/step-by-step/plugins-2.md"></embed>
## Summary
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](/en/manual/core-concept/graph).
Detailed explanations of options such as elements, layouts, and plugins can be found in the [API](/en/api).

View File

@ -125,20 +125,7 @@ graph.render();
如下所示,可以看到图表已经顺利绘制出来:
```js | ob { pin: false }
createGraph(
{
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' }],
},
},
{ width: 200, height: 100 },
);
```
<embed src="@/docs/manual/getting-started-common/step-by-step/create-chart.md"></embed>
### 元素
@ -177,30 +164,7 @@ graph.render();
正如代码所示,我们在图表实例中配置了节点的填充颜色为粉色,边的描边颜色为浅绿色。你可以在下面的示例中看到效果:
```js | ob { pin: false }
createGraph(
{
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',
},
},
},
{ width: 200, height: 100 },
);
```
<embed src="@/docs/manual/getting-started-common/step-by-step/elements-1.md"></embed>
其中的关键部分是 `node.style``edge.style` 配置项,分别用来配置节点和边的样式。
@ -234,32 +198,7 @@ createGraph(
你可以在下面的示例中看到效果:
```js | ob { pin: false }
createGraph(
{
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',
},
},
},
{ width: 200, height: 100 },
);
```
<embed src="@/docs/manual/getting-started-common/step-by-step/elements-2.md"></embed>
### 交互
@ -275,33 +214,7 @@ G6 提供了多种交互行为,我们添加几个常用的交互,使得用
尝试在下面的示例中拖拽节点和画布,并使用滚轮缩放画布:
```js | ob { pin: false }
createGraph(
{
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'],
},
{ width: 300, height: 200 },
);
```
<embed src="@/docs/manual/getting-started-common/step-by-step/behaviors.md"></embed>
### 布局
@ -366,32 +279,7 @@ graph.render();
</details>
```js | ob { pin: false }
createGraph(
{
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: 'd3force',
},
},
{ width: 200, height: 200 },
);
```
<embed src="@/docs/manual/getting-started-common/step-by-step/layout.md"></embed>
### 色板
@ -426,38 +314,7 @@ const data = {
> 需要注意将 `node.style` 中的 `fill` 样式移除,因为其优先级高于色板分配的颜色。
```js | ob { pin: false }
createGraph(
{
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: 'd3force',
},
},
{ width: 200, height: 200 },
);
```
<embed src="@/docs/manual/getting-started-common/step-by-step/palette.md"></embed>
### 插件
@ -473,39 +330,7 @@ createGraph(
可以看到画布已经添加了网格线:
```js | ob { pin: false }
createGraph(
{
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: 'd3force',
},
plugins: ['grid-line'],
},
{ width: 200, height: 200 },
);
```
<embed src="@/docs/manual/getting-started-common/step-by-step/plugins-1.md"></embed>
上面的插件配置项中使用了简写形式,大部分的插件都支持传递额外的参数,例如 `grid-line` 插件可以配置 `follow` 属性来指定拖拽画布时网格线是否跟随画布移动。
@ -517,39 +342,7 @@ createGraph(
尝试在下面的示例中拖拽画布,可以看到网格线跟随画布移动:
```js | ob { pin: false }
createGraph(
{
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: 'd3force',
},
plugins: [{ type: 'grid-line', follow: true }],
},
{ width: 200, height: 200 },
);
```
<embed src="@/docs/manual/getting-started-common/step-by-step/plugins-2.md"></embed>
## 小结

View File

@ -1,4 +1,20 @@
---
title: Glossary
order: 7
---
---
| Term | Explanation |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Graph | A concept in graph theory, specifically refers to the class used to instantiate the canvas in `G6` |
| Element | Refers to `node`, `edge`, and `combo` in a general sense |
| Node | Represents a single or composite shape in a Graph, denoting an independently existing entity |
| Edge | Represents a `line` connecting nodes in a Graph, indicating a relationship between two nodes |
| Combo | A collection of nodes that can include sub-combos |
| State | The state in which an element exists, such as selected, hovered, activated, etc. |
| Layout | The process of arranging elements in a graph according to certain rules |
| Behavior | A series of operational behaviors between the user and the canvas or elements, such as dragging, scaling, panning, selecting, etc. |
| Plugin | A flexible extension mechanism provided by G6 |
| Extension | A collective term for all registrable content, including elements, behaviors, layouts, plugins, etc. |
| Canvas | The content area where the Graph is drawn |
| Viewport | The area observed by the camera, i.e., the current visible range of the user |
| Shape | Basic shapes provided by G, including circles, rectangles, text, etc. |

View File

@ -2,3 +2,66 @@
title: Introduction
order: 0
---
![](https://user-images.githubusercontent.com/6113694/45008751-ea465300-b036-11e8-8e2a-166cbb338ce2.png)
[![Build Status](https://github.com/antvis/g6/workflows/build/badge.svg?branch=v5)](https://github.com/antvis//actions)
[![Coverage Status](https://img.shields.io/coveralls/github/antvis/G6/v5.svg)](https://coveralls.io/github/antvis/G6?branch=v5)
![typescript](https://img.shields.io/badge/language-typescript-red.svg)
![MIT](https://img.shields.io/badge/license-MIT-000000.svg)
[![npm package](https://img.shields.io/npm/v/@antv/g6.svg)](https://www.npmjs.com/package/@antv/g6)
[![NPM downloads](http://img.shields.io/npm/dm/@antv/g6.svg)](https://npmjs.org/package/@antv/g6)
[![Percentage of issues still open](http://isitmaintained.com/badge/open/antvis/g6.svg)](http://isitmaintained.com/project/antvis/g6 'Percentage of issues still open')
<h3 style="text-align: center;">AntV G6</h3>
<h3 style="text-align: center;"><image width="500" src="https://gw.alipayobjects.com/mdn/rms_f8c6a0/afts/img/A*zTjwQaXokeQAAAAAAAAAAABkARQnAQ" /></h3>
<p style="text-align: center;">G6 is a graph visualization engine. It provides capabilities for graph drawing, layout, analysis, interaction, animation, and other aspects of graph visualization. It aims to offer developers a set of tools that are easy to use, professionally reliable, and highly customizable for graph visualization development.</p>
<h4 style="text-align: center; color: #678ff3;">Rich Elements</h4>
<p style="text-align: center;">Built-in 10+ elements to meet the needs of common scenarios.</p>
<h4 style="text-align: center; color: #678ff3;">Flexible Interactions</h4>
<p style="text-align: center;">Built-in 10+ interactions that can be freely combined according to different scenarios.</p>
<h4 style="text-align: center; color: #678ff3;">High-Performance Layout Algorithms</h4>
<p style="text-align: center;">High-performance layouts, built-in 10+ common graph layouts, with support for WebGPU and WASM computational acceleration.</p>
<h4 style="text-align: center; color: #678ff3;">Multicolor Themes for Various Scenarios</h4>
<p style="text-align: center;"><img height="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*QjJoSbD7GTwAAAAAAAAAAAAADmJ7AQ/original"></p>
<h4 style="text-align: center; color: #678ff3;">3D Scenes</h4>
<p style="text-align: center;"><img width="400" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*IUOnSbLisyoAAAAAAAAAAAAADmJ7AQ/original"></p>
<p style="text-align: center;"><img width="400" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*BK0OSYplirUAAAAAAAAAAAAADmJ7AQ/original"></p>
<p style="text-align: center;">Supports 3D elements and layouts to create immersive graph visualization scenarios.</p>
<h4 style="text-align: center; color: #678ff3;">High Customizability</h4>
<p style="text-align: center;">Elements, layouts, interactions, and plugins are all customizable, enabling every creative idea you have.</p>
<h4 style="text-align: center; color: #678ff3;">Start Your G6 Journey in Just 3 Minutes</h4>
<p style="text-align: center;">Click to enter 👉 <a href="/manual/getting-started/quick-start">Quick Start</a></p>
<div>
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*YXHtRZUKAZcAAAAAAAAAAAAADmJ7AQ/original" />
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*VChnTLySxScAAAAAAAAAAAAADmJ7AQ/original" />
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*tqlbS7ukmYUAAAAAAAAAAAAADmJ7AQ/original" />
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*I5uDQZWTzMsAAAAAAAAAAAAADmJ7AQ/original" />
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*hnLoRJR8EvMAAAAAAAAAAAAADmJ7AQ/original" />
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*8LqvQJ09-EEAAAAAAAAAAAAADmJ7AQ/original" />
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*UgMZS6vrUlgAAAAAAAAAAAAADmJ7AQ/original" />
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*SDQKSb8gcxgAAAAAAAAAAAAADmJ7AQ/original" />
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*ZC1CT7q0fM4AAAAAAAAAAAAADmJ7AQ/original" />
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*YMxxTZwt54UAAAAAAAAAAAAADmJ7AQ/original" />
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*h3eWT4loiTwAAAAAAAAAAAAADmJ7AQ/original" />
<image width="200" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*XTcoRKPMDloAAAAAAAAAAAAADmJ7AQ/original" />
</div>

View File

@ -1,4 +1,509 @@
---
title: Upgrade To 5.0
order: 5
---
---
This document will guide you through the process of upgrading from G6 version `4.x` to `5.x`. If you are using version `3.x`, please upgrade to version `4.x` first.
## Preparation Before Upgrade
1. Please ensure that your current git branch is clean and there is no uncommitted code.
2. Refer to the [Installation](./getting-started/installation) document to install version `5.x` and remove the dependencies for version `4.x`.
## Start Upgrade
### Data
The data format in the new version has changed as follows:
1. All style attributes in `nodes`, `edges`, and `combos` need to be placed within `style`, and data attributes should be stored in `data`:
```typescript
// 4.x
const data = {
nodes: [
{ id: 'node1', label: 'node1', size: 20 },
{ id: 'node2', label: 'node2', size: 20 },
],
edges: [{ source: 'node1', target: 'node2' }],
};
// 5.x
const data = {
nodes: [
// The label is a non-stylistic attribute, placed in the data, and can be accessed in the style mapping function
// The `size` is a stylistic attribute, placed within the `style`
{ id: 'node1', data: { label: 'node1' }, style: { size: 20 } },
{ id: 'node2', data: { label: 'node2' }, style: { size: 20 } },
],
edges: [{ source: 'node1', target: 'node2' }],
};
```
Since we have redesigned and implemented the elements, please refer to the corresponding documentation to modify the new element options:
- [Node](/en/api/elements/nodes/base-node)
- [Edge](/en/api/elements/edges/base-edge)
- [Combo](/en/api/elements/combos/base-combo)
2. If you need to specify the element type in the data, you can use the `type` attribute:
```typescript
{
nodes: [
// Specify the node type as rect
{ id: 'node1', type: 'rect' },
];
}
```
### Options
<Badge type="warning">Change</Badge> **fitView / fitCenter / fitViewPadding**
- The `fitView` and `fitCenter` options have been merged into `autoFit`.
- To use `fitView`, you can configure it as `autoFit: 'view'`
- To use `fitCenter`, you can configure it as `autoFit: 'center'`
- You can also pass an object for full configuration:
```js
autoFit: {
type: 'view',
options: {
// ...
}
}
```
- The `fitViewPadding` has been changed to `padding`.
<Badge type="error">Removed</Badge> **linkCenter**
In version 5.x, the edge connection mechanism will attempt to connect to nodes/Combos in the following order:
1. Connect Port
2. Outline
3. Center
<Badge type="error">Removed</Badge> **groupByTypes**
<Badge type="error">Removed</Badge> **autoPaint**
Please manually call the `render` or `draw` method to perform rendering.
<Badge type="warning">Changed</Badge> **modes**
In version 5.x, interaction modes have been removed. You can switch the currently enabled behaviors by setting `behaviors`.
```typescript
// 4.x
{
modes: {
default: ['drag-canvas', 'zoom-canvas'],
preview: ['drag-canvas'],
},
}
graph.setMode('preview');
```
```typescript
// 5.x
{
behaviors: ['drag-canvas', 'zoom-canvas'],
}
graph.setBehaviors(['drag-canvas']);
```
<Badge type="warning">Change</Badge> **defaultNode / defaultEdge / defaultCombo**
The element styles have been moved to `[element].style`, for example, `defaultNode` has been changed to `node.style`:
```typescript
// 4.x
{
defaultNode: {
size: 20,
fill: 'red',
}
}
// 5.x
{
node: {
style: {
size: 20,
fill: 'red',
}
}
}
```
<Badge type="warning">Change</Badge> **nodeStateStyles / edgeStateStyles / comboStateStyle**
Element state styles have been moved to `[element].state`, for example, `nodeStateStyles` has been changed to `node.stateStyles`:
```typescript
// 4.x
{
nodeStateStyles: {
selected: {
fill: 'red',
}
}
}
// 5.x
{
node: {
state: {
selected: {
fill: 'red',
}
}
}
}
```
<Badge type="warning">Change</Badge> **animate / animateCfg**
- The `animate` options has been changed to `animation`
- `animate` and `animateCfg` have been merged into `animation`
```typescript
// 4.x
{
animate: true,
}
// 5.x
{
animation: true,
}
{
animation: {
duration: 500,
easing: 'easeLinear',
}
}
```
<Badge type="warning">Change</Badge> **minZoom / maxZoom**
- The `minZoom` and `maxZoom` options have been merged into `zoomRange`
```typescript
// 4.x
{
minZoom: 0.5,
maxZoom: 2,
}
// 5.x
{
zoomRange: [0.5, 2],
}
```
<Badge type="warning">Change</Badge> **renderer**
G6 5.x supports multi-layer canvases and defaults to using the `canvas` renderer.
The `renderer` no longer supports the string type and has been changed to a callback function:
```typescript
// 4.x
var options = {
renderer: 'svg',
};
// 5.x
import { Renderer } from '@antv/g-svg';
{
renderer: () => new Renderer(),
}
```
<Badge type="error">Removed</Badge> **enabledStack / maxStep**
The built-in undo and redo functionality has been removed in version 5.x. For related capabilities, please use a plugin to implement.
### API
<Badge type="warning">Change</Badge> **data / save / read / changeData**
Version 5.x offers a completely new data API. For details, see [Data API](/en/api/graph/method#data).
- The `data` and `changeData` methods from 4.x are replaced by `setData` in 5.x.
- The `save` method from 4.x is replaced by `getData` in 5.x.
- The `read` method from 4.x is replaced by `setData` + `render` in 5.x.
<Badge type="warning">Change</Badge> **get / set**
To access Graph options, please use `getOptions` or the `getXxx` API, such as `getZoomRange`, `getBehaviors`, etc. The `set` method is analogous.
<Badge type="warning">Change</Badge> **getContainer**
Direct API to obtain the container is not currently supported, but you can obtain it through `graph.getCanvas().getContainer()`.
> In most cases, you do not need to directly manipulate the container.
<Badge type="error">Removed</Badge> **getGroup**
<Badge type="warning">Change</Badge> **getMinZoom / getMaxZoom**
Use `getZoomRange` to obtain the values.
<Badge type="warning">Change</Badge> **setMinZoom / setMaxZoom**
Use the `setZoomRange` method to set the values.
<Badge type="warning">Change</Badge> **getWidth / getHeight**
Use `getSize` to get the dimensions.
<Badge type="warning">Change</Badge> **changeSize**
Use `setSize` to set the dimensions.
<Badge type="warning">Change</Badge> **zoom**
Changed to `zoomBy`.
<Badge type="warning">Change</Badge> **translate**
Changed to `translateBy`.
<Badge type="warning">Change</Badge> **moveTo**
Changed to `translateTo`.
<Badge type="warning">Change</Badge> **focusItem**
Changed to `focusElement`.
<Badge type="error">Removed</Badge> **addItem / updateItem / removeItem**
To add or remove elements, use the methods `addData` / `updateData` / `removeData` to manipulate data.
<Badge type="error">Removed</Badge> **refreshItem**
<Badge type="error">Removed</Badge> **refreshPositions**
<Badge type="error">Removed</Badge> **updateCombo**
<Badge type="error">Removed</Badge> **updateCombos**
<Badge type="error">Removed</Badge> **updateComboTree**
<Badge type="warning">Change</Badge> **node / edge / combo**
Use the `setNode` / `setEdge` / `setCombo` methods as alternatives.
<Badge type="warning">Change</Badge> **showItem / hideItem**
Use the `setElementVisibility` method as an alternative.
<Badge type="error">Removed</Badge> **getNodes / getEdges / getCombos / getComboChildren / getNeighbors / find / findById / findAll / findAllByState**
In version 5.x, direct retrieval of element instances is not supported.
- To obtain element data, use the methods `getData`, `getNodeData`, `getEdgeData`, `getComboData`, which support searching by element ID.
- To obtain child node data, use the `getChildrenData` method.
- To obtain neighbor node data, use the `getNeighborNodesData` method.
- To find element data based on state, use the `getElementDataByState` method.
<Badge type="warning">Change</Badge> **collapseCombo / expandCombo**
Use the `collapseElement` / `expandElement` methods as alternatives.
<Badge type="error">Removed</Badge> **collapseExpandCombo**
<Badge type="error">Removed</Badge> **createCombo**
Combos can now be added using the `addData` / `addComboData` methods.
<Badge type="error">Removed</Badge> **uncombo**
Combos can now be removed using the `removeData` / `removeComboData` methods.
<Badge type="warning">Change</Badge> **setItemState**
Use the `setElementState` method as an alternative.
<Badge type="error">Removed</Badge> **clearItemStates**
- To clear all states of a single element: `graph.setElementState(id, [])`
- To clear all states of multiple elements: `graph.setElementState({ id1: [], id2: [] })`
<Badge type="error">Removed</Badge> **priorityState**
When using `setElementState`, the state that appears later in the array has a higher priority.
<Badge type="error">Removed</Badge> **setMode**
Use `setBehaviors` to set the current behaviors.
<Badge type="error">Removed</Badge> **setCurrentMode**
<Badge type="warning">Change</Badge> **layout**
Does not support parameters. To configure the layout, please use `setLayout`.
<Badge type="warning">Change</Badge> **updateLayout**
Changed to `setLayout`.
<Badge type="error">Removed</Badge> **destroyLayout**
<Badge type="warning">Change</Badge> **addBehaviors / removeBehaviors**
Replaced with `setBehaviors`.
<Badge type="error">Removed</Badge> **createHull / getHulls / removeHull / removeHulls**
- For multiple `Hull` instances, you need to configure multiple `hull` plugins in `plugins`, such as:
```typescript
{
plugins: ['hull', 'hull'],
};
```
- Operations to retrieve, update, and remove `Hull` are implemented through `setPlugins`, `updatePlugin`.
<Badge>Not yet available</Badge> **getNodeDegree**
<Badge>Not yet available</Badge> **getShortestPathMatrix**
<Badge>Not yet available</Badge> **getAdjMatrix**
<Badge type="error">Removed</Badge> **pushStack / getUndoStack / getRedoStack / getStackData / clearStack**
All undo and redo related APIs should be called after obtaining the corresponding plugin, for example:
```typescript
// 'history' is the key configured for use with the plugin
const history = graph.getPluginInstance('history');
history.redo();
```
<Badge type="error">Removed</Badge> **positionsAnimate / stopAnimate / isAnimating**
Animation-related information is now emitted through events:
- Animation start event: `beforeanimate`
- Animation end event: `afteranimate`
- To stop an animation:
```typescript
graph.on('beforeanimate', (event) => {
event.animation.stop();
});
```
<Badge type="warning">Change</Badge> **getPointByClient / getClientByPoint / getPointByCanvas / getCanvasByPoint / getGraphCenterPoint / getViewPortCenterPoint**
G6 5.x uses a different coordinate system than 4.x. For details, see [Coordinate](/en/manual/further-reading/coordinate).
<Badge type="error">Removed</Badge> **setTextWaterMarker / setImageWaterMarker**
For watermark functionality, please refer to the [Watermark](/en/api/plugins/watermark)plugin.
<Badge type="warning">Change</Badge> **toFullDataURL**
Replaced with `toDataURL`, specify the parameter as: `mode: 'overall'`
```typescript
graph.toDataURL({ mode: 'overall' });
```
<Badge type="error">Removed</Badge> **downloadFullImage / downloadImage**
Only the capability to export as a `DataURL` is provided. If you need to download an image, please refer to the following example code:
```typescript
async function downloadImage() {
const dataURL = await graph.toDataURL();
const [head, content] = dataURL.split(',');
const contentType = head.match(/:(.*?);/)![1];
const bstr = atob(content);
let length = bstr.length;
const u8arr = new Uint8Array(length);
while (length--) {
u8arr[length] = bstr.charCodeAt(length);
}
const blob = new Blob([u8arr], { type: contentType });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'graph.png';
a.click();
}
```
<Badge type="error">Removed</Badge> **clear**
Use `setData` + `draw` to clear data and the canvas.
### Extension Registration
Unlike G6 4.x, G6 5.x uses a unified extension registration function (register). You can refer to the [Extension Register](/en/manual/core-concept/extension#register-extension) to register G6 extensions.
The following G6 4.x registration functions have been deprecated:
- registerNode
- registerEdge
- registerCombo
- registerLayout
- registerBehavior
### Events
Compared to G6 4.x, G6 5.x has the following differences in events:
- The `mouse` and `touch` events have been removed and are unified under the `pointer` event.
- The naming convention for lifecycle events is usually in the format of: `before/after` + `object/property` + `action`, for example: `beforeelementcreate` is triggered before an element is created.
- The following events have been removed:
- afteractivaterelations
- afteradditem
- aftercreateedge
- aftergraphrefresh
- aftergraphrefreshposition
- afteritemrefresh
- aftermodechange
- afterremoveitem
- afterupdateitem
- beforeadditem
- beforecreateedge
- beforegraphrefresh
- beforegraphrefreshposition
- beforeitemrefresh
- beforemodechange
- beforeremoveitem
- beforeupdateitem
- dragnodeend
- nodeselectchange
- stackchange
- tooltipchange
- The following element change events have been removed, but you can still access them through `beforeelementupdate` and `afterelementupdate`:
- afteritemstatechange
- afteritemstatesclear
- afteritemvisibilitychange
- beforeitemstatechange
- beforeitemstatesclear
- beforeitemvisibilitychange
- The following events have been changed:
- The `graphstatechange` event has been changed to `beforeelementstatechange` / `afterelementstatechange`.
- The `viewportchange` event has been changed to `beforetransform` / `aftertransform`.
For a complete list of events, please refer to [Event](/en/api/reference/g6#event).