Chart.js 坐标轴通用配置权威指南:从 scaleId 到 min/max、堆叠与回调的完整解析
【免费下载链接】Chart.jsSimple HTML5 Charts using the项目地址: https://gitcode.com/gh_mirrors/ch/Chart.js
Chart.js 的所有坐标轴(笛卡尔坐标轴与径向坐标轴)都共享一套以options.scales[scaleId]为命名空间的通用配置项,涵盖坐标轴类型、显示、范围、堆叠、网格、边框与刻度等核心行为。本篇指南以官方文档 docs/axes/_common.md 为主体,结合 docs/axes/index.md 与源码实现,系统讲解每个通用选项的作用、默认值、适用范围与底层机制,帮助你掌握轴范围控制(min/max/suggested*)、数据堆叠、刻度定制以及通过回调钩子介入坐标轴更新流程等实战能力。
一、坐标轴与 scaleId 基础:理解通用配置的入口
在深入通用配置项之前,先明确坐标轴(Axis,源码中称为 Scale)的定位方式。Chart.js 中坐标轴配置全部挂在options.scales对象下,每个坐标轴以自定义的scaleId作为键名,例如:
options: { scales: { x: { /* x 轴配置 */ }, y: { /* y 轴配置 */ }, r: { /* 径向坐标轴配置 */ } } }默认情况下,笛卡尔图表使用'x'和'y'两个 scaleId,径向图表(雷达图、极区图)使用'r'。每个数据集通过xAxisID、yAxisID或rAxisID映射到对应坐标轴;如果未指定 ID,则使用该方向的第一个坐标轴;如果找不到对应坐标轴,Chart.js 会自动创建一个新坐标轴。
以下示例展示了 scaleId 的三种典型用法(完整示例见 docs/axes/index.md):
// 1. 默认生成 'x' 与 'y' 两个坐标轴 let chart = new Chart(ctx, { type: 'line' }); // 2. 自定义 scaleId 'myScale',position 为 'right' 时自动判定轴方向为 'y' let chart2 = new Chart(ctx, { type: 'bar', data: { datasets: [{ data: [1, 2, 3] }] }, options: { scales: { myScale: { type: 'logarithmic', position: 'right', // axis 由 position 推导为 'y' } } } }); // 3. 通过 yAxisID 将数据集绑定到命名坐标轴 let chart3 = new Chart(ctx, { type: 'bar', data: { datasets: [{ yAxisID: 'yAxis' }] }, options: { scales: { xAxis: { type: 'time', // 未显式指定 position/axis 时,轴方向由 id 首字母 'x' 推断 } } } });需要说明的是,坐标轴类型可以由内置类型(linear、logarithmic、category、time、timeseries等,见 docs/axes/cartesian/index.md)或自定义注册的类型名称指定,这正是type通用配置项存在的意义。
二、所有坐标轴通用配置项(核心表格)
以下配置作用于options.scales[scaleId],是所有轴类型都支持的通用选项(来自 docs/axes/_common.md):
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type | string | — | 使用的坐标轴类型。可注册自定义坐标轴类型并通过字符串键指定,从而为图表更换某个轴的底层类型。 |
alignToPixels | boolean | false | 是否将像素值对齐到设备像素。 |
backgroundColor | Color | — | 坐标轴区域的背景色。 |
border | object | — | 边框配置。详见 Border 配置。 |
display | boolean|string | true | 控制坐标轴全局可见性(true显示,false隐藏)。当为'auto'时,仅当至少一个关联数据集可见时才显示该坐标轴。 |
grid | object | — | 网格线配置。详见 Grid 配置。 |
min | number | — | 用户自定义的坐标轴最小值,覆盖从数据计算出的最小值。详见 轴范围设置。 |
max | number | — | 用户自定义的坐标轴最大值,覆盖从数据计算出的最大值。详见 轴范围设置。 |
reverse | boolean | false | 反转坐标轴方向。 |
stacked | boolean|string | false | 数据是否堆叠。详见 数据堆叠。 |
suggestedMax | number | — | 计算数据最大值时的调整值。详见 轴范围设置。 |
suggestedMin | number | — | 计算数据最小值时的调整值。详见 轴范围设置。 |
ticks | object | — | 刻度配置。详见 Tick 配置。 |
weight | number | 0 | 用于坐标轴排序的权重,权重越高的坐标轴离图表区域越远。 |
:::tip 提示 以上只是所有坐标轴共享的通用配置。各具体轴类型(线性、对数、类别、时间等)还有各自专属的配置项,请参考对应轴类型的文档,例如 docs/axes/cartesian/linear.md、docs/axes/cartesian/time.md。 :::
2.1 从源码看通用默认值
这些通用配置的默认值定义在 src/core/core.scale.defaults.js 中,源码确认了以下关键默认行为:
defaults.set('scale', { display: true, offset: false, reverse: false, beginAtZero: false, bounds: 'ticks', // 边界策略:保证刻度完全可见 clip: true, // 裁剪超出图表区域的内容 grace: 0, // 数据范围外的留白余量 grid: { display: true, lineWidth: 1, drawOnChartArea: true, drawTicks: true, tickLength: 8 }, border: { display: true, dash: [], dashOffset: 0.0, width: 1 }, ticks: { display: true, autoSkip: true, padding: 3, minRotation: 0, maxRotation: 50, ... }, ... });值得注意的细节包括:
bounds(边界策略)默认是'ticks',即优先保证刻度标签完全可见、数据可以被截断;切换为'data'则优先保证数据完全可见、范围外的刻度被移除。该策略会被显式的min/max绕过。ticks.callback默认使用Ticks.formatters.values(即原样输出数值字符串,不做格式化)。- 默认值通过
defaults.route(...)将scale.ticks.color、scale.grid.color、scale.border.color、scale.title.color统一路由到全局的borderColor/color,因此修改全局颜色即可联动多个组件。
2.2weight:多坐标轴布局排序的底层逻辑
weight的语义在 src/core/core.layouts.js 的布局排序逻辑中得到了直接印证:布局系统按weight对布局项排序,权重高者离图表区域更远:
return array.sort((a, b) => { const v0 = reverse ? b : a; const v1 = reverse ? a : b; return v0.weight === v1.weight ? v0.index - v1.index : v0.weight - v1.weight; });从源码结构可以推断,当同一侧存在多个坐标轴(如左右双 Y 轴)时,通过调整各轴的weight,可以控制它们距离图表绘制区域的距离顺序,从而避免轴标题、刻度相互重叠。
三、通用刻度配置(Tick Options)
刻度(ticks)是坐标轴最常定制的部分。以下通用刻度选项作用于options.scales[scaleId].ticks(来自 docs/axes/_common_ticks.md),被所有坐标轴共享:
| 名称 | 类型 | 可脚本化 | 默认值 | 说明 |
|---|---|---|---|---|
backdropColor | Color | Yes | 'rgba(255, 255, 255, 0.75)' | 刻度标签背景(backdrop)的颜色。 |
backdropPadding | Padding | — | 2 | 刻度标签背景的内边距。 |
callback | function | — | — | 返回刻度值在图表上的字符串表示。详见 自定义刻度格式。 |
display | boolean | — | true | 是否显示刻度标签。 |
color | Color | Yes | Chart.defaults.color | 刻度颜色。 |
font | Font | Yes | Chart.defaults.font | 刻度字体,见 Fonts。 |
major | object | — | {} | 主刻度配置,见 Major tick configuration。 |
padding | number | — | 3 | 刻度标签相对坐标轴的偏移量。 |
showLabelBackdrop | boolean | Yes | 径向坐标轴为true,其余为false | 是否在刻度标签后绘制背景。 |
textStrokeColor | Color | Yes | `` | 文本描边颜色。 |
textStrokeWidth | number | Yes | 0 | 文本描边宽度。 |
z | number | — | 0 | 刻度层的 z 索引。<= 0绘制在数据集之下,> 0绘制在数据集之上。 |
3.1 刻度回调:定制标签格式
ticks.callback是最常用的刻度定制手段。回调接收三个参数:
value:刻度值,使用关联坐标轴的内部数据格式(时间轴中是时间戳);index:刻度在刻度数组中的索引;ticks:包含所有刻度对象的数组。
回调的作用域绑定到坐标轴本身,this即坐标轴对象。如果回调返回null或undefined,对应的网格线将被隐藏。以下示例为 Y 轴所有刻度加上美元符号前缀(完整说明见 docs/axes/labelling.md):
const chart = new Chart(ctx, { type: 'line', data: data, options: { scales: { y: { ticks: { // 在刻度值前加上美元符号 callback: function(value, index, ticks) { return '$' + value; } } } } } });覆盖ticks.callback意味着你接管了全部标签格式化逻辑。如需在默认格式基础上修改,可以先调用默认格式化器再加工输出:
// 调用默认格式化器并转发 this return '$' + Chart.Ticks.formatters.numeric.apply(this, [value, index, ticks]);:::tip 提示 默认作为折线图/柱状图 X 轴的类别轴(category),其内部数据格式是索引值。要获取真正的类别标签,请在回调内使用this.getLabelForValue(value)。 :::
四、display的三种状态与可见性控制
display选项支持boolean与string两种取值:
true(默认):坐标轴始终可见;false:坐标轴完全隐藏;'auto':仅当至少一个与该轴关联的数据集可见时,坐标轴才显示。这在数据集动态显隐(如点击图例切换显示)的场景下非常实用,可避免出现“空轴”。
五、轴范围设置:min/max 与 suggestedMin/suggestedMax
坐标轴范围相关的设置较多,理解它们之间的交互关系至关重要(原理解析见 docs/axes/index.md 的 Axis Range Settings 一节)。
5.1 suggested*:扩展范围的“软”调整
suggestedMax和suggestedMin只改变参与坐标轴缩放计算的数据值,适合在保持坐标轴自动适配(auto-fit)行为的同时扩展范围。其计算逻辑等价于:
let minDataValue = Math.min(mostNegativeValue, options.suggestedMin); let maxDataValue = Math.max(mostPositiveValue, options.suggestedMax);看一个官方示例:数据最大值为 50,但通过suggestedMax: 100将数据上限扩展到 100;同时因为真实数据最小值 0 低于suggestedMin: 50,suggestedMin会被忽略(它只负责扩展,不会收缩数据范围):
let chart = new Chart(ctx, { type: 'line', data: { datasets: [{ label: 'First dataset', data: [0, 20, 40, 50] }], labels: ['January', 'February', 'March', 'April'] }, options: { scales: { y: { suggestedMin: 50, suggestedMax: 100 } } } });5.2 min/max:设定坐标轴端点
与suggested*相反,min和max是坐标轴的显式硬边界。一旦设置,超出该范围的数据点可能无法显示在图表中:
options: { scales: { y: { min: 0, // 强制从 0 开始 max: 100 // 强制到 100 结束 } } }5.3 源码中的解析与合并逻辑
在 src/core/core.scale.js 中,init()会解析这四个范围选项,getUserBounds()负责合并处理:
init(options) { ... this._userMin = this.parse(options.min); this._userMax = this.parse(options.max); this._suggestedMin = this.parse(options.suggestedMin); this._suggestedMax = this.parse(options.suggestedMax); } getUserBounds() { ... return { min: finiteOrDefault(_userMin, _suggestedMin), max: finiteOrDefault(_userMax, _suggestedMax), minDefined: isFinite(_userMin), maxDefined: isFinite(_userMax) }; }随后getMinMax()只在min/max未定义时才遍历可见数据集元数据(getMatchingVisibleMetas())计算数据范围,并确保min <= max。这从源码层面印证了文档所述的行为:min/max具有最高优先级,suggested*仅作为未显式定义时的补充。此外,update()中还会调用_addGrace(this, grace, beginAtZero)在数据范围上追加grace留白,这是通用配置之外、对范围有影响的另一项隐藏行为。
六、数据堆叠(stacked)
默认情况下数据不堆叠。stacked选项作用于值轴(水平图表中的 Y 轴),取值与行为如下:
false(默认):不堆叠;true:正负值分别堆叠(正值归正值、负值归负值);'single':正负值合并堆叠在一起(适合需要正负抵消的图表场景)。
此外,还可以在每个数据集上定义stack选项,将堆叠进一步细分为多个堆叠组(详见 数据集配置)。典型配置:
options: { scales: { y: { stacked: true } } }七、坐标轴更新回调(Callbacks)
Chart.js 在坐标轴更新流程的不同阶段暴露了一系列回调钩子,用于在特定时机修改坐标轴参数。这些回调配置在options.scales[scaleId]顶层(来自 docs/axes/index.md):
| 名称 | 参数 | 触发时机 |
|---|---|---|
beforeUpdate | axis | 更新流程开始前。 |
beforeSetDimensions | axis | 设置尺寸前。 |
afterSetDimensions | axis | 设置尺寸后。 |
beforeDataLimits | axis | 确定数据范围前。 |
afterDataLimits | axis | 确定数据范围后。 |
beforeBuildTicks | axis | 创建刻度前。 |
afterBuildTicks | axis | 创建刻度后,适合用于过滤刻度。 |
beforeTickToLabelConversion | axis | 刻度转换为字符串前。 |
afterTickToLabelConversion | axis | 刻度转换为字符串后。 |
beforeCalculateLabelRotation | axis | 计算刻度旋转角前。 |
afterCalculateLabelRotation | axis | 计算刻度旋转角后。 |
beforeFit | axis | 坐标轴适配画布前。 |
afterFit | axis | 坐标轴适配画布后。 |
afterUpdate | axis | 更新流程结束时。 |
这些回调在 src/core/core.scale.js 的update()方法中按生命周期依次触发,源码调用顺序如下(节选关键行):
update(maxWidth, maxHeight, margins) { ... this.beforeUpdate(); // -> options.beforeUpdate ... this.beforeSetDimensions(); this.setDimensions(); this.afterSetDimensions(); ... this.beforeDataLimits(); this.determineDataLimits(); this.afterDataLimits(); ... this.beforeBuildTicks(); this.ticks = this.buildTicks() || []; this.afterBuildTicks(); // 常用于过滤刻度 ... this.beforeFit(); this.fit(); this.afterFit(); this.afterUpdate(); }一个常见用法是在afterBuildTicks中过滤刻度:
options: { scales: { y: { afterBuildTicks: function(axis) { // 只保留偶数索引的刻度 axis.ticks = axis.ticks.filter((tick, i) => i % 2 === 0); } } } }八、修改坐标轴默认配置:Chart.defaults.scales
所有坐标轴的默认配置都可以通过Chart.defaults.scales[type]全局修改,修改后之后创建的该类型坐标轴都会继承新默认值。例如让所有线性轴最小值为 0:
Chart.defaults.scales.linear.min = 0;同理,也可以全局调整Chart.defaults.scales.linear.ticks.color、Chart.defaults.scales.category.grid.display等,实现整套图表的统一风格,而无需在每个图表的 options 中重复书写。
九、创建自定义坐标轴类型
type选项支持注册自定义坐标轴类型。要创建全新的坐标轴类型,需要继承现有的 Scale 类并注册到 Chart.js 中,具体开发流程与插件式注册机制请参考 开发者文档 - 坐标轴 与 docs/developers/plugins.md。自定义类型注册后,即可通过type: 'myScaleType'在任意图表中复用,这正是文档所述“无需重写整个图表类型即可扩展新坐标轴类型”的能力基础。
总结
Chart.js 的坐标轴通用配置体系以options.scales[scaleId]为入口,由type、display、min/max/suggested*、stacked、ticks、grid、border、weight等核心选项构成,配合options.scales[scaleId].ticks下的通用刻度选项与贯穿更新生命周期的回调钩子,几乎可以覆盖所有坐标轴定制需求。本文列出的默认值均可在 src/core/core.scale.defaults.js 中找到对应实现,生命周期回调的触发顺序亦有 src/core/core.scale.js 的update()方法逐一佐证,可放心作为二次开发与排障的依据。具体轴类型的专属配置请继续查阅 笛卡尔坐标轴 与 径向坐标轴 文档。
【免费下载链接】Chart.jsSimple HTML5 Charts using the项目地址: https://gitcode.com/gh_mirrors/ch/Chart.js
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考