Merge branch 'site-20191104' of https://github.com/antvis/g6 into site-20191104

This commit is contained in:
Yanyan-Wang 2019-11-05 19:26:00 +08:00
commit e7c9d7f3dd
13 changed files with 2215 additions and 2 deletions

View File

@ -5,7 +5,7 @@ redirect_from:
- /zh/docs/manual
---
![](https://user-images.githubusercontent.com/6113694/45008751-ea465300-b036-11e8-8e2a-166cbb338ce2.png)
<img src='https://user-images.githubusercontent.com/6113694/45008751-ea465300-b036-11e8-8e2a-166cbb338ce2.png' width='750' height='250' />
[![](https://img.shields.io/travis/antvis/g6.svg)](https://travis-ci.org/antvis/g6)
![](https://img.shields.io/badge/language-javascript-red.svg)

View File

@ -0,0 +1,31 @@
---
title: 监听和绑定事件
order: 1
---
除了 [内置交互行为 Behavior](./defaultBehavior) 和 [交互模式 Mode](./mode) 搭配的事件管理方式外G6 提供了直接的单个事件、时机的监听方法,可以监听画布、节点、边、以及各函数被调用的时机等。这些事件可以分为以下四个层次:
- 画布、图形层次的事件,`mousedown` `mouseup``click``mouseenter``mouseleave` 等;
- 节点/边 上的事件,`node:mousedown` `edge:click` 等,以 `type:eventName` 为事件名称;
- 时机事件:
- 节点/边增删改时的事件, 例如:`beforeadditem`  `afteradditem` 等;
- 节点/边状态改变时的事件,例如:`beforerefreshitem``afterrefreshitem`。
- 布局时机,例如:`beforelayout``afterlayout`。
如果要了解G6支持的所有事件请参考[Event文档](https://www.yuque.com/antv/g6/event-api)。
G6 上所有的事件都需要在graph上监听。
```javascript
graph.on('click', ev => {
const shape = ev.target;
const item = ev.item;
if (item) {
const type = item.getType();
}
});
graph.on('node:click', ev => {
const shape = ev.target;
const node = ev.item;
});
```

View File

@ -0,0 +1,389 @@
---
title: 内置的 Behavior
order: 4
---
<a name="iNlRp"></a>
## 什么是 Behavior
Behavior 是 G6 提供的定义图上交互事件的机制。它与[交互模式 Mode](https://www.yuque.com/antv/g6/g6-mode) 搭配使用,如何将下文所述各种 Behavior 配置到图上,见 [交互模式](https://www.yuque.com/antv/g6/g6-mode)。
<a name="1FVPj"></a>
## 内置 Behavior
理论上说 G6 上的所有基础图形、Item节点/边)都能通过事件来进行操作,考虑到通用性, G6目前共提供了以下9个内置的 Behavior。
<a name="EzfvY"></a>
### drag-canvas
- 含义:拖拽画布;
- `type: 'drag-canvas'`
- `direction`: 允许拖拽方向,支持`'x'` `'y'``'both'`,默认方向为 `'both'`
**默认配置**
```javascript
const graph = new G6.Graph({
modes: {
default: [ 'drag-canvas' ]
}
})
```
默认配置下,可以在 x 和 y 两个方向上拖动画布。
**配置参数**
```javascript
const graph = new G6.Graph({
modes: {
default: [
{
type: 'drag-canvas',
direction: 'x'
}
]
}
})
```
此时只能在 x 方向上面拖动y 方向上不允许拖动。<br />![3.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570778658995-88e2bf4e-e201-43a0-9ffd-15ceadc8334e.gif#align=left&display=inline&height=333&name=3.gif&originHeight=517&originWidth=783&search=&size=669012&status=done&width=504)
<a name="12uvu"></a>
### zoom-canvas
- 含义:缩放画布;
- `type: 'zoom-canvas'`
- `sensitivity`: 缩放灵敏度,支持 1-10 的数值,默认灵敏度为 5。
**提示:若要限定缩放尺寸,请在 graph 上设置 **`**minZoom**`** 和 **`**maxZoom**`**。**
<a name="DubUE"></a>
### drag-node
- 含义:拖拽节点;
- `type: 'drag-node'`
- `delegateStyle`: 节点拖拽时的绘图属性,默认为 `{ strokeOpacity: 0.6, fillOpacity: 0.6 }`
- `updateEdge`: 是否在拖拽节点时更新所有与之相连的边,默认为 `true`
- 3.1.2 `enableDelegate`:拖动节点过程中是否启用 `delegate`,即在拖动过程中是否使用方框代替元素的直接移动,效果区别见下面两个动图。默认值为 `false`
**默认配置**
```javascript
const graph = new G6.Graph({
modes: {
default: [ 'drag-node' ]
}
})
```
![3.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570777651736-e68e2d92-eabe-4b58-bc39-66a6cfbd6cf5.gif#align=left&display=inline&height=374&name=3.gif&originHeight=517&originWidth=783&search=&size=149678&status=done&width=567)
**启用** `delegate`
```javascript
const graph = new G6.Graph({
modes: {
default: [
{
type: 'drag-node',
enableDelegate: true
}
]
}
})
```
![3.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570778113574-f65eeb6b-4df4-4db4-a4d3-5cf2141607f3.gif#align=left&display=inline&height=279&name=3.gif&originHeight=517&originWidth=783&search=&size=219983&status=done&width=422)
<a name="6EYBA"></a>
### click-select
- 含义:点击选中节点,再次点击节点或点击 Canvas 取消选中状态;
- `type: 'click-select'`
- `multiple`: 是否允许多选,默认为 `true`,当设置为 `false`,表示不允许多选,此时 `trigger` 参数无效。
- 3.1.2 `trigger`: 指定按住哪个键进行多选,默认为 shift按住 Shift 键多选,用户可配置 shift、ctrl、alt
**默认配置**<br />**
```javascript
const graph = new G6.Graph({
modes: {
default: [ 'click-select' ]
}
})
```
按住 **`Shift`** 键可多选。<br />![3.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570778352084-ca8b1694-0e10-4dfa-b69e-2fc35130b9a9.gif#align=left&display=inline&height=517&name=3.gif&originHeight=517&originWidth=783&search=&size=48383&status=done&width=783)
**配置参数**
```javascript
const graph = new G6.Graph({
modes: {
default: [
{
type: 'click-select',
trigger: 'ctrl'
}
]
}
})
```
以上配置中,用户可按住 **Ctrl** 键进行多选,也可以配置 **Alt** 键。当配置了 `multiple` 参数为 `false`,则表示不允许多谢,此时 `trigger` 参数无效。
<a name="a415de36"></a>
### tooltip
- 含义:节点文本提示;
- `type: 'tooltip'`
- `formatText(model)` 格式化函数,可以返回文本或者 HTML
```javascript
const graph = new G6.Graph({
container: 'mountNode',
width: 500,
height: 500,
modes: {
default: [{
type: 'tooltip',
formatText(model) {
return model.xxx;
}
}],
}
});
```
**提示:由于 G6 没有内置任何 tooltip 的样式,用户需要自己定义样式,例如:**
```css
.g6-tooltip {
padding: 10px 6px;
color: #444;
background-color: rgba(255,255,255,0.9);
border: 1px solid #e2e2e2;
border-radius: 4px;
}
```
<a name="uvumm"></a>
### edge-tooltip
使用方式基本与 tooltip 相同,但是移到边时触发。主要是为了将两个交互区分开,以满足用户边与节点的提示样式或 HTML 结构不同,以及不需要在事件中去区分是节点事件还是边事件等。
- 含义:边文本提示;
- `type: 'edge-tooltip'`
- `formatText(model)` 格式化函数,可以返回文本或者 HTML。
<a name="FWfLl"></a>
### activate-relations
- 含义:当鼠标移到某节点时,突出显示该节点以及与其直接关联的节点和连线;
- `type: 'activate-relations'`
- 参数:
- `trigger: 'mouseenter'`, 可以是 `mousenter` , 鼠标移入时触发;也可以是 `click` ,鼠标点击时触发;
- `activeState: 'active'`, 活跃节点状态;当行为被触发,需要被突出显示的节点和边都会附带此状态,默认值为 `active`;可以与 graph 实例的 `nodeStyle` 和 `edgeStyle` 结合实现丰富的视觉效果。
- `inactiveState: 'inactive'`,非活跃节点状态,不需要被突出显示的节点和边都会附带此状态,默认值为 `inactive`;可以与 graph 实例的 `nodeStyle` 和 `edgeStyle` 结合实现丰富的视觉效果;
- 3.1.2 `resetSelected`高亮相连节点时是否重置已经选中的节点默认为false即选中的节点状态不会被 `activate-relations` 覆盖。
<br />**默认配置**<br />
```javascript
const graph = new G6.Graph({
modes: {
default: [ 'activate-relations' ]
}
})
```
默认情况下,选中的节点状态,在操作完以后仍然会保持选中状态。<br />![3.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570783971145-6588e49f-79d7-40b4-aa66-3308f060f2b4.gif#align=left&display=inline&height=542&name=3.gif&originHeight=542&originWidth=610&search=&size=358920&status=done&width=610)
**配置参数**
```javascript
const graph = new G6.Graph({
modes: {
default: [
{
type: 'activate-relations',
resetSelected: true
}
]
}
})
```
配置 `resetSelected` 参数为 `true` 后,交互后会重置节点的选择状态。
![3.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570784093933-beb50a11-eef7-4076-a05c-5723be7e7e1d.gif#align=left&display=inline&height=542&name=3.gif&originHeight=542&originWidth=610&search=&size=142174&status=done&width=610)
<a name="HUu9U"></a>
### brush-select
- 含义:拖动框选节点;
- `type: 'brush-select'`
- 参数:
- `brushStyle`:拖动框选框的样式;
- `onSelect(nodes)`:选中节点时的回调,参数 `nodes` 表示选中的节点;
- `onDeselect(nodes)`:取消选中节点时的回调,参数 `nodes` 表示取消选中的节点;
- `brushStyle`:框选时样式的配置项,包括 `fill`、`fillOpacity`、`stroke` 和 `lineWidth` 四个属性;
- `selectedState`:选中的状态,默认值为 `'selected'`
- `includeEdges`:框选过程中是否选中边,默认为 `true`,用户配置为 `false` 时,则不选中边;
- 3.1.2 `trigger`:触发框选的动作,默认为 `'shift'`,即用户按住 Shift 键拖动就可以进行框选操作,可配置的的选项为: `'shift'`、`'ctrl' / 'control'`、`'alt'` 和 `'drag'` ,不区分大小写:
- `'shift'`:按住 Shift 键进行拖动框选;
- `'ctrl' / 'control'`:按住 Ctrl 键进行拖动框选;
- `'alt'`:按住 Alt 键进行拖动框选;
- 风险 `'drag'`:不需要按任何键,进行拖动框选,如果同时配置了 `drag-canvas`,则会与该选项冲突。
**默认配置**
```javascript
const graph = new G6.Graph({
modes: {
default: [ 'brush-select' ]
}
})
```
默认情况下,按住 Shift 键进行框选,选中节点的同时,也会选中边。<br />![3.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570779252901-1efaccf6-a268-47a6-8db9-f63c82d355fe.gif#align=left&display=inline&height=542&name=3.gif&originHeight=542&originWidth=610&search=&size=188323&status=done&width=610)
**配置参数**
```javascript
const graph = new G6.Graph({
modes: {
default: [
{
type: 'brush-select',
trigger: 'ctrl',
includeEdges: false
}
]
}
})
```
上面的配置,按住 Ctrl 键,进行框选,框选过程中不会选中边。<br />![3.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570779434063-6bf4fe39-88c8-44c2-a25d-6b8980db4a39.gif#align=left&display=inline&height=370&name=3.gif&originHeight=542&originWidth=610&search=&size=115882&status=done&width=416)
**配置冲突**
```javascript
const graph = new G6.Graph({
modes: {
default: [ 'drag-canvas',
{
type: 'brush-select',
trigger: 'drag'
}
]
}
})
```
当用户配置 `brush-select``trigger``drag`,同时又配置了 `drag-canvas` 时,在交互上面会出现冲突的情况。<br />![3.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570779665370-63bb8a65-f4e3-4a05-8c42-21b2e79b6b76.gif#align=left&display=inline&height=412&name=3.gif&originHeight=542&originWidth=610&search=&size=559913&status=done&width=464)
可以看到,在拖动过程中也出现了框选的情况,这种情况很显然不是我们期望的效果,除过使用 `brush-select ``trigger` 参数避免这种冲突外,我们还可以通过下面的方式来实现:
```javascript
const graph = new G6.Graph({
modes: {
default: [ 'drag-canvas' ],
brush: [
{
type: 'brush-select',
trigger: 'drag'
}
]
}
})
```
上面这种方式是使用不同的 mode 来区分mode 可以达到使用相同交互动作而产生不同的效果,更多关于 mode 的内容请参数 [G6 中的 Mode 文档](https://www.yuque.com/antv/g6/g6-mode)。
使用 mode 区分,默认情况下使用的是 `drag-canvas`,但用户需要切换到框选时,通过 `graph.setModel('brush')` 即可实现,此时同样的交互产生的就是框选的效果。
<a name="AYLPq"></a>
### collapse-expand
- 含义:只适用于树图,展开或收起节点;
- `type: 'collapse-expand'`
- 参数:
- `trigger`:收起和展开树图的方式,支持`click`和`dblclick`两种方式,默认为`click`
- `onChange`:收起或展开的回调函数,警告 `3.1.2 `版本中将移除。
<a name="nTWyy"></a>
**用法**
```javascript
const graph = new G6.TreeGraph({
modes: {
default: [{
type: 'collapse-expand',
trigger: 'click',
onChange(item, collapsed) {
const data = item.get('model').data;
data.collapsed = collapsed;
return true;
}
}, 'drag-canvas', 'zoom-canvas']
}
});
```
<a name="7tpo7"></a>
### collapse-expand-group
- 含义:收起和展开群组;
- `type'collapse-expand-group'`
- 参数:
- 3.1.2 trigger收起和展开节点分组的方式支持`click`和`dblclick`两种方式,默认为`dblclick`
**默认配置**
```javascript
const graph = new G6.Graph({
modes: {
default: [ 'collapse-expand-group' ]
}
})
```
**配置参数**<br />配置 `trigger` 参数为 **`click`** 后,单击节点分组即可收起或展开分组。
```javascript
const graph = new G6.Graph({
modes: {
default: [
{
type: 'collapse-expand-group',
trigger: 'click'
}
]
}
})
```
![3.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570785874686-a7333f95-e8d3-45a7-873e-8ee56c3b4b21.gif#align=left&display=inline&height=542&name=3.gif&originHeight=542&originWidth=610&search=&size=57719&status=done&width=610)
<a name="6X4y5"></a>
### drag-group
3.1.0
- 含义:拖动节点分组;
- `type: 'drag-group'`
- 参数:
- `delegateStyle`:拖动节点分组时 `delegate` 的样式。
**默认配置**
```javascript
const graph = new G6.Graph({
modes: {
default: [ 'drag-group' ]
}
})
```
<a name="UcuYD"></a>
### drag-node-with-group
3.1.0
- 含义:拖动节点分组中的节点;
- `type'drag-node-with-group'`
- 参数:
- `delegateStyle`:拖动节点分组时 `delegate` 的样式;
- `maxMultiple`
- `minMultiple`
**默认配置**
```javascript
const graph = new G6.Graph({
modes: {
default: [ 'drag-node-with-group' ]
}
})
```

View File

@ -0,0 +1,296 @@
---
title: 内置的边
order: 3
---
G6 提供了 9 种内置边:
- line直线不支持控制点
- polyline折线支持多个控制点
- arc圆弧线
- quadratic二阶贝塞尔曲线
- cubic三阶贝塞尔曲线
- cubic-vertical垂直方向的三阶贝塞尔曲线不考虑用户从外部传入的控制点
- cubic-horizontal水平方向的三阶贝塞尔曲线不考虑用户从外部传入的控制点
- loop自环。
这些内置边的默认样式分别如下图所示。<br />
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1570858853371-d9c7fea4-5e7b-42e1-a2f4-559a70298149.png#align=left&display=inline&height=135&name=image.png&originHeight=270&originWidth=1768&search=&size=74956&status=done&width=884' width='750' height='200' />
<a name="rETE1"></a>
# 内置边类型说明
下面表格中显示了内置的各类边,同时对一些特殊的字段进行了说明:
| 名称 | 描述 | |
| --- | --- | --- |
| line | 连接两个节点的直线:<br />- controlPoints 不生效<br />- 更多配置详见 line 边的配置<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570858805015-2171552a-56fc-44f9-a8d0-608de6aeb3f8.png#align=left&display=inline&height=36&name=image.png&originHeight=72&originWidth=210&search=&size=6061&status=done&width=105) |
| polyline | 多段线段构成的折线,连接两个端点:<br />- controlPoints 表示所有线段的拐点,不指定时根据 [A* 算法](https://yuque.alibaba-inc.com/antv/blog/polyline-edges-with-border-radius)自动生成折线<br />- 更多配置详见 polyline 边的配置<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570858897304-9b5e3045-4b8c-4e84-8373-7fda9ca2193a.png#align=left&display=inline&height=105&name=image.png&originHeight=210&originWidth=222&search=&size=12334&status=done&width=111) |
| arc | 连接两个节点的一段圆弧:<br />- controlPoints 不生效<br />- 使用 curveOffset 指定弧的弯曲程度,其正负影响弧弯曲的方向<br />- 更多配置详见 arc 边的配置<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570858921616-3dc5034d-ede0-425f-874b-620af6fe2dc9.png#align=left&display=inline&height=49&name=image.png&originHeight=98&originWidth=218&search=&size=8131&status=done&width=109) |
| quadratic | 只有一个控制点的曲线:<br />- controlPoints 不指定时,会默认线的一半处弯曲<br />- 更多配置详见 quadratic 边的配置<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570858940562-cea717dc-c0be-4bd1-af07-0f71e22f9243.png#align=left&display=inline&height=48&name=image.png&originHeight=96&originWidth=214&search=&size=8780&status=done&width=107) |
| cubic | 有两个控制点的曲线:<br />- controlPoints 不指定时,会默认线的 1/3, 2/3 处弯曲<br />- 更多配置详见 cubic 边的配置<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570858972322-2ba56d44-bd65-4fbb-9de2-a0c4bbbc8e8d.png#align=left&display=inline&height=36&name=image.png&originHeight=72&originWidth=216&search=&size=8066&status=done&width=108) |
| cubic-vertical | 垂直方向的三阶贝塞尔曲线,不考虑用户从外部传入的控制点 | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570858985655-b18e4465-0534-4dbf-a097-460a967d1100.png#align=left&display=inline&height=109&name=image.png&originHeight=218&originWidth=222&search=&size=15336&status=done&width=111) |
| cubic-horizontal | 水平方向的三阶贝塞尔曲线,不考虑用户从外部传入的控制点 | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570858999282-e9e4d9c1-f2da-4804-975f-d4abed62933f.png#align=left&display=inline&height=114&name=image.png&originHeight=228&originWidth=206&search=&size=16769&status=done&width=103) |
| loop | 自环。更多配置详见 arc 边的配置 | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570859007824-5b9c3023-9851-4bda-917b-3216811d2e45.png#align=left&display=inline&height=56&name=image.png&originHeight=112&originWidth=76&search=&size=6558&status=done&width=38) |
<a name="NvG16"></a>
# 边的通用属性
所有内置的边支持的通用属性:
| 名称 | 是否必须 | 类型 | 备注 |
| --- | --- | --- | --- |
| id | false | String | 边编号 |
| source | true | String | Number | 起始点 id |
| target | true | String | 结束点 id |
| shape | false | String | 边图形,默认为 'line' |
| sourceAnchor | false | Number | 边的起始节点上的锚点的索引值 |
| targetAnchor | false | Number | 边的终止节点上的锚点的索引值 |
| style | false | Object | 边的样式属性 |
| label | false | String | 文本文字,如果没有则不会显示 |
| labelCfg | false | Object | 文本配置项 |
<a name="FqvB0"></a>
### 样式属性 style
Object 类型。通过 `style` 配置来修改边的颜色、线宽等属性。下表是 `style` 对象中常用的配置项:
| 名称 | 是否必须 | 类型 | 备注 |
| --- | --- | --- | --- |
| stroke | false | String | 边的颜色 |
| lineWidth | false | Number | 边宽度 |
| lineAppendWidth | false | Number | 边响应鼠标事件时的检测宽度,当 `lineWidth` 太小而不易选中时,可以通过该参数提升击中范围 |
| endArrow | false | Boolean | 边的结束端是否有箭头 |
| strokeOpacity | false | Number | 边透明度 |
| shadowColor | false | String | 阴影颜色 |
| shadowBlur | false | Number | 阴影范围 |
| shadowOffsetX | false | Number | 阴影 x 方向偏移量 |
| shadowOffsetX | false | Number | 阴影 y 方向偏移量 |
| ... | | | |
下面代码演示在实例化图时全局配置方法中配置 `style`
```javascript
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
defaultEdge: {
// ... 其他属性
style: {
stroke: '#eaff8f',
lineWidth: 5,
// ... 其他属性
}
}
})
```
<a name="UMA2n"></a>
### 标签文本 label 及其配置 labelCfg
`label` String 类型。标签文本的文字内容。<br />`labelCfg` Object 类型。配置标签文本。下面是 `labelCfg` 对象中的常用配置项:
| 名称 | 是否必须 | 类型 | 备注 |
| --- | --- | --- | --- |
| refX | false | Number | 标签在 x 方向的偏移量 |
| refY | false | Number | 标签在 y 方向的偏移量 |
| position | false | String | 文本相对于边的位置,目前支持的位置有: `start``middle`, `end`。默认为`middle`。 |
| autoRotate | false | Boolean | 标签文字是否跟随边旋转,默认 `false` |
| style | false | Object | 标签的样式属性 |
上表中的标签的样式属性 `style` 的常用配置项如下: 
| 名称 | 是否必须 | 类型 | 备注 |
| --- | --- | --- | --- |
| fill | false | String | 文本颜色 |
| stroke | false | String | 文本描边颜色 |
| lineWidth | false | Number | 文本描边粗细 |
| opacity | false | Number | 文本透明度 |
| font | false | String | 文本内容的当前字体属性 |
| fontSize | false | Number | 文本字体大小 |
| ... | | | |
下面代码演示在实例化图时全局配置方法中配置 `label` 和 `labelCfg`
```javascript
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
defaultEdge: {
// ... 其他属性
label: 'edge-label',
labelCfg: {
refY: -10,
refX: 60
}
}
})
```
<a name="mZxA3"></a>
# 边的配置方法
配置边的方式有三种:实例化图时全局配置,在数据中动态配置,使用 `graph.edge(edgeFn)` 函数配置。这几种配置方法可以同时使用,优先级:
使用 graph.edge(edgeFn) 配置 > 数据中动态配置 > 实例化图时全局配置
即有相同的配置项时,优先级高的方式将会覆盖优先级低的。
<a name="Tu5VB"></a>
## 实例化图时全局配置
用户在实例化 Graph 时候可以通过 `defaultEdge` 配置边,这里的配置是全局的配置,将会在所有边上生效。
```javascript
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
defaultEdge: {
shape: 'line',
// 其他配置
}
})
```
<a name="fnVk4"></a>
## 在数据中动态配置
如果需要使不同边有不同的配置,可以将配置写入到边数据中。这种配置方式可以通过下面代码的形式直接写入数据,也可以通过遍历数据的方式写入。
```javascript
const data = {
nodes: [
... // 节点
],
edges: [{
source: 'node0',
target: 'node1'
shape: 'polyline',
... // 其他配置
style: {
... // 样式属性,每种边的详细样式属性参见各边文档
}
},{
source: 'node1',
target: 'node2'
shape: 'cubic',
... // 其他配置
style: {
... // 样式属性,每种边的详细样式属性参见各边文档
}
},
... // 其他边
]
}
```
<a name="wt5Si"></a>
## 使用 graph.edge(edgeFn) 配置
该方法可以为不同边进行不同的配置。<br />提示:
- 该方法必须**在 render 之前调用**,否则不起作用;
- 由于该方法优先级最高,将覆盖其他地方对边的配置,这可能将造成一些其他配置不生效的疑惑;
- 该方法在增加元素、更新元素时会被调用,如果数据量大、每条边上需要更新的内容多时,可能会有性能问题。
```javascript
// const data = ...
// const graph = ...
graph.edge((edge) => {
return {
id: edge.id,
shape: 'polyline',
style: {
fill: 'steelblue'
}
}
});
graph.data(data);
graph.render();
```
<a name="6IzVM"></a>
# 实例演示
```javascript
const data = {
nodes: [
{id: '1', x: 50, y: 50, size: 20},
{id: '2', x: 150, y: 50, size: 20},
{id: '3', x: 200, y: 50, size: 20},
{id: '4', x: 300, y: 130, size: 20},
{id: '5', x: 350, y: 50, size: 20},
{id: '6', x: 450, y: 50, size: 20},
{id: '7', x: 500, y: 50, size: 20},
{id: '8', x: 600, y: 50, size: 20},
{id: '9', x: 650, y: 50, size: 20},
{id: '10', x: 750, y: 50, size: 20},
{id: '11', x: 800, y: 50, size: 20},
{id: '12', x: 900, y: 150, size: 20},
{id: '13', x: 950, y: 50, size: 20},
{id: '14', x: 1050, y: 150, size: 20},
{id: '15', x: 1100, y: 50, size: 20},
],
edges: [
{source: '1', target: '2', shape: 'line', label: 'line'},
{source: '3', target: '4', shape: 'polyline', label: 'polyline'},
{source: '5', target: '6', shape: 'arc', label: 'arc'},
{source: '7', target: '8', shape: 'quadratic', label: 'quadratic'},
{source: '9', target: '10', shape: 'cubic', label: 'cubic'},
{source: '11', target: '12', shape: 'cubic-vertical', label: 'cubic-vertical'},
{source: '13', target: '14', shape: 'cubic-horizontal', label: 'cubic-horizontal'},
{source: '15', target: '15', shape: 'loop', label: 'loop'}
]
}
const graph = new G6.Graph({
container: 'mountNode',
width: 1500,
height: 300,
linkCenter: true // 使边连入节点的中心
});
graph.data(data);
graph.render();
```
显示结果:<br />
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1570858853371-d9c7fea4-5e7b-42e1-a2f4-559a70298149.png#align=left&display=inline&height=135&name=image.png&originHeight=270&originWidth=1768&search=&size=74956&status=done&width=884' width='750' height='200' />
<a name="WHNad"></a>
## 调整边的样式
可以在边上添加文本,修改边的样式。下面演示将配置写入数据的方式配置边。使用下面代码替换上面代码中的 9-10、11-12 两条边数据,修改这两条边的样式和其文本。
```javascript
// 使 9-10 的 cubic 边文本下移 15 像素
{
source: '9',
target: '10',
shape: 'cubic',
label: 'cubic',
labelCfg: {
refY: -15 // refY 默认是顺时针方向向下,所以需要设置负值
}
},
// 设置 11-12 的 cubic-vertical 边的颜色、虚线、粗细,并设置文本样式、随边旋转
{
source: '11',
target: '12',
shape: 'cubic-vertical',
color: '#722ed1', // 边颜色
size: 5, // 边粗细
style: {
lineDash: [2, 2] // 虚线边
},
label: 'cubic-vertical',
labelCfg: {
position: 'center', // 其实默认就是 center这里写出来便于理解
autoRotate: true, // 使文本随边旋转
style: {
stroke: 'white', // 给文本添加白边和白色背景
lineWidth: 5, // 文本白边粗细
fill: '#722ed1', // 文本颜色
}
}
}
```
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1570859444095-76fc5c73-0444-4636-b2a2-57eb1786987c.png#align=left&display=inline&height=138&name=image.png&originHeight=276&originWidth=1782&search=&size=81146&status=done&width=891' width='750' height='200' />
<a name="dmJ1b"></a>
# 相关阅读
- [边的状态样式](https://www.yuque.com/antv/g6/fqnn9w) —— 交互过程中的样式变化。

View File

@ -0,0 +1,314 @@
---
title: 内置的节点
order: 2
---
G6 默认提供的节点是一个基础图形加一个文本图形的实现。可选的内置节点包括 circlerectellipsediamondtrianglestarimagemodelRect这些内置节点的默认样式分别如下图所示。<br />
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1570852701188-ea33cdb0-71c4-4d53-8827-01912934e7de.png#align=left&display=inline&height=103&name=image.png&originHeight=206&originWidth=1528&search=&size=135825&status=done&width=764' width='750' height='100'>
<a name="rETE1"></a>
## 内置节点类型说明
下面表格中显示了内置的各类节点,同时对一些特殊的字段进行了说明:
| 名称 | 描述 | 默认示例 |
| --- | --- | --- |
| circle | 圆形:<br />- `size` 是单个数字,表示直径<br />- 圆心位置对应节点的位置<br />- `color` 字段默认在描边上生效<br />- 标签文本默认在节点中央<br />- 更多字段见 [circle 节点的配置]()<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570852503218-902e8221-e7e7-49c5-911f-ec3cabe7e04f.png#align=left&display=inline&height=56&name=image.png&originHeight=112&originWidth=110&search=&size=13270&status=done&width=55) |
| rect | 矩形:<br />- `size` 是数组,例如:[100, 50]<br />- 矩形的中心位置是节点的位置,而不是左上角<br />- `color` 字段默认在描边上生效<br />- 标签文本默认在节点中央<br />- 更多字段见 [rect 节点的配置](https://www.yuque.com/antv/g6/vdqpdt#qWf35)<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570852565858-345455f4-2ddb-4c40-9c8a-67e337a9e746.png#align=left&display=inline&height=38&name=image.png&originHeight=76&originWidth=178&search=&size=5514&status=done&width=89) |
| ellipse | 椭圆:<br />- `size` 是数组,表示椭圆的长和宽<br />- 椭圆的圆心是节点的位置<br />- `color` 字段默认在描边上生效<br />- 标签文本默认在节点中央<br />- 更多字段见 [ellipse 节点的配置](https://www.yuque.com/antv/g6/pxt157#qWf35)<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570852588313-3dcaee5b-b2aa-45d6-99be-6f4c56d494f1.png#align=left&display=inline&height=63&name=image.png&originHeight=126&originWidth=216&search=&size=19099&status=done&width=108) |
| diamond | 菱形:<br />- `size` 是数组,表示菱形的长和宽<br />- 菱形的中心位置是节点的位置<br />- `color` 字段默认在描边上生效<br />- 标签文本默认在节点中央<br />- 更多字段见 [diamond 节点的配置](https://www.yuque.com/antv/g6/ilnhgt#qWf35)<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570852597814-e4e4585a-fbe0-41a4-af92-a2de2f837220.png#align=left&display=inline&height=92&name=image.png&originHeight=184&originWidth=178&search=&size=20859&status=done&width=89) |
| triangle | 三角形:<br />- `size` 是数组,表示三角形的长和高<br />- 三角形的中心位置是节点的位置<br />- `color` 字段默认在描边上生效<br />- 标签文本默认在节点下方<br />- 更多字段见 [triangle 节点的配置](https://www.yuque.com/antv/g6/sfcm38#qWf35)<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570852606815-2f8526a8-1349-452e-a9f7-dccb37be57f9.png#align=left&display=inline&height=78&name=image.png&originHeight=156&originWidth=126&search=&size=11213&status=done&width=63) |
| star | 星形:<br />- `size` 是单个数字,表示星形的大小<br />- 星星的中心位置是节点的位置<br />- `color` 字段默认在描边上生效<br />- 标签文本默认在节点中央<br />- 更多字段见 [star 节点的配置](https://www.yuque.com/antv/g6/gwn2mq#qWf35)<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570852618082-bfe59c69-08ce-4538-be49-ee72984c4830.png#align=left&display=inline&height=99&name=image.png&originHeight=198&originWidth=194&search=&size=24192&status=done&width=97) |
| image | 图片:<br />- `size` 是数组,表示图片的长和宽<br />- 图片的中心位置是节点位置<br />- `img` 图片的路径,也可以在 `style` 里面设置<br />- `color` 字段不生效<br />- 标签文本默认在节点下方<br />- 更多字段见 [image 节点的配置](https://www.yuque.com/antv/g6/ng8a0q#qWf35)<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570852649476-7c6c4aeb-8172-4a69-a6a3-b6cd24d7ea46.png#align=left&display=inline&height=67&name=image.png&originHeight=134&originWidth=112&search=&size=16354&status=done&width=56) |
| modelRect | 菱形:<br />- `size` 是数组,表示菱形的长和宽<br />- 菱形的中心位置是节点的位置<br />- `color` 字段默认在描边上生效<br />- 标签文本默认在节点中央<br />- 若有 `description` 字段则显示在标签文本下方显示 `description` 内容<br />- 更多字段见 [modelRect 节点的配置](https://www.yuque.com/antv/g6/sdfcpq#qWf35)<br /> | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570852629046-62c03494-82ac-4e76-b3b4-9ca242d9459a.png#align=left&display=inline&height=74&name=image.png&originHeight=148&originWidth=324&search=&size=15378&status=done&width=162)<br /> ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570852931313-42f193db-c9f0-4098-af7f-6c5eaf32923a.png#align=left&display=inline&height=69&name=image.png&originHeight=138&originWidth=316&search=&size=17261&status=done&width=158) |
<a name="NvG16"></a>
## 节点的通用属性
所有内置的节点支持的通用属性:
| 名称 | 是否必须 | 类型 | 备注 |
| --- | --- | --- | --- |
| id | true | String | 节点编号 |
| x | false | Number | x 坐标 |
| y | false | Number | y 坐标 |
| shape | false | String | 节点图形,默认为 `'circle'` |
| size | false | Number | Array | 节点的大小 |
| anchorPoints | false | Array | 指定边连如节点的连接点的位置(相对于该节点而言),可以为空。例如: `[0, 0]`,代表节点左上角的锚点,`[1, 1]`,代表节点右下角的锚点。 |
| style | false | Object | 节点的样式属性 |
| label | false | String | 文本文字 |
| labelCfg | false | Object | 文本配置项 |
<a name="FqvB0"></a>
#### 样式属性 style
Object 类型。通过 `style` 配置来修改节点的填充色、边框颜色、阴影等属性。下表是 `style` 对象中常用的配置项:
| 名称 | 是否必须 | 类型 | 备注 |
| --- | --- | --- | --- |
| fill | false | String | 节点填充色 |
| stroke | false | String | 节点的描边颜色 |
| lineWidth | false | Number | 描边宽度 |
| shadowColor | false | String | 阴影颜色 |
| shadowBlur | false | Number | 阴影范围 |
| shadowOffsetX | false | Number | 阴影 x 方向偏移量 |
| shadowOffsetX | false | Number | 阴影 y 方向偏移量 |
| ... | | | |
下面代码演示在实例化图时全局配置方法中配置 `style`
```javascript
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
defaultNode: {
// ... 其他属性
style: {
fill: '#steelblue',
stroke: '#eaff8f',
lineWidth: 5,
// ... 其他属性
}
}
})
```
<a name="UMA2n"></a>
#### 标签文本 label 及其配置 labelCfg
`label` String 类型。标签文本的文字内容。<br />`labelCfg` Object 类型。配置标签文本。下面是 `labelCfg` 对象中的常用配置项:
| 名称 | 是否必须 | 类型 | 备注 |
| --- | --- | --- | --- |
| position | false | String | 文本相对于节点的位置,目前支持的位置有:  `'center'``'top'``'left'``'right'``'bottom'`。默认为 `'center'`。 |
| offset | false | Number | Array | 文本的偏移,在 `'top'``'left'``'right'``'bottom'` 位置上的偏移量 |
| style | false | Object | 标签的样式属性 |
上表中的标签的样式属性 `style` 的常用配置项如下: 
| 名称 | 是否必须 | 类型 | 备注 |
| --- | --- | --- | --- |
| fill | false | String | 文本颜色 |
| stroke | false | String | 文本描边颜色 |
| lineWidth | false | Number | 文本描边粗细 |
| opacity | false | Number | 文本透明度 |
| font | false | String | 文本内容的当前字体属性 |
| fontSize | false | Number | 文本字体大小 |
| ... | | | |
下面代码演示在实例化图时全局配置方法中配置 `label` 和 `labelCfg`
```javascript
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
defaultNode: {
// ... 其他属性
label: 'node-label',
labelCfg: {
position: 'bottom',
offset: [10, 10, 10, 10],
style: {
fill: '#666'
}
}
}
})
```
<a name="n74sg"></a>
## 节点的配置方法
配置节点的方式有三种:实例化图时全局配置,在数据中动态配置,使用 `graph.node(nodeFn)` 函数配置。这几种配置方法可以同时使用,优先级:
使用 graph.node(nodeFn) 配置 > 数据中动态配置 > 实例化图时全局配置
即有相同的配置项时,优先级高的方式将会覆盖优先级低的。
<a name="Tu5VB"></a>
### 实例化图时全局配置
用户在实例化 Graph 时候可以通过 `defaultNode` 配置节点,这里的配置是全局的配置,将会在所有节点上生效。
```javascript
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
defaultNode: {
shape: 'circle',
// 其他配置
}
})
```
<a name="fnVk4"></a>
### 在数据中动态配置
如果需要为不同节点进行不同的配置,可以将配置写入到节点数据中。这种配置方式可以通过下面代码的形式直接写入数据,也可以通过遍历数据的方式写入。
```
const data = {
nodes: [{
id: 'node0',
size: 100,
shape: 'rect',
... // 其他属性
style: {
... // 样式属性,每种节点的详细样式属性参见各节点文档
}
},{
id: 'node1',
size: [50, 100],
shape: 'ellipse',
... // 其他属性
style: {
... // 样式属性,每种节点的详细样式属性参见各节点文档
}
},
... // 其他节点
],
edges: [
... // 边
]
}
```
<a name="wt5Si"></a>
### 使用 graph.node(nodeFn) 配置
该方法可以为不同节点进行不同的配置。<br />提示:
- 该方法必须**在 render 之前调用**,否则不起作用;
- 由于该方法优先级最高,将覆盖其他地方对节点的配置,这可能将造成一些其他配置不生效的疑惑;
- 该方法在增加元素、更新元素时会被调用,如果数据量大、每个节点上需要更新的内容多时,可能会有性能问题。
```
// const data = ...
// const graph = ...
graph.node((node) => {
return {
id: node.id,
shape: 'rect',
style: {
fill: 'blue'
}
}
});
graph.data(data);
graph.render();
```
## 实例演练
```
const data = {
nodes: [{
x: 100,
y: 100,
shape: 'circle',
label: 'circle',
},{
x: 200,
y: 100,
shape: 'rect',
label: 'rect',
},{
id: 'node-ellipse',
x: 330,
y: 100,
shape: 'ellipse',
label: 'ellipse'
},{
id: 'node-diamond',
x: 460,
y: 100,
shape: 'diamond',
label: 'diamond'
},{
id: 'node-triangle',
x: 560,
y: 100,
//size: 80,
shape: 'triangle',
label: 'triangle'
},{
id: 'node-star',
x: 660,
y: 100,
//size: [60, 30],
shape: 'star',
label: 'star'
},{
x: 760,
y: 100,
size: 50,
shape: 'image',
img: 'https://gw.alipayobjects.com/zos/rmsportal/XuVpGqBFxXplzvLjJBZB.svg',
label: 'image',
},{
id: 'node-modelRect',
x: 900,
y: 100,
shape: 'modelRect',
label: 'modelRect'
}]
};
const graph = new G6.Graph({
container: 'mountNode',
width: 1500,
height: 300
});
graph.data(data);
graph.render();
```
显示结果:
<br />
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1570866064078-162301ab-e5c6-41c0-8009-030aba5ac216.png#align=left&display=inline&height=98&name=image.png&originHeight=196&originWidth=1530&search=&size=123948&status=done&width=765' width='750' height='100'>
- triangle 节点和 image 节点的标签文本默认位置为:`position:'bottom'` ,其他节点文本的默认位置都为:`position: 'center'`
<a name="go086"></a>
### 调整节点配置
下面演示通过将配置写入数据的方式,调整 `id``'node-ellipse'` 的椭圆节点的文本位置,颜色和样式。将下面代码替换上面代码中 `id` 为 `'node-ellipse'` 的节点数据即可生效。
```
{
id: 'node-ellipse',
x: 330,
y: 100,
shape: 'ellipse',
size: [60, 30],
label: 'ellipse',
labelCfg: {
position: 'bottom',
offset: 5
},
style: {
fill: '#fa8c16',
stroke: '#000',
lineWidth: 2
}
}
```
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1570866208293-efddc382-b519-421a-a50c-20a5b6651995.png#align=left&display=inline&height=110&name=image.png&originHeight=220&originWidth=1556&search=&size=126345&status=done&width=778' width='750' height='100'>
再为 `id``'node-modelRect'` 的 modelRect 节点添加描述文字,使用下面代码替换 `id` 为 `'node-modelRect'` 的节点数据即可得到带有内容为 '描述文本xxxxxxxxxxx' 的 modelRect 节点。
```
{
id: 'node-modelRect',
x: 900,
y: 100,
description: '描述文本xxxxxxxxxxx',
shape: 'modelRect',
label: 'modelRect'
}
```
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1570866381579-8296a2bb-9f23-45a5-b229-fe82b55a7a5b.png#align=left&display=inline&height=110&name=image.png&originHeight=220&originWidth=1524&search=&size=135905&status=done&width=762' width='750' height='100'>
<a name="dmJ1b"></a>
## 相关阅读
- [节点的状态样式](https://www.yuque.com/antv/g6/fqnn9w) —— 交互过程中的样式变化。

View File

@ -0,0 +1,115 @@
---
title: React 中使用 G6
order: 9
---
<a name="ubzSk"></a>
### 概述
G6是一个纯JS库不与任何框架耦合也就是可以在任何前端框架中使用如 React、Vue、Angular 等。由于我们内部绝大多数都是基于 React 技术栈的,所以我们也仅提供一个 G6 在 React 中使用的 Demo。
在 React 中使用 G6和在 HTML 中使用基本相同,唯一比较关键的区分就是在实例化 Graph 时,要**保证 DOM 容器渲染完成,并能获取到 DOM 元素**。
在 Demo 中,我们以一个简单的流程图为例,实现如下的效果。![demo.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570264721327-6afda2c1-2edf-4bb4-84dc-14f91f820d0c.gif#align=left&display=inline&height=545&name=demo.gif&originHeight=545&originWidth=1207&search=&size=166134&status=done&width=1207)
<a name="7sO3b"></a>
### 功能及实现
Demo 包括以下功能点:
- 自定义节点;
- 自定义边;
- 节点的 tooltip
- 边的 tooltip
- 节点上面弹出右键菜单;
- tooltip 及 ContextMenu 如何渲染自定义的 React 组件。
在 React 中,通过 `**ReactDOM.findDOMNode(ref.current)**`** **获取到真实的 DOM 元素。
```javascript
import React, { useEffect, useState } from 'react';
import ReactDOM from 'react-dom';
import { data } from './data';
import G6 from '@antv/g6';
export default function() {
const ref = React.useRef(null)
let graph = null
useEffect(() => {
if(!graph) {
graph = new G6.Graph({
container: ReactDOM.findDOMNode(ref.current),
width: 1200,
height: 800,
modes: {
default: ['drag-canvas']
},
layout: {
type: 'dagre',
direction: 'LR'
},
defaultNode: {
shape: 'node',
labelCfg: {
style: {
fill: '#000000A6',
fontSize: 10
}
},
style: {
stroke: '#72CC4A',
width: 150
}
},
defaultEdge: {
shape: 'polyline'
}
})
}
graph.data(data)
graph.render()
}, [])
return (
<div ref={ref}></div>
);
}
```
<a name="CahRL"></a>
### G6中渲染React组件
节点和边的 tooltip、节点上的右键菜单G6 中内置的很难满足样式上的需求,这个时候我们就可以通过渲染自定义的 React 组件来实现。Tooltip 和 ContextMenu 都是普通的 React 组件样式完全由用户控制。交互过程中在G6 中需要做的事情就是确定何时渲染组件,以及渲染到何处。在 G6 中获取到是否渲染组件的标识值和渲染位置后,这些值就可以使用 React state 进行管理,后续的所有工作就全部由 React 负责了。
```javascript
// 边tooltip坐标
const [showNodeTooltip, setShowNodeTooltip] = useState(false)
const [nodeTooltipX, setNodeToolTipX] = useState(0)
const [nodeTooltipY, setNodeToolTipY] = useState(0)
// 监听node上面mouse事件
graph.on('node:mouseenter', evt => {
const { item } = evt
const model = item.getModel()
const { x, y } = model
const point = graph.getCanvasByPoint(x, y)
setNodeToolTipX(point.x - 75)
setNodeToolTipY(point.y + 15)
setShowNodeTooltip(true)
})
// 节点上面触发mouseleave事件后隐藏tooltip和ContextMenu
graph.on('node:mouseleave', () => {
setShowNodeTooltip(false)
})
return (
<div ref={ref}>
{ showNodeTooltip && <NodeTooltips x={nodeTooltipX} y={nodeTooltipY} /> }
</div>
);
```
完整的 Demo 源码请👉戳[这里](https://github.com/baizn/g6-in-react)。
关于 G6 如何在 Vue 及 Angular 中使用,还望社区中有相关实践的同学能提供一些,供其他同学学习和参考,非常感谢!

View File

@ -15,7 +15,7 @@ order: 1
<a name="cRVfC"></a>
## 前提代码
本文的讲解将会基于下面这份内嵌 JavaScript 的 HTML 代码。该代码通过定义数据、实例化图、读取数据、渲染图等操作中完成了下图中简单的图:<br />
[image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571034737611-563c61e5-d3c0-407b-89fc-ca8c6fb97f66.png#align=left&display=inline&height=29&name=image.png&originHeight=148&originWidth=736&search=&size=20441&status=done&width=146)
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1571034737611-563c61e5-d3c0-407b-89fc-ca8c6fb97f66.png#align=left&display=inline&height=29&name=image.png&originHeight=148&originWidth=736&search=&size=20441&status=done&width=146' width='400' height='80' />
```html
<!DOCTYPE html>

View File

@ -0,0 +1,117 @@
---
title: G6 中的关键概念
order: 0
---
<a name="FVpps"></a>
## 图形 Shape
Shape 指 G6 中的图形、形状,它可以是圆形、矩形、路径等。它一般与 G6 中的节点、边相关。G6 中的每一种节点或边由一个或多个 Shape 组成。
例如下图(左)的节点包含了一个圆形图形;下图(中)的节点含有有一个圆形和一个文本图形;下图(右)的节点中含有 5 个圆形(蓝绿色的圆和上下左右四个锚点)、一个文本图形。但每种节点和边都会有自己的唯一关键图形 keyShape下图中三个节点的 keyShape 都是蓝绿色的圆keyShape 主要用于交互检测、样式随[状态](https://www.yuque.com/antv/g6/fqnn9w)自动更新等,见 [keyShape](#UNCAz)。<br />![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570860282365-a580467a-9843-4aa5-a016-d73dff38fc0a.png#align=left&display=inline&height=68&name=image.png&originHeight=136&originWidth=138&search=&size=14236&status=done&width=69)      ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570860291602-5729dfa6-4c25-4547-82f8-2d388422df67.png#align=left&display=inline&height=85&name=image.png&originHeight=170&originWidth=150&search=&size=16796&status=done&width=75)      ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1570859851766-0358416c-65d1-4637-93d1-e5cf12017bc8.png#align=left&display=inline&height=94&name=image.png&originHeight=188&originWidth=196&search=&size=24941&status=done&width=98)
> 只含有一个圆形图形的节点keyShape 是该圆形。含有圆形和文本图形的节点keyShape 是圆形。含有主要圆形、文本、上下左右四个小圆形的节点keyShape 是圆形。
G6 使用不同的 shape 及组合设计了多种内置的节点和边。G6 内置节点的有 'circle' 'rect''ellipse'...(详见 [内置节点](https://www.yuque.com/antv/g6/internal-node));内置边的有 'line''polyline''cubic'...(详见 [内置边](https://www.yuque.com/antv/g6/internal-edge))。
除了使用内置的节点和边外G6 还允许用户通过自己搭配和组合 Shape 进行节点和边的自定义,详见 [自定义节点](https://www.yuque.com/antv/g6/self-node) 和 [自定义边](https://www.yuque.com/antv/g6/self-edge)。
<a name="UNCAz"></a>
## KeyShape
如上所述,每一种节点和边都有一个唯一的关键图形 keyShape。keyShape 是在节点的 draw 方法中返回的图形对象,用于**确定节点的包围盒Bounding Box —— bboxx, y, width, height)** ,从而计算相关边的连入点(与相关边的交点)。若 keyShape 不同,节点与边的交点计算结果不同。 
<a name="IXt42"></a>
### 示例 
本例中的一个节点由一个 rect 图形和一个带灰色描边、填充透明的 circle 图形构成。
- 当节点的 keyShape 为 circle 时:
![2019-06-13.07.png](https://cdn.nlark.com/yuque/0/2019/png/244306/1561033286841-e52f2489-4c31-4235-9d3c-0dfcc95ff4c6.png#align=left&display=inline&height=145&name=%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202019-06-13%20%E4%B8%8A%E5%8D%8811.31.07.png&originHeight=166&originWidth=392&search=&size=8734&status=done&width=342)
- 当节点的 keyShape 为 rect 时:
![2019-06-13.png](https://cdn.nlark.com/yuque/0/2019/png/244306/1561033286856-823a0f11-a768-456f-b510-d823799d1bfe.png#align=left&display=inline&height=150&name=%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202019-06-13%20%E4%B8%8A%E5%8D%8811.31.56.png&originHeight=180&originWidth=432&search=&size=8968&status=done&width=359)
<a name="69UmU"></a>
## Shape 的生命周期
> 当用户需要[自定义节点](https://www.yuque.com/antv/g6/self-node)和[自定义边](https://www.yuque.com/antv/g6/self-edge)时,需要了解 Shape 的生命周期。使用内置节点和边则可以跳过这一部分内容。
从整体来看Shape 的生命周期分为:
- 初始化渲染;
- 更新;
- 操作;
- 销毁。
Shape 作为 Graph 上的核心元素,这几个阶段都需要考虑,但是销毁可以交给 Graph 来处理,所以在定义 Shape 时不需要考虑,仅需要考虑三个阶段即可:
- 绘制:从无到有的绘制 Shape 及文本;
- 更新:数据发生改变导致 Shape 及文本发生变化;
- 操作:给 Shape 添加状态selectedactive 等。
所以我们在设计自定义节点和边时,定义了三个方法,若需要自定义节点和边,需要有选择性地复写它们:
- `draw(cfg, group)`: 绘制,提供了绘制的配置项(数据定义时透传过来)和图形容器;
- `update(cfg, n)`: 更新,更新时的配置项(更新的字段和原始字段的合并)和节点对象;
- `setState(name, value, item)`: 设置节点状态。
关于自定义Shape更多的方法请[参考 Shape API 文档](https://www.yuque.com/antv/g6/shape-api)。
## anchorPoint
节点的连接点 anchorPoint 指的是边连入节点的相对位置即节点与其相关边的交点位置。anchorPoints 是一个二维数组,每一项表示一个连接点的位置,在一个[图形 shape](https://www.yuque.com/antv/g6/shape-crycle) 中连接点的位置如下图所示x 和 y 方向上范围都是 [0, 1]<br />
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1571036680989-45a97f57-c247-4408-8b38-37c1e0d6c8c7.png#align=left&display=inline&height=190&name=image.png&originHeight=654&originWidth=1364&search=&size=204253&status=done&width=396' width='600' height='300' />
节点中有了 anchorPoints 之后,相关边可以分别选择连入起始点、结束点的哪一个 anchorPoint。当需要在节点之间连多条线时这种机制能够使边的连入更美观。
边可以通过指定 `sourceAnchor``targetAnchor` 分别选择起始点、结束点的 anchorPoint。`sourceAnchor` 和 `targetAnchor` 取的值是相对应节点上 anchorPoints 数组的索引值。
下面数据演示了如何在节点上配置连接点、在边上指定连接点:
```javascript
const data = {
nodes: [
{
id: 'node1',
label: 'node1',
x: 100,
y: 200,
// 该节点可选的连接点集合,该点有两个可选的连接点
anchorPoints: [[0, 1], [0.5, 1]],
shape: 'rect'
},
{
id: 'node2',
label: 'node2',
x: 300,
y: 400,
// 该节点可选的连接点集合,该点有两个可选的连接点
anchorPoints: [[0.5, 0], [1, 0.5]],
shape: 'rect'
}
],
edges: [
{
source: 'node1',
target: 'node2',
// 该边连入 source 点的第 0 个 anchorPoint
sourceAnchor: 0,
// 该边连入 target 点的第 0 个 anchorPoint
targetAnchor: 0,
style: {
endArrow: true
}
},
{
source: 'node2',
target: 'node1',
// 该边连入 source 点的第 1 个 anchorPoint
sourceAnchor: 1,
// 该边连入 source 点的第 1 个 anchorPoint
targetAnchor: 1,
style: {
endArrow: true
}
}
]
}
```

View File

@ -0,0 +1,478 @@
---
title: 使用布局 Layout
order: 7
---
<a name="45oSN"></a>
## 简介
图布局是指图中节点的排布方式根据图的数据结构不同布局可以分为两类一般图布局、树图布局。G6 为这两类图都内置了一些常用的图布局算法。使用内置的图布局可以完成[布局的参数、方法、数据的切换](#FCFKL)等。
除了内置布局方法外,一般图布局还支持 [自定义布局](https://www.yuque.com/antv/g6/zpg5ty) 机制。
事实上G6 的布局是自由的,内置布局算法仅仅是操作了数据中节点的 `x``y` 值。因此,除了使用内置布局以及自定义的一般图布局外,用户还可以使用外部图布局算法,计算节点位置后赋值到数据中节点的 `x``y` 字段上G6 便可以根据该位置信息进行绘制。
本文将逐一介绍内置的布局算法,及其使用方式。
<a name="SNVtf"></a>
## G6 布局方法总览
<a name="yYuT9"></a>
### 一般图 Graph
- [Random Layout](#AIkrd):随机布局;
- [Force Layout](#B6ZYA):经典力导向布局;
- [Fruchterman Layout](#TirhH)Fruchterman 布局,一种力导布局;
- [Circular Layout](#0lVZj):环形布局;
- [Radial Layout](#lALX0):辐射状布局;
- [MDS Layout](#RBhhk):高维数据降维算法布局;
- [Dagre Layout](#RUeWF):层次布局;
- [Concentric Layout](#4JMfP):同心圆布局;
- [Grid Layout](#XG0RD):网格布局。
<a name="Zb2dL"></a>
### 树图 TreeGraph
- [CompactBox Layout](#AyYPj):紧凑树布局;
- [Dendrogram Layout](#sH1z0):树状布局(叶子节点布局对齐到同一层);
- [Intended Layout](#04ZZ5):缩进布局;
- [Mindmap Layout](#AOAs2):脑图布局。
<a name="a73ba"></a>
## 一般图 Graph
<a name="hNWmC"></a>
### 配置一般图布局
用户可以通过在实例化图时使用图的配置项 `layout` 指定布局方法。下面代码在实例化图时设置了布局方法为 `type: 'force'`,即经典力导向图布局。并设置了参数 `preventOverlap: true` 和 `nodeSize: 30`,表示希望节点不重叠。节点大小 `nodeSize` 用于算法中判断节点是否重叠,更多配置项见 [Graph 各布局的配置项](https://www.yuque.com/antv/g6/qopkkg#a73ba)。
```javascript
const graph = new G6.Graph({
... // 其他配置项
layout: { // Object可选布局的方法及其配置项默认为 random 布局。
type: 'force',
preventOverlap: true,
nodeSize: 30,
... // 其他配置
}
});
```
当实例化图时没有配置布局时:
- 若数据中节点有位置信息(`x` 和 `y`),则按照数据的位置信息进行绘制;
- 若数据中节点没有位置信息,则默认使用 Random Layout 进行布局。
<a name="MtaAB"></a>
### 一般图布局方法
图布局通用 API[Layout API](https://www.yuque.com/antv/g6/agbmu2)。
<a name="AIkrd"></a>
#### Random
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1571883164107-fc95c5f2-3461-409f-b176-e28ad87f89a7.png#align=left&display=inline&height=141&name=image.png&originHeight=562&originWidth=846&search=&size=187661&status=done&width=213' width='600' height='400'/>
<br />**描述**:随机布局。
<br />**API**[Random API](https://www.yuque.com/antv/g6/nrxlhg)
<br />**参数**
| 参数名 | 类型 | 示例 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| center | Array | [ 0, 0 ] | 图的中心 | 随机布局的中心 |
| width | Number | 300 | 图的宽 | |
| height | Number | 300 | 图的高 | |
<a name="B6ZYA"></a>
#### Force
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1571883178937-a961fd60-e3f0-478c-b5d3-8e326fe18e6c.png#align=left&display=inline&height=180&name=image.png&originHeight=596&originWidth=959&search=&size=71243&status=done&width=289' width='600' height='400' />
<br /> **描述**:经典力导向布局。
<br /> **API**[Force API](https://www.yuque.com/antv/g6/rllgdl)
<br /> **参数**:与 d3 的力导布局参数相对应。
| 参数名 | 类型 | 示例 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| center | Array | [ 0, 0 ] | 图的中心 | 随机布局的中心 |
| linkDistance | Number | Function | 示例1: 50 <br />示例2:<br />d => {<br />  // d 是一条边<br />  if (d.id === 'edge1') {<br />    return 100;<br />  }<br />  return 50;<br />} | 50 | 边长。可以使用回调函数的形式对不同对边定义不同边长如示例2 |
| nodeStrength | Number | Function | 示例1: -30 <br />示例2:<br />d => {<br />  // d 是一个节点<br />  if (d.id === 'node1') {<br />    return -100;<br />  }<br />  return -30;<br />} | null | 节点作用力正数代表节点之间的引力作用负数代表节点之间的斥力作用。可以使用回调函数的形式对不同对节点定义不同节点作用力如示例2 |
| edgeStrength | Number | 示例1: 1 <br />示例2:<br />d => {<br />  // d 是一个节点<br />  if (d.id === 'node1') {<br />    return 10;<br />  }<br />  return 1;<br />} | null | 边的作用力默认根据节点的出入度自适应。可以使用回调函数的形式对不同对节点定义不同边作用力如示例2 |
| preventOverlap | Boolean | false | false | 是否防止重叠,必须配合属性 `nodeSize` ,只有设置了与当前图节点大小相同的 `nodeSize` 值,才能够进行节点重叠的碰撞检测。若未设置 `nodeSize` ,则根据节点数据中的 `size` 进行碰撞检测。若二者都未设置,则默认以 10 为节点大小进行碰撞检测 |
| nodeSize | Array | Number | 20 | undefined | 节点大小(直径)。用于碰撞检测。<br />若不指定,则根据传入的数据节点中的 `size` 字段计算。若即不指定,节点中也没有 `size`,则默认大小为 10 |
| nodeSpacing<br /><br />3.1.6 后支持 | Number | Function | 示例 1 : 10<br />示例 2 : <br />d => {<br />  // d 是一个节点<br />  if (d.id === 'node1') {<br />    return 100;<br />  }<br />  return 10;<br />} | 0 | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1572589493571-733b149d-2887-4b75-bd22-a2808233d0d5.png#align=left&display=inline&height=115&name=image.png&originHeight=200&originWidth=378&search=&size=46987&status=done&width=217)<br />`preventOverlap` 为 `true` 时生效,防止重叠时节点边缘间距的最小值。可以是回调函数,为不同节点设置不同的最小间距,如示例 2 所示<br /> |
| alphaDecay | Number | 0.03 | 0.028 | 迭代阈值的衰减率。[0, 1]0.028 对应迭代书为 300 |
| alphaMin | Number | 0.03 | 0.001 | 停止迭代的阈值 |
| alpha | Number | 0.1 | 0.3 | 当前阈值 |
| collideStrength | Number | 0.8 | 1 | 防止重叠的力强度,[0, 1]。 |
| forceSimulation | Object | | null | 自定义 force 方法,若不指定,则使用 d3 的方法。 |
| onTick | Function | | {} | 每一次迭代的回调函数 |
| onLayoutEnd | Function | | {} | 布局完成后的回调函数 |
<a name="TirhH"></a>
#### Fruchterman
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1571883212048-50bef140-5a93-463a-a763-c8dcc907af2c.png#align=left&display=inline&height=200&name=image.png&originHeight=650&originWidth=686&search=&size=242098&status=done&width=211' width='600' height='500' />
<br />**描述**Fruchterman 布局,一种力导布局。
<br />**API**[Fruchterman API](https://www.yuque.com/antv/g6/vzqn07)
<br />**参数**
| 参数名 | 类型 | 示例 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| center | Array | [ 0, 0 ] | 图的中心 | 随机布局的中心 |
| maxIteration | Number | 1000 | 1000 | 最大迭代次数 |
| gravity | Number | 10 | 10 | 重力大小,影响布局的紧凑程度 |
| speed | Number | 1 | 1 | 每次迭代节点移动的速度。速度太快可能会导致强烈震荡 |
| clustering | Boolean | false | false | 是否按照聚类布局 |
| clusterGravity | Number | 30 | 10 | 聚类内部的重力大小,影响聚类的紧凑程度 |
<a name="0lVZj"></a>
#### Circular
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1571883225141-27fe8b99-f365-47e4-827f-fc9da4319b19.png#align=left&display=inline&height=142&name=image.png&originHeight=456&originWidth=472&search=&size=130944&status=done&width=147' width='250' height='250' />
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1571883232409-50dd7848-dfd6-42a4-9879-9b06b74e244c.png#align=left&display=inline&height=142&name=image.png&originHeight=472&originWidth=486&search=&size=128693&status=done&width=146' width='250' height='250' />
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1571883238564-ee51a954-82f8-4023-9ce9-fbdf26b31f5d.png#align=left&display=inline&height=141&name=image.png&originHeight=467&originWidth=400&search=&size=113276&status=done&width=121' width='250' height='250' />
<br />**描述**:环形布局。
<br />**API**[Circular API](https://www.yuque.com/antv/g6/ml1qe3)
<br />**参数**
| 参数名 | 类型 | 示例/可选值 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| center | Array | [ 0, 0 ] | 图的中心 | 随机布局的中心 |
| radius | Number | 50 | null | 圆的半径。若设置了 radius则 startRadius 与 endRadius 不生效 |
| startRadius | Number | 10 | null | 螺旋状布局的起始半径 |
| endRadius | Number | 100 | null | 螺旋状布局的结束半径 |
| clockwise | Boolean | true | true | 是否顺时针排列 |
| divisions | Number | 3 | 1 | 节点在环上的分段数(几个段将均匀分布),在 endRadius - startRadius != 0 时生效 |
| ordering | String | null | 'topology' | 'degree' | null | 节点在环上排序的依据。默认 null 代表直接使用数据中的顺序。'topology' 按照拓扑排序。'degree' 按照度数大小排序 |
| angleRatio | Number | 1 | 1 | 从第一个节点到最后节点之间相隔多少个 2*PI |
<a name="lALX0"></a>
#### Radial
<img src='https://cdn.nlark.com/yuque/0/2019/png/156681/1571883250046-b1986e95-78f7-476d-9b5d-36398ce344a0.png#align=left&display=inline&height=126&name=image.png&originHeight=428&originWidth=558&search=&size=213913&status=done&width=164' width='600' height='300' />
<br />**描述**:辐射状布局。
<br />**API**[Radial API](https://www.yuque.com/antv/g6/ngp0vg#7ZOs7)
<br />**参数**
| 参数名 | 类型 | 示例 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| center | Array | [ 0, 0 ] | 图的中心 | 随机布局的中心 |
| linkDistance | Number | 50 | 50 | 边长 |
| maxIteration | Number | 1000 | 1000 | 停止迭代到最大迭代数 |
| focusNode | String | Object | 'node1' | null | 中心点,默认为数据中第一个节点。可以传入节点 id 或节点本身。 |
| unitRadius | Number | 10 | 100 | 每一圈距离上一圈的距离。默认填充整个画布,即根据图的大小决定 |
| preventOverlap | Boolean | false | false | 是否防止重叠,必须配合属性 `nodeSize` ,只有设置了与当前图节点大小相同的 `nodeSize` 值,才能够进行节点重叠的碰撞检测。<br />3.1.6 后支持:<br />若未设置 `nodeSize`,则将会根据数据中节点的 size 字段数值进行碰撞检测计算。若二者皆未设置,则以节点大小为 10 进行计算。 |
| maxPreventOverlapIteration | Number | 500 | 200 | 防止重叠步骤的最大迭代次数 |
| nodeSize | Number | 10 | 10 | 节点大小(直径)。用于防止节点重叠时的碰撞检测。<br />3.1.6 后支持:<br />若未设置则使用数据中节点的 `size` 字段数值进行碰撞检测计算。若二者皆未设置,则以节点大小为 10 进行计算。 |
| nodeSpacing<br />3.1.6 后支持 | Number | Function | 示例 1 : 10<br />示例 2 : <br />d => {<br />  // d 是一个节点<br />  if (d.id === 'node1') {<br />    return 100;<br />  }<br />  return 10;<br />} | 0 | ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1572589493571-733b149d-2887-4b75-bd22-a2808233d0d5.png#align=left&display=inline&height=115&name=image.png&originHeight=200&originWidth=378&search=&size=46987&status=done&width=217)<br />`preventOverlap` 为 `true` 时生效,防止重叠时节点边缘间距的最小值。可以是回调函数,为不同节点设置不同的最小间距,如示例 2 所示<br /> |
| strictRadial | Boolean | true | false | 是否必须是严格的 radial 布局,即每一层的节点严格布局在一个环上。`preventOverlap` 为 `true` 时生效。详见 [Radial-strictRadial API](https://www.yuque.com/antv/g6/ngp0vg#7ZOs7)<br />- 当 `preventOverlap``true`,且 `strictRadial``false` 时,有重叠的节点严格沿着所在的环展开,但在一个环上若节点过多,可能无法完全避免节点重叠。<br />- 当 `preventOverlap``true`,且 `strictRadial``true` 时,允许同环上重叠的节点不严格沿着该环布局,可以在该环的前后偏移以避免重叠。<br /> |
<a name="RBhhk"></a>
#### MDS
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571883196380-9194f4b6-fb45-49c1-9a15-17e1c694a82f.png#align=left&display=inline&height=138&name=image.png&originHeight=549&originWidth=862&search=&size=134489&status=done&width=216)<br />**描述**:高维数据降维算法布局。<br />**API**[MDS API](https://www.yuque.com/antv/g6/kbvo7q)<br />**参数**
| 参数名 | 类型 | 示例 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| center | Array | [ 0, 0 ] | 图的中心 | 随机布局的中心 |
| linkDistance | Number | 50 | 50 | 边长 |
<a name="RUeWF"></a>
#### Dagre
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571883264071-64862e9a-a850-499b-8063-253c3d380b76.png#align=left&display=inline&height=159&name=image.png&originHeight=567&originWidth=392&search=&size=45070&status=done&width=110)<br />**描述**:层次布局。<br />**API**[Dagre API](https://www.yuque.com/antv/g6/fkhp3c)<br />**参数**
| 参数名 | 类型 | 示例 / 可选值 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| rankdir | String | 'TB' | 'BT' | 'LR' | 'RL' | 'TB' | layout 的方向。TtopBbottomLleftRright |
| align | String | 'UL' | 'UR' | 'DL' | 'DR' | 'UL' | 节点对齐方式。UupperDdownLleftRright |
| nodesep | Number | 40 | 50 | 节点水平间距px。优先级高于 `nodesepFunc` |
| ranksep | Number | 40 | 50 | 层间距px。优先级高于 `ranksep``Func` |
| nodesepFunc<br /><br />3.1.6 后支持 | Function | d => {<br />  // d 是一个节点<br />  if (d.id === 'node1') {<br />    return 100;<br />  }<br />  return 10;<br />} | undefined | 节点水平间距px的回调函数通过该参数可以对不同节点设置不同的节点间距。优先级低于 `nodesep`,即若设置了 `nodesep`,则 `nodesepFunc` 不生效 |
| ranksepFunc<br /><br />3.1.6 后支持 | Function | d => {<br />  // d 是一个节点<br />  if (d.id === 'node1') {<br />    return 100;<br />  }<br />  return 10;<br />} | undefined | 层间距px的回调函数通过该参数可以对不同节点设置不同的层间距。优先级低于 `ranksep`,即若设置了 `ranksep`,则 `ranksepFunc` 不生效 |
| controlPoints | Boolean | true | true | 是否保留布局连线的控制点 |
<a name="4JMfP"></a>
#### Concentric
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571883276351-a0d32bcb-7d1d-4a29-b2b6-f78345c8c752.png#align=left&display=inline&height=186&name=image.png&originHeight=694&originWidth=728&search=&size=268711&status=done&width=195)<br />注:该算法参考 [cytoscape.js](https://github.com/cytoscape/cytoscape.js),遵守 MIT 开源协议。<br />**描述**:同心圆布局。<br />**API**[Concentric API](https://www.yuque.com/antv/g6/lx038n)<br />**参数**
| 参数名 | 类型 | 示例 / 可选值 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| center | Array | [ 0, 0 ] | 图的中心 | 随机布局的中心 |
| nodeSize | Number | 30 | 30 | 节点大小(直径)。用于防止节点重叠时的碰撞检测 |
| minNodeSpacing | Number | 10 | 10 | 环与环之间最小间距,用于调整半径 |
| preventOverlap | Boolean | false | false | 是否防止重叠,必须配合属性 `nodeSize` ,只有设置了与当前图节点大小相同的 `nodeSize` 值,才能够进行节点重叠的碰撞检测。若未设置 `nodeSize` ,则将根据节点数据中的 `size` 进行碰撞检测。若二者都未设置,则默认以 30 为节点大小进行碰撞检测 |
| sweep | Number | Math.PI | undefined | 第一个节点与最后一个节点之间的弧度差 |
| equidistant | Boolean | false | false | 环与环之间的距离是否相等 |
| startAngle | Number | 3.14 | 3 / 2 * Math.PI | 开始放置节点的弧度 |
| clockwise | Boolean | false | false | 是否按照顺时针顺序 |
| maxLevelDiff | Number | 0.5 | undefined | 每一层同心值的求和。若为 undefined则将会被设置为 maxValue / 4 ,其中 maxValue 为最大的排序依据的属性值。例如,若 sortBy='degree',则 maxValue 为所有节点中度数最大的节点的度数 |
| sortBy | String | 'degree' | 'property1' | 'weight' | ... | undefined | 指定的节点排序的依据(节点属性名)。该属性值高的放在中心。如果是 `sortBy``undefined` 则会计算节点度数,度数最高的放在中心。<br /> |
<a name="XG0RD"></a>
#### Grid
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571883294360-430a03bf-82cf-4ebf-989e-ae0be742bf54.png#align=left&display=inline&height=151&name=image.png&originHeight=696&originWidth=1396&search=&size=529788&status=done&width=302)<br />注:该算法参考 [cytoscape.js](https://github.com/cytoscape/cytoscape.js),遵守 MIT 开源协议。<br />**描述**:网格布局。<br />**API**[Grid API](https://www.yuque.com/antv/g6/wn4kg9)<br />**参数**
| 参数名 | 类型 | 示例 / 可选值 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| begin | Array | [ 0, 0 ] | [ 0, 0 ] | 网格开始位置(左上角) |
| preventOverlap | Boolean | false | false | 是否防止重叠,必须配合属性 `nodeSize` ,只有设置了与当前图节点大小相同的 `nodeSize` 值,才能够进行节点重叠的碰撞检测。若未设置 `nodeSize` ,则将根据节点数据中的 `size` 进行碰撞检测。若二者都未设置,则默认以 30 为节点大小进行碰撞检测 |
| preventOverlapPadding | Number | 10 | 10 | 避免重叠时节点的间距 padding。preventOverlap 为 true 时生效 |
| nodeSize | Number | 30 | 30 | 节点大小(直径)。用于防止节点重叠时的碰撞检测 |
| condense | Boolean | false | false | 为 false 时表示利用所有可用画布空间,为 true 时表示利用最小的画布空间 |
| rows | Number | 5 | undefined | 网格的行数,为 undefined 时算法根据节点数量、布局空间、cals若指定自动计算 |
| cals | Number | 5 | undefined | 网格的列数,为 undefined 时算法根据节点数量、布局空间、rows若指定自动计算 |
| sortBy | String | 'degree' | 'property1' | 'weight' | ... | 'degree' | 指定排序的依据(节点属性名),数值越高则该节点被放置得越中心。若为 undefined则会计算节点的度数度数越高节点将被放置得越中心 |
<a name="9ce7Y"></a>
## 树图 TreeGraph
由于树图特殊性G6扩展出了 TreeGraph 详细文档请见[TreeGraph](https://www.yuque.com/antv/g6/treegraph) API。树布局是一种能很好展示有一定层次结构数据的布局方式。推荐使用 G6.TreeGraph 实现。
<a name="rzsBE"></a>
### 配置树图布局
与一般图 Graph 配置方法相似,通过实例化图时配置 `layout` 属性设置树的布局,还可以通过 `modes` 属性为树配置 [展开/收缩行为](https://www.yuque.com/antv/g6/treegraph#157b6823)。以下代码声明了一个实例,定义了布局为从左到右结构的基础树图,并且定义了展开收缩行为。
```javascript
const graph = new G6.TreeGraph({
container: 'mountNode',
modes: {
default: [{
// 定义展开/收缩行为
type: 'collapse-expand'
}, 'drag-canvas']
},
// 定义布局
layout: {
type: 'dendrogram' // 布局类型
direction: 'LR', // 自左至右布局,可选的有 H / V / LR / RL / TB / BT
nodeSep: 50, // 节点之间间距
rankSep: 100 // 每个层级之间的间距
}
});
```
<a name="T3idk"></a>
###
<a name="af7yc"></a>
### 树图布局方法
<a name="AyYPj"></a>
#### compactBox
**描述**:紧凑树布局。从根节点开始,同一深度的节点在同一层,并且布局时会将节点大小考虑进去。<br />![compact-box.png](https://cdn.nlark.com/yuque/0/2019/png/174835/1551166323476-178c0e50-0999-4b07-ab72-a61f779cce28.png#align=left&display=inline&height=166&name=compact-box.png&originHeight=687&originWidth=1916&search=&size=53500&status=done&width=464)<br />**API**[CompactBox API](https://www.yuque.com/antv/g6/rufc7b)<br />**参数**
| 参数名 | 类型 | 示例 / 可选值 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| direction | String | 'TB' | 'BT' | 'LR' | 'RL' | 'H' | 'V' | 'LR' | layout 的方向。<br />- TB —— 根节点在上,往下布局<br />- BT —— 根节点在下,往上布局<br />
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571833657395-7b291d7b-5408-41fa-bfb6-533ef39250ad.png#align=left&display=inline&height=59&name=image.png&originHeight=744&originWidth=1786&search=&size=397159&status=done&width=141)      ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571833676794-31f862f3-8cb5-412e-81d4-2ac246e37c0d.png#align=left&display=inline&height=60&name=image.png&originHeight=762&originWidth=1790&search=&size=390312&status=done&width=140)> TB。BT。
- LR —— 根节点在左,往右布局<br />- RL —— 根节点在右,往左布局<br />
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571833574730-5d76d7a2-0e82-4ef7-a7d9-a45efd5b6b30.png#align=left&display=inline&height=119&name=image.png&originHeight=906&originWidth=518&search=&size=164555&status=done&width=68)             ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571833593889-e98c6f6d-0c38-4408-a4c0-ba83d0bbba74.png#align=left&display=inline&height=115&name=image.png&originHeight=932&originWidth=454&search=&size=154391&status=done&width=56)> LR。RL。
- H —— 根节点在中间,水平对称布局<br />- V —— 根节点在中间,垂直对称布局<br />
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571833726277-822e5104-2189-4fe4-bcdc-7b43d183d541.png#align=left&display=inline&height=110&name=image.png&originHeight=906&originWidth=824&search=&size=226469&status=done&width=100)          ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571833702068-8f409559-1765-4154-bd4d-bb782de8cd23.png#align=left&display=inline&height=92&name=image.png&originHeight=924&originWidth=1028&search=&size=314177&status=done&width=102)<br />> H。V。 |
| getId | Function | (d) => {<br />  // d 是一个节点<br />  return d.id;<br />} | undefined | 节点 id 的回调函数 |
| getHeight | Function | (d) => {<br />  // d 是一个节点<br />  return 10;<br />} | undefined | 节点高度的回调函数 |
| getWidth | Function | (d) => {<br />  // d 是一个节点<br />  return 20;<br />} | undefined | 节点宽度的回调函数 |
| getVGap | Function | (d) => {<br />  // d 是一个节点<br />  return 100;<br />} | undefined | 节点纵向间距的回调函数 |
| getHGap | Function | (d) => {<br />// d 是一个节点<br />  return 50;<br />} | undefined | 节点横向间距的回调函数 |
| radial | Boolean | true | false | 是否按照辐射状布局。若 `radial``true`,建议 `direction` 设置为 `'LR'``'RL'`![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571833817425-f944eadd-fd68-4107-8425-81c1c9bd1ce4.png#align=left&display=inline&height=97&name=image.png&originHeight=886&originWidth=990&search=&size=213310&status=done&width=108) |
<a name="sH1z0"></a>
#### dendrogram
**描述**生态树布局。不管数据的深度多少总是叶节点对齐。不考虑节点大小布局时将节点视为1个像素点。<br />![dendrogram-lr.png](https://cdn.nlark.com/yuque/0/2019/png/174835/1551166332942-ecdc3c6f-bcc3-48f4-aa64-c9b1a3a2ab67.png#align=left&display=inline&height=145&name=dendrogram-lr.png&originHeight=652&originWidth=888&search=&size=75483&status=done&width=198)<br />**API**[Dendrogram API](https://www.yuque.com/antv/g6/co00r6)<br />**参数**
| 参数名 | 类型 | 示例 / 可选值 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| direction | String | 'TB' | 'BT' | 'LR' | 'RL' | 'H' | 'V' | 'LR' | layout 的方向。<br />- TB —— 根节点在上,往下布局<br />- BT —— 根节点在下,往上布局<br />
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571832831947-89713eef-7898-446b-9edc-604ed63b77d4.png#align=left&display=inline&height=48&name=image.png&originHeight=760&originWidth=1784&search=&size=518414&status=done&width=112)      ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571832849059-ada0d199-ca15-4ce0-83e0-de00f9482c0b.png#align=left&display=inline&height=50&name=image.png&originHeight=786&originWidth=1814&search=&size=517688&status=done&width=115)<br />> TB。BT。
- LR —— 根节点在左,往右布局<br />- RL —— 根节点在右,往左布局<br />
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571832767625-ad86a4b6-dabb-4f53-9800-31bb3fef88c6.png#align=left&display=inline&height=114&name=image.png&originHeight=896&originWidth=408&search=&size=214689&status=done&width=52)             ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571832804357-6b4c6e65-22fe-45b1-ab9f-bf954cdb0b13.png#align=left&display=inline&height=116&name=image.png&originHeight=912&originWidth=410&search=&size=213061&status=done&width=52)> LR。RL。
- H —— 根节点在中间,水平对称布局<br />- V —— 根节点在中间,垂直对称布局<br />
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571832893099-55fa98c8-30f2-49c6-b582-76dd69de7b4a.png#align=left&display=inline&height=104&name=image.png&originHeight=892&originWidth=712&search=&size=279079&status=done&width=83)          ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571832910720-f3d479c3-b822-4123-b207-a81e22fad324.png#align=left&display=inline&height=91&name=image.png&originHeight=922&originWidth=1172&search=&size=366086&status=done&width=116)<br />> H。V。 |
| nodeSep | Number | 50 | 0 | 节点间距 |
| rankSep | Number | 100 | 0 | 层与层之间的间距 |
| radial | Boolean | true | false | 是否按照辐射状布局。若 `radial``true`,建议 `direction` 设置为 `'LR'``'RL'`<br />![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571833294684-7874d71d-fb44-4340-95d0-c03b56c67a18.png#align=left&display=inline&height=98&name=image.png&originHeight=926&originWidth=922&search=&size=286654&status=done&width=98) |
<a name="04ZZ5"></a>
#### indented
**描述**:缩进树布局。每个元素会占一行/一列。<br />![indented.png](https://cdn.nlark.com/yuque/0/2019/png/174835/1551172247854-99aa0e77-61f0-4b7e-8ab6-6d854fcd2396.png#align=left&display=inline&height=222&name=indented.png&originHeight=876&originWidth=497&search=&size=36070&status=done&width=126)
**API**[Indented API](https://www.yuque.com/antv/g6/hl4syb)<br />**参数**
| 参数名 | 类型 | 示例 / 可选值 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| direction | String | 'LR' | 'RL' | 'H' | 'LR' | layout 的方向。<br />- LR —— 根节点在左,往右布局(下图左)
- RL —— 根节点在右,往左布局(下图中)
- H —— 根节点在中间,水平对称布局(下图右)
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571832031826-33f11b5c-3d7a-4767-89b0-1d7cb6f64510.png#align=left&display=inline&height=172&name=image.png&originHeight=908&originWidth=354&search=&size=141929&status=done&width=67)  ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571832083137-c38a3f7a-885e-4acf-954a-73fbeb822bde.png#align=left&display=inline&height=166&name=image.png&originHeight=890&originWidth=278&search=&size=133215&status=done&width=52)  ![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571832100885-51d8526e-d530-4090-9f37-4fdd4f9e865a.png#align=left&display=inline&height=128&name=image.png&originHeight=910&originWidth=526&search=&size=205642&status=done&width=74) |
| indent | Number | 80 | 20 | 列间间距 |
| getHeight | Function | (d) => {<br />  // d 是一个节点<br />  return 10;<br />} | undefined | 节点高度的回调函数 |
| getWidth | Function | (d) => {<br />  // d 是一个节点<br />  return 20;<br />} | undefined | 节点宽度的回调函数 |
<a name="AOAs2"></a>
#### mindmap
**描述**:脑图布局。深度相同的节点将会被放置在同一层,与 compactBox 不同的是,布局不会考虑节点的大小。<br />![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571830487985-0c3dfc8c-fadd-4911-8ea4-1b4091a86538.png#align=left&display=inline&height=160&name=image.png&originHeight=906&originWidth=1266&search=&size=267710&status=done&width=223)<br />**API**[Mindmap API](https://www.yuque.com/antv/g6/wk3mh8)<br />**参数**
| 参数名 | 类型 | 示例 / 可选值 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| direction | String | 'H' | 'V' | 'H' | layout 的方向。<br />- Hhorizontal水平—— 根节点的子节点分成两部分横向放置在根节点左右两侧<br />
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571830487985-0c3dfc8c-fadd-4911-8ea4-1b4091a86538.png#align=left&display=inline&height=101&name=image.png&originHeight=906&originWidth=1266&search=&size=267710&status=done&width=141)<br />- Vvertical (竖直)—— 将根节点的所有孩子纵向排列<br />
![image.png](https://cdn.nlark.com/yuque/0/2019/png/156681/1571830515639-e66a5347-09fe-4583-81d6-178aa6920f7b.png#align=left&display=inline&height=112&name=image.png&originHeight=920&originWidth=982&search=&size=252410&status=done&width=120) |
| getHeight | Function | (d) => {<br />  // d 是一个节点<br />  return 10;<br />} | undefined | 节点高度的回调函数 |
| getWidth | Function | (d) => {<br />  // d 是一个节点<br />  return 20;<br />} | undefined | 节点宽度的回调函数 |
| getVGap | Function | (d) => {<br />  // d 是一个节点<br />  return 100;<br />} | 18 | 节点纵向间距的回调函数 |
| getHGap | Function | (d) => {<br />  // d 是一个节点<br />  return 50;<br />} | 18 | 节点横向间距的回调函数 |
| getSide | String | Function | (d) => {<br />  // d 是一个节点<br />  return 'left';<br />} | 'right' | 节点排布在根节点的左侧/右侧。若设置了该值,则所有节点会在根节点同一侧,即 direction = 'H' 不再起效。若该参数为回调函数,则可以指定每一个节点在根节点的左/右侧 |
<a name="FCFKL"></a>
## 布局的切换机制
G6 提供了两种关于布局的切换机制:
- `updateLayout(params)`:布局方法或参数的切换
- `changeData()`:数据的切换
<a name="zAoyl"></a>
### 布局方法或参数切换
**接口定义:**
```javascript
/**
* 更换布局或布局参数
* @param {String | object} cfg 新布局配置项
* 若 cfg 为 String 或含有 type 字段,且与之前的布局方法不同时将会更换布局
* 否则只是更新原有布局的参数
*/
updateLayout(cfg);
```
**布局方法切换:**<br />若参数 `cfg``String` 或是含有 `type` 字段的对象,且与之前的布局方法名不同时将会更换布局。
**布局参数切换:**<br />若参数 `cfg` 是对象且其中不含有 `type` 字段,或指定的布局方法名称与之前的布局方法相同,则保持原有布局方法,仅更新该布局的参数。
<a name="mC4a0"></a>
### 数据切换
**接口定义:**
```javascript
/**
* 更改源数据,根据新数据重新渲染视图
* @param {object} data 源数据
* @return {object} this
*/
changeData(data);
```
<a name="Rp5Wk"></a>
### 切换示例
<a name="X8sJ1"></a>
#### 期待效果
初始化时使用默认 random 布局2000 ms 后更换为允许节点重叠的 force 布局4000 ms 后更换为不允许节点重叠的 force 布局6000 ms 后更换数据为 `data2`<br />![tutorial-layout.gif](https://cdn.nlark.com/yuque/0/2019/gif/156681/1569837754937-a1b91cef-8846-487f-a1cd-b5231fcf09a3.gif#align=left&display=inline&height=329&name=tutorial-layout.gif&originHeight=329&originWidth=440&search=&size=84736&status=done&width=440)
<a name="6Wf0G"></a>
#### 完整代码
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tutorial Layout Demo</title>
</head>
<body>
<div id="mountNode"></div>
<script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g6-3.1.0/build/g6.js"></script>
<script src="https://gw.alipayobjects.com/os/antv/assets/lib/jquery-3.2.1.min.js"></script>
<script>
const data = {
nodes: [
{ id: '0', label: '0' },
{ id: '1', label: '1' },
{ id: '2', label: '2' },
{ id: '3', label: '3' },
{ id: '4', label: '4' }
], edges: [
{ source: '0', target: '1' },
{ source: '0', target: '2' },
{ source: '0', target: '3' },
{ source: '0', target: '4' },
{ source: '1', target: '2' },
{ source: '1', target: '3' }
]
};
const data2 = {
nodes: [
{ id: '0', label: '0' },
{ id: '1', label: '1' },
{ id: '2', label: '2' }
], edges: [
{ source: '0', target: '1' },
{ source: '0', target: '2' }
]
};
const graph = new G6.Graph({
container: 'mountNode', // String | HTMLElement必须容器 id 或容器本身
width: 300, // Number必须图的宽度
height: 300, // Number必须图的高度
animate: true // Boolean可选切换布局时是否使用动画过度
});
// 读取数据和渲染
graph.data(data);
graph.render();
// 2000 ms 后切换为允许节点重叠的 force 布局
setTimeout(() => {
graph.updateLayout('force'); // 参数为 String 代表布局名称
}, 8000);
// 4000 ms 后切换为不允许节点重叠且边长为 100 的 force 布局。
setTimeout(() => {
graph.updateLayout({
type: 'force', // 布局名称
preventOverlap: true, // 布局参数,是否允许重叠
nodeSize: 40, // 布局参数,节点大小,用于判断节点是否重叠
linkDistance: 100 // 布局参数,边长
});
}, 10000);
// 6000 ms 后切换数据为 data2
setTimeout(() => {
graph.changeData(data2);
}, 12000);
</script>
</body>
</html>
```
<a name="eYZc6"></a>
## 子图布局
目前,子图布局独立与全局布局的思路,与 graph 不挂钩,直接使用实例化布局方法的方式,灌入子图数据,通过布局将位置写到相应数据中。这种机制还可供外部的全局布局使用,即使不用 G6 渲染,也可以计算节点布局后的位置。但与萧庆讨论后,决定这种方式暂时不透出够用户。在子图布局上,这种机制后续需要修改,并与全局布局思路统一( graphcontroller )。
<a name="KptLp"></a>
### 使用方法
```javascript
// 实例化布局
const subgraphLayout = new G6.Layout['force']({
center: [ 500, 450 ]
});
// 初始化布局,灌入子图数据
subgraphLayout.init({
'nodes': subGraphNodes,
'edges': subGraphEdges
});
//执行布局
subgraphLayout.execute();
// 图实例根据数据更新节点位置
graph.positionsAnimate();
```

View File

@ -0,0 +1,82 @@
---
title: 交互模式 Mode
order: 5
---
<a name="LTkXZ"></a>
## 什么是 Mode
用户在交互一张图时,可能由于意图不同而存在不同的交互模式,例如在编辑模式下点击节点需要弹出窗口让用户编辑,在查看模式下点击节点需要选中节点。
为了解决上述问题G6 提供了交互模式 Mode它是图上交互行为 [Behavior](./defaultBehavior) 的管理机制。一个图上可以有存在多种交互模式,每个交互模式包含多种交互行为 [Behavior](./defaultBehavior)。
例如,存在 default 和 edit 两种 mode交互模式:
- default 模式中包含点击选中节点行为和拖拽画布行为;
- edit 模式中包含点击节点弹出编辑框行为和拖拽节点行为。
默认情况下,该图对 default 模式中的行为见效,即点击节点时节点被选中而不是弹出编辑框。用户可以通过简单的命令切换该图的行为模式到 edit 模式,则 default 模式中的行为失效edit 交互模式中的行为起效,即点击节点将弹出编辑框。
<a name="hboeP"></a>
## 配置 Mode
在实例化图时配置 `modes` 属性:
```javascript
const graph = new G6.Graph({
container: 'mountNode',
width: 500,
height: 500,
modes: {
// 支持的 behavior
default: [ 'drag-canvas', 'zoom-canvas' ],
edit: [ 'click-select' ]
}
});
```
以上是模式定义的一个例子。在图上定义了两个模式,分别是 `default` `edit` 。其中 `default` 包含两个个 [Behavior](https://www.yuque.com/antv/g6/default-behavior)`'drag-canvas'` 和 `'``zoom-canvas'`,都使用行为的默认参数。
<a name="3IuAF"></a>
## 切换 Mode
默认时 Graph 会使用 `default` 的 Mode ,可以拖动和缩放画布,当需要点击选中节点时,可以通过 `graph.``setMode('edit')` 来切换到 `edit` 的 Mode 。
```javascript
graph.setMode('edit');
```
此时 Graph 就支持了拖拽节点,`default` 模式下的拖拽画布 `'drag-canvas'`、放缩画布行为 `'zoom-canvas'` 失效。
在调用了 `setMode` 方法后G6 内部进行了以下操作:
- 解绑目前图模式的所有事件监听;
- 生成新的 Behavior ,进行事件初始化;
- 绑定新的行为对应的事件监听。
<a name="WDKiv"></a>
## 编辑已有的 Mode
如果有已经定义好的 Behavior [内置 Behavior](https://www.yuque.com/antv/g6/default-behavior) 或 [自定义 Behavior](https://www.yuque.com/antv/g6/self-behavior)),需要把它添加到某个模式下,可以通过 `graph.addBehaviors` 方法;需要从某个模式中移除一些 Behavior可以使用 `graph.removeBehaviors` 方法。如下示例:
```javascript
// 向 default 模式中添加名为 drag-canvas 的行为,并使用行为的默认配置
graph.addBehaviors('drag-canvas', 'default');
// 从 default 模式中移除名为 drag-canvas 的行为
graph.removeBehaviors('drag-canvas', 'default');
// 向 edit 模式中添加名为 drag-canvas 的行为,并定义个性化配置
graph.addBehaviors({
type: 'drag-canvas',
direction: 'x'
}, 'edit');
// 从 edit 模式中移除名为 drag-canvas 的行为
graph.removeBehaviors('drag-canvas', 'edit');
// 一次向 default 模式中添加多个行为
graph.addBehaviors([ 'drag-canvas', 'zoom-canvas' ], 'default');
// 一次从 default 模式中移除多个行为
graph.removeBehaviors([ 'drag-canvas', 'zoom-canvas' ], 'default');
```
<a name="9Ez4t"></a>
## 相关阅读
- [内置交互行为 Behavior](./defaultBehavior)
- [自定义交互行为 Behavior](https://www.yuque.com/antv/g6/self-behavior)

View File

@ -0,0 +1,254 @@
---
title: 节点分组 Group
order: 8
---
> Feature 自 G6 3.1.2 开始支持自定义节点分组的标题了,可以渲染带有标题的分组。
对于熟悉图可视化类库的用户来说,节点分组可能是比较实用的一个功能。自 G6 3.0.5 版本开始G6 加入了节点分组的功能,详情参考[Demo](https://github.com/antvis/g6/blob/master/demos/drag-group.html)。<br />![group2.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1567391660645-308be946-1119-45c0-af7c-5373e78ffa7c.gif#align=left&display=inline&height=533&name=group2.gif&originHeight=533&originWidth=763&search=&size=261828&status=done&width=763)
<a name="07gsB"></a>
### 数据结构
新增节点分组功能时,尽量保持了 G6 数据结构的稳定性。为了体现分组的特性,我们在 nodes 数据项中加入了 groupId 属性,另外新增了 groups 字段,用于表示数据中所包括的分组及各分组之间的层级关系。
当 groups 中的对象包括 title 属性字段时表示要渲染带有标题的分组title 字段的类型可以是 string 或 object
- title类型为 string 时,值表示标题名称,不能设置任何样式,也不能调整标题位置;
- title 为 object 时可以设置标题的样式及位置title 中各字段含义:
- text必选分组的标题类型为 string
- offsetX可选默认为 0表示 x 方向上的偏移量;
- offsetY可选默认为 0表示 y 方向上的偏移量;
- stroke字体边框颜色同时也支持 fill、fontSize 等所有的[文本样式属性](https://www.yuque.com/antv/g6/gs4gno)。
```javascript
{
nodes: [
{
id: 'node1',
label: 'node1',
groupId: 'group1',
x: 100,
y: 100
},
{
id: 'node2',
label: 'node2',
groupId: 'group1',
x: 150,
y: 100
},
{
id: 'node3',
label: 'node3',
groupId: 'group2',
x: 300,
y: 100
},
],
edges: [
{
source: 'node1',
target: 'node2'
}
],
groups: [
{
id: 'group1',
title: {
text: '第一个分组',
stroke: '#444',
offsetX: 0,
offsetY: 0
},
parentId: 'p1'
},
{
id: 'group2',
parentId: 'p1'
},
{
id: 'p1'
}
]
}
```
<a name="fCWQJ"></a>
### 如何渲染 group
当 nodes 中存在 `groupId` 属性字段时在渲染过程中G6 就会自动去渲染分组,当存在 groups 属性时G6 就会自定去判断各分组之间的层级关系,并渲染出嵌套的分组。但当没有使用任何布局的时候,需要在 nodes 中指定各个阶段的坐标信息,即阶段的 `x``y` 属性值。
```javascript
const data = {
nodes: [
{
id: 'node6',
groupId: 'group3',
label: 'rect',
x: 100,
y: 300
},
{
id: 'node1',
label: 'fck',
groupId: 'group1',
x: 100,
y: 100
},
{
id: 'node9',
label: 'noGroup1',
groupId: 'p1',
x: 300,
y: 210
},
{
id: 'node2',
label: 'node2',
groupId: 'group1',
x: 150,
y: 200
},
{
id: 'node3',
label: 'node3',
groupId: 'group2',
x: 300,
y: 100
},
{
id: 'node7',
groupId: 'p1',
label: 'node7-p1',
x: 200,
y: 200
},
{
id: 'node10',
label: 'noGroup',
groupId: 'p2',
x: 300,
y: 210
}
],
edges: [
{
source: 'node1',
target: 'node2'
},
{
source: 'node2',
target: 'node3'
}
],
groups: [
{
id: 'group1',
title: {
text: '第一个分组',
stroke: '#444',
offsetX: -30,
offsetY: 30
},
parentId: 'p1'
},
{
id: 'group2',
parentId: 'p1'
},
{
id: 'group3',
parentId: 'p2'
},
{
id: 'p1'
},
{
id: 'p2'
}
]
};
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
pixelRatio: 2,
modes: {
default: [ 'drag-canvas' ]
},
defaultNode: {
shape: 'circleNode'
},
defaultEdge: {
color: '#bae7ff'
}
});
graph.data(data);
graph.render();
```
渲染的效果如下图所示:<br />![image.png](https://cdn.nlark.com/yuque/0/2019/png/244306/1571190983755-4599403c-7c3d-4c23-9539-e91a5c038984.png#align=left&display=inline&height=503&name=image.png&originHeight=1006&originWidth=1600&search=&size=415977&status=done&width=800)<br />此时,不能对分组中的节点及分组进行任何操作,接下来,我们介绍可以对分组进行的各种操作。
<a name="msaWq"></a>
### 操作分组
只是简单地将分组渲染出来,并没有多大的实用价值,只有支持一系列的交互操作后,才能最大程度地体现分组的价值。
在 G6 中,我们内置了 `drag-group`、`collapse-expand-group` 及  `drag-node-with-group`  三个[Behavior](https://www.yuque.com/antv/g6/default-behavior),共支持以下的交互行为:
- 拖动分组;
- 通过拖拽,动态改变分组中的节点数量及分组大小;
- 将一个分组从父分组中拖拽出来,并取消分组直接的关联关系,动态改变父分组的大小;
- 双击分组,收起和展开分组:
- 当收起分组后,与分组节点中的连线会自动连到分组上;
- 展开分组后,恢复之前的连接和位置。
- 拖动节点,所在的分组高亮,当拖到其他分组时,其他分组高亮;
- [暂不支持] ~~将分组拖入到另外个分组,并改变分组层级的所属关系~~
<a name="e8sCW"></a>
#### drag-group
`drag-group` Behavior支持拖动分组拖动分组过程中会动态改变分组中节点和边的位置在拖拽完成以后保持分组和节点的相对位置不变。
<a name="VP4XU"></a>
#### collapse-expand-group
`collapse-expand-group` Behavior支持双击分组收起和展开分组收起分组以后隐藏分组中的所有节点外部节点和分组中节点有连线的情况下所有连接会连接到分组上面。
优化目前只支持双击交互,正式发布时,会支持用户自定义交互方式,来实现分组的收起和展开。
<a name="ZgBe1"></a>
#### drag-node-with-group
`drag-node-with-group` Behavior `drag-node` 类似,但该 Behavior 仅用于用 group 时 node 的拖拽。拖拽 node 过程中,会动态改变 node 所在的分组。
优化目前暂不支持将多个节点拖出拖入到分组中。
```javascript
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
pixelRatio: 2,
modes: {
default: [ 'drag-group', 'collapse-expand-group', 'drag- node-with-group' ]
},
defaultNode: {
shape: 'circleNode'
},
defaultEdge: {
color: '#bae7ff'
}
});
```
将这三个内置提供的 Behavior 加入到 modes 中以后的效果如下图所示。
![group2.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1567391075518-249e7649-5861-41ec-9e81-ea58224de9cb.gif#align=left&display=inline&height=533&name=group2.gif&originHeight=533&originWidth=763&search=&size=261828&status=done&width=763)
<a name="nmZxu"></a>
### 适用的场景
1. 风控、反洗钱、保险骗保、网络诈骗、信用卡诈骗等场景下团伙分析;
1. 特征分析:同一个分组中的节点在某些特征上面比较相似;
1. 整理节点:当类似的节点放到一个分组中,只渲染分组,不渲染节点,减少干扰元素。

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

137
docs/manual/middle/state.md Normal file
View File

@ -0,0 +1,137 @@
---
title: 状态 State
order: 6
---
<a name="pJSSm"></a>
## 什么是 state
G6 中的 **state**,指的是状态,包括**交互状态**和**业务状态**两种。
<a name="gVhNL"></a>
### 交互状态
交互状态是与具体的交互动作密切相关的如用户使用鼠标选中某个节点hover 到某条边。
G6 中默认处理的是交互状态。
<a name="eFYG6"></a>
### 业务状态
指根据用户业务需求自定义的状态。业务状态是与交互动作无关的,与具体业务逻辑强相关的,也可理解为是强数据驱动的。如某个任务的执行状态、某条申请的审批状态等,不同的数据值代表不同的业务状态。业务状态与用户交互动作无关,但在 G6 中的处理方式同交互状态一致。
<a name="LQQdD"></a>
## 何时使用 state
判断是否该使用 state 的原则很简单,从交互和业务两个层面来看:
- 某个交互动作要改变节点或边的样式及属性;
- 呈现给用户的内容会根据数据改变(如 1 代表成功0 代表失败)。
满足上述条件其一,则应该使用 state。
<a name="I23fx"></a>
## 配置不同 state 的样式
在 G6 中,配置交互状态和业务状态的方式是相同的。对于部分只使用 G6 来完成某个需求的开发而不想深入理解G6的用户其实不用区分交互状态和业务状态的区别使用相同的方式定义状态使用相同的方式使用状态完全没有理解成本。
在 G6 中,定义 state 时,我们有两种选择:
- 在实例化 Graph 时,通过 `nodeStateStyles``edgeStateStyles` 来定义;
- 在自定义节点时,在 options 配置项的 `stateStyles` 中定义状态。
<a name="7ZVYk"></a>
### 实例化 Graph 时定义 state 样式
```javascript
const graph = new G6.Graph({
container: 'mountNode',
width: 800,
height: 600,
defaultNode: {
shape: 'diamond',
style: { // 默认状态样式
fill: 'blue'
}
},
nodeStateStyles: {
hover: { // hover 状态为 true 时的样式
fill: '#d3adf7'
},
running: { // running 状态为 true 时的样式
stroke: 'steelblue'
}
}
})
```
上面的实例代码中,我们在实例化 Graph 时候,通过 `nodeStateStyles` 定义了交互状态 `hover` 和业务状态`running`,当用户操作过程中,鼠标 `hover` 到某个节点上时,节点的填充色就会变为指定的颜色,当某个任务状态变为正在执行时,节点的边框就会变为 `running` 状态定义的颜色。<br />![3.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570584254138-c2ef66cc-0067-41bf-8235-63798c65a3c1.gif#align=left&display=inline&height=181&name=3.gif&originHeight=181&originWidth=247&search=&size=8886&status=done&width=247)
同理defaultEdge 中的 style 属性定义了默认状态下边的样式,使用 `edgeStateStyles` 可以定义不同状态下边的样式。
<a name="vNa7S"></a>
### 自定义节点和边时定义 state 样式
下面代码是在自定义节点时候通过 `stateStyles` 定义的交互状态 `hover``selected`。用户在操作过程中如果hover到某个节点则节点的透明度会变为 0.8,如果选中某个节点,选中节点的边框宽度变为 3。
```javascript
G6.registerNode('customShape', {
// 自定义节点时的配置
options: {
size: 60,
style: {
lineWidth: 1
},
stateStyles: {
// 鼠标hover状态下的配置
hover: {
fillOpacity: 0.8
},
// 选中节点状态下的配置
selected: {
lineWidth: 3
}
}
}
}
```
![3.gif](https://cdn.nlark.com/yuque/0/2019/gif/244306/1570584254137-65f129dd-45fc-430d-9485-991ee1d2dbba.gif#align=left&display=inline&height=181&name=3.gif&originHeight=181&originWidth=247&search=&size=8385&status=done&width=247)
<a name="P7aHJ"></a>
## 使用 state
不管使用哪种方式,当我们定义好了 state 以后,**使用 `graph.setItemState` 来使定义的状态生效**。
那么,我们该在什么地方使用 **`graph.setItemState`** 来使 state 生效呢?一种是直接使用 `graph.on` 监听事件,在回调中使 state 生效,另一种是在自定义 Behavior 中使 state 生效。
<a name="kFcu4"></a>
### graph.on
在回调函数中使定义的交互状态 hover 生效。
```javascript
graph.on('node:mouseenter', evt => {
const { item } = evt
graph.setItemState(item, 'hover', true)
})
graph.on('node:mouseleave', evt => {
const { item } = evt
graph.setItemState(item, 'hover', false)
})
```
<a name="GfbN6"></a>
### Behavior
在自定义 Behavior 中使定义的交互状态 selected 生效。
```javascript
G6.registerBehavior('nodeClick', {
getEvents() {
return {
'node:click': 'onClick'
};
},
onClick(e) {
e.preventDefault();
if (!this.shouldUpdate.call(this, e)) {
return;
}
const { item } = e;
const graph = this.graph;
graph.setItemState(item, 'selected', true)
}
})
```
<a name="RhfkK"></a>
## 小结
G6 底层提供了状态管理的能力,通过使用 state简化了状态管理降低了用户的认知成本。更多关于 G6 中状态的内容请参考 [G6 状态量思考](https://www.yuque.com/antv/g6/xiux28)。