import d3 from 'd3';
export default class NumberFormatter { constructor(prec, src) { this.fixedPrecision = prec; if (!this.fixedPrecision || this.fixedPrecision < 1) { this.fixedPrecision = 3; } this.numbers = null; if (src) { this.set(src); } }
set(src) { this.numbers = [...src].sort((a, b) => a - b); }
add(num) { if (!Number.isFinite(num)) { return -1; } if (!this.numbers) { this.numbers = [num]; return 0; } if (this.numbers.length > 0) { const i0 = d3.bisectLeft(this.numbers, num); if (this.numbers[i0] === num) { return i0; } } const i1 = d3.bisectRight(this.numbers, num); this.numbers = this.numbers .slice(0, i1) .concat(num) .concat(this.numbers.slice(i1, this.numbers.length)); return i1; }
del(num) { if (!Number.isFinite(num) || !this.numbers) { return -1; } if (this.numbers.length > 0) { const i0 = d3.bisectLeft(this.numbers, num); if (this.numbers[i0] === num) { this.numbers = this.numbers .slice(0, i0) .concat(this.numbers.slice(i0 + 1, this.numbers.length)); return i0; } } return -1; }
eval(num) { if (num === 0.0) { return '0'; } else if (num === Infinity) { return '∞'; } else if (num === -Infinity) { return '-∞'; } else if (Number.isNaN(num)) { return 'NaN'; } const szn = Math.log10(Math.abs(num)); let prec = this.fixedPrecision; if (this.numbers) { const i0 = d3.bisectLeft(this.numbers, num) - 1; const i1 = d3.bisectRight(this.numbers, num); if (i0 >= 0 && i0 < this.numbers.length) { const dnl = num - this.numbers[i0]; const ld0 = Math.ceil(szn - Math.log10(dnl)); if (ld0 > prec) { prec = ld0; } } if (i1 > i0 && i1 < this.numbers.length) { const dnr = this.numbers[i1] - num; const ld1 = Math.ceil(szn - Math.log10(dnr)); if (ld1 > prec) { prec = ld1; } } } if (szn <= 3.0 && szn > -2) { return num.toFixed(prec - Math.floor(szn)); } const exponent = -Math.floor(Math.log10(Math.abs(num)) / 3) * 3; const scaled = 10 ** exponent * num; return scaled .toFixed(prec - Math.ceil(szn + exponent)) .concat('e') .concat(-exponent.toFixed()); }
evaluator() { const self = this; return (o) => self.eval(o); } }
export const sciNotationRegExp = '[-+]?[0-9]*[.]?[0-9]*[eE]?[-+]?[0-9]*';
|