news 2026/9/3 13:45:31

Chart.js 饼图与环形图实战:doughnut 定制、偏移与空状态处理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Chart.js 饼图与环形图实战:doughnut 定制、偏移与空状态处理

Chart.js 饼图与环形图实战:doughnut 定制、偏移与空状态处理

【免费下载链接】Chart.jsSimple HTML5 Charts using thetag项目地址: https://gitcode.com/gh_mirrors/ch/Chart.js

Chart.js 是一款基于 HTML5<canvas>标签的轻量级图表库,而饼图(pie)与环形图(doughnut)正是其中最受欢迎、上手最快的两种图表类型——它们天生适合展示"部分占整体"的比例关系。本文将带你快速掌握 doughnut 的定制技巧:如何调整中空比例、如何把某一块"拉出来"突出显示(offset 偏移)、以及在数据为空时如何优雅地处理空状态,让新手也能一步到位做出专业的占比图表。

一、pie 与 doughnut:同一个"类",只差一个参数

很多新手会疑惑:饼图和环形图为什么要写两份代码?

答案是:它们在 Chart.js 中其实是同一个控制器,仅在一个默认值上有区别——cutout(中间挖掉的空洞比例):

图表类型cutout默认值效果
pie(饼图)0实心圆
doughnut(环形图)'50%'中间镂空,呈环状

其余配置、事件、动画逻辑完全一致。它们的默认值都定义在 controller.doughnut.js 中,而 pie 类型只是在 controller.pie.js 里克隆了这份默认值并把cutout改为0

💡 实战建议:数据只有"占比"一个维度时用 pie;需要在中间放 KPI 数字、图标或标题时选 doughnut,信息密度更高。

二、五分钟上手:第一个环形图

一个最简环形图只需要labels(图例和提示框的文本)加一组data数值,Chart.js 会自动求和并计算每块弧长:

