和弦图
上一篇
子弹图
Loading...
和弦图(Chord Diagram)是一种显示矩阵中数据间相互关系的可视化方法,节点数据沿圆周径向排列,节点之间使用带权重(有宽度)的弧线链接。特别适合展示多个实体之间的相互关系和流量。
和弦图能够直观地展示多个节点之间的复杂关系网络,特别适用于展示双向流动数据,如人口迁移、贸易流向、资金往来、软件依赖关系等场景。
英文名:Chord Diagram
图表类型 | 和弦图 |
---|---|
适合的数据 | 节点数据集(可选)、边数据集:源节点、目标节点、流量值 |
功能 | 观察节点关系,展示多个实体间的双向流动关系 |
数据与图形的映射 | 权重映射到节点和边的宽度 源节点和目标节点映射到圆周上的弧段位置 节点可以用颜色区分 |
适合的数据条数 | 节点数据两组以上,5-15 个节点效果最佳 |
例子 1: 适合应用到流量关系展示
下图展示了不同城市之间的人口流动情况,通过和弦图可以清晰地看到各城市间的双向流动关系。
source(源城市) | target(目标城市) | value(流动人口) |
---|---|---|
北京 | 上海 | 100,000 |
北京 | 广州 | 80,000 |
上海 | 北京 | 70,000 |
上海 | 广州 | 90,000 |
广州 | 深圳 | 120,000 |
import { Chart } from '@antv/g2';const chart = new Chart({container: 'container',theme: 'classic',});chart.options({type: 'chord',autoFit: true,data: {value: {links: [{ source: '北京', target: '上海', value: 100 },{ source: '北京', target: '广州', value: 80 },{ source: '北京', target: '深圳', value: 60 },{ source: '上海', target: '北京', value: 70 },{ source: '上海', target: '广州', value: 90 },{ source: '上海', target: '深圳', value: 50 },{ source: '广州', target: '北京', value: 40 },{ source: '广州', target: '上海', value: 85 },{ source: '广州', target: '深圳', value: 120 },{ source: '深圳', target: '北京', value: 35 },{ source: '深圳', target: '上海', value: 45 },{ source: '深圳', target: '广州', value: 110 },],},},layout: { nodeWidthRatio: 0.05 },scale: {color: {type: 'ordinal',range: ['#5B8FF9', '#5AD8A6', '#F6BD16', '#E86452'],},},style: {labelFontSize: 12,labelFill: '#333',linkFillOpacity: 0.6,},tooltip: {items: [{ field: 'source', name: '源城市' },{ field: 'target', name: '目标城市' },{ field: 'value', name: '流动人口' },],},interaction: [{type: 'elementHighlight',background: true,},],});chart.render();
例子 2: 展示软件依赖关系
下图展示了软件包之间的依赖关系,每个节点表示一个独立的包,每条边展示了包与包之间的依赖关系。边的粗细表示依赖的强度。
import { Chart } from '@antv/g2';const chart = new Chart({container: 'container',theme: 'classic',});chart.options({type: 'chord',autoFit: true,data: {value: {links: [{ source: 'vis.core', target: 'vis.data', value: 85 },{ source: 'vis.core', target: 'vis.event', value: 45 },{ source: 'vis.core', target: 'vis.util', value: 120 },{ source: 'vis.data', target: 'vis.core', value: 30 },{ source: 'vis.data', target: 'vis.util', value: 60 },{ source: 'vis.event', target: 'vis.core', value: 25 },{ source: 'vis.event', target: 'vis.data', value: 40 },{ source: 'vis.util', target: 'vis.core', value: 15 },{ source: 'vis.render', target: 'vis.core', value: 95 },{ source: 'vis.render', target: 'vis.util', value: 55 },{ source: 'vis.layout', target: 'vis.core', value: 75 },{ source: 'vis.layout', target: 'vis.util', value: 35 },],},},layout: { nodeWidthRatio: 0.05 },scale: {color: {type: 'ordinal',range: ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd'],},},style: {labelFontSize: 11,labelFill: '#333',linkFillOpacity: 0.6,},tooltip: {items: [{ field: 'source', name: '依赖包' },{ field: 'target', name: '目标包' },{ field: 'value', name: '依赖强度' },],},interaction: [{type: 'elementHighlight',background: true,},],});chart.render();
说明:
例子 1: 节点过多导致可读性差
当节点数量超过15个时,和弦图会变得拥挤难读,连接线重叠严重。
import { Chart } from '@antv/g2';const chart = new Chart({container: 'container',theme: 'classic',});// 模拟20个省份的数据,节点过多导致可读性差const provinces = ['北京', '上海', '广州', '深圳', '杭州', '南京', '武汉', '成都', '西安', '重庆','天津', '苏州', '青岛', '大连', '厦门', '宁波', '长沙', '郑州', '济南', '福州'];const data = [];provinces.forEach((source, i) => {provinces.forEach((target, j) => {if (i !== j && Math.random() > 0.7) {data.push({source,target,value: Math.floor(Math.random() * 50) + 10});}});});chart.options({type: 'chord',autoFit: true,data: {value: {links: data.slice(0, 40), // 只取前40条数据演示},},layout: { nodeWidthRatio: 0.05 },style: {labelFontSize: 8, // 字体变小以适应更多标签labelFill: '#666',linkFillOpacity: 0.5,},});chart.render();
例子 2: 不适合展示层次关系
和弦图主要用于展示平等节点间的关系,不适合展示有明显层次结构的数据。
下图展示了某个时段用户使用Uber软件在美国旧金山各个城市之间乘车交通的情况。图中的节点表示城市,节点大小表示了交通流量的多少,从图中可以看出,交通行为主要发生在几个主要城市之间。
以下是使用自定义颜色和样式的和弦图示例:
import { Chart } from '@antv/g2';const chart = new Chart({container: 'container',theme: 'classic',});chart.options({type: 'chord',autoFit: true,data: {value: {links: [{ source: '中国', target: '美国', value: 4200 },{ source: '中国', target: '日本', value: 3200 },{ source: '中国', target: '韩国', value: 2800 },{ source: '美国', target: '中国', value: 1200 },{ source: '美国', target: '墨西哥', value: 6100 },{ source: '日本', target: '中国', value: 1400 },{ source: '日本', target: '韩国', value: 800 },{ source: '韩国', target: '中国', value: 1100 },],},},layout: { nodeWidthRatio: 0.05 },scale: {color: {type: 'ordinal',range: ['#5B8FF9', '#5AD8A6', '#F6BD16', '#E86452'],},},style: {labelFontSize: 14,labelFontWeight: 'bold',labelFill: '#000',linkFillOpacity: 0.7,},tooltip: {items: [{ field: 'source', name: '出口国' },{ field: 'target', name: '进口国' },{ field: 'value', name: '贸易额(亿美元)' },],},interaction: [{type: 'elementHighlight',background: true,},],});chart.render();