VISALL 动态桑基图 (Dynamic Sankey) 使用文档
简介
动态桑基图是VISALL数据可视化库中的特殊图表类型,用于展示随时间变化的流量分配情况。该组件支持动态时间轴切换,能够直观地展示不同时间点的节点关系和流量大小。适用于展示资金流向、能源分配、人口迁移等场景中的动态变化过程。
基本用法
import { render } from 'path/to/bundle.esm.min.js';
// 创建动态桑基图
const chart = render(container, {
layers: [
{
type: 'dynamicSankey',
dataIndex: 0,
encoding: {
name: 'nodeName', // 节点名称字段
value: 'nodeValue', // 节点值字段
valueText: 'displayValue', // 显示值字段
target: 'targetNodes', // 目标节点字段
date: 'timeStamp', // 时间字段
describe: 'description', // 描述字段
unit: 'unit', // 单位字段
otherInfo: 'extraInfo' // 附加信息字段
},
animationDuration: 1000 // 动画持续时间
}
],
data: [
{
values: [
{
nodeName: '节点A',
nodeValue: 100,
displayValue: '100',
depth: 0,
root: true,
itemStyle: { color: '#5470c6' },
unit: '万元',
targetNodes: [
{ name: '节点B', value: 40 },
{ name: '节点C', value: 60 }
],
timeStamp: '2023-01',
description: '第一季度流向',
extraInfo: [
{ name: '增长率', value: '12%', unit: '' },
{ name: '占比', value: '40', unit: '%' }
]
},
// ... 更多数据
]
}
]
});
配置参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| encoding.name | string | - | 节点名称映射字段,必须提供一个字符串类型字段 |
| encoding.value | string | - | 节点值映射字段,必须是数值类型 |
| encoding.valueText | string | - | 节点显示值映射字段,字符串或数值类型 |
| encoding.target | string | - | 目标节点映射字段,必须是数组类型 |
| encoding.date | string | - | 时间映射字段,字符串或日期类型 |
| encoding.describe | string | - | 描述映射字段,字符串类型 |
| encoding.unit | string | - | 单位映射字段,字符串类型 |
| encoding.otherInfo | string | - | 附加信息映射字段,数组类型 |
| animationDuration | number | 1000 | 动画持续时间(毫秒) |
| dataIndex | number | 0 | 指定使用的数据集索引 |
数据要求
- name字段要求为字符串类型
- value字段要求为数值类型
- target字段要求为数组类型,包含目标节点信息
- date字段要求为字符串或日期类型
- 节点必须包含depth属性,用于确定节点层级
- 根节点必须设置root属性为true
- 每个节点需要有itemStyle属性定义样式
- 数据量至少需要大于1条
- 需要按时间点组织数据,保证时间顺序
高级用法
1. 自定义节点样式
可以通过itemStyle属性自定义节点的样式:
{
nodeName: '节点A',
itemStyle: {
color: '#5470c6',
opacity: 0.8,
borderWidth: 1,
borderColor: '#333'
}
}
2. 添加详细信息
通过otherInfo字段添加节点的详细信息,这些信息将在tooltip中显示:
{
nodeName: '节点A',
// ... 其他属性
extraInfo: [
{ name: '增长率', value: '12%', unit: '' },
{ name: '占比', value: '40', unit: '%' },
{ name: '同比', value: '+8.5', unit: '%' }
]
}
3. 自定义时间轴
时间轴基于date字段自动生成,会按照时间顺序排列:
{
// ... 其他配置
encoding: {
// ... 其他编码
date: 'quarter' // 使用季度字段作为时间轴
}
}
潜规则与注意事项
-
节点层级设置:
- 每个节点必须通过depth属性定义其层级关系。
- 根节点的depth通常设置为0,并且root属性设置为true。
- 不同层级的节点会按照深度自动排列。
-
数据排序机制:
- 时间轴数据会自动按照升序排序,无需手动排序。
- 排序通过transforms实现:
[{ type: 'deDuplication' }, { type: 'sort', order: 'ascending' }]。
-
标签显示规则:
- 根节点和普通节点的标签显示规则不同,根节点会显示更多信息。
- 当节点名称过长时,会自动截断并显示省略号。
- 标签文字宽度通过
measureTextWidth函数动态计算。
-
链接生成机制:
- 链接数据通过
ThsDataVStandardChart.helper.sankeyHelper.handleLinks方法自动生成。 - 同一时间点的节点之间的链接关系基于target字段定义。
- 链接数据通过
-
节点宽度计算:
- 节点宽度百分比通过
ThsDataVStandardChart.helper.sankeyHelper.handleNodeLengthPercent计算。 - 节点宽度范围在33%到66%之间,采用线性计算方式。
- 节点宽度百分比通过
-
时间轴交互:
- 时间轴切换会触发图表动画重绘。
- 动画通过
chartIns.play方法实现,确保平滑的过渡效果。
实现原理
动态桑基图组件内部使用了复杂的数据处理逻辑,主要包括以下步骤:
- 数据预处理:时间排序、去重和数据分组
- 节点构建:基于每个时间点构建节点数据
- 链接构建:根据target字段生成节点之间的连接关系
- 时间轴生成:基于date字段生成时间轴
- 动态渲染:根据时间轴位置动态切换数据视图
类型兼容性问题
使用本组件时,需要注意以下类型兼容性问题:
- target字段必须是数组类型,且包含name和value属性
- 根节点必须正确设置root属性为true
- 每个节点必须包含必要的属性,如depth、name、value等
- 数据处理过程中会进行扁平化操作,请确保数据结构符合要求
示例
基础动态桑基图
{
type: 'dynamicSankey',
encoding: {
name: 'nodeName',
value: 'nodeValue',
valueText: 'displayValue',
target: 'targetNodes',
date: 'timeStamp',
describe: 'description',
unit: 'unit',
otherInfo: 'extraInfo'
}
}
自定义动画速度
{
type: 'dynamicSankey',
encoding: {
// ... 编码配置
},
animationDuration: 800 // 更快的动画速度
}
常见问题解决
-
图表不显示或显示异常
- 检查数据结构是否符合要求,特别是target字段
- 确保每个节点都有正确的depth和root属性
- 验证时间字段是否有效且可排序
-
链接显示错误
- 检查target字段的数据结构
- 确保源节点和目标节点的名称匹配
- 验证链接值是否为数值类型
-
时间轴切换问题
- 确保date字段中的时间数据格式一致
- 检查时间数据是否可正确排序
- 验证每个时间点都有完整的节点和链接数据
-
节点标签显示不全
- 节点名称过长时会自动截断,可以考虑使用更短的名称
- 调整容器大小以获得更好的显示效果