@gravity-ui/charts 1.32.0 → 1.33.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/hooks/index.d.ts +1 -0
- package/dist/cjs/hooks/index.js +1 -0
- package/dist/cjs/hooks/useAxis/x-axis.js +2 -0
- package/dist/cjs/hooks/useAxis/y-axis.js +2 -0
- package/dist/cjs/hooks/useAxisScales/index.d.ts +6 -8
- package/dist/cjs/hooks/useAxisScales/index.js +145 -47
- package/dist/cjs/hooks/useAxisScales/types.d.ts +6 -0
- package/dist/cjs/hooks/useAxisScales/types.js +1 -0
- package/dist/cjs/hooks/useAxisScales/utils.d.ts +9 -1
- package/dist/cjs/hooks/useAxisScales/utils.js +74 -0
- package/dist/cjs/hooks/useNormalizedOriginalData/index.d.ts +2 -0
- package/dist/cjs/hooks/useRangeSlider/index.js +1 -0
- package/dist/cjs/hooks/useRangeSlider/types.d.ts +1 -1
- package/dist/cjs/hooks/useRangeSlider/utils.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/area/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +25 -11
- package/dist/cjs/hooks/useShapes/bar-x/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +10 -3
- package/dist/cjs/hooks/useShapes/heatmap/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/index.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/line/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/scatter/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/utils.d.ts +1 -1
- package/dist/cjs/hooks/useShapes/waterfall/prepare-data.d.ts +1 -1
- package/dist/cjs/hooks/useZoom/index.d.ts +1 -1
- package/dist/cjs/hooks/useZoom/utils.d.ts +1 -1
- package/dist/cjs/hooks/utils/bar-x.d.ts +1 -1
- package/dist/cjs/hooks/utils/bar-y.d.ts +1 -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 +25 -0
- package/dist/cjs/utils/chart/index.js +3 -5
- package/dist/cjs/validation/validate-axes.js +35 -0
- package/dist/esm/hooks/index.d.ts +1 -0
- package/dist/esm/hooks/index.js +1 -0
- package/dist/esm/hooks/useAxis/x-axis.js +2 -0
- package/dist/esm/hooks/useAxis/y-axis.js +2 -0
- package/dist/esm/hooks/useAxisScales/index.d.ts +6 -8
- package/dist/esm/hooks/useAxisScales/index.js +145 -47
- package/dist/esm/hooks/useAxisScales/types.d.ts +6 -0
- package/dist/esm/hooks/useAxisScales/types.js +1 -0
- package/dist/esm/hooks/useAxisScales/utils.d.ts +9 -1
- package/dist/esm/hooks/useAxisScales/utils.js +74 -0
- package/dist/esm/hooks/useNormalizedOriginalData/index.d.ts +2 -0
- package/dist/esm/hooks/useRangeSlider/index.js +1 -0
- package/dist/esm/hooks/useRangeSlider/types.d.ts +1 -1
- package/dist/esm/hooks/useRangeSlider/utils.d.ts +1 -1
- package/dist/esm/hooks/useShapes/area/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/area/prepare-data.js +25 -11
- package/dist/esm/hooks/useShapes/bar-x/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +10 -3
- package/dist/esm/hooks/useShapes/heatmap/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/index.d.ts +1 -1
- package/dist/esm/hooks/useShapes/line/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/scatter/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useShapes/utils.d.ts +1 -1
- package/dist/esm/hooks/useShapes/waterfall/prepare-data.d.ts +1 -1
- package/dist/esm/hooks/useZoom/index.d.ts +1 -1
- package/dist/esm/hooks/useZoom/utils.d.ts +1 -1
- package/dist/esm/hooks/utils/bar-x.d.ts +1 -1
- package/dist/esm/hooks/utils/bar-y.d.ts +1 -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 +25 -0
- package/dist/esm/utils/chart/index.js +3 -5
- package/dist/esm/validation/validate-axes.js +35 -0
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ticks } from 'd3';
|
|
1
2
|
import get from 'lodash/get';
|
|
2
3
|
import { SERIES_TYPE } from '../../constants';
|
|
3
4
|
const MARKER_SERIES_TYPES = [SERIES_TYPE.Area, SERIES_TYPE.Line, SERIES_TYPE.Scatter];
|
|
@@ -49,3 +50,76 @@ export function getXMaxDomainResult(args) {
|
|
|
49
50
|
}
|
|
50
51
|
return xMaxDomainResult;
|
|
51
52
|
}
|
|
53
|
+
export function clusterYAxes(yAxes) {
|
|
54
|
+
if (yAxes.length <= 1) {
|
|
55
|
+
return yAxes.map((axis) => [axis]);
|
|
56
|
+
}
|
|
57
|
+
const clusters = {};
|
|
58
|
+
yAxes.forEach((axis) => {
|
|
59
|
+
var _a;
|
|
60
|
+
const plotIndex = (_a = axis.plotIndex) !== null && _a !== void 0 ? _a : 0;
|
|
61
|
+
if (!clusters[plotIndex]) {
|
|
62
|
+
clusters[plotIndex] = [];
|
|
63
|
+
}
|
|
64
|
+
clusters[plotIndex].push(axis);
|
|
65
|
+
});
|
|
66
|
+
return Object.values(clusters).map((cluster) => {
|
|
67
|
+
if (cluster.length <= 1) {
|
|
68
|
+
return [cluster[0]];
|
|
69
|
+
}
|
|
70
|
+
const leftAxis = cluster.find((a) => a.position === 'left');
|
|
71
|
+
const secondaryAxis = cluster.find((a) => a !== leftAxis);
|
|
72
|
+
if (leftAxis) {
|
|
73
|
+
return [leftAxis, secondaryAxis];
|
|
74
|
+
}
|
|
75
|
+
return [cluster[0], cluster[1]];
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
export function getDomainSyncedToPrimaryTicks(args) {
|
|
79
|
+
const { primaryTickPositions, range, scaleFn, secondaryDomain } = args;
|
|
80
|
+
const [dMin, dMax] = secondaryDomain;
|
|
81
|
+
const primaryPosBottom = primaryTickPositions[0];
|
|
82
|
+
const primaryPosTop = primaryTickPositions[primaryTickPositions.length - 1];
|
|
83
|
+
let secondaryTicks = ticks(dMin, dMax, primaryTickPositions.length);
|
|
84
|
+
let originalStep = 0;
|
|
85
|
+
if (typeof secondaryTicks[0] === 'number' && typeof secondaryTicks[1] === 'number') {
|
|
86
|
+
originalStep = secondaryTicks[1] - secondaryTicks[0];
|
|
87
|
+
}
|
|
88
|
+
let i = 1;
|
|
89
|
+
while (secondaryTicks.length > primaryTickPositions.length) {
|
|
90
|
+
secondaryTicks = ticks(dMin, dMax, primaryTickPositions.length - i);
|
|
91
|
+
i += 1;
|
|
92
|
+
}
|
|
93
|
+
let step = originalStep;
|
|
94
|
+
if (typeof secondaryTicks[0] === 'number' && typeof secondaryTicks[1] === 'number') {
|
|
95
|
+
step = secondaryTicks[1] - secondaryTicks[0];
|
|
96
|
+
}
|
|
97
|
+
let ticksCountDiff = primaryTickPositions.length - secondaryTicks.length;
|
|
98
|
+
let deltaMin = Math.abs(dMin - secondaryTicks[0]);
|
|
99
|
+
let deltaMax = Math.abs(dMax - secondaryTicks[secondaryTicks.length - 1]);
|
|
100
|
+
while (ticksCountDiff > 0) {
|
|
101
|
+
if (deltaMin > deltaMax) {
|
|
102
|
+
secondaryTicks.unshift(secondaryTicks[0] - step);
|
|
103
|
+
deltaMin -= step;
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
secondaryTicks.push(secondaryTicks[secondaryTicks.length - 1] + step);
|
|
107
|
+
deltaMax -= step;
|
|
108
|
+
}
|
|
109
|
+
ticksCountDiff -= 1;
|
|
110
|
+
}
|
|
111
|
+
let tmpScale = scaleFn()
|
|
112
|
+
.domain([secondaryTicks[0], secondaryTicks[secondaryTicks.length - 1]])
|
|
113
|
+
.range([primaryPosBottom, primaryPosTop]);
|
|
114
|
+
let dNewMin = tmpScale.invert(range[0]);
|
|
115
|
+
let dNewMax = tmpScale.invert(range[1]);
|
|
116
|
+
if (dNewMin < dMin) {
|
|
117
|
+
secondaryTicks = secondaryTicks.map((st) => st + step);
|
|
118
|
+
tmpScale = scaleFn()
|
|
119
|
+
.domain([secondaryTicks[0], secondaryTicks[secondaryTicks.length - 1]])
|
|
120
|
+
.range([primaryPosBottom, primaryPosTop]);
|
|
121
|
+
dNewMin = tmpScale.invert(range[0]);
|
|
122
|
+
dNewMax = tmpScale.invert(range[1]);
|
|
123
|
+
}
|
|
124
|
+
return [dNewMin, dNewMax];
|
|
125
|
+
}
|
|
@@ -29,6 +29,8 @@ export declare function useNormalizedOriginalData(props: UseOriginalDataProps):
|
|
|
29
29
|
plotBands?: import("../..").AxisPlotBand[];
|
|
30
30
|
visible?: boolean;
|
|
31
31
|
order?: "sortAsc" | "sortDesc" | "reverse";
|
|
32
|
+
startOnTick?: boolean;
|
|
33
|
+
endOnTick?: boolean;
|
|
32
34
|
};
|
|
33
35
|
normalizedYAxis: import("../..").ChartYAxis[] | undefined;
|
|
34
36
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ChartXAxis, ChartYAxis } from '../../types';
|
|
2
2
|
import type { PreparedRangeSlider, PreparedXAxis, PreparedYAxis } from '../useAxis/types';
|
|
3
|
-
import type { ChartScale } from '../useAxisScales';
|
|
3
|
+
import type { ChartScale } from '../useAxisScales/types';
|
|
4
4
|
import type { BrushSelection, UseBrushProps } from '../useBrush/types';
|
|
5
5
|
import type { PreparedChart } from '../useChartOptions/types';
|
|
6
6
|
import type { PreparedLegend, PreparedSeries, PreparedSeriesOptions } from '../useSeries/types';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PreparedRangeSlider } from '../useAxis/types';
|
|
2
|
-
import type { ChartScale } from '../useAxisScales';
|
|
2
|
+
import type { ChartScale } from '../useAxisScales/types';
|
|
3
3
|
import type { BrushSelection } from '../useBrush/types';
|
|
4
4
|
import type { PreparedChart } from '../useChartOptions/types';
|
|
5
5
|
import type { PreparedLegend } from '../useSeries/types';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
|
|
2
|
-
import type { ChartScale } from '../../useAxisScales';
|
|
2
|
+
import type { ChartScale } from '../../useAxisScales/types';
|
|
3
3
|
import type { PreparedAreaSeries } from '../../useSeries/types';
|
|
4
4
|
import type { PreparedSplit } from '../../useSplit/types';
|
|
5
5
|
import type { PreparedAreaData } from './types';
|
|
@@ -91,9 +91,11 @@ export const prepareAreaData = async (args) => {
|
|
|
91
91
|
for (let i = 0; i < list.length; i++) {
|
|
92
92
|
const [_stackId, seriesStack] = list[i];
|
|
93
93
|
const xValues = getXValues(seriesStack, xAxis, xScale);
|
|
94
|
-
const
|
|
94
|
+
const positiveStackValues = new Map();
|
|
95
|
+
const negativeStackValues = new Map();
|
|
95
96
|
xValues.forEach(([key]) => {
|
|
96
|
-
|
|
97
|
+
positiveStackValues.set(key, 0);
|
|
98
|
+
negativeStackValues.set(key, 0);
|
|
97
99
|
});
|
|
98
100
|
const seriesStackData = [];
|
|
99
101
|
for (let j = 0; j < seriesStack.length; j++) {
|
|
@@ -122,24 +124,36 @@ export const prepareAreaData = async (args) => {
|
|
|
122
124
|
return m.set(key, d);
|
|
123
125
|
}, new Map());
|
|
124
126
|
const points = xValues.reduce((pointsAcc, [x, xValue]) => {
|
|
125
|
-
var _a;
|
|
126
|
-
const accumulatedYValue = accumulatedYValues.get(x) || 0;
|
|
127
|
+
var _a, _b;
|
|
127
128
|
const d = (_a = seriesData.get(x)) !== null && _a !== void 0 ? _a : {
|
|
128
129
|
x,
|
|
129
130
|
y: 0,
|
|
130
131
|
};
|
|
132
|
+
const yDataValue = (_b = d.y) !== null && _b !== void 0 ? _b : null;
|
|
131
133
|
const yValue = getYValue({ point: d, yAxis: seriesYAxis, yScale: seriesYScale });
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
let y = null;
|
|
135
|
+
let y0 = yAxisTop + yMin;
|
|
136
|
+
if (typeof yDataValue === 'number' && yValue !== null) {
|
|
137
|
+
if (yDataValue >= 0) {
|
|
138
|
+
const positiveStackHeight = positiveStackValues.get(x) || 0;
|
|
139
|
+
y = yAxisTop + yValue - positiveStackHeight;
|
|
140
|
+
y0 -= positiveStackHeight;
|
|
141
|
+
positiveStackValues.set(x, positiveStackHeight + (yMin - yValue));
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
const negativeStackHeight = negativeStackValues.get(x) || 0;
|
|
145
|
+
y = yAxisTop + yValue + negativeStackHeight;
|
|
146
|
+
y0 += negativeStackHeight;
|
|
147
|
+
negativeStackValues.set(x, negativeStackHeight + (yValue - yMin));
|
|
148
|
+
}
|
|
135
149
|
}
|
|
136
|
-
if (s.nullMode === 'connect' &&
|
|
150
|
+
if (s.nullMode === 'connect' && yDataValue === null) {
|
|
137
151
|
return pointsAcc;
|
|
138
152
|
}
|
|
139
153
|
pointsAcc.push({
|
|
140
|
-
y0
|
|
154
|
+
y0,
|
|
141
155
|
x: xValue,
|
|
142
|
-
y
|
|
156
|
+
y,
|
|
143
157
|
data: d,
|
|
144
158
|
series: s,
|
|
145
159
|
});
|
|
@@ -183,7 +197,7 @@ export const prepareAreaData = async (args) => {
|
|
|
183
197
|
}
|
|
184
198
|
if (series.some((s) => s.stacking === 'percent')) {
|
|
185
199
|
xValues.forEach(([x], index) => {
|
|
186
|
-
const stackHeight =
|
|
200
|
+
const stackHeight = positiveStackValues.get(x) || 0;
|
|
187
201
|
let acc = 0;
|
|
188
202
|
const ratio = plotHeight / stackHeight;
|
|
189
203
|
seriesStackData.forEach((item) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
|
|
2
|
-
import type { ChartScale } from '../../useAxisScales';
|
|
2
|
+
import type { ChartScale } from '../../useAxisScales/types';
|
|
3
3
|
import type { PreparedBarXSeries, PreparedSeriesOptions } from '../../useSeries/types';
|
|
4
4
|
import type { PreparedSplit } from '../../useSplit/types';
|
|
5
5
|
import type { PreparedBarXData } from './types';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
|
|
2
|
-
import type { ChartScale } from '../../useAxisScales';
|
|
2
|
+
import type { ChartScale } from '../../useAxisScales/types';
|
|
3
3
|
import type { PreparedBarYSeries, PreparedSeriesOptions } from '../../useSeries/types';
|
|
4
4
|
import type { BarYShapesArgs } from './types';
|
|
5
5
|
export declare function prepareBarYData(args: {
|
|
@@ -45,7 +45,8 @@ export async function prepareBarYData(args) {
|
|
|
45
45
|
stacks.forEach((measureValues, groupItemIndex) => {
|
|
46
46
|
const baseValue = xAxis.type === 'logarithmic' ? 0 : xLinearScale(0);
|
|
47
47
|
const base = baseValue - measureValues[0].series.borderWidth;
|
|
48
|
-
let
|
|
48
|
+
let positiveStack = base;
|
|
49
|
+
let negativeStack = base;
|
|
49
50
|
const stackItems = [];
|
|
50
51
|
const sortedData = sortKey
|
|
51
52
|
? sort(measureValues, (a, b) => comparator(get(a, sortKey), get(b, sortKey)))
|
|
@@ -93,7 +94,8 @@ export async function prepareBarYData(args) {
|
|
|
93
94
|
const isLastStackItem = xValueIndex === sortedData.length - 1;
|
|
94
95
|
// Calculate position with border compensation
|
|
95
96
|
// Border extends halfBorder outward from the shape, so we need to adjust position
|
|
96
|
-
let itemX =
|
|
97
|
+
let itemX = xValue > baseRangeValue ? positiveStack : negativeStack - width;
|
|
98
|
+
itemX += itemStackGap;
|
|
97
99
|
const halfBorder = borderWidth / 2;
|
|
98
100
|
if (isFirstInStack && xValue > 0) {
|
|
99
101
|
// Positive bar: border extends left, so shift position left by halfBorder
|
|
@@ -119,7 +121,12 @@ export async function prepareBarYData(args) {
|
|
|
119
121
|
isLastStackItem,
|
|
120
122
|
};
|
|
121
123
|
stackItems.push(item);
|
|
122
|
-
|
|
124
|
+
if (xValue > baseRangeValue) {
|
|
125
|
+
positiveStack += width;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
negativeStack -= width;
|
|
129
|
+
}
|
|
123
130
|
});
|
|
124
131
|
result.push(...stackItems);
|
|
125
132
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PreparedXAxis, PreparedYAxis } from '../../../hooks/useAxis/types';
|
|
2
|
-
import type { ChartScale } from '../../../hooks/useAxisScales';
|
|
2
|
+
import type { ChartScale } from '../../../hooks/useAxisScales/types';
|
|
3
3
|
import type { PreparedHeatmapSeries } from '../../useSeries/types';
|
|
4
4
|
import type { PreparedHeatmapData } from './types';
|
|
5
5
|
type PrepareHeatmapDataArgs = {
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import type { Dispatch } from 'd3';
|
|
3
3
|
import type { SeriesType } from '../../constants';
|
|
4
4
|
import type { PreparedXAxis, PreparedYAxis } from '../useAxis/types';
|
|
5
|
-
import type { ChartScale } from '../useAxisScales';
|
|
5
|
+
import type { ChartScale } from '../useAxisScales/types';
|
|
6
6
|
import type { PreparedSeries, PreparedSeriesOptions } from '../useSeries/types';
|
|
7
7
|
import type { PreparedSplit } from '../useSplit/types';
|
|
8
8
|
import type { PreparedAreaData } from './area/types';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
|
|
2
|
-
import type { ChartScale } from '../../useAxisScales';
|
|
2
|
+
import type { ChartScale } from '../../useAxisScales/types';
|
|
3
3
|
import type { PreparedLineSeries } from '../../useSeries/types';
|
|
4
4
|
import type { PreparedSplit } from '../../useSplit/types';
|
|
5
5
|
import type { PreparedLineData } from './types';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
|
|
2
|
-
import type { ChartScale } from '../../useAxisScales';
|
|
2
|
+
import type { ChartScale } from '../../useAxisScales/types';
|
|
3
3
|
import type { PreparedScatterSeries } from '../../useSeries/types';
|
|
4
4
|
import type { PreparedScatterData } from './types';
|
|
5
5
|
export declare function prepareScatterData(args: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BaseType } from 'd3';
|
|
2
2
|
import type { BasicInactiveState } from '../../types';
|
|
3
3
|
import type { PreparedXAxis, PreparedYAxis } from '../useAxis/types';
|
|
4
|
-
import type { ChartScale } from '../useAxisScales';
|
|
4
|
+
import type { ChartScale } from '../useAxisScales/types';
|
|
5
5
|
export declare function getXValue(args: {
|
|
6
6
|
point: {
|
|
7
7
|
x?: number | string | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
|
|
2
|
-
import type { ChartScale } from '../../useAxisScales';
|
|
2
|
+
import type { ChartScale } from '../../useAxisScales/types';
|
|
3
3
|
import type { PreparedSeriesOptions, PreparedWaterfallSeries } from '../../useSeries/types';
|
|
4
4
|
import type { PreparedWaterfallData } from './types';
|
|
5
5
|
export declare const prepareWaterfallData: (args: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PreparedXAxis, PreparedYAxis } from '../useAxis/types';
|
|
2
|
-
import type { ChartScale } from '../useAxisScales';
|
|
2
|
+
import type { ChartScale } from '../useAxisScales/types';
|
|
3
3
|
import type { PreparedZoom } from '../useChartOptions/types';
|
|
4
4
|
import type { PreparedSplit } from '../useSplit/types';
|
|
5
5
|
import type { ZoomState } from './types';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BrushSelection } from 'd3';
|
|
2
2
|
import type { ZoomType } from '../../constants';
|
|
3
3
|
import type { PreparedXAxis, PreparedYAxis } from '../useAxis/types';
|
|
4
|
-
import type { ChartScale } from '../useAxisScales';
|
|
4
|
+
import type { ChartScale } from '../useAxisScales/types';
|
|
5
5
|
import type { ZoomState } from './types';
|
|
6
6
|
export declare function selectionToZoomBounds(args: {
|
|
7
7
|
selection: BrushSelection;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BarXSeries, BarXSeriesData } from '../../types';
|
|
2
2
|
import type { PreparedXAxis } from '../useAxis/types';
|
|
3
|
-
import type { ChartScale } from '../useAxisScales';
|
|
3
|
+
import type { ChartScale } from '../useAxisScales/types';
|
|
4
4
|
import type { PreparedBarXSeries, PreparedSeriesOptions } from '../useSeries/types';
|
|
5
5
|
export declare function groupBarXDataByXValue<T extends BarXSeries | PreparedBarXSeries>(series: T[], xAxis: PreparedXAxis): Record<string | number, Record<string, {
|
|
6
6
|
data: BarXSeriesData;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BarYSeries, BarYSeriesData } from '../../types';
|
|
2
2
|
import type { PreparedYAxis } from '../useAxis/types';
|
|
3
|
-
import type { ChartScale } from '../useAxisScales';
|
|
3
|
+
import type { ChartScale } from '../useAxisScales/types';
|
|
4
4
|
import type { PreparedBarYSeries, PreparedSeriesOptions } from '../useSeries/types';
|
|
5
5
|
/**
|
|
6
6
|
* BarY always filters out data with null or replace null by zero.
|
|
@@ -20,7 +20,8 @@
|
|
|
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
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
|
+
"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.",
|
|
24
|
+
"label_inconsistent-y-axis-configuration": "It seems you have inconsistent Y-axis configuration. Possible reasons:\n1. Multiple Y axes with the same position and plot index.\n2. At the moment, 'category' axis is not supported in dual Y-axis configurations."
|
|
24
25
|
},
|
|
25
26
|
"tooltip": {
|
|
26
27
|
"label_totals_sum": "Sum",
|
|
@@ -20,7 +20,8 @@
|
|
|
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
22
|
"label_duplicate-axis-categories": "Похоже, что у вас есть дублирующееся значение категории \"{{duplicate}}\" в оси {{key}}[{{axisIndex}}].",
|
|
23
|
-
"label_invalid-axis-categories": "Похоже, что вы пытаетесь использовать недопустимое значение для \"categories\", или указали его неверно. Категории для оси типа \"category\" должны быть непустым массивом."
|
|
23
|
+
"label_invalid-axis-categories": "Похоже, что вы пытаетесь использовать недопустимое значение для \"categories\", или указали его неверно. Категории для оси типа \"category\" должны быть непустым массивом.",
|
|
24
|
+
"label_inconsistent-y-axis-configuration": "Похоже, что конфигурация осей Y неконсистентна. Возможные причины:\n1. Несколько осей Y имеют одинаковые значения position и plotIndex.\n2. На данный момент категорийные оси не поддерживаются в конфигурациях с двумя осями Y."
|
|
24
25
|
},
|
|
25
26
|
"tooltip": {
|
|
26
27
|
"label_totals_sum": "Сумма",
|
|
@@ -164,6 +164,31 @@ export interface ChartAxis {
|
|
|
164
164
|
* the "reverse" value is needed to use the reverse order without sorting
|
|
165
165
|
*/
|
|
166
166
|
order?: 'sortAsc' | 'sortDesc' | 'reverse';
|
|
167
|
+
/**
|
|
168
|
+
* Whether to force the axis to start on a tick.
|
|
169
|
+
*
|
|
170
|
+
* When enabled, the axis minimum is rounded to a "nice" value (e.g., round numbers)
|
|
171
|
+
* for better readability. This can create a visual gap at the beginning of the chart
|
|
172
|
+
* if the data minimum doesn't align with the tick.
|
|
173
|
+
*
|
|
174
|
+
* Use `startOnTick: false` to make the chart start exactly at the data minimum,
|
|
175
|
+
* preventing gaps at the chart start.
|
|
176
|
+
*
|
|
177
|
+
* @default true for X axis and datetime Y axis, false for linear/logarithmic Y axis
|
|
178
|
+
*/
|
|
179
|
+
startOnTick?: boolean;
|
|
180
|
+
/**
|
|
181
|
+
* Whether to force the axis to end on a tick.
|
|
182
|
+
*
|
|
183
|
+
* When enabled, the axis maximum is rounded to a "nice" value (e.g., round numbers)
|
|
184
|
+
* for better readability. This can create extra space at the end of the chart
|
|
185
|
+
* if the data maximum doesn't align with the tick.
|
|
186
|
+
*
|
|
187
|
+
* Use `endOnTick: false` to make the chart end closer to the data maximum.
|
|
188
|
+
*
|
|
189
|
+
* @default true for X axis and datetime Y axis, false for linear/logarithmic Y axis
|
|
190
|
+
*/
|
|
191
|
+
endOnTick?: boolean;
|
|
167
192
|
}
|
|
168
193
|
export interface ChartXAxis extends ChartAxis {
|
|
169
194
|
/**
|
|
@@ -104,11 +104,9 @@ export function getDefaultMaxXAxisValue(series) {
|
|
|
104
104
|
}
|
|
105
105
|
export function getDefaultMinXAxisValue(series) {
|
|
106
106
|
if (series === null || series === void 0 ? void 0 : series.some((s) => CHART_SERIES_WITH_VOLUME_ON_X_AXIS.includes(s.type))) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const minXValue = s.data.reduce((res, d) => Math.min(res, get(d, 'x', 0)), 0);
|
|
111
|
-
return Math.min(minValue, minXValue);
|
|
107
|
+
const domainData = getDomainDataXBySeries(series);
|
|
108
|
+
return domainData.reduce((minValue, d) => {
|
|
109
|
+
return Math.min(minValue, d);
|
|
112
110
|
}, 0);
|
|
113
111
|
}
|
|
114
112
|
return undefined;
|
|
@@ -57,6 +57,40 @@ function validateLabelsHtmlOptions(args) {
|
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
+
function validateYAxesConsistency(yAxis) {
|
|
61
|
+
const axesByPlot = {};
|
|
62
|
+
yAxis.forEach((axis) => {
|
|
63
|
+
const plotIndex = axis.plotIndex || 0;
|
|
64
|
+
if (!axesByPlot[plotIndex]) {
|
|
65
|
+
axesByPlot[plotIndex] = [];
|
|
66
|
+
}
|
|
67
|
+
axesByPlot[plotIndex].push(axis);
|
|
68
|
+
});
|
|
69
|
+
Object.values(axesByPlot).forEach((axes) => {
|
|
70
|
+
const seenPositions = new Set();
|
|
71
|
+
axes.forEach((axis, index) => {
|
|
72
|
+
const isFirstPlotAxis = index === 0;
|
|
73
|
+
const defaultAxisPosition = isFirstPlotAxis ? 'left' : 'right';
|
|
74
|
+
const position = axis.position || defaultAxisPosition;
|
|
75
|
+
if (seenPositions.has(position)) {
|
|
76
|
+
throw new ChartError({
|
|
77
|
+
code: CHART_ERROR_CODE.INVALID_DATA,
|
|
78
|
+
message: i18n('error', 'label_inconsistent-y-axis-configuration'),
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
seenPositions.add(position);
|
|
82
|
+
});
|
|
83
|
+
if (axes.length > 1) {
|
|
84
|
+
const hasCategoryAxis = axes.some((axis) => axis.type === 'category');
|
|
85
|
+
if (hasCategoryAxis) {
|
|
86
|
+
throw new ChartError({
|
|
87
|
+
code: CHART_ERROR_CODE.INVALID_DATA,
|
|
88
|
+
message: i18n('error', 'label_inconsistent-y-axis-configuration'),
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
60
94
|
export function validateAxes(args) {
|
|
61
95
|
const { xAxis, yAxis = [] } = args;
|
|
62
96
|
if (xAxis) {
|
|
@@ -71,6 +105,7 @@ export function validateAxes(args) {
|
|
|
71
105
|
});
|
|
72
106
|
}
|
|
73
107
|
}
|
|
108
|
+
validateYAxesConsistency(yAxis);
|
|
74
109
|
yAxis.forEach((axis, axisIndex) => {
|
|
75
110
|
validateAxisType({ axis, key: 'y' });
|
|
76
111
|
if (axis.type === 'category') {
|