@gravity-ui/charts 1.0.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/Axis/AxisX.d.ts +1 -0
- package/dist/cjs/components/Axis/AxisX.js +57 -12
- package/dist/cjs/components/Axis/AxisY.d.ts +1 -0
- package/dist/cjs/components/Axis/AxisY.js +83 -12
- package/dist/cjs/components/ChartInner/index.js +3 -3
- package/dist/cjs/components/ChartInner/styles.css +2 -0
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +3 -0
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +14 -3
- package/dist/cjs/components/Legend/index.js +2 -2
- package/dist/cjs/components/Title/index.js +1 -1
- package/dist/cjs/components/Tooltip/DefaultContent.js +41 -23
- package/dist/cjs/hooks/useChartDimensions/index.js +3 -0
- package/dist/cjs/hooks/useChartDimensions/utils.js +3 -0
- package/dist/cjs/hooks/useChartOptions/types.d.ts +5 -3
- package/dist/cjs/hooks/useChartOptions/x-axis.js +8 -0
- package/dist/cjs/hooks/useChartOptions/y-axis.js +8 -0
- package/dist/cjs/hooks/useSeries/prepare-waterfall.js +40 -28
- package/dist/cjs/hooks/useSeries/types.d.ts +4 -3
- package/dist/cjs/hooks/useShapes/HtmlLayer.js +2 -1
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +1 -0
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +1 -0
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +1 -0
- package/dist/cjs/hooks/useShapes/line/prepare-data.js +1 -0
- package/dist/cjs/hooks/useShapes/pie/index.js +1 -1
- package/dist/cjs/hooks/useShapes/pie/prepare-data.js +1 -0
- package/dist/cjs/hooks/useShapes/radar/prepare-data.js +1 -0
- package/dist/cjs/hooks/useShapes/treemap/index.js +1 -1
- package/dist/cjs/hooks/useShapes/treemap/prepare-data.js +3 -2
- package/dist/cjs/hooks/useShapes/waterfall/prepare-data.js +4 -2
- package/dist/cjs/i18n/keysets/en.json +3 -1
- package/dist/cjs/i18n/keysets/ru.json +3 -1
- package/dist/cjs/libs/chart-error/index.d.ts +1 -0
- package/dist/cjs/libs/chart-error/index.js +1 -0
- package/dist/cjs/types/chart/axis.d.ts +32 -7
- package/dist/cjs/types/chart/waterfall.d.ts +9 -0
- package/dist/cjs/types/chart-ui.d.ts +1 -0
- package/dist/cjs/utils/chart/axis-generators/bottom.d.ts +1 -0
- package/dist/cjs/utils/chart/axis-generators/bottom.js +16 -1
- package/dist/cjs/utils/chart/axis.d.ts +12 -1
- package/dist/cjs/utils/chart/axis.js +35 -0
- package/dist/cjs/utils/chart/get-closest-data.js +23 -13
- package/dist/cjs/utils/chart/index.d.ts +2 -1
- package/dist/cjs/utils/chart/index.js +5 -5
- package/dist/cjs/utils/chart/series/waterfall.d.ts +2 -2
- package/dist/cjs/utils/chart/series/waterfall.js +1 -7
- package/dist/cjs/utils/chart/types.d.ts +1 -0
- package/dist/cjs/utils/chart/types.js +1 -0
- package/dist/cjs/utils/chart-ui/pie-center-text.d.ts +1 -0
- package/dist/cjs/utils/chart-ui/pie-center-text.js +3 -1
- package/dist/cjs/validation/index.js +144 -0
- package/dist/esm/components/Axis/AxisX.d.ts +1 -0
- package/dist/esm/components/Axis/AxisX.js +57 -12
- package/dist/esm/components/Axis/AxisY.d.ts +1 -0
- package/dist/esm/components/Axis/AxisY.js +83 -12
- package/dist/esm/components/ChartInner/index.js +3 -3
- package/dist/esm/components/ChartInner/styles.css +2 -0
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +3 -0
- package/dist/esm/components/ChartInner/useChartInnerProps.js +14 -3
- package/dist/esm/components/Legend/index.js +2 -2
- package/dist/esm/components/Title/index.js +1 -1
- package/dist/esm/components/Tooltip/DefaultContent.js +41 -23
- package/dist/esm/hooks/useChartDimensions/index.js +3 -0
- package/dist/esm/hooks/useChartDimensions/utils.js +3 -0
- package/dist/esm/hooks/useChartOptions/types.d.ts +5 -3
- package/dist/esm/hooks/useChartOptions/x-axis.js +8 -0
- package/dist/esm/hooks/useChartOptions/y-axis.js +8 -0
- package/dist/esm/hooks/useSeries/prepare-waterfall.js +40 -28
- package/dist/esm/hooks/useSeries/types.d.ts +4 -3
- package/dist/esm/hooks/useShapes/HtmlLayer.js +2 -1
- package/dist/esm/hooks/useShapes/area/prepare-data.js +1 -0
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +1 -0
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +1 -0
- package/dist/esm/hooks/useShapes/line/prepare-data.js +1 -0
- package/dist/esm/hooks/useShapes/pie/index.js +1 -1
- package/dist/esm/hooks/useShapes/pie/prepare-data.js +1 -0
- package/dist/esm/hooks/useShapes/radar/prepare-data.js +1 -0
- package/dist/esm/hooks/useShapes/treemap/index.js +1 -1
- package/dist/esm/hooks/useShapes/treemap/prepare-data.js +3 -2
- package/dist/esm/hooks/useShapes/waterfall/prepare-data.js +4 -2
- package/dist/esm/i18n/keysets/en.json +3 -1
- package/dist/esm/i18n/keysets/ru.json +3 -1
- package/dist/esm/libs/chart-error/index.d.ts +1 -0
- package/dist/esm/libs/chart-error/index.js +1 -0
- package/dist/esm/types/chart/axis.d.ts +32 -7
- package/dist/esm/types/chart/waterfall.d.ts +9 -0
- package/dist/esm/types/chart-ui.d.ts +1 -0
- package/dist/esm/utils/chart/axis-generators/bottom.d.ts +1 -0
- package/dist/esm/utils/chart/axis-generators/bottom.js +16 -1
- package/dist/esm/utils/chart/axis.d.ts +12 -1
- package/dist/esm/utils/chart/axis.js +35 -0
- package/dist/esm/utils/chart/get-closest-data.js +23 -13
- package/dist/esm/utils/chart/index.d.ts +2 -1
- package/dist/esm/utils/chart/index.js +5 -5
- package/dist/esm/utils/chart/series/waterfall.d.ts +2 -2
- package/dist/esm/utils/chart/series/waterfall.js +1 -7
- package/dist/esm/utils/chart/types.d.ts +1 -0
- package/dist/esm/utils/chart/types.js +1 -0
- package/dist/esm/utils/chart-ui/pie-center-text.d.ts +1 -0
- package/dist/esm/utils/chart-ui/pie-center-text.js +3 -1
- package/dist/esm/validation/index.js +144 -0
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AxisDomain, AxisScale, ScaleBand } from 'd3';
|
|
2
|
-
import type { PreparedAxis, PreparedSplit } from '../../hooks';
|
|
2
|
+
import type { PreparedAxis, PreparedAxisPlotBand, PreparedSplit } from '../../hooks';
|
|
3
3
|
import type { TextRow } from './text';
|
|
4
|
+
import type { AxisDirection } from './types';
|
|
4
5
|
export declare function getTicksCount({ axis, range }: {
|
|
5
6
|
axis: PreparedAxis;
|
|
6
7
|
range: number;
|
|
@@ -29,3 +30,13 @@ export declare function getAxisTitleRows(args: {
|
|
|
29
30
|
axis: PreparedAxis;
|
|
30
31
|
textMaxWidth: number;
|
|
31
32
|
}): TextRow[];
|
|
33
|
+
interface GetBandsPositionArgs {
|
|
34
|
+
band: PreparedAxisPlotBand;
|
|
35
|
+
axisScale: AxisScale<AxisDomain>;
|
|
36
|
+
axis: AxisDirection;
|
|
37
|
+
}
|
|
38
|
+
export declare function getBandsPosition(args: GetBandsPositionArgs): {
|
|
39
|
+
from: number;
|
|
40
|
+
to: number;
|
|
41
|
+
};
|
|
42
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import clamp from 'lodash/clamp';
|
|
1
2
|
import { wrapText } from './text';
|
|
2
3
|
export function getTicksCount({ axis, range }) {
|
|
3
4
|
let ticksCount;
|
|
@@ -69,3 +70,37 @@ export function getAxisTitleRows(args) {
|
|
|
69
70
|
return acc;
|
|
70
71
|
}, []);
|
|
71
72
|
}
|
|
73
|
+
export function getBandsPosition(args) {
|
|
74
|
+
var _a, _b, _c;
|
|
75
|
+
const { band, axisScale } = args;
|
|
76
|
+
const scalePosTo = axisScale(band.to);
|
|
77
|
+
const scalePosFrom = axisScale(band.from);
|
|
78
|
+
const isX = args.axis === 'x';
|
|
79
|
+
if (scalePosTo !== undefined && scalePosFrom !== undefined) {
|
|
80
|
+
return {
|
|
81
|
+
from: Math.max(scalePosFrom, 0),
|
|
82
|
+
to: Math.max(scalePosTo, 0),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (typeof band.from !== 'number' || typeof band.to !== 'number') {
|
|
86
|
+
throw new Error('Filed to create plot band');
|
|
87
|
+
}
|
|
88
|
+
const category = axisScale.domain();
|
|
89
|
+
const bandwidth = (_b = (_a = axisScale.bandwidth) === null || _a === void 0 ? void 0 : _a.call(axisScale)) !== null && _b !== void 0 ? _b : 1;
|
|
90
|
+
const halfBandwidth = bandwidth / 2;
|
|
91
|
+
const calcPosition = (value) => {
|
|
92
|
+
var _a, _b;
|
|
93
|
+
if (value >= category.length) {
|
|
94
|
+
return ((_a = axisScale(category[category.length - 1])) !== null && _a !== void 0 ? _a : 0) + halfBandwidth * (isX ? 1 : -1);
|
|
95
|
+
}
|
|
96
|
+
return (((_b = axisScale(category[clamp(Math.floor(value), 0, category.length - 1)])) !== null && _b !== void 0 ? _b : 0) +
|
|
97
|
+
bandwidth * (value - Math.floor(Math.abs(value))) * (isX ? 1 : -1));
|
|
98
|
+
};
|
|
99
|
+
const to = calcPosition(band.to);
|
|
100
|
+
const from = calcPosition(band.from);
|
|
101
|
+
const maxPos = ((_c = axisScale(category[isX ? category.length - 1 : 0])) !== null && _c !== void 0 ? _c : 0) + halfBandwidth;
|
|
102
|
+
return {
|
|
103
|
+
from: clamp(from, -halfBandwidth, maxPos),
|
|
104
|
+
to: clamp(to, -halfBandwidth, maxPos),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
@@ -1,30 +1,40 @@
|
|
|
1
1
|
import { Delaunay, bisector, sort } from 'd3';
|
|
2
2
|
import get from 'lodash/get';
|
|
3
3
|
import groupBy from 'lodash/groupBy';
|
|
4
|
-
function
|
|
4
|
+
function getClosestYIndex(items, y) {
|
|
5
5
|
var _a, _b, _c, _d;
|
|
6
|
-
const sorted = sort(points, (p) => p.x);
|
|
7
|
-
const closestXIndex = bisector((p) => p.x).center(sorted, x);
|
|
8
|
-
if (closestXIndex === -1) {
|
|
9
|
-
return [];
|
|
10
|
-
}
|
|
11
|
-
const closestX = sorted[closestXIndex].x;
|
|
12
|
-
const closestPoints = sort(points.filter((p) => p.x === closestX), (p) => p.y0);
|
|
13
6
|
let closestYIndex = -1;
|
|
14
|
-
if (y < ((_a =
|
|
7
|
+
if (y < ((_a = items[0]) === null || _a === void 0 ? void 0 : _a.y0)) {
|
|
15
8
|
closestYIndex = 0;
|
|
16
9
|
}
|
|
17
|
-
else if (y > ((_b =
|
|
18
|
-
closestYIndex =
|
|
10
|
+
else if (y > ((_b = items[items.length - 1]) === null || _b === void 0 ? void 0 : _b.y1)) {
|
|
11
|
+
closestYIndex = items.length - 1;
|
|
19
12
|
}
|
|
20
13
|
else {
|
|
21
|
-
closestYIndex =
|
|
14
|
+
closestYIndex = items.findIndex((p) => y > p.y0 && y < p.y1);
|
|
22
15
|
if (closestYIndex === -1) {
|
|
23
|
-
const sortedY = sort(
|
|
16
|
+
const sortedY = sort(items.map((p, index) => ({ index, y: p.y1 + (p.y0 - p.y1) / 2 })), (p) => p.y);
|
|
24
17
|
const sortedYIndex = bisector((p) => p.y).center(sortedY, y);
|
|
25
18
|
closestYIndex = (_d = (_c = sortedY[sortedYIndex]) === null || _c === void 0 ? void 0 : _c.index) !== null && _d !== void 0 ? _d : -1;
|
|
26
19
|
}
|
|
27
20
|
}
|
|
21
|
+
return closestYIndex;
|
|
22
|
+
}
|
|
23
|
+
function getClosestPointsByXValue(x, y, points) {
|
|
24
|
+
const sorted = sort(points, (p) => p.x);
|
|
25
|
+
const closestXIndex = bisector((p) => p.x).center(sorted, x);
|
|
26
|
+
if (closestXIndex === -1) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const closestX = sorted[closestXIndex].x;
|
|
30
|
+
const filtered = points.filter((p) => p.x === closestX);
|
|
31
|
+
const groupedBySeries = Object.values(groupBy(filtered, (p) => get(p.series, 'id'))).map((items) => {
|
|
32
|
+
const sortedByY = sort(items, (p) => p.y0);
|
|
33
|
+
const index = getClosestYIndex(sortedByY, y);
|
|
34
|
+
return sortedByY[index === -1 ? 0 : index];
|
|
35
|
+
});
|
|
36
|
+
const closestPoints = sort(groupedBySeries, (p) => p.y0);
|
|
37
|
+
const closestYIndex = getClosestYIndex(closestPoints, y);
|
|
28
38
|
return closestPoints.map((p, i) => ({
|
|
29
39
|
data: p.data,
|
|
30
40
|
series: p.series,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AxisDomain } from 'd3';
|
|
2
2
|
import type { PreparedAxis } from '../../hooks';
|
|
3
3
|
import type { BaseTextStyle, ChartSeries, ChartSeriesData } from '../../types';
|
|
4
|
+
import type { AxisDirection } from './types';
|
|
4
5
|
export * from './math';
|
|
5
6
|
export * from './text';
|
|
6
7
|
export * from './time';
|
|
@@ -12,7 +13,6 @@ export * from './series';
|
|
|
12
13
|
export * from './color';
|
|
13
14
|
export declare const CHART_SERIES_WITH_VOLUME_ON_Y_AXIS: ChartSeries['type'][];
|
|
14
15
|
export declare const CHART_SERIES_WITH_VOLUME_ON_X_AXIS: ChartSeries['type'][];
|
|
15
|
-
export type AxisDirection = 'x' | 'y';
|
|
16
16
|
type UnknownSeries = {
|
|
17
17
|
type: ChartSeries['type'];
|
|
18
18
|
data: unknown;
|
|
@@ -76,3 +76,4 @@ export declare const getDataCategoryValue: (args: {
|
|
|
76
76
|
data: ChartSeriesData;
|
|
77
77
|
}) => string;
|
|
78
78
|
export declare function getClosestPointsRange(axis: PreparedAxis, points: AxisDomain[]): number | undefined;
|
|
79
|
+
export { AxisDirection };
|
|
@@ -2,6 +2,7 @@ import { dateTime } from '@gravity-ui/date-utils';
|
|
|
2
2
|
import { group, select } from 'd3';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
4
|
import isNil from 'lodash/isNil';
|
|
5
|
+
import sortBy from 'lodash/sortBy';
|
|
5
6
|
import { DEFAULT_AXIS_LABEL_FONT_SIZE } from '../../constants';
|
|
6
7
|
import { getSeriesStackId } from '../../hooks/useSeries/utils';
|
|
7
8
|
import { formatNumber, getNumberUnitRate } from '../../libs/format-number';
|
|
@@ -100,11 +101,10 @@ export const getDomainDataYBySeries = (series) => {
|
|
|
100
101
|
}
|
|
101
102
|
case 'waterfall': {
|
|
102
103
|
let yValue = 0;
|
|
103
|
-
seriesList.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
});
|
|
104
|
+
const points = seriesList.map((s) => s.data).flat();
|
|
105
|
+
sortBy(points, (p) => p.index).forEach((d) => {
|
|
106
|
+
yValue += Number(d.y) || 0;
|
|
107
|
+
acc.push(yValue);
|
|
108
108
|
});
|
|
109
109
|
break;
|
|
110
110
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { PreparedWaterfallSeries } from '../../../hooks';
|
|
1
|
+
import type { PreparedWaterfallSeries, PreparedWaterfallSeriesData } from '../../../hooks';
|
|
2
2
|
import type { WaterfallSeriesData } from '../../../types';
|
|
3
3
|
export declare function getWaterfallPointColor(point: WaterfallSeriesData, series: PreparedWaterfallSeries): string;
|
|
4
|
-
export declare function getWaterfallPointSubtotal(point:
|
|
4
|
+
export declare function getWaterfallPointSubtotal(point: PreparedWaterfallSeriesData, series: PreparedWaterfallSeries): number | null;
|
|
@@ -2,13 +2,7 @@ export function getWaterfallPointColor(point, series) {
|
|
|
2
2
|
if (point.color) {
|
|
3
3
|
return point.color;
|
|
4
4
|
}
|
|
5
|
-
|
|
6
|
-
return series.color;
|
|
7
|
-
}
|
|
8
|
-
if (Number(point.y) > 0) {
|
|
9
|
-
return series.positiveColor;
|
|
10
|
-
}
|
|
11
|
-
return series.negativeColor;
|
|
5
|
+
return series.color;
|
|
12
6
|
}
|
|
13
7
|
export function getWaterfallPointSubtotal(point, series) {
|
|
14
8
|
const pointIndex = series.data.indexOf(point);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type AxisDirection = 'x' | 'y';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -7,6 +7,7 @@ export function pieCenterText(text, options) {
|
|
|
7
7
|
return undefined;
|
|
8
8
|
}
|
|
9
9
|
const padding = get(options, 'padding', 12);
|
|
10
|
+
const color = get(options, 'color', 'currentColor');
|
|
10
11
|
return function (args) {
|
|
11
12
|
let fontSize = MAX_FONT_SIZE;
|
|
12
13
|
const textSize = getLabelsSize({ labels: [text], style: { fontSize: `${fontSize}px` } });
|
|
@@ -17,7 +18,8 @@ export function pieCenterText(text, options) {
|
|
|
17
18
|
.text(text)
|
|
18
19
|
.attr('text-anchor', 'middle')
|
|
19
20
|
.attr('alignment-baseline', 'middle')
|
|
20
|
-
.style('font-size', `${fontSize}px`)
|
|
21
|
+
.style('font-size', `${fontSize}px`)
|
|
22
|
+
.style('fill', color);
|
|
21
23
|
return container.node();
|
|
22
24
|
};
|
|
23
25
|
}
|
|
@@ -95,6 +95,148 @@ const validateXYSeries = (args) => {
|
|
|
95
95
|
}
|
|
96
96
|
});
|
|
97
97
|
};
|
|
98
|
+
const validateAxisPlotValues = (args) => {
|
|
99
|
+
const { series, xAxis, yAxis = [] } = args;
|
|
100
|
+
const yAxisIndex = get(series, 'yAxis', 0);
|
|
101
|
+
const seriesYAxis = yAxis[yAxisIndex];
|
|
102
|
+
if (yAxisIndex !== 0 && typeof seriesYAxis === 'undefined') {
|
|
103
|
+
throw new ChartError({
|
|
104
|
+
code: CHART_ERROR_CODE.INVALID_DATA,
|
|
105
|
+
message: i18n('error', 'label_invalid-y-axis-index', {
|
|
106
|
+
index: yAxisIndex,
|
|
107
|
+
}),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const xPlotBands = get(xAxis, 'plotBands', []);
|
|
111
|
+
const yPlotBands = get(yAxis, 'plotBands', []);
|
|
112
|
+
if (!xPlotBands.length && !yPlotBands.length) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const xType = get(xAxis, 'type', DEFAULT_AXIS_TYPE);
|
|
116
|
+
const yType = get(seriesYAxis, 'type', DEFAULT_AXIS_TYPE);
|
|
117
|
+
xPlotBands.forEach(({ from = 0, to = 0 }) => {
|
|
118
|
+
const fromNotEqualTo = typeof to !== typeof from;
|
|
119
|
+
if (fromNotEqualTo) {
|
|
120
|
+
throw new ChartError({
|
|
121
|
+
code: CHART_ERROR_CODE.INVALID_OPTION_TYPE,
|
|
122
|
+
message: i18n('error', 'label_axis-plot-band-options-not-equal', {
|
|
123
|
+
axis: 'x',
|
|
124
|
+
option: 'from',
|
|
125
|
+
}),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
switch (xType) {
|
|
129
|
+
case 'category': {
|
|
130
|
+
const invalidFrom = typeof from !== 'string' && typeof from !== 'number';
|
|
131
|
+
const invalidTo = typeof to !== 'string' && typeof to !== 'number';
|
|
132
|
+
if (invalidFrom) {
|
|
133
|
+
throw new ChartError({
|
|
134
|
+
code: CHART_ERROR_CODE.INVALID_OPTION_TYPE,
|
|
135
|
+
message: i18n('error', 'label_invalid-axis-plot-band-option', {
|
|
136
|
+
axis: 'x',
|
|
137
|
+
option: 'from',
|
|
138
|
+
}),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
if (invalidTo) {
|
|
142
|
+
throw new ChartError({
|
|
143
|
+
code: CHART_ERROR_CODE.INVALID_OPTION_TYPE,
|
|
144
|
+
message: i18n('error', 'label_invalid-axis-plot-band-option', {
|
|
145
|
+
axis: 'x',
|
|
146
|
+
option: 'to',
|
|
147
|
+
}),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case 'linear':
|
|
153
|
+
case 'datetime': {
|
|
154
|
+
const invalidFrom = typeof from !== 'number';
|
|
155
|
+
const invalidTo = typeof to !== 'number';
|
|
156
|
+
if (invalidFrom) {
|
|
157
|
+
throw new ChartError({
|
|
158
|
+
code: CHART_ERROR_CODE.INVALID_OPTION_TYPE,
|
|
159
|
+
message: i18n('error', 'label_invalid-axis-plot-band-option', {
|
|
160
|
+
axis: 'x',
|
|
161
|
+
option: 'from',
|
|
162
|
+
}),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (invalidTo) {
|
|
166
|
+
throw new ChartError({
|
|
167
|
+
code: CHART_ERROR_CODE.INVALID_OPTION_TYPE,
|
|
168
|
+
message: i18n('error', 'label_invalid-axis-plot-band-option', {
|
|
169
|
+
axis: 'x',
|
|
170
|
+
option: 'to',
|
|
171
|
+
}),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
yPlotBands.forEach(({ from = 0, to = 0 }) => {
|
|
179
|
+
const fromNotEqualTo = typeof to !== typeof from;
|
|
180
|
+
if (fromNotEqualTo) {
|
|
181
|
+
throw new ChartError({
|
|
182
|
+
code: CHART_ERROR_CODE.INVALID_OPTION_TYPE,
|
|
183
|
+
message: i18n('error', 'label_axis-plot-band-options-not-equal', {
|
|
184
|
+
axis: 'x',
|
|
185
|
+
option: 'from',
|
|
186
|
+
}),
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
switch (yType) {
|
|
190
|
+
case 'category': {
|
|
191
|
+
const invalidFrom = typeof from !== 'string' && typeof from !== 'number';
|
|
192
|
+
const invalidTo = typeof to !== 'string' && typeof to !== 'number';
|
|
193
|
+
if (invalidFrom) {
|
|
194
|
+
throw new ChartError({
|
|
195
|
+
code: CHART_ERROR_CODE.INVALID_OPTION_TYPE,
|
|
196
|
+
message: i18n('error', 'label_invalid-axis-plot-band-option', {
|
|
197
|
+
axis: 'y',
|
|
198
|
+
option: 'from',
|
|
199
|
+
}),
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
if (invalidTo) {
|
|
203
|
+
throw new ChartError({
|
|
204
|
+
code: CHART_ERROR_CODE.INVALID_OPTION_TYPE,
|
|
205
|
+
message: i18n('error', 'label_invalid-axis-plot-band-option', {
|
|
206
|
+
axis: 'y',
|
|
207
|
+
option: 'to',
|
|
208
|
+
}),
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
case 'linear':
|
|
214
|
+
case 'datetime': {
|
|
215
|
+
const invalidFrom = typeof from !== 'number';
|
|
216
|
+
const invalidTo = typeof to !== 'number';
|
|
217
|
+
if (invalidFrom) {
|
|
218
|
+
throw new ChartError({
|
|
219
|
+
code: CHART_ERROR_CODE.INVALID_OPTION_TYPE,
|
|
220
|
+
message: i18n('error', 'label_invalid-axis-plot-band-option', {
|
|
221
|
+
axis: 'y',
|
|
222
|
+
option: 'from',
|
|
223
|
+
}),
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
if (invalidTo) {
|
|
227
|
+
throw new ChartError({
|
|
228
|
+
code: CHART_ERROR_CODE.INVALID_OPTION_TYPE,
|
|
229
|
+
message: i18n('error', 'label_invalid-axis-plot-band-option', {
|
|
230
|
+
axis: 'y',
|
|
231
|
+
option: 'to',
|
|
232
|
+
}),
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
};
|
|
98
240
|
const validatePieSeries = ({ series }) => {
|
|
99
241
|
series.data.forEach(({ value }) => {
|
|
100
242
|
if (typeof value !== 'number') {
|
|
@@ -163,12 +305,14 @@ const validateSeries = (args) => {
|
|
|
163
305
|
case 'area':
|
|
164
306
|
case 'bar-y':
|
|
165
307
|
case 'bar-x': {
|
|
308
|
+
validateAxisPlotValues({ series, xAxis, yAxis });
|
|
166
309
|
validateXYSeries({ series, xAxis, yAxis });
|
|
167
310
|
validateStacking({ series });
|
|
168
311
|
break;
|
|
169
312
|
}
|
|
170
313
|
case 'line':
|
|
171
314
|
case 'scatter': {
|
|
315
|
+
validateAxisPlotValues({ series, xAxis, yAxis });
|
|
172
316
|
validateXYSeries({ series, xAxis, yAxis });
|
|
173
317
|
break;
|
|
174
318
|
}
|