Chart.js 轴标签技术指南:轴标题配置与自定义刻度格式
【免费下载链接】Chart.jsSimple HTML5 Charts using the项目地址: https://gitcode.com/gh_mirrors/ch/Chart.js
当使用 Chart.js 创建图表时,为了让查看者理解正在查看的数据含义,需要为坐标轴添加标签说明。本文聚焦 docs/axes/labelling.md 中讲解的两大核心能力——轴标题(Scale Title)配置与自定义刻度格式(Custom Tick Formats),并结合仓库源码深入讲解其底层实现。读完本文后,你将掌握如何为笛卡尔坐标轴添加带完整样式控制的标题、如何通过ticks.callback定制千变万化的刻度文本,以及如何安全地复用默认格式化器避免重写完整格式化逻辑。
一、轴标题配置(Scale Title Configuration)
轴标题用于说明该轴所代表的数据含义(例如 "人口数量"、"响应选项")。其配置命名空间为options.scales[scaleId].title,注意该功能仅适用于笛卡尔坐标轴(cartesian axes),雷达图、极区图等径向坐标轴不支持。
1.1 配置项总览
| 名称 | 类型 | 默认值 | 描述 |
|---|---|---|---|
display | boolean | false | 为true时显示轴标题 |
align | string | 'center' | 轴标题的对齐方式,可选值为'start'、'center'、'end' |
text | string|string[] | '' | 标题文本(例如 "# of People" 或 "Response Choices"),传入数组可渲染为多行文本 |
color | Color | Chart.defaults.color | 标签颜色 |
strokeColor | Color | — | 文字描边颜色 |
strokeWidth | number | — | 描边宽度(像素) |
font | Font | Chart.defaults.font | 字体配置,详见 Fonts |
padding | Padding | 4 | 轴标签周围的留白,仅top、bottom与y方向被实现 |
1.2 完整可运行的示例
下面的示例展示了一个带标题的折线图:X 轴标题为 "Month",Y 轴标题为 "Value",并分别自定义了颜色、字体与内边距(源自仓库 docs/samples/scale-options/titles.md 的官方示例配置):
const config = { type: 'line', data: data, options: { responsive: true, scales: { x: { display: true, title: { display: true, text: 'Month', color: '#911', font: { family: 'Comic Sans MS', size: 20, weight: 'bold', lineHeight: 1.2, }, padding: {top: 20, left: 0, right: 0, bottom: 0} } }, y: { display: true, title: { display: true, text: 'Value', color: '#191', font: { family: 'Times', size: 20, style: 'normal', lineHeight: 1.2 }, padding: {top: 30, left: 0, right: 0, bottom: 0} } } } }, };注意示例中padding传入的是完整的{top, left, right, bottom}对象,但由于源码只实现了top、bottom与y方向,left/right方向的留白不会生效。
1.3 源码级实现原理
轴标题的默认值与绘制逻辑可以在仓库源码中直接印证:
- 默认值定义:src/core/core.scale.defaults.js 中
scale.title默认display: false、text: '',且padding的默认结构为{top: 4, bottom: 4}(即文档表格中的默认值4);同时通过defaults.route('scale.title', 'color', '', 'color')(src/core/core.scale.defaults.js)将标题颜色路由到全局color默认值,这也解释了为何color的默认值是Chart.defaults.color。 - 绘制流程:src/core/core.scale.js 中的
drawTitle()方法按以下顺序处理:先判断title.display是否为真,否则直接返回;随后通过toFont(title.font)解析字体、toPadding(title.padding)解析留白、读取title.align对齐方式;若title.text是数组,则按font.lineHeight * (text.length - 1)累加多行偏移(这正是text支持string[]多行文本的实现基础);最后调用renderText统一渲染,并传入strokeColor、strokeWidth实现描边效果。 - 标题定位:src/core/core.scale.js 中的
titleArgs()负责计算标题坐标与旋转角——对于非水平轴(如左侧 Y 轴)会设置rotation = -HALF_PI(即 -90 度)实现竖排标题,align则通过_alignStartEnd决定标题在轴线方向上的起止位置。 - 绘制顺序:src/core/core.scale.js 的
draw()方法中,drawTitle()位于drawBackground()、drawGrid()、drawBorder()之后、drawLabels()(刻度标签)之前,即标题绘制在网格之上、刻度标签之下。
二、创建自定义刻度格式(Creating Custom Tick Formats)
除了轴标题,另一个高频需求是改造刻度标签的文本内容——例如给数值加上货币符号$、百分比后缀、或者按业务规则过滤掉部分刻度。这需要覆盖轴配置中的ticks.callback方法。
2.1 回调函数签名与运行上下文
ticks.callback方法接收 3 个参数:
value—— 刻度值,为该刻度所属比例的"内部数据格式"。对时间刻度(time scale)而言它是一个时间戳;index—— 刻度在刻度数组中的索引;ticks—— 包含所有刻度对象的数组。
方法的调用作用域(this)被绑定到比例对象本身,因此你可以在回调中访问比例的属性与方法(如this.getLabelForValue、this.chart等)。
特别的技巧:若回调返回null或undefined,则该刻度对应的网格线会被隐藏。这一机制常被用来"过滤"刻度标签——在 docs/samples/scale-options/ticks.md 的官方示例中,通过return index % 2 === 0 ? this.getLabelForValue(val) : '';隐藏了每隔一个的刻度标签。
Tip(category 轴的特别提醒):category 轴是折线图、柱状图默认的 X 轴,它的内部数据格式是**索引值(index)**而非标签文本。要取回真正的标签,请使用
this.getLabelForValue(value)(API: getLabelForValue)。从源码看,src/scales/scale.category.js 中_getLabelForValue的实现就是通过this.getLabels()拿到标签数组后按下标取值。
2.2 基础示例:为 Y 轴数值添加美元符号
以下示例(源自原文档)演示如何让 Y 轴的每个刻度标签都带上前缀$:
const chart = new Chart(ctx, { type: 'line', data: data, options: { scales: { y: { ticks: { // Include a dollar sign in the ticks callback: function(value, index, ticks) { return '$' + value; } } } } } });2.3 复用默认格式化器:避免丢失所有格式化行为
需要注意的是:一旦覆盖ticks.callback,你就需要对标签的全部格式化负责(小数位数、科学计数法、本地化数字分隔符等都不会再自动应用)。如果你的需求只是"在默认格式基础上加前缀/后缀",最稳妥的做法是调用默认格式化器后再修改其输出:
ticks: { callback: function(value, index, ticks) { // call the default formatter, forwarding `this` return '$' + Chart.Ticks.formatters.numeric.apply(this, [value, index, ticks]); } }关键点在于使用apply(this, ...)转发当前作用域——因为默认的 numeric 格式化器内部会读取this.chart.options.locale与this.options.ticks.format(见 src/core/core.ticks.js),不转发this会导致本地化与ticks.format配置失效。
2.4 源码级补充:默认格式化器都做了什么
src/core/core.ticks.js 中Chart.Ticks.formatters提供了三套内置格式化器,理解它们有助于你决定何时覆写、何时复用:
values(value)—— 默认值格式化器:数组原样返回(用于多行标签),其余值转成字符串;numeric(tickValue, index, ticks)—— 数值格式化器:针对极小(< 1e-4)或极大(> 1e+15)的刻度自动切换为科学计数法;根据相邻刻度的间隔动态计算保留的小数位数;并合并this.options.ticks.format中的自定义Intl.NumberFormat选项;对0永远不显示小数位;logarithmic(tickValue, index, ticks)—— 对数轴专用格式化器:只在"有意义"的刻度位置(如 1、2、3、5、10、15 的整数幂位置)显示标签,其余位置返回空字符串,以保持对数轴的整洁。
此外,src/core/core.scale.defaults.js 中刻度默认配置还有一组与标签显示密切相关的选项:display: true(是否显示刻度标签)、padding: 3(刻度标签与轴线的偏移)、textStrokeWidth: 0与textStrokeColor: ''(文本描边,与轴标题的strokeColor/strokeWidth对应)、autoSkip: true(自动跳过重叠标签)等;而ticks.callback的默认值即为Ticks.formatters.values。更多刻度通用配置见 docs/axes/_common_ticks.md。
2.5 进阶实践:基于比例类型选择格式化策略
由于callback中的value是"内部数据格式",实际应用中可按比例类型分别处理:
- 线性/数值轴(linear):
value就是数值本身,直接拼接前缀/后缀即可; - 时间轴(time / timeseries):
value是时间戳(毫秒),需要用this.getLabelForValue(value)或自行new Date(value)格式化; - 类别轴(category):
value是索引,务必用this.getLabelForValue(value)取得真实标签(参见 src/scales/scale.category.js 的getLabelForValue公开方法)。
三、配套示例与延伸阅读
仓库中与本主题直接对应的官方示例:
- Tick configuration sample:演示多行标签、标签过滤、刻度颜色修改与 X 轴刻度对齐(
ticks.align的start/center/end动态切换); - Title configuration sample:演示轴标题的对齐、字体与颜色配置(即上文 1.2 节完整示例)。
与本主题相关的仓库文档,可继续深入:
- 轴标题配置的默认值与路由:查看
scale.title与scale.ticks的完整默认值; - 轴标题绘制实现:
drawTitle()与titleArgs()的完整实现; - 内置刻度格式化器:
Chart.Ticks.formatters的values、numeric、logarithmic实现; - 类别轴实现:category 轴
getLabelForValue与默认ticks.callback的实现; - 刻度通用配置:
options.scales[scaleId].ticks命名空间下的全部通用选项; - 坐标轴样式:包含网格线、边框与刻度相关的更多样式配置;
- 颜色、字体、内边距:本主题所依赖的三个基础配置类型。
【免费下载链接】Chart.jsSimple HTML5 Charts using the项目地址: https://gitcode.com/gh_mirrors/ch/Chart.js
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考