UNPKG

ag-charts-community

Version:

Advanced Charting / Charts supporting Javascript / Typescript / React / Angular / Vue

142 lines 4.58 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const value_1 = require("../interpolate/value"); const number_1 = require("../interpolate/number"); const bisect_1 = require("../util/bisect"); const compare_1 = require("../util/compare"); const constant = (x) => () => x; const identity = (x) => x; function clamper(domain) { let a = domain[0]; let b = domain[domain.length - 1]; if (a > b) { [a, b] = [b, a]; } return x => Math.max(a, Math.min(b, x)); } exports.clamper = clamper; class ContinuousScale { constructor() { /** * The output value of the scale for `undefined` or `NaN` input values. */ this.unknown = undefined; this.clamper = clamper; this._clamp = identity; this._domain = [0, 1]; this._range = [0, 1]; this.transform = identity; // transforms domain value this.untransform = identity; // untransforms domain value this._interpolate = value_1.default; this.rescale(); } set clamp(value) { this._clamp = value ? this.clamper(this.domain) : identity; } get clamp() { return this._clamp !== identity; } setDomain(values) { this._domain = Array.prototype.map.call(values, (v) => +v); if (this._clamp !== identity) { this._clamp = this.clamper(this.domain); } this.rescale(); } getDomain() { return this._domain.slice(); } set domain(values) { this.setDomain(values); } get domain() { return this.getDomain(); } set range(values) { this._range = Array.prototype.slice.call(values); this.rescale(); } get range() { return this._range.slice(); } set interpolate(value) { this._interpolate = value; this.rescale(); } get interpolate() { return this._interpolate; } rescale() { if (Math.min(this.domain.length, this.range.length) > 2) { this.piecewise = this.polymap; } else { this.piecewise = this.bimap; } this.output = undefined; this.input = undefined; } /** * Returns a function that converts `x` in `[a, b]` to `t` in `[0, 1]`. Non-clamping. * @param a * @param b */ normalize(a, b) { return (b -= (a = +a)) ? (x) => (x - a) / b : constant(isNaN(b) ? NaN : 0.5); } bimap(domain, range, interpolate) { const x0 = domain[0]; const x1 = domain[1]; const y0 = range[0]; const y1 = range[1]; let xt; let ty; if (x1 < x0) { xt = this.normalize(x1, x0); ty = interpolate(y1, y0); } else { xt = this.normalize(x0, x1); ty = interpolate(y0, y1); } return (x) => ty(xt(x)); // domain value x --> t in [0, 1] --> range value y } polymap(domain, range, interpolate) { // number of segments in the polylinear scale const n = Math.min(domain.length, range.length) - 1; if (domain[n] < domain[0]) { domain = domain.slice().reverse(); range = range.slice().reverse(); } // deinterpolators from domain segment value to t const dt = Array.from({ length: n }, (_, i) => this.normalize(domain[i], domain[i + 1])); // reinterpolators from t to range segment value const tr = Array.from({ length: n }, (_, i) => interpolate(range[i], range[i + 1])); return (x) => { const i = bisect_1.bisectRight(domain, x, compare_1.ascending, 1, n) - 1; // Find the domain segment that `x` belongs to. // This also tells us which deinterpolator/reinterpolator pair to use. return tr[i](dt[i](x)); }; } convert(x, clamper) { x = +x; if (isNaN(x)) { return this.unknown; } if (!this.output) { this.output = this.piecewise(this.domain.map(this.transform), this.range, this.interpolate); } const clamp = clamper ? clamper(this.domain) : this._clamp; return this.output(this.transform(clamp(x))); } invert(y) { if (!this.input) { this.input = this.piecewise(this.range, this.domain.map(this.transform), number_1.default); } return this._clamp(this.untransform(this.input(y))); } } exports.ContinuousScale = ContinuousScale; //# sourceMappingURL=continuousScale.js.map