@antv/scale
Version:
Toolkit for mapping abstract data into visual representation.
82 lines • 3.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Linear = void 0;
const util_1 = require("@antv/util");
const continuous_1 = require("./continuous");
const utils_1 = require("../utils");
const d3_ticks_1 = require("../tick-methods/d3-ticks");
/**
* Linear 比例尺
*
* 构造可创建一个在输入和输出之间具有线性关系的比例尺
*/
class Linear extends continuous_1.Continuous {
getDefaultOptions() {
return {
domain: [0, 1],
range: [0, 1],
unknown: undefined,
nice: false,
clamp: false,
round: false,
interpolate: utils_1.createInterpolateValue,
tickMethod: d3_ticks_1.d3Ticks,
tickCount: 5,
};
}
transformDomain(options) {
const { domain, range = [1, 0], breaks = [], tickCount = 5 } = options;
const [domainMin, domainMax] = [Math.min(...domain), Math.max(...domain)];
const sortedBreaks = breaks.filter(({ end }) => end < domainMax).sort((a, b) => a.start - b.start);
const breaksDomain = (0, d3_ticks_1.d3Ticks)(domainMin, domainMax, tickCount, sortedBreaks);
if ((0, util_1.last)(breaksDomain) < domainMax) {
breaksDomain.push(domainMax);
}
const [r0, r1] = [range[0], (0, util_1.last)(range)];
const diffDomain = domainMax - domainMin;
const diffRange = Math.abs(r1 - r0);
const reverse = r0 > r1;
// Calculate the new range based on breaks.
const breaksRange = breaksDomain.map((d) => {
const ratio = (d - domainMin) / diffDomain;
return reverse ? r0 - ratio * diffRange : r0 + ratio * diffRange;
});
// Compress the range scale according to breaks.
sortedBreaks.forEach(({ start, end, gap = 0.05 }) => {
const startIndex = breaksDomain.indexOf(start);
const endIndex = breaksDomain.indexOf(end);
const center = (breaksRange[startIndex] + breaksRange[endIndex]) / 2;
const scaledSpan = gap * diffRange;
// Calculate the new start and end values based on the center and scaled span.
const startValue = reverse ? center + scaledSpan / 2 : center - scaledSpan / 2;
const endValue = reverse ? center - scaledSpan / 2 : center + scaledSpan / 2;
breaksRange[startIndex] = startValue;
breaksRange[endIndex] = endValue;
});
return { breaksDomain, breaksRange };
}
transformBreaks(options) {
const { domain, breaks = [] } = options;
if (!(0, util_1.isArray)(options.breaks))
return options;
const domainMax = Math.max(...domain);
const filteredBreaks = breaks.filter(({ end }) => end < domainMax);
const optWithFilteredBreaks = { ...options, breaks: filteredBreaks };
const { breaksDomain, breaksRange } = this.transformDomain(optWithFilteredBreaks);
return {
...options,
domain: breaksDomain,
range: breaksRange,
breaks: filteredBreaks,
tickMethod: () => [...breaksDomain],
};
}
chooseTransforms() {
return [util_1.identity, util_1.identity];
}
clone() {
return new Linear(this.options);
}
}
exports.Linear = Linear;
//# sourceMappingURL=linear.js.map