Skip to content

Commit

Permalink
feat(mark): add chord mark (#5810)
Browse files Browse the repository at this point in the history
* feat(mark): add chord mark

* docs: add docs for chord mark

---------

Co-authored-by: GavinChen <chenrui92@gmail.com>
  • Loading branch information
Gavinchen92 and GavinChen committed Nov 20, 2023
1 parent 2f9c729 commit 42fdab2
Show file tree
Hide file tree
Showing 15 changed files with 1,092 additions and 6 deletions.
67 changes: 67 additions & 0 deletions __tests__/data/population-flow.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
[
{
"source": "北京",
"target": "天津",
"value": 30
},
{
"source": "北京",
"target": "上海",
"value": 80
},
{
"source": "北京",
"target": "河北",
"value": 46
},
{
"source": "北京",
"target": "辽宁",
"value": 49
},
{
"source": "北京",
"target": "黑龙江",
"value": 69
},
{
"source": "北京",
"target": "吉林",
"value": 19
},
{
"source": "天津",
"target": "河北",
"value": 62
},
{
"source": "天津",
"target": "辽宁",
"value": 82
},
{
"source": "天津",
"target": "上海",
"value": 16
},
{
"source": "上海",
"target": "黑龙江",
"value": 16
},
{
"source": "河北",
"target": "黑龙江",
"value": 76
},
{
"source": "河北",
"target": "内蒙古",
"value": 24
},
{
"source": "内蒙古",
"target": "北京",
"value": 32
}
]
650 changes: 650 additions & 0 deletions __tests__/integration/snapshots/static/populationFlowChordDefault.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions __tests__/plots/static/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,4 @@ export { mockLineZeroY } from './mock-line-zero-y';
export { mockLineCloseX } from './mock-line-close-x';
export { premierLeagueTable } from './premier-league-table';
export { singlePointBasic } from './single-point-basic';
export { populationFlowChordDefault } from './population-flow-chord-default';
17 changes: 17 additions & 0 deletions __tests__/plots/static/population-flow-chord-default.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { G2Spec } from '../../../src';

export async function populationFlowChordDefault(): Promise<G2Spec> {
return {
type: 'chord',
data: {
type: 'fetch',
value: 'data/population-flow.json',
transform: [
{
type: 'custom',
callback: (d) => ({ links: d }),
},
],
},
};
}
10 changes: 9 additions & 1 deletion __tests__/unit/lib/graph.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
import { graphlib } from '../../../src/lib';
import { ForceGraph, Tree, Sankey, Treemap, Pack } from '../../../src/mark';
import {
ForceGraph,
Tree,
Sankey,
Treemap,
Pack,
Chord,
} from '../../../src/mark';
import { Cluster, Arc } from '../../../src/data';

describe('graphlib', () => {
Expand All @@ -10,6 +17,7 @@ describe('graphlib', () => {
'mark.forceGraph': ForceGraph,
'mark.tree': Tree,
'mark.sankey': Sankey,
'mark.chord': Chord,
'mark.treemap': Treemap,
'mark.pack': Pack,
});
Expand Down
2 changes: 2 additions & 0 deletions __tests__/unit/lib/std.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import {
Density as DensityGeometry,
Heatmap,
Liquid,
Chord,
} from '../../../src/mark';
import { Category10, Category20 } from '../../../src/palette';
import {
Expand Down Expand Up @@ -248,6 +249,7 @@ describe('stdlib', () => {
'mark.rangeX': RangeX,
'mark.rangeY': RangeY,
'mark.sankey': Sankey,
'mark.chord': Chord,
'mark.path': Path,
'mark.treemap': Treemap,
'mark.pack': PackGeometry,
Expand Down
5 changes: 5 additions & 0 deletions site/docs/spec/mark/chord.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: chord
order: 1
---
`<embed src="@/docs/spec/mark/chord.zh.md"></embed>`
45 changes: 45 additions & 0 deletions site/docs/spec/mark/chord.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
title: chord
order: 1
---
弦图(Chord diagram)是一种用于可视化关系和连接的图表形式。它主要用于展示多个实体之间的相互关系、联系的强度或流量的分布。

## 开始使用

<img alt="chord" src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*x6h_RZR7r0QAAAAAAAAAAAAADmJ7AQ/original" width="600" />

```js
import { Chart } from '@antv/g2';

const chart = new Chart({
container: 'container',
autoFit: true,
});

chart.chord().data({
type: 'fetch',
value: 'https://assets.antv.antgroup.com/g2/population-flow.json',
transform: [
{
type: 'custom',
callback: (d) => ({ links: d }),
},
],
});

chart.render();
```

## 选项

| 属性 | 描述 | 类型 | 默认值 |
| ---------------- | --------------------------------------------------------- | ----------------------------- | ----------------------------- |
| y | 布局时y轴的坐标 | `number` | `0` |
| id | 节点的键 | `Function<string \| number>` | `(node) => node.key` |
| source | 设置弦图的来源节点数据字段 | `Function<string>` | `(node) => node.source` |
| target | 设置弦图的目标节点数据字段 | `Function<string>` | `(node) => node.target` |
| sourceWeight | 来源的权重 | `Function<number>` | `(node) => node.value \|\| 1` |
| targetWeight | 目标的权重 | `Function<number>` | `(node) => node.value \|\| 1` |
| sortBy | 排序方法,可选id, weight, frequency排序或者自定义排序方法 | `string \| Function<number>` | - |
| nodeWidthRatio | 弦图节点的宽度配置,0 ~ 1,参考画布的宽度 | `number`  | `0.05` |
| nodePaddingRatio | 弦图节点之间的间距,0 ~ 1,参考画布的高度 | `number` | `0.1` |
90 changes: 90 additions & 0 deletions site/examples/graph/network/demo/chord.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { Chart } from '@antv/g2';
import { schemeTableau10 } from 'd3-scale-chromatic';

const chart = new Chart({
container: 'container',
width: 900,
height: 600,
});

const data = [
{
source: '北京',
target: '天津',
value: 30,
},
{
source: '北京',
target: '上海',
value: 80,
},
{
source: '北京',
target: '河北',
value: 46,
},
{
source: '北京',
target: '辽宁',
value: 49,
},
{
source: '北京',
target: '黑龙江',
value: 69,
},
{
source: '北京',
target: '吉林',
value: 19,
},
{
source: '天津',
target: '河北',
value: 62,
},
{
source: '天津',
target: '辽宁',
value: 82,
},
{
source: '天津',
target: '上海',
value: 16,
},
{
source: '上海',
target: '黑龙江',
value: 16,
},
{
source: '河北',
target: '黑龙江',
value: 76,
},
{
source: '河北',
target: '内蒙古',
value: 24,
},
{
source: '内蒙古',
target: '北京',
value: 32,
},
];

chart
.chord()
.data({
value: { links: data },
})
.layout({
nodeWidthRatio: 0.05,
})
.scale('color', { range: schemeTableau10 })
.style('labelFontSize', 15)
.style('linkFillOpacity', 0.6);

chart.render();
8 changes: 8 additions & 0 deletions site/examples/graph/network/demo/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@
},
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*dACBR7ANcfEAAAAAAAAAAAAADmJ7AQ/original"
},
{
"filename": "chord.ts",
"title": {
"zh": "弦图",
"en": "Chord"
},
"screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*x6h_RZR7r0QAAAAAAAAAAAAADmJ7AQ/original"
},
{
"filename": "forceGraph.ts",
"title": {
Expand Down
8 changes: 4 additions & 4 deletions src/data/utils/arc/arc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,16 +190,16 @@ export function Arc(options?: ArcOptions) {
*/
sourceEdges.map((edge) => {
const w = (edge.sourceWeight / value) * width;
edge.x[0] = node.x[0] + offset;
edge.x[1] = node.x[0] + offset + w;
edge.x[0] = x[0] + offset;
edge.x[1] = x[0] + offset + w;

offset += w;
});

targetEdges.forEach((edge) => {
const w = (edge.targetWeight / value) * width;
edge.x[3] = node.x[0] + offset;
edge.x[2] = node.x[0] + offset + w;
edge.x[3] = x[0] + offset;
edge.x[2] = x[0] + offset + w;

offset += w;
});
Expand Down
3 changes: 2 additions & 1 deletion src/lib/graph.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Sankey, Treemap, Pack, ForceGraph, Tree } from '../mark';
import { Sankey, Treemap, Pack, ForceGraph, Tree, Chord } from '../mark';
import { Arc, Cluster } from '../data';

export function graphlib() {
Expand All @@ -9,6 +9,7 @@ export function graphlib() {
'mark.tree': Tree,
'mark.pack': Pack,
'mark.sankey': Sankey,
'mark.chord': Chord,
'mark.treemap': Treemap,
} as const;
}

0 comments on commit 42fdab2

Please sign in to comment.