const data = { labels: ['Red', 'Blue', 'Yellow'], datasets: [{ label: 'My First Dataset', data: [300, 50, 100], backgroundColor: [ 'rgb(255, 99, 132)', 'rgb(54, 162, 235)', 'rgb(255, 205, 86)' ], hoverOffset: 4 // 鼠标悬停时该块向外弹出 4 像素 }] }; const config = { type: 'doughnut', data: data };

type改成'pie'就变成实心饼图,一行都不用动。完整示例可参考 docs/charts/doughnut.md 与 docs/samples/other-charts/doughnut.md。

三、doughnut 定制:cutout、radius、rotation 与 circumference

环形图有 4 个"骨架级"配置选项(均可写百分比字符串或像素数字):

选项默认值作用
cutout'50%'(doughnut)/0(pie)中心空洞大小,可设为'80%'做出细窄的进度环
radius'100%'图表外径
rotation0第一块弧线从哪个角度开始画(0 = 正上方)
circumference360总扫过的角度,设为180即得到半环图
options: { cutout: '70%', // 细环 rotation: 90, // 从右侧 3 点钟方向开始 circumference: 270 // 只画 270 度,留一个缺口 }

📌 小贴士:当circumference < 360时,Chart.js 会通过getRatioAndOffset()重新计算弧线的外包尺寸并自动居中,图形不会被裁切,这一点在源码 controller.doughnut.js 中可以找到。另外每块弧的圆角、虚线边框由borderRadiusborderDashborderAlign'center'/'inner')控制,详见官方文档 docs/charts/doughnut.md。

四、offset 偏移实战:把某一块"弹出来"

想突出某一块数据?两个参数配合使用效果最好:

  • offset:静态偏移(像素),让指定弧块常驻"拉出"圆环之外。支持两种写法:
    • 数字:所有弧统一偏移,例如offset: 10
    • 数组:逐块指定,例如offset: [0, 0, 30, 0, 0]—— 只有第 3 块被拉出,非常适合做"重点指标高亮"。
  • hoverOffset:悬停时的动态偏移(默认0),配合hoverBackgroundColor使用,鼠标划过哪块哪块就弹出,交互反馈非常直观。

Chart.js 在计算可用半径时会通过getMaxOffset()把所有offset/hoverOffset计入安全边距,所以拉出的弧块永远不会被画布边缘裁掉,这块逻辑在 controller.doughnut.js 中实现。

datasets: [{ data: [300, 50, 100], offset: [0, 0, 30], // 只把 Yellow 拉出来 hoverOffset: 4 // 其余块悬停时轻微弹出 }]

对应的测试用例可以直接查看 test/fixtures/controller.doughnut/doughnut-offset.js,运行后能看到偏移弧块与圆环的视觉效果对比。

五、spacing 与 weight:间隙弧线与多层嵌套环

  • spacing+spacingMode:给所有弧块之间加固定像素间隙,形成"分段环"的视觉效果。spacingMode有三种模式:

    • angular(默认):按角度均匀分配间隙;
    • proportional:间隙随弧长等比缩放;
    • parallel:间隙保持平行(两侧间距一致),视觉更整齐。

    效果对比可参考 docs/samples/other-charts/ 目录下的 doughnut 示例与测试图 doughnut-spacing.png、doughnut-spacing-parallel.png。

  • weight:控制数据集的"环带粗细"。环形图支持多个数据集叠加,每个数据集是一个同心圆环,粗细按weight之和等比分配。官方示例 multi-series-pie.md 就用 4 组数据集 + 不同 weight 画出了"整体 vs 分组"的多层投票环。

    ⚠️ 注意:多层环默认共用同一组角度,若每个数据集数值总和不同,弧段角度会错位;配合图例的generateLabels自定义(示例中已给出写法)才能让图例与嵌套环一一对应。

六、空状态处理:用 afterDraw 插件画一个"占位环"

当接口还没返回数据、或筛选后data: []时,doughnut 默认只画一个空圆——看起来像渲染失败。官方给出的标准做法是写一个迷你插件,在afterDraw钩子里判断"是否真的没数据",然后在图表中央补画一个浅色圆环占位:

const plugin = { id: 'emptyDoughnut', afterDraw(chart, args, options) { const hasData = chart.data.datasets.some(d => d.data.length > 0); if (hasData) return; const {chartArea: {left, top, right, bottom}, ctx} = chart; const centerX = (left + right) / 2; const centerY = (top + bottom) / 2; const r = Math.min(right - left, bottom - top) / 2; ctx.beginPath(); ctx.lineWidth = options.width || 2; ctx.strokeStyle = options.color || 'rgba(255, 128, 0, 0.5)'; ctx.arc(centerX, centerY, r - (options.radiusDecrease || 0), 0, 2 * Math.PI); ctx.stroke(); } };

插件的colorwidthradiusDecrease都可以通过options.plugins.emptyDoughnut传参自定义,完整可运行版本见 docs/samples/plugins/doughnut-empty-state.md。

七、图例交互:点击隐藏某一块

doughnut 内置了贴心的图例交互:点击图例会调用toggleDataVisibility()隐藏对应的单块弧(而不是整个数据集),剩余的弧会自动重算角度填满整圆,非常适合做多条件筛选场景。这个默认行为定义在 controller.doughnut.js 的overrides中。若想按数据集整体隐藏/显示,可参考多层环示例中自定义onClick的写法(multi-series-pie.md)。

八、总结与扩展阅读

一句话回顾本文的 doughnut 定制清单:

  1. 选类型pie实心 /doughnut镂空,本质同一控制器,只差cutout
  2. 调骨架cutoutradiusrotationcircumference四个选项控制形态,半环图、细环图信手拈来;
  3. 做高亮offset(支持数组逐块偏移)静态拉出 +hoverOffset悬停弹出;
  4. 加细节spacing/spacingMode做间隙弧,weight做多层嵌套环;
  5. 防尴尬afterDraw插件 + 占位圆环优雅处理空状态。

📚 延伸阅读(均为仓库内文件):

  • 完整配置参考:docs/charts/doughnut.md
  • 弧元素(arc element)底层实现:src/elements/element.arc.ts
  • 官方可交互示例:docs/samples/other-charts/pie.md、docs/samples/other-charts/doughnut.md
  • 行为测试用例(可当"活文档"看):test/fixtures/controller.doughnut/

【免费下载链接】Chart.jsSimple HTML5 Charts using thetag项目地址: https://gitcode.com/gh_mirrors/ch/Chart.js

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 13:44:53

智慧排水监测系统平台是什么?5 大核心功能与应用价值详解

地下排水管网是城市运行中不可见的“毛细血管”&#xff0c;一旦堵塞或超负荷&#xff0c;便可能引发内涝、污水冒溢等连锁问题。近年来&#xff0c;国内多个城市开始借助物联网、大数据与人工智能技术建设智慧排水监测平台&#xff0c;将分散的管网数据汇聚为统一管理视图。本…

作者头像 李华
网站建设 2026/9/3 13:44:41

Dify+RAG实战:零代码搭建私有知识库问答系统(含Qwen模型配置)

1. 先搞清楚 Dify RAG 到底能帮你解决什么问题如果你手头有一堆内部文档、产品手册、技术资料或者行业规范&#xff0c;每次想快速查个具体信息都得人工翻找&#xff0c;那这个组合就值得试试。Dify 是一个能让你用图形界面拖拽搭建 AI 应用的低代码平台&#xff0c;RAG&#…

作者头像 李华
网站建设 2026/9/3 13:41:29

单片机毕设选题推荐:基于 STM32 单片机的车载阈值可调智能通风系统设计 基于 STM32 与移动 APP 的车载远程监控终端设计(013606)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机&#xff0c;Java、小程序技术领域和毕业项目实战 ✌️…

作者头像 李华
网站建设 2026/9/3 13:40:48

OCRmyPDF:让扫描PDF变得可检索

OCRmyPDF&#xff1a;让扫描PDF变得可检索 【免费下载链接】OCRmyPDF OCRmyPDF adds an OCR text layer to scanned PDF files, allowing them to be searched 项目地址: https://gitcode.com/GitHub_Trending/oc/OCRmyPDF 拿到一个扫描版PDF&#xff0c;选不中字、搜不…

作者头像 李华