@gravity-ui/charts 1.28.0 → 1.28.1
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/AxisX/prepare-axis-data.js +8 -1
- package/dist/cjs/components/AxisY/prepare-axis-data.js +8 -1
- package/dist/cjs/i18n/keysets/en.json +2 -1
- package/dist/cjs/i18n/keysets/ru.json +2 -1
- package/dist/cjs/types/chart/axis.d.ts +4 -4
- package/dist/cjs/utils/chart/axis/common.js +2 -2
- package/dist/cjs/validation/validate-axes.js +13 -3
- package/dist/esm/components/AxisX/prepare-axis-data.js +8 -1
- package/dist/esm/components/AxisY/prepare-axis-data.js +8 -1
- package/dist/esm/i18n/keysets/en.json +2 -1
- package/dist/esm/i18n/keysets/ru.json +2 -1
- package/dist/esm/types/chart/axis.d.ts +4 -4
- package/dist/esm/utils/chart/axis/common.js +2 -2
- package/dist/esm/validation/validate-axes.js +13 -3
- package/package.json +1 -1
|
@@ -244,11 +244,15 @@ export async function prepareXAxisData({ axis, yAxis, scale, boundsWidth, bounds
|
|
|
244
244
|
const labelSize = plotBand.label.text
|
|
245
245
|
? await getPlotLabelSize(plotBand.label.text)
|
|
246
246
|
: null;
|
|
247
|
+
const plotBandWidth = Math.min(endPos, axisWidth);
|
|
248
|
+
if (plotBandWidth < 0) {
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
247
251
|
plotBands.push({
|
|
248
252
|
layerPlacement: plotBand.layerPlacement,
|
|
249
253
|
x: Math.max(0, startPos),
|
|
250
254
|
y: 0,
|
|
251
|
-
width:
|
|
255
|
+
width: plotBandWidth,
|
|
252
256
|
height: axisHeight,
|
|
253
257
|
color: plotBand.color,
|
|
254
258
|
opacity: plotBand.opacity,
|
|
@@ -268,6 +272,9 @@ export async function prepareXAxisData({ axis, yAxis, scale, boundsWidth, bounds
|
|
|
268
272
|
const plotLine = axis.plotLines[i];
|
|
269
273
|
const axisScale = scale;
|
|
270
274
|
const plotLineValue = Number(axisScale(plotLine.value));
|
|
275
|
+
if (plotLineValue < 0 || plotLineValue > boundsWidth) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
271
278
|
const points = [
|
|
272
279
|
[plotLineValue, 0],
|
|
273
280
|
[plotLineValue, axisHeight],
|
|
@@ -211,12 +211,16 @@ export async function prepareYAxisData({ axis, split, scale, top: topOffset, wid
|
|
|
211
211
|
const startPos = halfBandwidth + Math.min(from, to);
|
|
212
212
|
const endPos = Math.min(Math.abs(to - from), axisHeight - Math.min(from, to));
|
|
213
213
|
const top = Math.max(0, startPos);
|
|
214
|
+
const plotBandHeight = Math.min(endPos, axisHeight);
|
|
215
|
+
if (plotBandHeight < 0) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
214
218
|
plotBands.push({
|
|
215
219
|
layerPlacement: plotBand.layerPlacement,
|
|
216
220
|
x: 0,
|
|
217
221
|
y: axisPlotTopPosition + top,
|
|
218
222
|
width,
|
|
219
|
-
height:
|
|
223
|
+
height: plotBandHeight,
|
|
220
224
|
color: plotBand.color,
|
|
221
225
|
opacity: plotBand.opacity,
|
|
222
226
|
label: plotBand.label.text
|
|
@@ -234,6 +238,9 @@ export async function prepareYAxisData({ axis, split, scale, top: topOffset, wid
|
|
|
234
238
|
const plotLine = axis.plotLines[i];
|
|
235
239
|
const axisScale = scale;
|
|
236
240
|
const plotLineValue = Number(axisScale(plotLine.value));
|
|
241
|
+
if (plotLineValue < 0 || plotLineValue > axisHeight) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
237
244
|
const points = [
|
|
238
245
|
[0, plotLineValue],
|
|
239
246
|
[width, plotLineValue],
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"label_invalid-axis-type": "It seems you are trying to use inappropriate type for \"{{key}}\" axis. Available types: [{{values}}].",
|
|
20
20
|
"label_invalid-axis-labels-html-type": "It seems you are trying to use inappropriate type for \"labels.html\" property. Only boolean is allowed.",
|
|
21
21
|
"label_invalid-axis-labels-html-not-supported-axis-type": "It seems you are trying to use \"labels.html\" property for an axis with an unsupported type. This property is supported only for \"category\" axis.",
|
|
22
|
-
"label_duplicate-axis-categories": "It seems you have duplicate value \"{{duplicate}}\" found in {{key}}[{{axisIndex}}]."
|
|
22
|
+
"label_duplicate-axis-categories": "It seems you have duplicate value \"{{duplicate}}\" found in {{key}}[{{axisIndex}}].",
|
|
23
|
+
"label_invalid-axis-categories": "It seems you are trying to use inappropriate value for \"categories\", or defined it incorrectly. Categories must be a non-empty array for an axis with \"category\" type."
|
|
23
24
|
},
|
|
24
25
|
"tooltip": {
|
|
25
26
|
"label_totals_sum": "Sum",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"label_invalid-axis-type": "Похоже, что вы пытаетесь использовать некорректный тип для оси \"{{key}}\". Доступные типы: [{{values}}].",
|
|
20
20
|
"label_invalid-axis-labels-html-type": "Похоже, что вы пытаетесь использовать некорректный тип для свойства \"labels.html\". Допускается только использование булевых значений.",
|
|
21
21
|
"label_invalid-axis-labels-html-not-supported-axis-type": "Похоже, что вы пытаетесь использовать свойство \"labels.html\" для оси с неподдерживаемым типом. Это свойство поддерживается только для оси типа \"category\".",
|
|
22
|
-
"label_duplicate-axis-categories": "Похоже, что у вас есть дублирующееся значение категории \"{{duplicate}}\" в оси {{key}}[{{axisIndex}}]."
|
|
22
|
+
"label_duplicate-axis-categories": "Похоже, что у вас есть дублирующееся значение категории \"{{duplicate}}\" в оси {{key}}[{{axisIndex}}].",
|
|
23
|
+
"label_invalid-axis-categories": "Похоже, что вы пытаетесь использовать недопустимое значение для \"categories\", или указали его неверно. Категории для оси типа \"category\" должны быть непустым массивом."
|
|
23
24
|
},
|
|
24
25
|
"tooltip": {
|
|
25
26
|
"label_totals_sum": "Сумма",
|
|
@@ -215,18 +215,18 @@ export interface AxisPlotBand extends AxisPlot {
|
|
|
215
215
|
* Can be a number, a string (e.g., a category), or a timestamp if representing a date.
|
|
216
216
|
* When representing a date, the value **must be a timestamp** (number of milliseconds since Unix epoch).
|
|
217
217
|
*
|
|
218
|
-
* If the value is `-Infinity`, it will be treated as the start of the axis.
|
|
218
|
+
* If the value is `-Infinity` or `null`, it will be treated as the start of the axis.
|
|
219
219
|
*/
|
|
220
|
-
from: number | string;
|
|
220
|
+
from: number | string | null;
|
|
221
221
|
/**
|
|
222
222
|
* The end position of the plot band in axis units.
|
|
223
223
|
*
|
|
224
224
|
* Can be a number, a string (e.g., a category), or a timestamp if representing a date.
|
|
225
225
|
* When representing a date, the value **must be a timestamp** (number of milliseconds since Unix epoch).
|
|
226
226
|
*
|
|
227
|
-
* If the value is `Infinity`, it will be treated as the end of the axis.
|
|
227
|
+
* If the value is `Infinity` or `null`, it will be treated as the end of the axis.
|
|
228
228
|
*/
|
|
229
|
-
to: number | string;
|
|
229
|
+
to: number | string | null;
|
|
230
230
|
}
|
|
231
231
|
export interface AxisCrosshair extends Omit<AxisPlotLine, 'value' | 'label'> {
|
|
232
232
|
/** Whether the crosshair should snap to the point or follow the pointer independent of points.
|
|
@@ -68,8 +68,8 @@ export function getBandsPosition(args) {
|
|
|
68
68
|
var _a, _b, _c;
|
|
69
69
|
const { band, axisScale } = args;
|
|
70
70
|
const range = axisScale.range();
|
|
71
|
-
const scalePosFrom = band.from === -Infinity ? range[0] : axisScale(band.from);
|
|
72
|
-
const scalePosTo = band.to === Infinity ? range[1] : axisScale(band.to);
|
|
71
|
+
const scalePosFrom = band.from === -Infinity || band.from === null ? range[0] : axisScale(band.from);
|
|
72
|
+
const scalePosTo = band.to === Infinity || band.to === null ? range[1] : axisScale(band.to);
|
|
73
73
|
const isX = args.axis === 'x';
|
|
74
74
|
if (scalePosTo !== undefined && scalePosFrom !== undefined) {
|
|
75
75
|
return {
|
|
@@ -2,7 +2,15 @@ import { AXIS_TYPE } from '../constants';
|
|
|
2
2
|
import { i18n } from '../i18n';
|
|
3
3
|
import { CHART_ERROR_CODE, ChartError } from '../libs';
|
|
4
4
|
const AVAILABLE_AXIS_TYPES = Object.values(AXIS_TYPE);
|
|
5
|
-
function
|
|
5
|
+
function validateCategories(axis) {
|
|
6
|
+
if (!axis.categories || !Array.isArray(axis.categories) || axis.categories.length === 0) {
|
|
7
|
+
throw new ChartError({
|
|
8
|
+
code: CHART_ERROR_CODE.INVALID_DATA,
|
|
9
|
+
message: i18n('error', 'label_invalid-axis-categories'),
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function validateDuplicateCategories({ axisIndex, key, categories = [], }) {
|
|
6
14
|
const seen = new Set();
|
|
7
15
|
categories.forEach((category) => {
|
|
8
16
|
if (seen.has(category)) {
|
|
@@ -54,7 +62,8 @@ export function validateAxes(args) {
|
|
|
54
62
|
if (xAxis) {
|
|
55
63
|
validateAxisType({ axis: xAxis, key: 'x' });
|
|
56
64
|
validateLabelsHtmlOptions({ axis: xAxis });
|
|
57
|
-
if ((xAxis === null || xAxis === void 0 ? void 0 : xAxis.type) === 'category'
|
|
65
|
+
if ((xAxis === null || xAxis === void 0 ? void 0 : xAxis.type) === 'category') {
|
|
66
|
+
validateCategories(xAxis);
|
|
58
67
|
validateDuplicateCategories({
|
|
59
68
|
categories: xAxis.categories,
|
|
60
69
|
key: 'x',
|
|
@@ -64,7 +73,8 @@ export function validateAxes(args) {
|
|
|
64
73
|
}
|
|
65
74
|
yAxis.forEach((axis, axisIndex) => {
|
|
66
75
|
validateAxisType({ axis, key: 'y' });
|
|
67
|
-
if (axis.type === 'category'
|
|
76
|
+
if (axis.type === 'category') {
|
|
77
|
+
validateCategories(axis);
|
|
68
78
|
validateDuplicateCategories({
|
|
69
79
|
categories: axis.categories,
|
|
70
80
|
key: 'y',
|
|
@@ -244,11 +244,15 @@ export async function prepareXAxisData({ axis, yAxis, scale, boundsWidth, bounds
|
|
|
244
244
|
const labelSize = plotBand.label.text
|
|
245
245
|
? await getPlotLabelSize(plotBand.label.text)
|
|
246
246
|
: null;
|
|
247
|
+
const plotBandWidth = Math.min(endPos, axisWidth);
|
|
248
|
+
if (plotBandWidth < 0) {
|
|
249
|
+
continue;
|
|
250
|
+
}
|
|
247
251
|
plotBands.push({
|
|
248
252
|
layerPlacement: plotBand.layerPlacement,
|
|
249
253
|
x: Math.max(0, startPos),
|
|
250
254
|
y: 0,
|
|
251
|
-
width:
|
|
255
|
+
width: plotBandWidth,
|
|
252
256
|
height: axisHeight,
|
|
253
257
|
color: plotBand.color,
|
|
254
258
|
opacity: plotBand.opacity,
|
|
@@ -268,6 +272,9 @@ export async function prepareXAxisData({ axis, yAxis, scale, boundsWidth, bounds
|
|
|
268
272
|
const plotLine = axis.plotLines[i];
|
|
269
273
|
const axisScale = scale;
|
|
270
274
|
const plotLineValue = Number(axisScale(plotLine.value));
|
|
275
|
+
if (plotLineValue < 0 || plotLineValue > boundsWidth) {
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
271
278
|
const points = [
|
|
272
279
|
[plotLineValue, 0],
|
|
273
280
|
[plotLineValue, axisHeight],
|
|
@@ -211,12 +211,16 @@ export async function prepareYAxisData({ axis, split, scale, top: topOffset, wid
|
|
|
211
211
|
const startPos = halfBandwidth + Math.min(from, to);
|
|
212
212
|
const endPos = Math.min(Math.abs(to - from), axisHeight - Math.min(from, to));
|
|
213
213
|
const top = Math.max(0, startPos);
|
|
214
|
+
const plotBandHeight = Math.min(endPos, axisHeight);
|
|
215
|
+
if (plotBandHeight < 0) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
214
218
|
plotBands.push({
|
|
215
219
|
layerPlacement: plotBand.layerPlacement,
|
|
216
220
|
x: 0,
|
|
217
221
|
y: axisPlotTopPosition + top,
|
|
218
222
|
width,
|
|
219
|
-
height:
|
|
223
|
+
height: plotBandHeight,
|
|
220
224
|
color: plotBand.color,
|
|
221
225
|
opacity: plotBand.opacity,
|
|
222
226
|
label: plotBand.label.text
|
|
@@ -234,6 +238,9 @@ export async function prepareYAxisData({ axis, split, scale, top: topOffset, wid
|
|
|
234
238
|
const plotLine = axis.plotLines[i];
|
|
235
239
|
const axisScale = scale;
|
|
236
240
|
const plotLineValue = Number(axisScale(plotLine.value));
|
|
241
|
+
if (plotLineValue < 0 || plotLineValue > axisHeight) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
237
244
|
const points = [
|
|
238
245
|
[0, plotLineValue],
|
|
239
246
|
[width, plotLineValue],
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"label_invalid-axis-type": "It seems you are trying to use inappropriate type for \"{{key}}\" axis. Available types: [{{values}}].",
|
|
20
20
|
"label_invalid-axis-labels-html-type": "It seems you are trying to use inappropriate type for \"labels.html\" property. Only boolean is allowed.",
|
|
21
21
|
"label_invalid-axis-labels-html-not-supported-axis-type": "It seems you are trying to use \"labels.html\" property for an axis with an unsupported type. This property is supported only for \"category\" axis.",
|
|
22
|
-
"label_duplicate-axis-categories": "It seems you have duplicate value \"{{duplicate}}\" found in {{key}}[{{axisIndex}}]."
|
|
22
|
+
"label_duplicate-axis-categories": "It seems you have duplicate value \"{{duplicate}}\" found in {{key}}[{{axisIndex}}].",
|
|
23
|
+
"label_invalid-axis-categories": "It seems you are trying to use inappropriate value for \"categories\", or defined it incorrectly. Categories must be a non-empty array for an axis with \"category\" type."
|
|
23
24
|
},
|
|
24
25
|
"tooltip": {
|
|
25
26
|
"label_totals_sum": "Sum",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"label_invalid-axis-type": "Похоже, что вы пытаетесь использовать некорректный тип для оси \"{{key}}\". Доступные типы: [{{values}}].",
|
|
20
20
|
"label_invalid-axis-labels-html-type": "Похоже, что вы пытаетесь использовать некорректный тип для свойства \"labels.html\". Допускается только использование булевых значений.",
|
|
21
21
|
"label_invalid-axis-labels-html-not-supported-axis-type": "Похоже, что вы пытаетесь использовать свойство \"labels.html\" для оси с неподдерживаемым типом. Это свойство поддерживается только для оси типа \"category\".",
|
|
22
|
-
"label_duplicate-axis-categories": "Похоже, что у вас есть дублирующееся значение категории \"{{duplicate}}\" в оси {{key}}[{{axisIndex}}]."
|
|
22
|
+
"label_duplicate-axis-categories": "Похоже, что у вас есть дублирующееся значение категории \"{{duplicate}}\" в оси {{key}}[{{axisIndex}}].",
|
|
23
|
+
"label_invalid-axis-categories": "Похоже, что вы пытаетесь использовать недопустимое значение для \"categories\", или указали его неверно. Категории для оси типа \"category\" должны быть непустым массивом."
|
|
23
24
|
},
|
|
24
25
|
"tooltip": {
|
|
25
26
|
"label_totals_sum": "Сумма",
|
|
@@ -215,18 +215,18 @@ export interface AxisPlotBand extends AxisPlot {
|
|
|
215
215
|
* Can be a number, a string (e.g., a category), or a timestamp if representing a date.
|
|
216
216
|
* When representing a date, the value **must be a timestamp** (number of milliseconds since Unix epoch).
|
|
217
217
|
*
|
|
218
|
-
* If the value is `-Infinity`, it will be treated as the start of the axis.
|
|
218
|
+
* If the value is `-Infinity` or `null`, it will be treated as the start of the axis.
|
|
219
219
|
*/
|
|
220
|
-
from: number | string;
|
|
220
|
+
from: number | string | null;
|
|
221
221
|
/**
|
|
222
222
|
* The end position of the plot band in axis units.
|
|
223
223
|
*
|
|
224
224
|
* Can be a number, a string (e.g., a category), or a timestamp if representing a date.
|
|
225
225
|
* When representing a date, the value **must be a timestamp** (number of milliseconds since Unix epoch).
|
|
226
226
|
*
|
|
227
|
-
* If the value is `Infinity`, it will be treated as the end of the axis.
|
|
227
|
+
* If the value is `Infinity` or `null`, it will be treated as the end of the axis.
|
|
228
228
|
*/
|
|
229
|
-
to: number | string;
|
|
229
|
+
to: number | string | null;
|
|
230
230
|
}
|
|
231
231
|
export interface AxisCrosshair extends Omit<AxisPlotLine, 'value' | 'label'> {
|
|
232
232
|
/** Whether the crosshair should snap to the point or follow the pointer independent of points.
|
|
@@ -68,8 +68,8 @@ export function getBandsPosition(args) {
|
|
|
68
68
|
var _a, _b, _c;
|
|
69
69
|
const { band, axisScale } = args;
|
|
70
70
|
const range = axisScale.range();
|
|
71
|
-
const scalePosFrom = band.from === -Infinity ? range[0] : axisScale(band.from);
|
|
72
|
-
const scalePosTo = band.to === Infinity ? range[1] : axisScale(band.to);
|
|
71
|
+
const scalePosFrom = band.from === -Infinity || band.from === null ? range[0] : axisScale(band.from);
|
|
72
|
+
const scalePosTo = band.to === Infinity || band.to === null ? range[1] : axisScale(band.to);
|
|
73
73
|
const isX = args.axis === 'x';
|
|
74
74
|
if (scalePosTo !== undefined && scalePosFrom !== undefined) {
|
|
75
75
|
return {
|
|
@@ -2,7 +2,15 @@ import { AXIS_TYPE } from '../constants';
|
|
|
2
2
|
import { i18n } from '../i18n';
|
|
3
3
|
import { CHART_ERROR_CODE, ChartError } from '../libs';
|
|
4
4
|
const AVAILABLE_AXIS_TYPES = Object.values(AXIS_TYPE);
|
|
5
|
-
function
|
|
5
|
+
function validateCategories(axis) {
|
|
6
|
+
if (!axis.categories || !Array.isArray(axis.categories) || axis.categories.length === 0) {
|
|
7
|
+
throw new ChartError({
|
|
8
|
+
code: CHART_ERROR_CODE.INVALID_DATA,
|
|
9
|
+
message: i18n('error', 'label_invalid-axis-categories'),
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function validateDuplicateCategories({ axisIndex, key, categories = [], }) {
|
|
6
14
|
const seen = new Set();
|
|
7
15
|
categories.forEach((category) => {
|
|
8
16
|
if (seen.has(category)) {
|
|
@@ -54,7 +62,8 @@ export function validateAxes(args) {
|
|
|
54
62
|
if (xAxis) {
|
|
55
63
|
validateAxisType({ axis: xAxis, key: 'x' });
|
|
56
64
|
validateLabelsHtmlOptions({ axis: xAxis });
|
|
57
|
-
if ((xAxis === null || xAxis === void 0 ? void 0 : xAxis.type) === 'category'
|
|
65
|
+
if ((xAxis === null || xAxis === void 0 ? void 0 : xAxis.type) === 'category') {
|
|
66
|
+
validateCategories(xAxis);
|
|
58
67
|
validateDuplicateCategories({
|
|
59
68
|
categories: xAxis.categories,
|
|
60
69
|
key: 'x',
|
|
@@ -64,7 +73,8 @@ export function validateAxes(args) {
|
|
|
64
73
|
}
|
|
65
74
|
yAxis.forEach((axis, axisIndex) => {
|
|
66
75
|
validateAxisType({ axis, key: 'y' });
|
|
67
|
-
if (axis.type === 'category'
|
|
76
|
+
if (axis.type === 'category') {
|
|
77
|
+
validateCategories(axis);
|
|
68
78
|
validateDuplicateCategories({
|
|
69
79
|
categories: axis.categories,
|
|
70
80
|
key: 'y',
|