- 数据可视化
- 前端
【免费下载链接】F2
📱📈An elegant, interactive and flexible charting library for mobile.
F2 是一个面向移动端的优雅、交互式且灵活的图表库。本篇指南以site/examples/pie/donut示例模块为核心,系统讲解如何在 F2 中实现环形图(Donut Chart)——从基础环形图与中心总计文本,到圆角环形图、双环形图、嵌套环图和环形进度条。读者完成后将掌握polar极坐标、innerRadius内半径、Interval + adjust="stack"堆叠扇区、Legend图例定制以及ArcGuide/TextGuide辅助标记的完整组合用法。
什么是环形图:饼图的变形
环形图是饼图的一种变形,通过中空的圆环形状来展示数据的占比关系(参见 donut 示例文档)。相比传统饼图,环形图的中心空白区域可以用来显示总计信息或其他重要数据,同时保持了饼图直观展示比例的特点。
在 F2 中,环形图并不是一个独立的 Chart 类型,而是通过**极坐标(polar)坐标系 + 转置(transposed)+ 内半径(innerRadius)**组合出的形态。其底层实现位于 packages/f2/src/coord/polar.ts:当坐标系为polar且transposed: true时,数据维度 x 被映射为弧度、y 被映射为半径,配合innerRadius挖空圆心,即得到环形。
基础环形图:完整可运行示例
环形图目录(site/examples/pie/donut/demo)下的第一个示例 donut.jsx 展示了带有中心文本的环形图,可在中心显示总计信息。
/** @jsx jsx */ import { Canvas, Chart, Interval, jsx, Legend } from '@antv/f2'; const data = [ { name: '股票类', percent: 83.59, a: '1' }, { name: '债券类', percent: 2.17, a: '1' }, { name: '现金类', percent: 14.24, a: '1' }, ]; const context = document.getElementById('container').getContext('2d'); const map = {}; data.forEach(function (obj) { map[obj.name] = obj.percent + '%'; }); const Text = (props, context) => { const { coord } = props; const { center } = coord; return ( <group style={{ display: 'flex', left: center.x, top: center.y - context.px2hd('30px'), width: '100px', }} > <text style={{ text: '总资产', fill: '#000', textAlign: 'center' }} /> <text style={{ marginTop: '10px', text: '100.33亿元', fill: '#000', textAlign: 'center' }} /> </group> ); }; const { props } = ( <Canvas context={context} pixelRatio={window.devicePixelRatio} theme={{ padding: [20, 'auto'] }}> <Chart scale={{ percent: { formatter: function formatter(val) { return val + '%'; }, }, }} data={data} coord={{ type: 'polar', transposed: true, innerRadius: 0.7, radius: 0.85, }} > <Interval x="a" y="percent" adjust="stack" color={{ field: 'name', range: ['#FE5D4D', '#3BA4FF', '#737DDE'], }} /> <Legend position="right" itemFormatter={(val, name) => { return map[name]; }} /> <Text /> </Chart> </Canvas> ); const chart = new Canvas(props); chart.render();关键点拆解如下:
coord.type: 'polar':切换到极坐标系,x 轴代表弧度、y 轴代表半径。transposed: true:转置坐标系,让分类字段a沿角度方向排布、数值字段percent沿半径方向延伸,这是扇区正确展开的前提。innerRadius: 0.7:内半径占外半径的 70%,挖空中心形成"环";该值越大,圆环越细。radius: 0.85:外半径占绘图区域短边一半的 85%,为图例和中心文本留出边距。Interval x="a" y="percent" adjust="stack":用区间图形叠加成"堆叠"扇区;所有数据行的a均为'1',因此各分类在同一个角度范围内按percent比例堆叠,构成完整圆环。color字段映射:field: 'name'让每个分类拥有独立颜色,range自定义调色板。- 中心文本:通过自定义组件读取
coord.center拿到圆心坐标,配合px2hd完成高清适配下的像素换算,将"总资产 / 100.33亿元"渲染在环心。 - 图例:
Legend position="right"将图例放在右侧,itemFormatter把默认项名替换为map[name](即百分比字符串),使图例直接显示83.59%之类的占比信息。
核心原理:polar 坐标系与 innerRadius 的底层实现
环形图的形态完全由 packages/f2/src/coord/polar.ts 中的Polar类决定。在update中可以看到两个配置的默认值与换算逻辑:
const { radius: radiusRatio = 1, innerRadius: innerRadiusRatio = 0 } = this.option; // 半径取宽高的最小值 const radius = radiusRatio * (Math.min(width, height) / 2); // 极坐标下 x 表示弧度,y 代表半径 const x: Range = [startAngle, endAngle]; const y: Range = [innerRadiusRatio * radius, radius];radius默认为 1,表示外半径取绘图区域宽高中较小值的一半;innerRadius默认为 0,即默认绘制实心饼图;只有显式设置大于 0 的值(如示例中的0.7),y 值域下界才从圆心抬升到innerRadius * radius,从而挖出中空圆环;- 角度默认从
-Math.PI / 2(12 点方向)顺时针到3 * Math.PI / 2,对应完整一圈。
convertPoint将归一化数据映射为画布坐标:angle = xStart + (xEnd - xStart) * point[xDim]、radius = yStart + (yEnd - yStart) * point[yDim],最终得到center + (cos(angle) * radius, sin(angle) * radius)。理解了这一换算,就能直观推断innerRadius、radius两个参数对环粗细与留白的影响。基类 packages/f2/src/coord/base.ts 中的transposed字段负责在极坐标下交换 x/y 维度的映射角色,正是"角度—半径"布局得以实现的基础。
圆角环形图:扇区圆角样式
donut-radius.jsx 展示了如何为环形图扇区添加圆角,适合营造柔和、现代的数据可视化风格。核心做法是在Interval上通过style配置radius数组:
<Interval x="a" y="percent" adjust="stack" color={{ field: 'name', range: ['#1890FF', '#13C2C2', '#2FC25B', '#FACC14', '#F04864', '#8543E0'], }} style={{ radius: [10, 7, 4, 2], }} />这里的style.radius为扇区四个角指定圆角半径(依次对应左上、右上、右下、左下或按内部绘制顺序解释的角),数值越大圆角越明显。该示例的innerRadius设为 0.5,得到中等粗细的圆环,同时Legend使用默认位置展示分类名称。
双环形图:同一 Canvas 布局两个图表
double-donut.jsx 展示了在同一个Canvas中并排渲染两个环形图的方法:通过给Chart设置style中的width与left控制横向布局,两份数据与配置相同的图表即可并排呈现,适合对比两个同构数据集(例如两个账户的资产构成)。
<Canvas context={context} pixelRatio={window.devicePixelRatio} theme={{ padding: [20, 'auto'] }}> <Chart ... style={{ width: 200 }}> {/* 第一个环形图:图例在 bottom */} </Chart> <Chart ... style={{ left: 200, width: 200 }}> {/* 第二个环形图:图例在 bottom,left 偏移 200 实现并排 */} </Chart> </Canvas>值得注意的细节:
- 每个
Chart均需独立配置scale、data、coord与子组件; theme={{ padding: [20, 'auto'] }}让上下留白固定为 20、左右自动计算;- 中心文本组件
Text在每个图表中复用,读取各自coord.center定位; - 两图图例均放底部(
position="bottom"),避免与并排布局冲突。
嵌套环图:多分类维度的堆叠
cascade.jsx 展示了用单一数据源绘制多环嵌套结构的能力。其数据包含两个分组字段:a(内环分类,取值为 1/2/3)与c(外环分类,取值为 1/2),通过color="c"让颜色随外层分类变化,同时adjust="stack"将同一a下的数据堆叠,形成内外两层嵌套环的视觉效果。
<Chart data={data} coord={{ type: 'polar', transposed: true, innerRadius: 0.5 }} > <Interval x="a" y="b" color="c" adjust="stack" /> <Legend position="top" /> </Chart>该实现的关键在于:极坐标下 x 维度的每个取值对应一圈扇区(a = '1'、'2'、'3'各占 120°),而堆叠后c的不同取值在同一角度范围内按b数值分层,视觉上自然形成"内环为分类、外环为子项占比"的嵌套结构。图例置于顶部以容纳更多分类。
环形进度条:ArcGuide + TextGuide 组合
progress-bar.jsx 将环形图的思路应用到进度条场景:用一条灰色底环 + 一段蓝色高亮弧表示进度,并在环心显示百分比文本。它不再使用Legend,而是引入两个辅助标记组件ArcGuide与TextGuide(从@antv/f2直接导入):
import { jsx, Canvas, Chart, Interval, TextGuide, ArcGuide } from '@antv/f2'; const data = [{ x: '1', y: 85 }]; <Chart data={data} coord={{ type: 'polar', transposed: true, innerRadius: 0.8 }} scale={{ y: { max: 100, min: 0 }, }} > <ArcGuide records={[ { x: 0, y: 0 }, { x: 1, y: 99.98 }, ]} style={{ lineWidth: 11, stroke: '#ccc' }} /> <TextGuide records={[{ x: '1', y: '25%' }]} content={'85%'} style={{ fill: '#1890FF' }} /> <Interval x="x" y="y" /> </Chart>要点说明:
scale.y限定 0~100:让单个数据点y: 85对应整个环的 85%,从而精确控制进度弧长;ArcGuide:records给出弧的起止归一化坐标,style.lineWidth: 11控制环的粗细,stroke: '#ccc'作为灰色底环;Interval:绘制蓝色进度弧(沿用默认主题色),innerRadius: 0.8使环较细,进度视觉更清晰;TextGuide:records中的y: '25%'表示沿半径方向 25% 处,content直接指定要显示的文本(如85%),fill设置颜色。
这套组合把"数据可视化"与"信息标注"分离:Interval负责数据层,ArcGuide/TextGuide负责背景与标注层,是 F2 组件化设计(参见 guide 组件目录)的典型应用。
使用场景总结
环形图在 F2 中适用于以下场景(归纳自 donut 示例文档 与各示例):
- 展示数据占比的同时显示总计信息:基础环形图在环心放置"总资产 / 100.33亿元"式的汇总文本;
- 节省空间的比例展示:圆环比实心饼图视觉更轻盈,中心还可承载其他信息;
- 突出显示重要的汇总数据:环形进度条用大字号百分比 + 高亮弧突出单一指标;
- 多层级数据的嵌套展示:嵌套环图用多层圆环表达分类与子类的层级占比;
- 多数据集的并排对比:双环形图在同一画布内横向呈现两个同构数据集的构成。
延伸阅读
- 完整示例源码与配套说明见 site/examples/pie/donut(目录内含 index.zh.md 与全部 demo);
- 示例清单及标题配置见 meta.json;
- 极坐标实现源码见 packages/f2/src/coord/polar.ts,坐标系基类见 packages/f2/src/coord/base.ts;
- 饼图/环形图相关的完整测试用例可参考 packages/f2/test/components/pieLabel 与 packages/f2/test/components/legend 目录,用于验证图例与标签在极坐标下的渲染行为。
- 数据可视化
- 前端
【免费下载链接】F2
📱📈An elegant, interactive and flexible charting library for mobile.
相关推荐
WTF-Solidity 链上交易调试实战:CirculateBUSD Rugpull 事件逆向分析,损失 227 万美元
WTF Solidity 链上交易调试实战:CirculateBUSD Rugpull 事件逆向分析,损失 227 万美元 本文是 WTF Solidity 仓
数据可视化前端Mermaid 饼图与环形图(Pie & Donut Chart)完整配置指南
Mermaid 饼图与环形图(Pie & Donut Chart)完整配置指南 Mermaid 通过类似 Markdown 的纯文本语法即可生成饼图(pie c
图表库前端数据可视化shadcn-vue 环形图(Donut Chart)组件完整指南:安装、API 与实战用法
shadcn vue 环形图(Donut Chart)组件完整指南:安装、API 与实战用法 环形图(Donut Chart)将数据以圆环形式可视化,与饼图相似
UI组件前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考