旭日图(Sunburst)是一种展示层次结构数据的可视化图表,其中层次结构的每个层级由一个圆环表示,圆心代表树的根节点。这种可视化方式既类似于矩形树图(Treemap),又结合了饼图(Pie Chart)的特点。
核心特点:
-
多层圆环:每一圈代表一个数据层级
-
圆心为根:最内圈是根节点,向外辐射
-
面积代表权重:每个扇区的角度(或面积)代表该节点的数值大小
-
父子关系:外层扇区属于内层扇区的子节点
与矩形树图的对比:
| 特性 | 旭日图 | 矩形树图 |
|---|---|---|
| 形状 | 同心圆环 | 嵌套矩形 |
| 空间利用率 | 中等 | 高 |
| 层级清晰度 | 非常直观 | 需要适应 |
| 适合的数据量 | 中等层级 | 大量节点 |
与饼图的对比:
| 特性 | 旭日图 | 饼图 |
|---|---|---|
| 层级支持 | 支持多层 | 仅一层 |
| 比例展示 | 支持 | 支持 |
| 复杂度 | 高 | 低 |
二、快速上手:第一个旭日图
2.1 模块加载
旭日图需要加载专门的模块:
html
<!-- 加载核心库 -->
<script src="https://code.highcharts.com/highcharts.js"></script>
<!-- 加载旭日图模块 -->
<script src="https://code.highcharts.com/modules/sunburst.js"></script>
<!-- 可选:加载导出模块 -->
<script src="https://code.highcharts.com/modules/exporting.js"></script>
2.2 基础示例:全球人口分布
html
<!DOCTYPE html>
<html>
<head>
<title>Highcharts旭日图示例 - 全球人口</title>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/sunburst.js"></script>
</head>
<body>
<div id="container" style="width: 800px; height: 600px;"></div>
<script>
Highcharts.chart('container', {
chart: {
type: 'sunburst'
},
title: {
text: '2023年全球人口分布(百万)'
},
subtitle: {
text: '数据来源:联合国人口司'
},
series: [{
type: 'sunburst',
name: '人口',
data: [{
name: '亚洲',
id: 'asia',
value: 4700
}, {
name: '中国',
parent: 'asia',
value: 1425
}, {
name: '印度',
parent: 'asia',
value: 1417
}, {
name: '日本',
parent: 'asia',
value: 125
}, {
name: '欧洲',
id: 'europe',
value: 745
}, {
name: '德国',
parent: 'europe',
value: 84
}, {
name: '法国',
parent: 'europe',
value: 68
}, {
name: '英国',
parent: 'europe',
value: 67
}, {
name: '美洲',
id: 'americas',
value: 1040
}, {
name: '美国',
parent: 'americas',
value: 340
}, {
name: '巴西',
parent: 'americas',
value: 216
}],
allowDrillToNode: true, // 允许点击钻取
levelIsConstant: false, // 层级是否恒定
dataLabels: {
format: '{point.name}',
filter: {
property: 'innerArcLength',
operator: '>',
value: 16
}
},
levels: [{
level: 1,
levelSize: {
unit: 'percentage',
value: 25
},
dataLabels: {
enabled: false // 第一层不显示标签
}
}, {
level: 2,
levelSize: {
unit: 'percentage',
value: 25
},
colorByPoint: true // 第二层按点着色
}]
}],
tooltip: {
pointFormat: '{point.name}: <b>{point.value}</b> 百万人口'
}
});
</script>
</body>
</html>
三、深入理解旭日图的数据结构
3.1 树形数据结构
旭日图的数据以树形结构组织,每个点代表一个节点,节点可以有子节点。系统会自动创建一个顶层节点作为根节点。
基本数据格式:
javascript
data: [{
name: '节点名称', // 显示名称
id: 'unique-id', // 唯一标识符(供子节点引用)
parent: 'parent-id', // 父节点ID(省略或不存在则自动归为根节点)
value: 数值, // 节点的数值(决定扇区大小)
color: '颜色' // 可选:自定义颜色
}]
3.2 根节点的处理机制
-
系统会自动创建一个不可见的根节点
-
如果某个节点的
parent未定义或指向不存在的 ID,该节点会被自动设置为根节点的子节点 -
根节点本身不显示,但其子节点形成最内层圆环
3.3 数据构建示例
javascript
// 构建一个三层树形结构
data: [{
name: '一级节点A',
id: 'A',
value: 10
}, {
name: '二级节点A1',
parent: 'A',
value: 6
}, {
name: '三级节点A1a',
parent: 'A1',
value: 3
}, {
name: '三级节点A1b',
parent: 'A1',
value: 2
}, {
name: '二级节点A2',
parent: 'A',
value: 4
}, {
name: '一级节点B',
id: 'B',
value: 5
}]
3.4 值的计算规则
旭日图中,节点的显示大小遵循以下规则:
-
如果节点有
value属性,则使用该值 -
如果节点没有
value但有子节点,系统会自动计算所有子节点的value之和 -
根节点的值是所有一级节点值的总和
javascript
// 示例:自动计算总值
data: [{
name: '部门A',
id: 'deptA'
// 没有value,将自动计算子节点总和 = 30
}, {
name: '团队A1',
parent: 'deptA',
value: 20
}, {
name: '团队A2',
parent: 'deptA',
value: 10
}]
四、层级配置(Levels)详解
4.1 什么是 levels?
levels 选项允许你针对特定层级设置样式和属性,让该层级的所有节点具有统一的视觉特征。
4.2 基础层级配置
javascript
series: [{
type: 'sunburst',
data: [...],
levels: [{
level: 1, // 第一层(紧邻根节点的层级)
colorByPoint: true, // 每个点不同颜色
levelSize: {
unit: 'percentage', // 单位:percentage 或 pixels
value: 25 // 该层圆环占整个半径的25%
},
dataLabels: {
enabled: true,
format: '{point.name}'
}
}, {
level: 2, // 第二层
colorByPoint: false, // 继承父节点颜色
levelSize: {
unit: 'percentage',
value: 20
}
}]
}]
4.3 levelSize 配置详解
levelSize 控制每一层圆环的厚度:
javascript
levelSize: {
// unit: 'percentage' - 相对整个半径的百分比
// unit: 'weight' - 相对其他层的权重
// unit: 'pixels' - 固定像素值
unit: 'percentage',
value: 25 // 占整个半径的25%
}
不同单位的对比:
-
percentage:所有层的百分比之和应为100 -
weight:按权重比例分配厚度(如第一层权重2,第二层权重3,则厚度比为2:3) -
pixels:固定像素值,适用于精确布局
4.4 静态层级 vs 动态层级
静态层级(默认):
html
levelIsConstant: true
// 层级编号在整个树结构中固定不变,无论当前显示到哪一层
动态层级:
html
levelIsConstant: false
// 当用户钻取到某个节点后,该节点成为新的第一层