尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Highcharts旭日图实战:从数据模型到交互细节的层级可视化指南
接手一个后台数据可视化需求时最让我头疼的不是接口性能而是怎么把一套“大区—品类—单品”的三级销售数据讲清楚。下拉表格太枯燥饼图只能看第一层树图能嵌套但矩形块的占比直觉总差一点。换成Highcharts旭日图Sunburst之后环形从圆心向外一层层展开层级从属关系和数值占比同时被表达出来我才算真正找到顺手的方案。这篇内容写给正在跟层级数据纠缠的前端、数据分析、产品运营同学内容包括数据模型怎么搭、核心配置怎么调、视觉和交互细节怎么打磨以及我踩过的几个真实坑。1. 旭日图到底解决什么问题从饼图到环形层级1.1 一张饼图看不完的层级才是旭日图的用武之地饼图擅长表达“整体中每个部分占多少”但它有个天然限制只能表达一层分类。如果业务数据是“华东大区→家电→空调→格力”这种多级结构你画一个饼图只能看到华东、华北、华南这些一级类目想知道家电在华东内部占多少就得再画一张饼想看空调又在其中占多少还得继续画。这一套操作做下来用户得在多个图表之间来回跳转很难建立起“从属占比”的整体认知。旭日图把这个问题压缩进了一个坐标系每增加一个层级就在环形外侧多套一层圆环所有层级的扇区共享同一个圆心角。也就是说华东大区是一块60度的扇区那么它下面所有品类的扇区也都落在这60度范围内继续向外延伸。这样用户一眼就能同时看到两个信息家电在整个公司销售额中的占比以及家电在华东大区内部的占比。换成生活里的类比这就像切蛋糕时先决定某个大块切多大角度再在大块内部按同样角度继续分小块每一刀都严格保持父级的角度边界。我自己在项目里最常见的用法是这么三类销售结构的层级拆解大区、品类、品牌、SKU、网站流量来源路径渠道、广告系列、落地页、转化、以及权限或组织架构的占比展示。它们共同的特点是层级在3到5层叶节点有明确数值而且用户希望同时看到每一层的量级和从属关系。1.2 旭日图不合适的场景也别硬套旭日图虽然好看但不是万能图。我见过不少人把完全扁平的数据硬塞进来结果就是一圈密密麻麻的扇区文字全挤在一起。如果你遇到下面这几种情况我建议先换个图场景适合旭日图更推荐的做法3到6层级的分类占比关系适合直接使用旭日图只有一层分类、几十个类目不推荐饼图、环形图更直观几百个扁平类目做占比对比不推荐条形图加颜色编码需要精确比较两个数值大小不推荐条形图或表格更有优势连续时间序列的趋势表达不推荐折线图、面积图更合适原因不复杂环形图的扇区角度差别对数值差异的感知没有条形图那么敏锐同一层级节点一多最外圈的扇区会窄到连标签都放不下。层级如果超过6层外层环带的宽度也会越来越小可读性会断崖式下降。所以我在选择旭日图之前通常先问自己一句用户需要看到“从属关系”多于“精确数值”吗如果答案是肯定的旭日图才值得用。2. 先把数据模型搞明白Highcharts旭日图怎么描述一棵树2.1 核心是id、parent、value三个字段Highcharts旭日图的数据结构和很多人想的不一样它并不要求你用嵌套对象而是提供了一个“扁平数组”让每个数据点声明自己的父亲是谁。这有点像公司组织架构系统里每个员工只知道自己汇报给谁系统最终仍然能还原出完整的汇报链路。每个节点的常用字段如下id节点唯一标识相当于身份ID不能重复。parent父节点的id。根节点不用写parent或者写成空字符串。name显示用的名称。value决定扇区大小的数值。一般只在叶子节点上写父节点不写时会自动累加所有子节点的值。color可选手动指定颜色优先级高于全局配置。举一个简单例子const data [ { id: root, name: 全部销售 }, { id: east, parent: root, name: 华东, value: 1200 }, { id: east-appliance, parent: east, name: 家电, value: 700 }, { id: east-daily, parent: east, name: 日化, value: 500 }, { id: north, parent: root, name: 华北, value: 800 }, { id: north-appliance, parent: north, name: 家电, value: 450 }, { id: north-daily, parent: north, name: 日化, value: 350 } ];在这个数组里east-appliance和east-daily的parent都指向east于是Highcharts知道它们属于华东。根节点root没有parent自然就是整棵树的顶部。计算占比时华东的1200会由两个子节点的700和500相加自动得出不需要手写两次。2.2 从一张业务表到旭日图数据转换过程并不复杂实际项目里后台返回的往往是关系型数据库那样的平铺行每一行是“某个品类下某个SKU在某大区的销售额”。比如一份模拟的原始数据表大区品类销售额华东家电700华东日化500华北家电450华北日化350这已经是二级数据转成旭日图的data时还需要补一层根节点同时为每个“大区”补一个父节点字段。通常我会在接口层或者前端统一处理function buildSunburstData(rows) { const result [{ id: root, name: 全部 }]; rows.forEach(row { const regionId row.region; if (!result.find(item item.id regionId)) { result.push({ id: regionId, parent: root, name: row.region }); } result.push({ id: ${row.region}-${row.category}, parent: regionId, name: row.category, value: row.sales }); }); return result; }这里有个关键细节父节点大区本身不写value只让叶子节点写数值。这样Highcharts会把各品类金额相加得到大区的总量角度才会和内层扇区保持对齐。如果你手贱给父节点也写了一个和子节点总和不一致的value图表会按你写的数据画视觉上可能出现父级扇区角度和子级扇区比例对不上的诡异现象。如果原始数据层级更深比如到品牌、SKU思路完全一样每个子节点id用路径拼接保证唯一parent指向上级id。比如“华东-家电-格力”其parent就是“华东-家电”这个节点。3. Highcharts旭日图核心配置拆解从能出图到能看3.1 最小可用配置先让图画出来Highcharts使用旭日图需要在引入核心脚本之外再引入sunburst模块script srchttps://code.highcharts.com/highcharts.js/script script srchttps://code.highcharts.com/modules/sunburst.js/script如果项目是离线环境就把这两个文件下载到本地再引用。接着写最基础的配置Highcharts.chart(container, { chart: { type: sunburst }, title: { text: 某零售企业区域销售结构 }, series: [{ type: sunburst, data: [ { id: root, name: 全部 }, { id: east, parent: root, name: 华东, value: 1200 }, { id: east-appliance, parent: east, name: 家电, value: 700 }, { id: east-daily, parent: east, name: 日化, value: 500 } ] }] });这一段跑起来你已经能得到一张基础旭日图根节点是中心圆华东扇区从中心向外展开。没有数据标签也没有提示框信息量少但结构已经对了。我建议所有刚接触旭日图的人都从这一步开始先把图跑通再逐步加配置而不是一上来就塞一堆levels、dataLabels、tooltip最后出了问题都不知道是哪个配置导致的。3.2 颜色策略让每一层都在视觉上“是一家人”旭日图最大的视觉风险是颜色过于杂乱。默认情况下Highcharts会给扇区分配不同的色板颜色同一父节点的子节点可能是红蓝绿各色虽然区分度强但看多了会觉得“花”。对于层级数据我更推荐“同层同族色系”的思路相邻层级的颜色保持冷暖一致仅靠明度或饱和度拉开层次。在Highcharts里可以用levels数组按层级统一配置plotOptions: { sunburst: { levels: [{ level: 1, color: #666d78, borderColor: #ffffff, borderWidth: 2 }, { level: 2, color: #8fa3bd, borderColor: #ffffff, borderWidth: 1.5 }] } }这里level从1开始计数1对应第一层节点通常是顶层分类2对应第二层。用白色边框把扇区隔开环形图会立刻变得清爽很多。如果想让某个扇区突出直接在该数据点上配置color{ id: east-appliance, parent: east, name: 家电, value: 700, color: #ff7043 }我常用的做法是业务上需要强调的“重点品类”用高饱和强调色其他节点用同一族系的浅色这样读者不会迷失在彩虹色里。3.3 数据标签策略什么时候显示、显示什么旭日图的数据标签是最容易翻车的配置项多层扇区叠在一起默认显示很容易出现文字互相遮挡。我的经验是分层处理里层只显示名称最外层可以显示“名称数值”太窄的扇区干脆不显示文字留在tooltip里体现。基础配置如下plotOptions: { sunburst: { dataLabels: { format: {point.name}, allowOverlap: false, crop: true, overflow: none, style: { textOutline: 2px contrast, color: #333333 } } } }format支持HTML想把数值也放出来可以写成dataLabels: { format: b{point.name}/bbr{point.value} }allowOverlap设为false时Highcharts会自动把放不下的标签隐藏掉这是防止“叠成黑坨”的第一道防线。crop和overflow配合控制文字是否截断、是否允许溢出扇区边界。推荐打开crop防止外层文字跑到图表外面去。需要特别说明的是如果你想让最里层和中间层的标签字号、颜色不同可以用dataLabels的style回调或按point.level判断但多数场景下统一格式反而更干净。3.4 tooltip定制把鼠标悬停变成信息密度最高的时刻扇区再大能直接写的文字也有限所以tooltip承担了大部分信息细节。我个人习惯在tooltip里展示四样东西节点名称、数值、该节点占整体的比例、完整路径。可以这样写tooltip: { formatter: function() { const point this.point; const total this.series.getTotal(); const percent (point.value / total * 100).toFixed(1); let path point.name; let node point.node; while (node.parent) { node node.parent; if (node.name) { path node.name path; } } return b path /bbr 数值 point.value br 占整体 percent %; } }这样鼠标悬停到任意扇区时用户能看到“华东 家电”的完整路径而不是只看到孤零零的“家电”两个字。这里用series.getTotal()拿全部数值总和计算占比比较稳。需要注意的是point.percentage在不同版本里语义有差异所以我一般不用它而是自己算避免版本升级后出现意料之外的结果。4. 把“环形可视化艺术”落到实处布局、交互与视觉细节4.1 levelSize控制环宽比例决定图的“呼吸感”很多刚上手的人不懂为什么旭日图看起来“闷”说白了就是每层环宽平均分配整个圆环又密又厚。levelSize配置可以按层级分别指定环带的厚度单位既可以是像素也可以是百分比不同Highcharts版本的写法略有差异但思路一致让最外层比内层更宽给数据标签留出空间。一个典型的配置长这样levelSize: { 1: 22, 2: 28, 3: 34 }含义是根节点那一圈厚度22像素第二层28像素第三层34像素。外层环更宽标签就有更多空间水平排布不会因为扇区太窄而被截断。中心圆如果留白太少整个图会显得“实”缺少视觉重心如果留白太多外层又被压缩。我个人的习惯是让中心圆面积占到整个图表宽度的15%到20%左右既保留了“从圆心向外发散的动势”又不会喧宾夺主。4.2 点击事件与钻取从全貌到明细的一条路旭日图通常已经展示了所有层级但它也可以配合点击事件做“钻取式”交互。Highcharts部分版本内置了allowTraversingTree配置允许点击非叶子节点后切换到子层级再点击中心圆圈返回。如果你的版本支持可以这样开启plotOptions: { sunburst: { allowTraversingTree: true } }如果不支持或想自己控制监听point的click事件即可plotOptions: { sunburst: { point: { events: { click: function() { // 拿当前节点的id请求右侧明细列表的数据 console.log(this.id); } } } } }我在实际项目中用第二种方式比较多因为可以顺带做很多联动点击“华东”扇区右侧表格刷新为华东的品类明细页面标题也跟着切换。这种交互比单纯切图更符合业务直觉——从总览到明细一次点击完成。4.3 图例与辅助说明不要让读者靠猜旭日图本身在扇区上写了名称所以图例不是必需品。如果开启默认图例反而会把所有叶子节点都列出来又长又乱。我通常的做法是关闭图例或者只保留顶层节点的图例legend: { enabled: true, align: right, verticalAlign: middle, layout: vertical }注意Highcharts的legend无法直接过滤到只显示某一层级所以如果嫌乱直接用symbolRadius等微调或者干脆enabled: false靠dataLabels和tooltip承担图例的功能。颜色本身暗示了层级归属时图例的意义就更小。必要的时候我会在图表下方加一行小字注释例如“内圈为区域外圈为品类扇区角度对应销售额占比”这比让用户在图表上自己摸索要友好得多。4.4 动效与大数据量下的体验取舍旭日图的默认动画在中小数据量下很漂亮节点会逐个展开层级感强。但节点一旦达到上千动画就可能变成累赘影响操作流畅度。追求流畅时可以把动画关掉chart: { animation: false }或者只保留一个非常短的过渡plotOptions: { sunburst: { animation: { duration: 300 } } }动态更新数据时先用setData并关闭重绘再一次性redrawconst series chart.series[0]; series.setData(newData, false); chart.redraw();这样能避免频繁重绘导致的闪烁。这个技巧在做联动筛选时尤其好用比如用户切换年份旭日图整体切换数据但视角和缩放状态保持不变。5. 我见过最多人翻车的几个地方旭日图避坑清单5.1 层级莫名消失或错乱先查id、parent和value旭日图排错优先级最高的三个字段就是id、parent、value。我见过一个同事调了半天图里只有根节点和一个大扇区原因是两个节点的id都为“a-1”Highcharts把它们当成同一个节点处理了于是数据“合并”成一个。解决方式很简单所有id都用能保证唯一的路径串比如“east-appliance-1001”而不是简单的“1001”。第二个常见问题是parent指向一个不存在的id。比如华东写成“east”但子节点的parent却写了“华东”大小写或编码不一致子节点直接变成“无家可归”的状态Highcharts里通常表现为多出一个独立的孤岛扇区。排查时可以打印整个data数组人工检查每个parent是否都能在id列表中找到。第三个问题是父节点和子节点数值矛盾。父节点手动写了value又同时有子节点当两者不一致时图表会出现让人费解的对不齐现象。我的建议是要么父节点不写value用子节点累加要么干脆把父节点value定义为子节点之和保持数据口径一致。5.2 中文标签叠成一团别把所有层级都抢着显示中文标签比英文长在窄扇区里更容易溢出。最典型的翻车现场是三层数据每一层都开了标签结果外圈标签被截断中圈标签和里圈标签叠在一起图表基本没法看。处理思路严格来说是“信息降级”当扇区角度太小时不显示标签让用户悬停看tooltip。一个有效配置是dataLabels: { allowOverlap: false, rotation: 0, crop: true, overflow: none, style: { textOutline: 1px contrast, fontSize: 11px } }allowOverlap:false让Highcharts自动隐藏挤不下的标签rotation设为0保证文字水平排布不会出一堆弧形文字。注意textOutline不要设太粗否则中文会变成“空心字”一般1px到2px就够。如果层级确实多我更建议只给最外层开标签里层全部靠tooltip这样图面非常干净。5.3 别天真地以为“数据量随便上”Highcharts的旭日图对几百上千个节点都可以轻松处理但到了几千甚至上万个扇区时渲染和交互都会开始掉帧tooltip悬停延迟明显。我曾经在一个项目里遇到近三千个SKU节点刷新一次图表要等两三秒交互体验很差。后来做了两层处理第一层按销售额排序只保留前200个叶子节点其余合并成“其他”第二层把SKU级别的下钻放到点击事件里初始视图只展示到品类。最终视觉效果更好性能问题也消失了。这个思路其实对所有可视化都适用不是把所有数据一股脑丢给图表而是让图表展示合适的聚合粒度细节留到交互里。6. 一个可以直接拿去改的完整示例页面6.1 完整HTML与JavaScript代码下面这个页面集成了上面提到的绝大部分配置三级数据、按层级配色、限制标签重叠、自定义tooltip、关闭动画适合作为项目起点。!DOCTYPE html html langzh-CN head meta charsetUTF-8 title旭日图示例/title script srchttps://code.highcharts.com/highcharts.js/script script srchttps://code.highcharts.com/modules/sunburst.js/script /head body div idcontainer stylewidth: 100%; height: 600px;/div script Highcharts.chart(container, { chart: { type: sunburst, animation: false }, title: { text: 某区域销售结构示例 }, tooltip: { formatter: function () { const point this.point; const total this.series.getTotal(); const percent (point.value / total * 100).toFixed(1); let path point.name; let node point.node; while (node.parent) { node node.parent; if (node.name) { path node.name path; } } return b path /bbr 数值 point.value br 占整体 percent %; } }, plotOptions: { sunburst: { borderColor: #ffffff, borderWidth: 1.5, dataLabels: { format: {point.name}, allowOverlap: false, crop: true, overflow: none, style: { textOutline: 1px contrast, fontSize: 11px, color: #333333 } }, levels: [{ level: 1, color: #666d78 }, { level: 2, color: #8fa3bd }, { level: 3, color: #b8c7de }] } }, series: [{ type: sunburst, name: 销售额, data: [ { id: root, name: 全部 }, { id: east, parent: root, name: 华东, value: 1200 }, { id: east-appliance, parent: east, name: 家电, value: 700 }, { id: east-appliance-air, parent: east-appliance, name: 空调, value: 400 }, { id: east-appliance-fridge, parent: east-appliance, name: 冰箱, value: 300 }, { id: east-daily, parent: east, name: 日化, value: 500 }, { id: north, parent: root, name: 华北, value: 800 }, { id: north-appliance, parent: north, name: 家电, value: 450 }, { id: north-daily, parent: north, name: 日化, value: 350 } ] }] }); /script /body /html如果这段代码直接放到本地打开应该能看到一张三层旭日图根节点为深灰色圆环第二层为灰蓝色第三层是更浅的灰蓝色。鼠标悬停时tooltip会显示“华东 家电 空调”这类完整路径和占比。6.2 从示例到业务的三个改造方向第一数据源替换。把series里的静态data换成fetch请求接口返回平铺行数据再按前面写的buildSunburstData函数转换就可以适配绝大多数后台系统。第二自定义强调色。如果业务上要突出某个重点品类比如“空调”直接在对应数据点里加color: #ff7043。需要给多个节点统一加色可以在转换函数里判断名称后添加。第三交互联动。给点事件加click监听当前节点id传出去让页面其他组件响应该扇区。比如右侧放一个同级明细表格点击不同扇区就刷新表格内容。最后再说两句实际使用中的体会如果让我给刚接触旭日图的人提一个建议我会说不要一上来就追求视觉效果先把数据模型捋顺。id、parent、value这三个字段的关系理清了后面所有配置都是锦上添花。配色和标签控制在图表审美里占比很大但它们救不了一个层级混乱的数据模型。我自己的习惯是先跑通最小配置再逐项加levels、dataLabels、tooltip和交互每一步都刷新看效果这样即使出了问题也知道是哪一步引入的。旭日图这门“环形可视化艺术”说到底是用几何语言把层级关系讲清楚。只要读者能三秒内看出整体由几部分组成、每个部分内部又长什么样这张图就成功了那些漂亮的细节都只是加分项。
RELATED

