From b52fea2ff5266a2a24f3b38fa1c87f65fe19e8e3 Mon Sep 17 00:00:00 2001 From: harukikuri Date: Fri, 29 May 2026 13:32:35 +0800 Subject: [PATCH] fix: apply ticks.format to the value 0 Closes #11905 --- src/core/core.ticks.js | 9 +++++++-- test/specs/core.ticks.tests.js | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/core/core.ticks.js b/src/core/core.ticks.js index c0e34b11eda..c92c4113581 100644 --- a/src/core/core.ticks.js +++ b/src/core/core.ticks.js @@ -26,11 +26,16 @@ const formatters = { * @return {string} string representation of the tickValue parameter */ numeric(tickValue, index, ticks) { + const locale = this.chart.options.locale; + if (tickValue === 0) { - return '0'; // never show decimal places for 0 + // Never show decimal places (or scientific notation) for 0, but still apply + // `ticks.format` (e.g. currency or percent) so 0 matches the other ticks. + const zeroOptions = {minimumFractionDigits: 0, maximumFractionDigits: 0}; + Object.assign(zeroOptions, this.options.ticks.format); + return formatNumber(0, locale, zeroOptions); } - const locale = this.chart.options.locale; let notation; let delta = tickValue; // This is used when there are less than 2 ticks as the tick interval. diff --git a/test/specs/core.ticks.tests.js b/test/specs/core.ticks.tests.js index 01db0cdce30..a2145ec2923 100644 --- a/test/specs/core.ticks.tests.js +++ b/test/specs/core.ticks.tests.js @@ -106,5 +106,22 @@ describe('Test tick generators', function() { expect(Chart.Ticks.formatters.numeric.apply(scale, [1, 0, [{value: 1}]])).toEqual('1'); expect(Chart.Ticks.formatters.numeric.apply(scale, [1, 0, [{value: 1}, {value: 1.01}]])).toEqual('1.00'); }); + + it('should apply `ticks.format` to the value 0 (#11905)', function() { + const ticks = [{value: 0}, {value: 100}]; + const currencyScale = {chart: {options: {locale: 'en'}}, options: {ticks: {format: {style: 'currency', currency: 'USD'}}}}; + expect(Chart.Ticks.formatters.numeric.apply(currencyScale, [0, 0, ticks])).toEqual('$0'); + expect(Chart.Ticks.formatters.numeric.apply(currencyScale, [100, 1, ticks])).toEqual('$100'); + + const percentScale = {chart: {options: {locale: 'en'}}, options: {ticks: {format: {style: 'percent'}}}}; + expect(Chart.Ticks.formatters.numeric.apply(percentScale, [0, 0, [{value: 0}, {value: 1}]])).toEqual('0%'); + }); + + it('should render 0 without decimals or scientific notation when no format is set', function() { + const scale = {chart: {options: {locale: 'en'}}, options: {ticks: {format: {}}}}; + expect(Chart.Ticks.formatters.numeric.apply(scale, [0, 0, [{value: 0}, {value: 0.1}, {value: 0.2}]])).toEqual('0'); + // a huge range would otherwise switch to scientific notation; 0 should stay '0' + expect(Chart.Ticks.formatters.numeric.apply(scale, [0, 0, [{value: 0}, {value: 1e16}]])).toEqual('0'); + }); }); });