---
title: 同心圆布局 Concentric
order: 6
---
## 概述
同心圆布局是一种将节点根据某种排序规则分层,并以圆心为中心、沿圆周排列每层节点的布局方式。参考更多同心圆布局[样例](/examples#layout-concentric)或[源码](https://github.com/antvis/layout/blob/v5/packages/layout/src/circular.ts)。
## 使用场景
- 分层数据可视化,如权限控制结构、组织架构图等,中心是顶级角色,外圈为下级节点。
- 排序分析结果可视化,高重要度放中心,低重要度放外围,快速表达图中节点的相对影响力。
## 配置项
| 属性 | 描述 | 类型 | 默认值 | 必选 |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | ---------------- | ---- |
| type | 布局类型 | `concentric` | - | ✓ |
| center | 圆形布局的中心位置,默认为当前容器的中心位置 | [number, number] \| [number, number, number] | - | |
| clockwise | 是否按照顺时针排列 | boolean | false |
| equidistant | 环与环之间的距离是否相等 | boolean | false | |
| width | 布局的宽度,默认使用容器宽度 | number | - | |
| height | 布局的高度,默认使用容器高度 | number | - | |
| sortBy | 指定排序的依据(节点属性名)
数值越高则该节点被放置得越中心。若为 degree,则会计算节点的度数,度数越高,节点将被放置得越中心 | string | `degree` | |
| maxLevelDiff | 同一层节点的最大属性差值
若为 undefined,则将会被设置为 maxValue / 4 ,其中 maxValue 为最大的排序依据的属性值。例如,若 sortBy 为 'degree',则 maxValue 为所有节点中度数最大的节点的度数 | number | undefined | |
| nodeSize | 节点大小(直径)。用于防止节点重叠时的碰撞检测 | number \| number[] \| ((nodeData: Node) => number) | 30 | |
| nodeSpacing | 环与环之间最小间距,用于调整半径 | number \| number[] \| ((node?: Node) => number) | 10 | |
| preventOverlap | 是否防止重叠
必须配合 nodeSize 属性或节点数据中的 data.size 属性,只有在数据中设置了 data.size 或在该布局中配置了与当前图节点大小相同的 nodeSize 值,才能够进行节点重叠的碰撞检测 | boolean | false | |
| startAngle | 开始布局节点的弧度 | number | 3 / 2 \* Math.PI | |
| sweep | 同一层中第一个节点与最后一个节点之间的弧度差
若为 undefined ,则将会被设置为 2 \* Math.PI \* (1 - 1 / \|level.nodes\|) ,其中 level.nodes 为该算法计算出的每一层的节点,\|level.nodes\| 代表该层节点数量 | number | undefined | |
## 代码示例
```js | ob { pin: false, inject: true }
import { Graph } from '@antv/g6';
const graph = new Graph({
container: 'container',
width: 500,
height: 250,
autoFit: 'view',
data: {
nodes: [
{ id: 'center', data: { label: '中心', level: 0 } },
{ id: 'level1-0', data: { label: 'L1-0', level: 1 } },
{ id: 'level1-1', data: { label: 'L1-1', level: 1 } },
{ id: 'level1-2', data: { label: 'L1-2', level: 1 } },
{ id: 'level1-3', data: { label: 'L1-3', level: 1 } },
{ id: 'level1-4', data: { label: 'L1-4', level: 1 } },
{ id: 'level1-5', data: { label: 'L1-5', level: 1 } },
{ id: 'level2-0', data: { label: 'L2-0', level: 2 } },
{ id: 'level2-1', data: { label: 'L2-1', level: 2 } },
{ id: 'level2-2', data: { label: 'L2-2', level: 2 } },
{ id: 'level2-3', data: { label: 'L2-3', level: 2 } },
{ id: 'level2-4', data: { label: 'L2-4', level: 2 } },
{ id: 'level2-5', data: { label: 'L2-5', level: 2 } },
{ id: 'level2-6', data: { label: 'L2-6', level: 2 } },
{ id: 'level2-7', data: { label: 'L2-7', level: 2 } },
{ id: 'level2-8', data: { label: 'L2-8', level: 2 } },
{ id: 'level2-9', data: { label: 'L2-9', level: 2 } },
{ id: 'level2-10', data: { label: 'L2-10', level: 2 } },
{ id: 'level2-11', data: { label: 'L2-11', level: 2 } },
],
edges: [
{ id: 'e-center-level1-0', source: 'center', target: 'level1-0' },
{ id: 'e-center-level1-1', source: 'center', target: 'level1-1' },
{ id: 'e-center-level1-2', source: 'center', target: 'level1-2' },
{ id: 'e-center-level1-3', source: 'center', target: 'level1-3' },
{ id: 'e-center-level1-4', source: 'center', target: 'level1-4' },
{ id: 'e-center-level1-5', source: 'center', target: 'level1-5' },
{ id: 'e-level1-0-level2-0', source: 'level1-0', target: 'level2-0' },
{ id: 'e-level1-0-level2-1', source: 'level1-0', target: 'level2-1' },
{ id: 'e-level1-1-level2-2', source: 'level1-1', target: 'level2-2' },
{ id: 'e-level1-1-level2-3', source: 'level1-1', target: 'level2-3' },
{ id: 'e-level1-2-level2-4', source: 'level1-2', target: 'level2-4' },
{ id: 'e-level1-2-level2-5', source: 'level1-2', target: 'level2-5' },
{ id: 'e-level1-3-level2-6', source: 'level1-3', target: 'level2-6' },
{ id: 'e-level1-3-level2-7', source: 'level1-3', target: 'level2-7' },
{ id: 'e-level1-4-level2-8', source: 'level1-4', target: 'level2-8' },
{ id: 'e-level1-4-level2-9', source: 'level1-4', target: 'level2-9' },
{ id: 'e-level1-5-level2-10', source: 'level1-5', target: 'level2-10' },
{ id: 'e-level1-5-level2-11', source: 'level1-5', target: 'level2-11' },
],
},
layout: {
type: 'concentric',
nodeSize: 32,
sortBy: 'degree',
preventOverlap: true,
},
behaviors: ['zoom-canvas', 'drag-canvas', 'drag-element'],
animation: false,
});
graph.render();
```
展开查看完整代码
```javascript
import { Graph } from '@antv/g6';
const graph = new Graph({
container: 'container',
autoFit: 'view',
data: {
nodes: [
{ id: 'center', data: { label: '中心', level: 0 } },
{ id: 'level1-0', data: { label: 'L1-0', level: 1 } },
{ id: 'level1-1', data: { label: 'L1-1', level: 1 } },
{ id: 'level1-2', data: { label: 'L1-2', level: 1 } },
{ id: 'level1-3', data: { label: 'L1-3', level: 1 } },
{ id: 'level1-4', data: { label: 'L1-4', level: 1 } },
{ id: 'level1-5', data: { label: 'L1-5', level: 1 } },
{ id: 'level2-0', data: { label: 'L2-0', level: 2 } },
{ id: 'level2-1', data: { label: 'L2-1', level: 2 } },
{ id: 'level2-2', data: { label: 'L2-2', level: 2 } },
{ id: 'level2-3', data: { label: 'L2-3', level: 2 } },
{ id: 'level2-4', data: { label: 'L2-4', level: 2 } },
{ id: 'level2-5', data: { label: 'L2-5', level: 2 } },
{ id: 'level2-6', data: { label: 'L2-6', level: 2 } },
{ id: 'level2-7', data: { label: 'L2-7', level: 2 } },
{ id: 'level2-8', data: { label: 'L2-8', level: 2 } },
{ id: 'level2-9', data: { label: 'L2-9', level: 2 } },
{ id: 'level2-10', data: { label: 'L2-10', level: 2 } },
{ id: 'level2-11', data: { label: 'L2-11', level: 2 } },
],
edges: [
{ id: 'e-center-level1-0', source: 'center', target: 'level1-0' },
{ id: 'e-center-level1-1', source: 'center', target: 'level1-1' },
{ id: 'e-center-level1-2', source: 'center', target: 'level1-2' },
{ id: 'e-center-level1-3', source: 'center', target: 'level1-3' },
{ id: 'e-center-level1-4', source: 'center', target: 'level1-4' },
{ id: 'e-center-level1-5', source: 'center', target: 'level1-5' },
{ id: 'e-level1-0-level2-0', source: 'level1-0', target: 'level2-0' },
{ id: 'e-level1-0-level2-1', source: 'level1-0', target: 'level2-1' },
{ id: 'e-level1-1-level2-2', source: 'level1-1', target: 'level2-2' },
{ id: 'e-level1-1-level2-3', source: 'level1-1', target: 'level2-3' },
{ id: 'e-level1-2-level2-4', source: 'level1-2', target: 'level2-4' },
{ id: 'e-level1-2-level2-5', source: 'level1-2', target: 'level2-5' },
{ id: 'e-level1-3-level2-6', source: 'level1-3', target: 'level2-6' },
{ id: 'e-level1-3-level2-7', source: 'level1-3', target: 'level2-7' },
{ id: 'e-level1-4-level2-8', source: 'level1-4', target: 'level2-8' },
{ id: 'e-level1-4-level2-9', source: 'level1-4', target: 'level2-9' },
{ id: 'e-level1-5-level2-10', source: 'level1-5', target: 'level2-10' },
{ id: 'e-level1-5-level2-11', source: 'level1-5', target: 'level2-11' },
],
},
layout: {
type: 'concentric',
nodeSize: 32,
sortBy: 'degree',
preventOverlap: true,
},
behaviors: ['zoom-canvas', 'drag-canvas', 'drag-element'],
animation: false,
});
graph.render();
```