in packages/charts/src/chart_types/xy_chart/utils/series.ts [363:470]
export function getDataSeriesFromSpecs(
seriesSpecs: BasicSeriesSpec[],
deselectedDataSeries: SeriesIdentifier[] = [],
orderOrdinalBinsBy?: OrderBy,
seriesSort?: SeriesCompareFn,
groupBySpec?: SmallMultiplesGroupBy,
): {
dataSeries: DataSeries[];
xValues: Set<string | number>;
smVValues: Set<string | number>;
smHValues: Set<string | number>;
fallbackScale?: XScaleType;
} {
const globalDataSeries: DataSeries[] = [];
const mutatedXValueSums = new Map<string | number, number>();
// the unique set of values along the x axis
const globalXValues: Set<string | number> = new Set();
let isNumberArray = true;
let isOrdinalScale = false;
const specsByYGroup = groupSeriesByYGroup(seriesSpecs);
let insertOrder = 0;
// eslint-disable-next-line no-restricted-syntax
for (const spec of seriesSpecs) {
// check scale type and cast to Ordinal if we found at least one series
// with Ordinal Scale
if (spec.xScaleType === ScaleType.Ordinal) {
isOrdinalScale = true;
}
const specGroup = specsByYGroup.get(spec.groupId);
const isStacked = Boolean(specGroup?.stacked.find(({ id }) => id === spec.id));
const isBanded = isBandedSpec(spec);
const { dataSeries, xValues } = splitSeriesDataByAccessors(
spec,
mutatedXValueSums,
insertOrder,
isStacked,
isBanded,
specGroup?.stackMode,
groupBySpec,
deselectedDataSeries,
);
insertOrder += dataSeries.size;
for (const [, ds] of dataSeries) {
globalDataSeries.push(ds);
}
// check the nature of the x values. If all of them are numbers
// we can use a continuous scale, if not we should use an ordinal scale.
// The xValue is already casted to be a valid number or a string
for (const xValue of xValues) {
if (isNumberArray && typeof xValue !== 'number') {
isNumberArray = false;
}
globalXValues.add(xValue);
}
}
const xValues =
isOrdinalScale || !isNumberArray
? getSortedOrdinalXValues(globalXValues, mutatedXValueSums, orderOrdinalBinsBy)
: new Set(
[...globalXValues].sort((a, b) => {
if (typeof a === 'string' || typeof b === 'string') {
return 0;
}
return a - b;
}),
);
globalDataSeries.sort(seriesSort).map((d, i) => {
d.sortOrder = i;
return d;
});
const smallMultipleUniqueValues = globalDataSeries.reduce<{
smVValues: Set<string | number>;
smHValues: Set<string | number>;
}>(
(acc, curr) => {
if (curr.isFiltered) {
return acc;
}
if (!isNil(curr.smHorizontalAccessorValue)) {
acc.smHValues.add(curr.smHorizontalAccessorValue);
}
if (!isNil(curr.smVerticalAccessorValue)) {
acc.smVValues.add(curr.smVerticalAccessorValue);
}
return acc;
},
{ smVValues: new Set(), smHValues: new Set() },
);
return {
dataSeries: globalDataSeries,
// keep the user order for ordinal scales
xValues,
...smallMultipleUniqueValues,
fallbackScale: !isOrdinalScale && !isNumberArray ? X_SCALE_DEFAULT.type : undefined,
};
}