Skip to content

Commit 5365621

Browse files
authored
Merge pull request #21126 from apache/fix-16266
Fix that extreme small numbers can not be displayed in Cartesian due to the inappropriate rounding precision.
2 parents a535504 + 9055fef commit 5365621

File tree

8 files changed

+208
-5
lines changed

8 files changed

+208
-5
lines changed

src/scale/Interval.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class IntervalScale<SETTING extends ScaleSettingDefault = ScaleSettingDefault> e
3535
// Step is calculated in adjustExtent.
3636
protected _interval: number = 0;
3737
protected _niceExtent: [number, number];
38-
private _intervalPrecision: number = 2;
38+
protected _intervalPrecision: number = 2;
3939

4040

4141
parse(val: ScaleDataValue): number {
@@ -213,9 +213,10 @@ class IntervalScale<SETTING extends ScaleSettingDefault = ScaleSettingDefault> e
213213
const minorTicksGroup = [];
214214
const interval = nextTick.value - prevTick.value;
215215
const minorInterval = interval / splitNumber;
216+
const minorIntervalPrecision = helper.getIntervalPrecision(minorInterval);
216217

217218
while (count < splitNumber - 1) {
218-
const minorTick = roundNumber(prevTick.value + (count + 1) * minorInterval);
219+
const minorTick = roundNumber(prevTick.value + (count + 1) * minorInterval, minorIntervalPrecision);
219220

220221
// For the first and last interval. The count may be less than splitNumber.
221222
if (minorTick > extent[0] && minorTick < extent[1]) {
@@ -276,6 +277,12 @@ class IntervalScale<SETTING extends ScaleSettingDefault = ScaleSettingDefault> e
276277
}
277278

278279
/**
280+
* FIXME: refactor - disallow override, use composition instead.
281+
*
282+
* The override of `calcNiceTicks` should ensure these members are provided:
283+
* this._intervalPrecision
284+
* this._interval
285+
*
279286
* @param splitNumber By default `5`.
280287
*/
281288
calcNiceTicks(splitNumber?: number, minInterval?: number, maxInterval?: number): void {
@@ -345,12 +352,13 @@ class IntervalScale<SETTING extends ScaleSettingDefault = ScaleSettingDefault> e
345352

346353
this.calcNiceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval);
347354
const interval = this._interval;
355+
const intervalPrecition = this._intervalPrecision;
348356

349357
if (!opt.fixMin) {
350-
extent[0] = roundNumber(Math.floor(extent[0] / interval) * interval);
358+
extent[0] = roundNumber(Math.floor(extent[0] / interval) * interval, intervalPrecition);
351359
}
352360
if (!opt.fixMax) {
353-
extent[1] = roundNumber(Math.ceil(extent[1] / interval) * interval);
361+
extent[1] = roundNumber(Math.ceil(extent[1] / interval) * interval, intervalPrecition);
354362
}
355363
this._innerSetExtent(extent[0], extent[1]);
356364
}

src/scale/Log.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
DimensionLoose, DimensionName, ParsedAxisBreakList, AxisBreakOption,
2828
ScaleTick
2929
} from '../util/types';
30-
import { logTransform } from './helper';
30+
import { getIntervalPrecision, logTransform } from './helper';
3131
import SeriesData from '../data/SeriesData';
3232
import { getScaleBreakHelper } from './break';
3333

@@ -165,6 +165,7 @@ class LogScale extends IntervalScale {
165165
] as [number, number];
166166

167167
this._interval = interval;
168+
this._intervalPrecision = getIntervalPrecision(interval);
168169
this._niceExtent = niceExtent;
169170
}
170171

src/scale/Time.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ class TimeScale extends IntervalScale<TimeScaleSetting> {
297297

298298
// Interval that can be used to calculate ticks
299299
this._interval = scaleIntervals[idx][1];
300+
this._intervalPrecision = scaleHelper.getIntervalPrecision(this._interval);
300301
// Min level used when picking ticks from top down.
301302
// We check one more level to avoid the ticks are to sparse in some case.
302303
this._minLevelUnit = scaleIntervals[Math.max(idx - 1, 0)][0];

src/util/number.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ export function round(x: number | string, precision: number, returnStr: false):
157157
export function round(x: number | string, precision: number, returnStr: true): string;
158158
export function round(x: number | string, precision?: number, returnStr?: boolean): string | number {
159159
if (precision == null) {
160+
// FIXME: the default precision should not be provided, since there is no universally adaptable
161+
// precision. The caller need to input a precision according to the scenarios.
160162
precision = 10;
161163
}
162164
// Avoid range error

test/logScale.html

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/runTest/actions/__meta__.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/runTest/actions/scale-extreme-number.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/scale-extreme-number.html

Lines changed: 161 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)