addon/utils/e3-ticks.js
const {abs, ceil, floor, pow, log, LN10} = Math;
export default function e3Ticks(domain, ticks) {
if(domain) {
return linearTickRange(domain, ticks);
} else {
return [];
}
}
function linearTickRange(extent, m = 10) {
let span = extent[1] - extent[0],
step = pow(10, floor(log(span / m) / LN10)),
err = m / span * step;
// Filter ticks to get closer to the desired count.
if (err <= 0.15) {
step *= 10;
} else if (err <= 0.35) {
step *= 5;
} else if (err <= 0.75) {
step *= 2;
}
// Round start and stop values to step interval.
return range(ceil(extent[0] / step) * step, floor(extent[1] / step) * step + step * 0.5, step);
}
function range(start, stop, step) {
if (arguments.length < 3) {
step = 1;
if (arguments.length < 2) {
stop = start;
start = 0;
}
}
if ((stop - start) / step === Infinity) {
throw new Error("infinite range");
}
let usedRage = [], k = integerScale(abs(step)), i = -1, j;
start *= k;
stop *= k;
step *= k;
if (step < 0) {
while ((j = start + step * ++i) > stop) {
usedRage.push(j / k);
}
} else {
while ((j = start + step * ++i) < stop) {
usedRage.push(j / k);
}
}
return usedRage;
}
function integerScale(x) {
let k = 1;
while (x * k % 1) {
k *= 10;
}
return k;
}