diff --git a/src/util/number.ts b/src/util/number.ts index 662695f7f7..35dd4ef67a 100644 --- a/src/util/number.ts +++ b/src/util/number.ts @@ -229,8 +229,12 @@ export function round(x: number | string, precision: number, returnStr?: boolean // precision utils (such as getAcceptableTickPrecision) may return NaN. return returnStr ? '' + x : +x; } - // Avoid range error - precision = mathMin(mathMax(0, precision), TO_FIXED_SUPPORTED_PRECISION_MAX); + // Avoid range error. Do not clamp large precision to 20 because it may + // over-round tiny values such as 3e-21 to zero. + if (precision > TO_FIXED_SUPPORTED_PRECISION_MAX) { + return returnStr ? '' + x : +x; + } + precision = mathMax(0, precision); // PENDING: 1.005.toFixed(2) is '1.00' rather than '1.01' x = (+x).toFixed(precision); return (returnStr ? x : +x); diff --git a/test/ut/spec/scale/interval.test.ts b/test/ut/spec/scale/interval.test.ts index 545d967ff7..20f0c84c73 100755 --- a/test/ut/spec/scale/interval.test.ts +++ b/test/ut/spec/scale/interval.test.ts @@ -68,6 +68,29 @@ describe('scale_interval', function () { expect(ticks[ticks.length - 1].value).toEqual(max); }); + it('ticks_tiny_max', function () { + chart.setOption({ + xAxis: {}, + yAxis: { + type: 'value', + scale: true, + max: 2.324097633474072e-20 + }, + series: [{ + type: 'line', + data: [1e-20] + }] + }); + + const yAxis = getECModel(chart).getComponent('yAxis', 0) as CartesianAxisModel; + const ticks = yAxis.axis.scale.getTicks(); + + expect(ticks.length).toBeGreaterThan(2); + ticks.forEach(function (tick) { + expect(tick.value).toBeFinite(); + }); + }); + it('ticks_small_value', function () { chart.setOption({ tooltip: {}, diff --git a/test/ut/spec/util/number.test.ts b/test/ut/spec/util/number.test.ts index 2c26932148..b51949f50e 100755 --- a/test/ut/spec/util/number.test.ts +++ b/test/ut/spec/util/number.test.ts @@ -958,6 +958,12 @@ describe('util/number', function () { expect(nice(3900000000000000000021)).toEqual(5000000000000000000000); expect(nice(0.00000000000000000656939, true)).toEqual(0.000000000000000005); expect(nice(0.00000000000000000656939)).toEqual(0.00000000000000001); + const niceTiny3 = nice(2.648195266948144e-21, true); + const niceTiny5 = nice(4.648195266948144e-21, true); + expect(niceTiny3).toBeGreaterThan(0); + expect(niceTiny3).toBeLessThan(1e-20); + expect(niceTiny5).toBeGreaterThan(0); + expect(niceTiny5).toBeLessThan(1e-20); expect(nice(0.10000000000000000656939, true)).toEqual(0.1); expect(nice(0.10000000000000000656939)).toEqual(0.2); });