相关推荐

为业务微调Rerank:从零构建领域专属多语言重排模型完整教程

为业务微调Rerank:从零构建领域专属多语言重排模型完整教程

【免费下载链接】Rerank 项目地址: https://ai.gitcode.com/netease-youdao/Rerank 点击查看 免费下载 Rerank 是一个基于 XLM-RoBERTa 的多语言重排(Reranking)模型,能够输出查询(query)与文档的相关性得…

📅 2026/10/18 7:07:20
饰面肌理:空间质感表达,从板材表面开始

饰面肌理:空间质感表达,从板材表面开始

室内设计中,材料肌理是很容易被家装爱好者忽略的维度。我们常常讨论配色、布局,却很少关注板材表面的触感与光影,而肌理饰面,恰好补齐了这一环。 传统平面饰面板,视觉效果单一,在灯光下容易显得扁平。肌理板…

📅 2026/10/18 7:07:20
JS逆向全流程实战:从浏览器断点调试到加密参数还原

JS逆向全流程实战:从浏览器断点调试到加密参数还原

懂行的朋友都知道,网上关于JS逆向的教程要么太零散、只讲某个点,要么门槛太高、上来就甩一堆混淆代码让人劝退。今天这篇不整虚的,就从一个纯粹的实操视角,把从打开浏览器到抠出加密参数的全流程拆开揉碎讲清楚。标题里提到的“断…

