Closed ZiedHf closed 2 years ago
Not sure if we can do anything better here. Feel free to open a pull request if you have a suggestion for a change to the ticks algorithm.
Yep, it's floating points issues.
// Problem
r0 + i * step;
0 + 3 * 2e+23; // This returns 5.9999999999999995e+23
It looks like using Big in the ticks method solve the issue. But maybe you don't prefer to use another dependencies to solve it ? I don't know.
Big(2e+23).mul(3).toString(); // 6e+23 Nice result !!
The ticks method
function ticks(start, stop, count) {
var reverse,
i = -1,
n,
ticks,
step;
stop = +stop, start = +start, count = +count;
if (start === stop && count > 0) return [start];
if (reverse = stop < start) n = start, start = stop, stop = n;
if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];
if (step > 0) {
let r0 = Math.round(start / step), r1 = Math.round(stop / step);
console.log(start, stop, step)
console.log(r0, r1)
if (r0 * step < start) ++r0;
console.log(r0, r1)
if (r1 * step > stop) --r1;
console.log(r0, r1)
ticks = new Array(n = r1 - r0 + 1);
console.log(ticks, n)
while (++i < n) ticks[i] = Number(Big(r0).add(i).mul(step).toString());
} else {
step = -step;
let r0 = Math.round(start * step), r1 = Math.round(stop * step);
if (r0 / step < start) ++r0;
if (r1 / step > stop) --r1;
ticks = new Array(n = r1 - r0 + 1);
while (++i < n) ticks[i] = Number(Big(r0).add(i).div(step).toString());
}
if (reverse) ticks.reverse();
return ticks;
}
JavaScript has native support for big integers now, so we could use that, but I don’t think I’d want to use big integers in the common path (since it’s rare that the domain is so big or so small). And it would need to be a new major version since it would reduce compatibility of d3-array with older JavaScript environments. So I probably don’t think this is worth it unless there is more evidence of demand.
I am not sure if this is what
ticks
should return for these domains or not. Is there a limit for themax
andmin
? Or maybe I am missing something to return nicer ticks ? It looks like a floating points problem.