@toast-ui/chart
Version:
TOAST UI Application: Chart
171 lines (170 loc) • 7.2 kB
JavaScript
import { getFirstValidValue, isNull, includes } from "../helpers/utils";
import { extend } from "./store";
import { getAxisName, isLabelAxisOnYAxis, getValueAxisNames, getYAxisOption, hasSecondaryYAxis, } from "../helpers/axes";
import { getCoordinateYValue, isCoordinateSeries } from "../helpers/coordinate";
import { isRangeValue } from "../helpers/range";
import { AxisType } from "../component/axis";
export function getLimitSafely(baseValues, isXAxis = false) {
const limit = {
min: Math.min(...baseValues),
max: Math.max(...baseValues),
};
if (baseValues.length === 1) {
const [firstValue] = baseValues;
if (isXAxis) {
limit.min = firstValue;
limit.max = firstValue;
}
else if (firstValue > 0) {
limit.min = 0;
}
else if (firstValue === 0) {
limit.max = 10;
}
else {
limit.max = 0;
}
}
else if (limit.min === 0 && limit.max === 0) {
limit.max = 10;
}
else if (limit.min === limit.max) {
limit.min -= limit.min / 10;
limit.max += limit.max / 10;
}
return limit;
}
function initDataRange(accDataRangeValue, curDataRangeValue, axisName) {
var _a, _b, _c, _d;
const defaultDataRange = {
min: Number.MAX_SAFE_INTEGER,
max: Number.MIN_SAFE_INTEGER,
};
return {
min: Math.min(curDataRangeValue[axisName].min, (_b = (_a = accDataRangeValue[axisName]) === null || _a === void 0 ? void 0 : _a.min, (_b !== null && _b !== void 0 ? _b : defaultDataRange.min))),
max: Math.max(curDataRangeValue[axisName].max, (_d = (_c = accDataRangeValue[axisName]) === null || _c === void 0 ? void 0 : _c.max, (_d !== null && _d !== void 0 ? _d : defaultDataRange.max))),
};
}
function getTotalDataRange(seriesDataRange) {
return Object.values(seriesDataRange).reduce((acc, cur) => {
if (cur.xAxis) {
acc.xAxis = initDataRange(acc, cur, 'xAxis');
}
if (cur.yAxis) {
acc.yAxis = initDataRange(acc, cur, 'yAxis');
}
if (cur.secondaryYAxis) {
acc.secondaryYAxis = initDataRange(acc, cur, 'secondaryYAxis');
}
if (cur.circularAxis) {
acc.circularAxis = initDataRange(acc, cur, 'circularAxis');
}
if (cur.verticalAxis) {
acc.verticalAxis = initDataRange(acc, cur, 'verticalAxis');
}
return acc;
}, {});
}
function setSeriesDataRange({ options, seriesName, values, valueAxisName, seriesDataRange, }) {
var _a;
let axisNames;
if (includes([AxisType.X, AxisType.CIRCULAR, AxisType.VERTICAL], valueAxisName)) {
axisNames = [valueAxisName];
}
else {
const optionsUsingYAxis = options;
const { secondaryYAxis } = getYAxisOption(optionsUsingYAxis);
axisNames =
hasSecondaryYAxis(optionsUsingYAxis) && ((_a = secondaryYAxis) === null || _a === void 0 ? void 0 : _a.chartType)
? [secondaryYAxis.chartType === seriesName ? 'secondaryYAxis' : 'yAxis']
: getValueAxisNames(optionsUsingYAxis, valueAxisName);
}
axisNames.forEach((axisName) => {
seriesDataRange[seriesName][axisName] = getLimitSafely([...new Set(values)]);
});
return seriesDataRange;
}
function getBoxPlotValues(series, seriesName) {
return series[seriesName].data.flatMap(({ data, outliers = [] }) => [
...((data !== null && data !== void 0 ? data : [])).flatMap((datum) => datum),
...((outliers !== null && outliers !== void 0 ? outliers : [])).flatMap((datum) => datum),
]);
}
function getBulletValues(series, seriesName) {
return series[seriesName].data.flatMap(({ data, markers, ranges }) => [
data,
...((markers !== null && markers !== void 0 ? markers : [])).flatMap((datum) => datum),
...((ranges !== null && ranges !== void 0 ? ranges : [])).flatMap((range) => range),
]);
}
function getCoordinateDataValues(values, categories, hasDateValue) {
const yAxisValues = values
.filter((value) => !isNull(value))
.map((value) => getCoordinateYValue(value));
const xAxisValues = categories.map((value) => hasDateValue ? Number(new Date(value)) : Number(value));
return { xAxisValues, yAxisValues };
}
const dataRange = {
name: 'dataRange',
state: () => ({
dataRange: {},
}),
action: {
setDataRange({ state, initStoreState }) {
const { series, disabledSeries, stackSeries, categories, options } = state;
const seriesDataRange = {};
const labelAxisOnYAxis = isLabelAxisOnYAxis({ series, options, categories });
const { labelAxisName, valueAxisName } = getAxisName(labelAxisOnYAxis, series);
Object.keys(series).forEach((seriesName) => {
var _a, _b;
seriesDataRange[seriesName] = {};
let values = series[seriesName].data.flatMap(({ data, name }) => disabledSeries.includes(name) ? [] : data);
const firstExistValue = getFirstValidValue(values);
if (isCoordinateSeries(initStoreState.series)) {
const hasDateValue = !!((_a = options.xAxis) === null || _a === void 0 ? void 0 : _a.date);
const { yAxisValues, xAxisValues } = getCoordinateDataValues(values, categories, hasDateValue);
values = yAxisValues;
seriesDataRange[seriesName][labelAxisName] = getLimitSafely([...xAxisValues], true);
}
else if (!series[seriesName].data.length) {
values = [];
}
else if (isRangeValue(firstExistValue)) {
values = values.reduce((arr, value) => {
if (isNull(value)) {
return arr;
}
return Array.isArray(value) ? [...arr, ...value] : [...value];
}, []);
}
else if (stackSeries && ((_b = stackSeries[seriesName]) === null || _b === void 0 ? void 0 : _b.stack)) {
values = stackSeries[seriesName].dataRangeValues;
}
else if (seriesName === 'boxPlot') {
values = getBoxPlotValues(series, seriesName);
}
else if (seriesName === 'bullet') {
values = getBulletValues(series, seriesName);
}
if (includes(['bar', 'column', 'radar', 'bullet'], seriesName)) {
values.push(0);
}
setSeriesDataRange({
options,
seriesName,
values,
valueAxisName,
seriesDataRange,
});
});
const newDataRange = getTotalDataRange(seriesDataRange);
extend(state.dataRange, newDataRange);
},
},
observe: {
updateDataRange() {
this.dispatch('setDataRange');
},
},
};
export default dataRange;