📅 2026/10/18 7:07:20
MORE NEWS

更多资讯

📰

REA技术解析:从响应式事件架构到资源高效应用

项目标题为“rea”,但提供的输入内容中,项目正文为空、关键词未列出、摘要描述缺失,且所有相关热词与网络搜索内容均为空白(仅显示)。这意味着:当前输入不构成一个可解析的项目信息单元。作为一名从业十余年…

📰

NTKO控件集成实战:Office文档Web嵌入的底层原理与避坑指南

简介:本资源是面向Web开发工程师与企业级文档系统集成者的NTKO Office控件实战学习包,聚焦解决在线文档编辑、权限管控与多端兼容等核心集成难题。压缩包共37个文件,涵盖9份关键文档(含V4/V5接口参考、JavaScript编程指南、技术白…

📰

Postman与JMeter集成:从接口调试到性能压测的闭环实践

做接口测试的人几乎都绕不开Postman,做性能测试的人几乎都绕不开JMeter。但多数人习惯把这两个工具各用各的:Postman调接口、JMeter压接口,中间隔着一道明显的断层。实际工作中,这道断层会带来不少麻烦——接口在Postman里调得好好…

📰

第 12 篇|Aspen Plus 进阶与工程案例:从稳态到 Aspen Dynamics 动态入门

第 12 篇|Aspen Plus 进阶与工程案例:从稳态到 Aspen Dynamics 动态入门版本声明块 软件:aspenONE V15 版 Aspen Plus 与 Aspen Plus Dynamics(Windows 64 位桌面版;截至 2026-10 公开渠道最新大版本为 V15&#xff09…

📰

WMSST结合MCNN-BiGRU的滚动轴承故障诊断方法及Matlab实现

搞故障诊断的人应该都有同感:设备一开机,传感器回来的振动信号看着就是一波波毛刺,细看全是噪声、谐波和调制成分搅在一起。以前靠频谱分析找特征频率,碰上变转速、变载荷这类非平稳工况,常规傅里叶手段基本失灵。我近…

📰

微信小程序+Java毕业设计:校园兼职系统实战指南

简介:本资源是一套完整的校园兼职信息管理平台毕业设计实现,面向计算机相关专业本科生及Java全栈初学者,解决高校学生兼职信息获取不及时、岗位匹配低效、企业发布流程繁琐等实际问题。压缩包共1254个文件,涵盖228个JS逻辑脚本、1…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