@mui/x-charts
Version:
The community edition of MUI X Charts components.
101 lines (98 loc) • 3.88 kB
JavaScript
import { isBandScaleConfig, isPointScaleConfig } from "../../../../models/axis.mjs";
import { getScale } from "../../../getScale.mjs";
import { getAxisDomainLimit } from "./getAxisDomainLimit.mjs";
import { getTickNumber } from "../../../ticks.mjs";
function niceDomain(scaleType, domain, tickNumber) {
return getScale(scaleType ?? 'linear', domain, [0, 1]).nice(tickNumber).domain();
}
/**
* Calculates the initial domain and tick number for a given axis.
* The domain should still run through the zoom filterMode after this step.
*/
export function calculateInitialDomainAndTickNumber(axis, axisDirection, axisIndex, formattedSeries, [minData, maxData], defaultTickNumber) {
const domainLimit = getAxisDomainLimit(axis, axisDirection, axisIndex, formattedSeries);
let axisExtrema = getActualAxisExtrema(axis, minData, maxData);
if (typeof domainLimit === 'function') {
const {
min,
max
} = domainLimit(minData.valueOf(), maxData.valueOf());
axisExtrema[0] = min;
axisExtrema[1] = max;
}
const tickNumber = getTickNumber(axis, axisExtrema, defaultTickNumber);
if (domainLimit === 'nice') {
axisExtrema = niceDomain(axis.scaleType, axisExtrema, tickNumber);
}
axisExtrema = ['min' in axis ? axis.min ?? axisExtrema[0] : axisExtrema[0], 'max' in axis ? axis.max ?? axisExtrema[1] : axisExtrema[1]];
return {
domain: axisExtrema,
tickNumber
};
}
/**
* Calculates the final domain for an axis.
* After this step, the domain can be used to create the axis scale.
*/
export function calculateFinalDomain(axis, axisDirection, axisIndex, formattedSeries, [minData, maxData], tickNumber) {
const domainLimit = getAxisDomainLimit(axis, axisDirection, axisIndex, formattedSeries);
let axisExtrema = getActualAxisExtrema(axis, minData, maxData);
if (typeof domainLimit === 'function') {
const {
min,
max
} = domainLimit(minData.valueOf(), maxData.valueOf());
axisExtrema[0] = min;
axisExtrema[1] = max;
}
if (domainLimit === 'nice') {
axisExtrema = niceDomain(axis.scaleType, axisExtrema, tickNumber);
}
return [axis.min ?? axisExtrema[0], axis.max ?? axisExtrema[1]];
}
/**
* Get the actual axis extrema considering the user defined min and max values.
* @param axisExtrema User defined axis extrema.
* @param minData Minimum value from the data.
* @param maxData Maximum value from the data.
*/
function getActualAxisExtrema(axisExtrema, minData, maxData) {
let min = minData;
let max = maxData;
if ('max' in axisExtrema && axisExtrema.max != null && axisExtrema.max < minData) {
min = axisExtrema.max;
}
if ('min' in axisExtrema && axisExtrema.min != null && axisExtrema.min > minData) {
max = axisExtrema.min;
}
if (!('min' in axisExtrema) && !('max' in axisExtrema)) {
return [min, max];
}
return [axisExtrema.min ?? min, axisExtrema.max ?? max];
}
/**
* Computes the domain map for a list of axes.
* Shared between the rendering selectors and the auto-size domain selectors
* to ensure consistent domain computation logic.
*/
export function computeAxisDomainsMap(axes, formattedSeries, defaultTickNumber, extremaMap, axisDirection) {
const domains = {};
axes?.forEach((eachAxis, axisIndex) => {
const axis = eachAxis;
if (isBandScaleConfig(axis) || isPointScaleConfig(axis)) {
domains[axis.id] = {
domain: axis.data
};
if (axis.ordinalTimeTicks !== undefined) {
domains[axis.id].tickNumber = getTickNumber(axis, [axis.data?.find(d => d !== null), axis.data?.findLast(d => d !== null)], defaultTickNumber);
}
return;
}
const extrema = extremaMap[axis.id];
if (!extrema) {
return;
}
domains[axis.id] = calculateInitialDomainAndTickNumber(axis, axisDirection, axisIndex, formattedSeries, extrema, defaultTickNumber);
});
return domains;
}