@gravity-ui/charts 1.34.1 → 1.34.3
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.d.ts +6 -5
- package/dist/cjs/components/AxisX/prepare-axis-data.js +29 -3
- package/dist/cjs/components/AxisY/utils.js +3 -3
- package/dist/cjs/components/ChartInner/index.js +18 -8
- package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +1 -0
- package/dist/cjs/components/ChartInner/useChartInnerProps.js +2 -1
- package/dist/cjs/hooks/useAxis/x-axis.js +2 -2
- package/dist/cjs/hooks/useShapes/area/prepare-data.js +85 -25
- package/dist/cjs/hooks/useShapes/index.d.ts +1 -0
- package/dist/cjs/hooks/useShapes/index.js +32 -26
- package/dist/cjs/setup-jsdom.d.ts +0 -0
- package/dist/cjs/setup-jsdom.js +19 -0
- package/dist/cjs/types/chart/axis.d.ts +4 -1
- package/dist/cjs/utils/chart/axis/common.d.ts +2 -2
- package/dist/cjs/utils/chart/axis/common.js +2 -2
- package/dist/cjs/utils/chart/axis/x-axis.d.ts +11 -10
- package/dist/cjs/utils/chart/axis/x-axis.js +24 -3
- package/dist/cjs/utils/chart/index.d.ts +2 -29
- package/dist/cjs/utils/chart/index.js +2 -19
- package/dist/cjs/utils/chart/series-type-guards.d.ts +30 -0
- package/dist/cjs/utils/chart/series-type-guards.js +19 -0
- package/dist/esm/components/AxisX/prepare-axis-data.d.ts +6 -5
- package/dist/esm/components/AxisX/prepare-axis-data.js +29 -3
- package/dist/esm/components/AxisY/utils.js +3 -3
- package/dist/esm/components/ChartInner/index.js +18 -8
- package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +1 -0
- package/dist/esm/components/ChartInner/useChartInnerProps.js +2 -1
- package/dist/esm/hooks/useAxis/x-axis.js +2 -2
- package/dist/esm/hooks/useShapes/area/prepare-data.js +85 -25
- package/dist/esm/hooks/useShapes/index.d.ts +1 -0
- package/dist/esm/hooks/useShapes/index.js +32 -26
- package/dist/esm/setup-jsdom.d.ts +0 -0
- package/dist/esm/setup-jsdom.js +19 -0
- package/dist/esm/types/chart/axis.d.ts +4 -1
- package/dist/esm/utils/chart/axis/common.d.ts +2 -2
- package/dist/esm/utils/chart/axis/common.js +2 -2
- package/dist/esm/utils/chart/axis/x-axis.d.ts +11 -10
- package/dist/esm/utils/chart/axis/x-axis.js +24 -3
- package/dist/esm/utils/chart/index.d.ts +2 -29
- package/dist/esm/utils/chart/index.js +2 -19
- package/dist/esm/utils/chart/series-type-guards.d.ts +30 -0
- package/dist/esm/utils/chart/series-type-guards.js +19 -0
- package/package.json +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BaseTextStyle, ChartSeries, ChartSeriesData } from '../../types';
|
|
2
|
+
import type { UnknownSeries } from './series-type-guards';
|
|
2
3
|
import type { AxisDirection } from './types';
|
|
3
4
|
export * from './axis/common';
|
|
4
5
|
export * from './array';
|
|
@@ -8,41 +9,13 @@ export * from './labels';
|
|
|
8
9
|
export * from './legend';
|
|
9
10
|
export * from './math';
|
|
10
11
|
export * from './series';
|
|
12
|
+
export * from './series-type-guards';
|
|
11
13
|
export * from './symbol';
|
|
12
14
|
export * from './text';
|
|
13
15
|
export * from './time';
|
|
14
16
|
export * from './zoom';
|
|
15
17
|
export declare const CHART_SERIES_WITH_VOLUME_ON_Y_AXIS: ChartSeries['type'][];
|
|
16
18
|
export declare const CHART_SERIES_WITH_VOLUME_ON_X_AXIS: ChartSeries['type'][];
|
|
17
|
-
type UnknownSeries = {
|
|
18
|
-
type: ChartSeries['type'];
|
|
19
|
-
data: unknown;
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* Checks whether the series should be drawn with axes.
|
|
23
|
-
*
|
|
24
|
-
* @param series - The series object to check.
|
|
25
|
-
* @returns `true` if the series should be drawn with axes, `false` otherwise.
|
|
26
|
-
*/
|
|
27
|
-
export declare function isAxisRelatedSeries(series: UnknownSeries): boolean;
|
|
28
|
-
export declare function isSeriesWithNumericalXValues(series: UnknownSeries): series is {
|
|
29
|
-
type: ChartSeries['type'];
|
|
30
|
-
data: {
|
|
31
|
-
x: number;
|
|
32
|
-
}[];
|
|
33
|
-
};
|
|
34
|
-
export declare function isSeriesWithNumericalYValues(series: UnknownSeries): series is {
|
|
35
|
-
type: ChartSeries['type'];
|
|
36
|
-
data: {
|
|
37
|
-
y: number;
|
|
38
|
-
}[];
|
|
39
|
-
};
|
|
40
|
-
export declare function isSeriesWithCategoryValues(series: UnknownSeries): series is {
|
|
41
|
-
type: ChartSeries['type'];
|
|
42
|
-
data: {
|
|
43
|
-
category: string;
|
|
44
|
-
}[];
|
|
45
|
-
};
|
|
46
19
|
export declare const getDomainDataXBySeries: (series: UnknownSeries[]) => ({} | undefined)[];
|
|
47
20
|
export declare function getDefaultMaxXAxisValue(series: UnknownSeries[]): 0 | undefined;
|
|
48
21
|
export declare function getDefaultMinXAxisValue(series: UnknownSeries[]): number | undefined;
|
|
@@ -5,6 +5,7 @@ import sortBy from 'lodash/sortBy';
|
|
|
5
5
|
import { DEFAULT_AXIS_LABEL_FONT_SIZE, SERIES_TYPE } from '../../constants';
|
|
6
6
|
import { getSeriesStackId } from '../../hooks/useSeries/utils';
|
|
7
7
|
import { getWaterfallPointSubtotal } from './series/waterfall';
|
|
8
|
+
import { isSeriesWithNumericalXValues, isSeriesWithNumericalYValues } from './series-type-guards';
|
|
8
9
|
export * from './axis/common';
|
|
9
10
|
export * from './array';
|
|
10
11
|
export * from './color';
|
|
@@ -13,35 +14,17 @@ export * from './labels';
|
|
|
13
14
|
export * from './legend';
|
|
14
15
|
export * from './math';
|
|
15
16
|
export * from './series';
|
|
17
|
+
export * from './series-type-guards';
|
|
16
18
|
export * from './symbol';
|
|
17
19
|
export * from './text';
|
|
18
20
|
export * from './time';
|
|
19
21
|
export * from './zoom';
|
|
20
|
-
const CHARTS_WITHOUT_AXIS = ['pie', 'treemap', 'sankey', 'radar', 'funnel'];
|
|
21
22
|
export const CHART_SERIES_WITH_VOLUME_ON_Y_AXIS = [
|
|
22
23
|
'bar-x',
|
|
23
24
|
'area',
|
|
24
25
|
'waterfall',
|
|
25
26
|
];
|
|
26
27
|
export const CHART_SERIES_WITH_VOLUME_ON_X_AXIS = ['bar-y'];
|
|
27
|
-
/**
|
|
28
|
-
* Checks whether the series should be drawn with axes.
|
|
29
|
-
*
|
|
30
|
-
* @param series - The series object to check.
|
|
31
|
-
* @returns `true` if the series should be drawn with axes, `false` otherwise.
|
|
32
|
-
*/
|
|
33
|
-
export function isAxisRelatedSeries(series) {
|
|
34
|
-
return !CHARTS_WITHOUT_AXIS.includes(series.type);
|
|
35
|
-
}
|
|
36
|
-
export function isSeriesWithNumericalXValues(series) {
|
|
37
|
-
return isAxisRelatedSeries(series);
|
|
38
|
-
}
|
|
39
|
-
export function isSeriesWithNumericalYValues(series) {
|
|
40
|
-
return isAxisRelatedSeries(series);
|
|
41
|
-
}
|
|
42
|
-
export function isSeriesWithCategoryValues(series) {
|
|
43
|
-
return isAxisRelatedSeries(series);
|
|
44
|
-
}
|
|
45
28
|
function getDomainDataForStackedSeries(seriesList, keyAttr = 'x', valueAttr = 'y') {
|
|
46
29
|
const acc = [];
|
|
47
30
|
const stackedSeries = group(seriesList, getSeriesStackId);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ChartSeries } from '../../types';
|
|
2
|
+
export type UnknownSeries = {
|
|
3
|
+
type: ChartSeries['type'];
|
|
4
|
+
data: unknown;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Checks whether the series should be drawn with axes.
|
|
8
|
+
*
|
|
9
|
+
* @param series - The series object to check.
|
|
10
|
+
* @returns `true` if the series should be drawn with axes, `false` otherwise.
|
|
11
|
+
*/
|
|
12
|
+
export declare function isAxisRelatedSeries(series: UnknownSeries): boolean;
|
|
13
|
+
export declare function isSeriesWithNumericalXValues(series: UnknownSeries): series is {
|
|
14
|
+
type: ChartSeries['type'];
|
|
15
|
+
data: {
|
|
16
|
+
x: number;
|
|
17
|
+
}[];
|
|
18
|
+
};
|
|
19
|
+
export declare function isSeriesWithNumericalYValues(series: UnknownSeries): series is {
|
|
20
|
+
type: ChartSeries['type'];
|
|
21
|
+
data: {
|
|
22
|
+
y: number;
|
|
23
|
+
}[];
|
|
24
|
+
};
|
|
25
|
+
export declare function isSeriesWithCategoryValues(series: UnknownSeries): series is {
|
|
26
|
+
type: ChartSeries['type'];
|
|
27
|
+
data: {
|
|
28
|
+
category: string;
|
|
29
|
+
}[];
|
|
30
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const CHARTS_WITHOUT_AXIS = ['pie', 'treemap', 'sankey', 'radar', 'funnel'];
|
|
2
|
+
/**
|
|
3
|
+
* Checks whether the series should be drawn with axes.
|
|
4
|
+
*
|
|
5
|
+
* @param series - The series object to check.
|
|
6
|
+
* @returns `true` if the series should be drawn with axes, `false` otherwise.
|
|
7
|
+
*/
|
|
8
|
+
export function isAxisRelatedSeries(series) {
|
|
9
|
+
return !CHARTS_WITHOUT_AXIS.includes(series.type);
|
|
10
|
+
}
|
|
11
|
+
export function isSeriesWithNumericalXValues(series) {
|
|
12
|
+
return isAxisRelatedSeries(series);
|
|
13
|
+
}
|
|
14
|
+
export function isSeriesWithNumericalYValues(series) {
|
|
15
|
+
return isAxisRelatedSeries(series);
|
|
16
|
+
}
|
|
17
|
+
export function isSeriesWithCategoryValues(series) {
|
|
18
|
+
return isAxisRelatedSeries(series);
|
|
19
|
+
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import type { ChartScale, PreparedAxis, PreparedSplit } from '../../hooks';
|
|
1
|
+
import type { ChartScale, PreparedAxis, PreparedSeries, PreparedSplit } from '../../hooks';
|
|
2
2
|
import type { AxisXData } from './types';
|
|
3
|
-
export declare function prepareXAxisData({ axis,
|
|
3
|
+
export declare function prepareXAxisData({ axis, boundsOffsetLeft, boundsOffsetRight, boundsWidth, height, scale, series, split, yAxis, }: {
|
|
4
4
|
axis: PreparedAxis;
|
|
5
|
-
yAxis: PreparedAxis[];
|
|
6
|
-
scale: ChartScale;
|
|
7
|
-
boundsWidth: number;
|
|
8
5
|
boundsOffsetLeft: number;
|
|
9
6
|
boundsOffsetRight: number;
|
|
7
|
+
boundsWidth: number;
|
|
10
8
|
height: number;
|
|
9
|
+
scale: ChartScale;
|
|
10
|
+
series: PreparedSeries[];
|
|
11
11
|
split: PreparedSplit;
|
|
12
|
+
yAxis: PreparedAxis[];
|
|
12
13
|
}): Promise<AxisXData[]>;
|
|
@@ -68,7 +68,7 @@ async function getSvgAxisLabel({ getTextSize, text, axis, top, left, labelMaxWid
|
|
|
68
68
|
return svgLabel;
|
|
69
69
|
}
|
|
70
70
|
// eslint-disable-next-line complexity
|
|
71
|
-
export async function prepareXAxisData({ axis,
|
|
71
|
+
export async function prepareXAxisData({ axis, boundsOffsetLeft, boundsOffsetRight, boundsWidth, height, scale, series, split, yAxis, }) {
|
|
72
72
|
var _a, _b, _c, _d, _e, _f;
|
|
73
73
|
const xAxisItems = [];
|
|
74
74
|
for (let plotIndex = 0; plotIndex < split.plots.length; plotIndex++) {
|
|
@@ -95,8 +95,34 @@ export async function prepareXAxisData({ axis, yAxis, scale, boundsWidth, bounds
|
|
|
95
95
|
const ticks = [];
|
|
96
96
|
const getTextSize = getTextSizeFn({ style: axis.labels.style });
|
|
97
97
|
const labelLineHeight = (await getTextSize('Tmp')).height;
|
|
98
|
-
|
|
99
|
-
|
|
98
|
+
let values = getXAxisTickValues({ scale, axis, labelLineHeight, series });
|
|
99
|
+
let tickStep = getMinSpaceBetween(values, (d) => Number(d.value));
|
|
100
|
+
if (axis.labels.enabled &&
|
|
101
|
+
axis.labels.rotation === 0 &&
|
|
102
|
+
!axis.labels.html &&
|
|
103
|
+
axis.type === 'datetime' &&
|
|
104
|
+
values.length > 1) {
|
|
105
|
+
let maxLabelWidth = 0;
|
|
106
|
+
for (let i = 0; i < values.length; i++) {
|
|
107
|
+
const label = formatAxisTickLabel({
|
|
108
|
+
value: values[i].value,
|
|
109
|
+
axis,
|
|
110
|
+
step: tickStep,
|
|
111
|
+
});
|
|
112
|
+
const size = await getTextSize(label);
|
|
113
|
+
maxLabelWidth = Math.max(maxLabelWidth, size.width);
|
|
114
|
+
}
|
|
115
|
+
const currentSpacing = Math.abs(values[0].x - values[1].x) - axis.labels.padding * 2;
|
|
116
|
+
if (maxLabelWidth > currentSpacing) {
|
|
117
|
+
values = getXAxisTickValues({
|
|
118
|
+
scale,
|
|
119
|
+
axis,
|
|
120
|
+
labelLineHeight: maxLabelWidth,
|
|
121
|
+
series,
|
|
122
|
+
});
|
|
123
|
+
tickStep = getMinSpaceBetween(values, (d) => Number(d.value));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
100
126
|
const labelMaxWidth = values.length > 1
|
|
101
127
|
? Math.abs(values[0].x - values[1].x) - axis.labels.padding * 2
|
|
102
128
|
: axisWidth;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getDomainDataYBySeries, getMinSpaceBetween,
|
|
1
|
+
import { getDomainDataYBySeries, getMinSpaceBetween, getTicksCountByPixelInterval, isBandScale, thinOut, } from '../../utils';
|
|
2
2
|
export function getTickValues({ scale, axis, labelLineHeight, series, }) {
|
|
3
3
|
if ('ticks' in scale && typeof scale.ticks === 'function') {
|
|
4
4
|
const range = scale.range();
|
|
@@ -13,10 +13,10 @@ export function getTickValues({ scale, axis, labelLineHeight, series, }) {
|
|
|
13
13
|
if (domainData.length < 3) {
|
|
14
14
|
return domainData;
|
|
15
15
|
}
|
|
16
|
-
const ticksCount = (_a =
|
|
16
|
+
const ticksCount = (_a = getTicksCountByPixelInterval({ axis, axisWidth: height })) !== null && _a !== void 0 ? _a : domainData.length;
|
|
17
17
|
return scale.ticks(Math.min(ticksCount, domainData.length));
|
|
18
18
|
}
|
|
19
|
-
const ticksCount =
|
|
19
|
+
const ticksCount = getTicksCountByPixelInterval({ axis, axisWidth: height });
|
|
20
20
|
return scale.ticks(ticksCount);
|
|
21
21
|
};
|
|
22
22
|
const scaleTicks = getScaleTicks();
|
|
@@ -64,7 +64,7 @@ export const ChartInner = (props) => {
|
|
|
64
64
|
preparedRangeSlider,
|
|
65
65
|
tooltip: preparedTooltip,
|
|
66
66
|
});
|
|
67
|
-
const { allPreparedSeries, boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, isOutsideBounds, legendConfig, legendItems, preparedLegend, preparedSeries, preparedSeriesOptions, preparedSplit, prevHeight, prevWidth, shapes, shapesData, xAxis, xScale, yAxis, yScale, } = useChartInnerProps(Object.assign(Object.assign({}, props), { clipPathId,
|
|
67
|
+
const { allPreparedSeries, boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, isOutsideBounds, legendConfig, legendItems, preparedLegend, preparedSeries, preparedSeriesOptions, preparedSplit, prevHeight, prevWidth, shapes, shapesData, shapesReady, xAxis, xScale, yAxis, yScale, } = useChartInnerProps(Object.assign(Object.assign({}, props), { clipPathId,
|
|
68
68
|
dispatcher,
|
|
69
69
|
htmlLayout, plotNode: plotRef.current, preparedChart, rangeSliderDomain: (_a = rangeSliderRef.current) === null || _a === void 0 ? void 0 : _a.getDomain(), rangeSliderState, svgContainer: svgRef.current, updateZoomState,
|
|
70
70
|
zoomState }));
|
|
@@ -160,18 +160,29 @@ export const ChartInner = (props) => {
|
|
|
160
160
|
if (axis && scale) {
|
|
161
161
|
const axisData = await prepareXAxisData({
|
|
162
162
|
axis,
|
|
163
|
-
yAxis,
|
|
164
|
-
scale,
|
|
165
|
-
boundsWidth,
|
|
166
163
|
boundsOffsetLeft: boundsOffsetLeft,
|
|
167
164
|
boundsOffsetRight: width - boundsWidth - boundsOffsetLeft,
|
|
165
|
+
boundsWidth,
|
|
168
166
|
height: boundsHeight,
|
|
167
|
+
scale,
|
|
168
|
+
series: preparedSeries.filter((s) => s.visible),
|
|
169
169
|
split: preparedSplit,
|
|
170
|
+
yAxis,
|
|
170
171
|
});
|
|
171
172
|
items.push(...axisData);
|
|
172
173
|
}
|
|
173
174
|
return items;
|
|
174
|
-
}, [
|
|
175
|
+
}, [
|
|
176
|
+
boundsHeight,
|
|
177
|
+
boundsOffsetLeft,
|
|
178
|
+
boundsWidth,
|
|
179
|
+
preparedSeries,
|
|
180
|
+
preparedSplit,
|
|
181
|
+
width,
|
|
182
|
+
xAxis,
|
|
183
|
+
xScale,
|
|
184
|
+
yAxis,
|
|
185
|
+
]);
|
|
175
186
|
const xAxisDataItems = useAsyncState([], setXAxisDataItems);
|
|
176
187
|
React.useEffect(() => {
|
|
177
188
|
if (!initialized && xScale) {
|
|
@@ -207,12 +218,11 @@ export const ChartInner = (props) => {
|
|
|
207
218
|
updateRangeSliderState,
|
|
208
219
|
xScale,
|
|
209
220
|
]);
|
|
210
|
-
const areShapesReady = shapes.length > 0;
|
|
211
221
|
React.useEffect(() => {
|
|
212
|
-
if (
|
|
222
|
+
if (shapesReady) {
|
|
213
223
|
onReady === null || onReady === void 0 ? void 0 : onReady({ dimensions: { width, height } });
|
|
214
224
|
}
|
|
215
|
-
}, [height,
|
|
225
|
+
}, [height, shapesReady, onReady, width]);
|
|
216
226
|
const chartContent = (React.createElement(React.Fragment, null,
|
|
217
227
|
React.createElement("defs", null,
|
|
218
228
|
React.createElement("clipPath", { id: getClipPathIdByBounds({ clipPathId }) },
|
|
@@ -44,6 +44,7 @@ export declare function useChartInnerProps(props: Props): {
|
|
|
44
44
|
prevWidth: number | undefined;
|
|
45
45
|
shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
|
|
46
46
|
shapesData: import("../../hooks").ShapeData[];
|
|
47
|
+
shapesReady: boolean;
|
|
47
48
|
svgXPos: number | undefined;
|
|
48
49
|
xAxis: import("../../hooks").PreparedXAxis | null;
|
|
49
50
|
xScale: import("../../hooks").ChartScale | undefined;
|
|
@@ -111,7 +111,7 @@ export function useChartInnerProps(props) {
|
|
|
111
111
|
const isOutsideBounds = React.useCallback((x, y) => {
|
|
112
112
|
return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight;
|
|
113
113
|
}, [boundsHeight, boundsWidth]);
|
|
114
|
-
const { shapes, shapesData } = useShapes({
|
|
114
|
+
const { shapes, shapesData, shapesReady } = useShapes({
|
|
115
115
|
boundsWidth,
|
|
116
116
|
boundsHeight,
|
|
117
117
|
clipPathBySeriesType: CLIP_PATH_BY_SERIES_TYPE,
|
|
@@ -183,6 +183,7 @@ export function useChartInnerProps(props) {
|
|
|
183
183
|
prevWidth,
|
|
184
184
|
shapes,
|
|
185
185
|
shapesData,
|
|
186
|
+
shapesReady,
|
|
186
187
|
svgXPos: x,
|
|
187
188
|
xAxis,
|
|
188
189
|
xScale,
|
|
@@ -15,7 +15,7 @@ async function setLabelSettings({ axis, seriesData, width, axisLabels, }) {
|
|
|
15
15
|
}
|
|
16
16
|
const getTextSize = getTextSizeFn({ style: axis.labels.style });
|
|
17
17
|
const labelLineHeight = (await getTextSize('Tmp')).height;
|
|
18
|
-
const tickValues = getXAxisTickValues({ axis, scale, labelLineHeight });
|
|
18
|
+
const tickValues = getXAxisTickValues({ axis, scale, labelLineHeight, series: seriesData });
|
|
19
19
|
const tickStep = getMinSpaceBetween(tickValues, (d) => Number(d.value));
|
|
20
20
|
if (axis.type === 'datetime' && !(axisLabels === null || axisLabels === void 0 ? void 0 : axisLabels.dateFormat)) {
|
|
21
21
|
axis.labels.dateFormat = getDefaultDateFormat(tickStep);
|
|
@@ -37,7 +37,7 @@ async function setLabelSettings({ axis, seriesData, width, axisLabels, }) {
|
|
|
37
37
|
}
|
|
38
38
|
return false;
|
|
39
39
|
};
|
|
40
|
-
const autoRotation = (_a = axisLabels === null || axisLabels === void 0 ? void 0 : axisLabels.autoRotation) !== null && _a !== void 0 ? _a :
|
|
40
|
+
const autoRotation = (_a = axisLabels === null || axisLabels === void 0 ? void 0 : axisLabels.autoRotation) !== null && _a !== void 0 ? _a : axis.type !== 'datetime';
|
|
41
41
|
const overlapping = axis.labels.html ? false : await hasOverlappingLabels();
|
|
42
42
|
const defaultRotation = overlapping && autoRotation ? -45 : 0;
|
|
43
43
|
const rotation = axis.labels.html ? 0 : ((_b = axisLabels === null || axisLabels === void 0 ? void 0 : axisLabels.rotation) !== null && _b !== void 0 ? _b : defaultRotation);
|
|
@@ -94,11 +94,13 @@ export const prepareAreaData = async (args) => {
|
|
|
94
94
|
const positiveStackValues = new Map();
|
|
95
95
|
const negativeStackValues = new Map();
|
|
96
96
|
xValues.forEach(([key]) => {
|
|
97
|
-
positiveStackValues.set(key, 0);
|
|
98
|
-
negativeStackValues.set(key, 0);
|
|
97
|
+
positiveStackValues.set(key, { prev: 0, next: 0 });
|
|
98
|
+
negativeStackValues.set(key, { prev: 0, next: 0 });
|
|
99
99
|
});
|
|
100
100
|
const seriesStackData = [];
|
|
101
|
-
|
|
101
|
+
// Process series in reverse order so that the first series in input
|
|
102
|
+
// appears at the top of the stack (furthest from baseline)
|
|
103
|
+
for (let j = seriesStack.length - 1; j >= 0; j--) {
|
|
102
104
|
const s = seriesStack[j];
|
|
103
105
|
const yAxisIndex = s.yAxis;
|
|
104
106
|
const seriesYAxis = yAxis[yAxisIndex];
|
|
@@ -123,40 +125,97 @@ export const prepareAreaData = async (args) => {
|
|
|
123
125
|
: d.x);
|
|
124
126
|
return m.set(key, d);
|
|
125
127
|
}, new Map());
|
|
126
|
-
const points = xValues.reduce((pointsAcc, [x, xValue]) => {
|
|
127
|
-
var _a, _b;
|
|
128
|
+
const points = xValues.reduce((pointsAcc, [x, xValue], index) => {
|
|
129
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
128
130
|
const d = (_a = seriesData.get(x)) !== null && _a !== void 0 ? _a : {
|
|
129
131
|
x,
|
|
130
132
|
y: 0,
|
|
131
133
|
};
|
|
132
134
|
const yDataValue = (_b = d.y) !== null && _b !== void 0 ? _b : null;
|
|
135
|
+
if (s.nullMode === 'connect' && yDataValue === null) {
|
|
136
|
+
return pointsAcc;
|
|
137
|
+
}
|
|
133
138
|
const yValue = getYValue({ point: d, yAxis: seriesYAxis, yScale: seriesYScale });
|
|
134
|
-
let y = null;
|
|
135
|
-
let y0 = yAxisTop + yMin;
|
|
136
139
|
if (typeof yDataValue === 'number' && yValue !== null) {
|
|
140
|
+
const prevPoint = seriesData.get((_c = xValues[index - 1]) === null || _c === void 0 ? void 0 : _c[0]);
|
|
141
|
+
const nextPoint = seriesData.get((_d = xValues[index + 1]) === null || _d === void 0 ? void 0 : _d[0]);
|
|
142
|
+
const currentPointStackHeight = Math.abs(yMin - yValue);
|
|
137
143
|
if (yDataValue >= 0) {
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
const positiveStackHeights = positiveStackValues.get(x);
|
|
145
|
+
let prevSectionStackHeight = (_e = positiveStackHeights === null || positiveStackHeights === void 0 ? void 0 : positiveStackHeights.prev) !== null && _e !== void 0 ? _e : 0;
|
|
146
|
+
let nextSectionStackHeight = (_f = positiveStackHeights === null || positiveStackHeights === void 0 ? void 0 : positiveStackHeights.next) !== null && _f !== void 0 ? _f : 0;
|
|
147
|
+
pointsAcc.push({
|
|
148
|
+
y0: yAxisTop + yMin - prevSectionStackHeight,
|
|
149
|
+
x: xValue,
|
|
150
|
+
y: yAxisTop + yValue - prevSectionStackHeight,
|
|
151
|
+
data: d,
|
|
152
|
+
series: s,
|
|
153
|
+
});
|
|
154
|
+
if (prevSectionStackHeight !== nextSectionStackHeight) {
|
|
155
|
+
pointsAcc.push({
|
|
156
|
+
y0: yAxisTop + yMin - nextSectionStackHeight,
|
|
157
|
+
x: xValue,
|
|
158
|
+
y: yAxisTop + yValue - nextSectionStackHeight,
|
|
159
|
+
data: d,
|
|
160
|
+
series: s,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
if ((prevPoint === null || prevPoint === void 0 ? void 0 : prevPoint.y) !== null) {
|
|
164
|
+
prevSectionStackHeight =
|
|
165
|
+
prevSectionStackHeight + currentPointStackHeight;
|
|
166
|
+
}
|
|
167
|
+
if ((nextPoint === null || nextPoint === void 0 ? void 0 : nextPoint.y) !== null) {
|
|
168
|
+
nextSectionStackHeight =
|
|
169
|
+
nextSectionStackHeight + currentPointStackHeight;
|
|
170
|
+
}
|
|
171
|
+
positiveStackValues.set(x, {
|
|
172
|
+
prev: prevSectionStackHeight,
|
|
173
|
+
next: nextSectionStackHeight,
|
|
174
|
+
});
|
|
142
175
|
}
|
|
143
176
|
else {
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
177
|
+
const negativeStackHeights = negativeStackValues.get(x);
|
|
178
|
+
let prevSectionStackHeight = (_g = negativeStackHeights === null || negativeStackHeights === void 0 ? void 0 : negativeStackHeights.prev) !== null && _g !== void 0 ? _g : 0;
|
|
179
|
+
let nextSectionStackHeight = (_h = negativeStackHeights === null || negativeStackHeights === void 0 ? void 0 : negativeStackHeights.next) !== null && _h !== void 0 ? _h : 0;
|
|
180
|
+
pointsAcc.push({
|
|
181
|
+
y0: yAxisTop + yMin + prevSectionStackHeight,
|
|
182
|
+
x: xValue,
|
|
183
|
+
y: yAxisTop + yValue + prevSectionStackHeight,
|
|
184
|
+
data: d,
|
|
185
|
+
series: s,
|
|
186
|
+
});
|
|
187
|
+
if (prevSectionStackHeight !== nextSectionStackHeight) {
|
|
188
|
+
pointsAcc.push({
|
|
189
|
+
y0: yAxisTop + yMin + nextSectionStackHeight,
|
|
190
|
+
x: xValue,
|
|
191
|
+
y: yAxisTop + yValue + nextSectionStackHeight,
|
|
192
|
+
data: d,
|
|
193
|
+
series: s,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
if ((prevPoint === null || prevPoint === void 0 ? void 0 : prevPoint.y) !== null) {
|
|
197
|
+
prevSectionStackHeight =
|
|
198
|
+
prevSectionStackHeight + currentPointStackHeight;
|
|
199
|
+
}
|
|
200
|
+
if ((nextPoint === null || nextPoint === void 0 ? void 0 : nextPoint.y) !== null) {
|
|
201
|
+
nextSectionStackHeight =
|
|
202
|
+
nextSectionStackHeight + currentPointStackHeight;
|
|
203
|
+
}
|
|
204
|
+
negativeStackValues.set(x, {
|
|
205
|
+
prev: prevSectionStackHeight,
|
|
206
|
+
next: nextSectionStackHeight,
|
|
207
|
+
});
|
|
148
208
|
}
|
|
149
209
|
}
|
|
150
|
-
|
|
151
|
-
|
|
210
|
+
else {
|
|
211
|
+
pointsAcc.push({
|
|
212
|
+
y0: yAxisTop + yMin,
|
|
213
|
+
x: xValue,
|
|
214
|
+
y: null,
|
|
215
|
+
data: d,
|
|
216
|
+
series: s,
|
|
217
|
+
});
|
|
152
218
|
}
|
|
153
|
-
pointsAcc.push({
|
|
154
|
-
y0,
|
|
155
|
-
x: xValue,
|
|
156
|
-
y,
|
|
157
|
-
data: d,
|
|
158
|
-
series: s,
|
|
159
|
-
});
|
|
160
219
|
return pointsAcc;
|
|
161
220
|
}, []);
|
|
162
221
|
const labels = [];
|
|
@@ -197,7 +256,8 @@ export const prepareAreaData = async (args) => {
|
|
|
197
256
|
}
|
|
198
257
|
if (series.some((s) => s.stacking === 'percent')) {
|
|
199
258
|
xValues.forEach(([x], index) => {
|
|
200
|
-
|
|
259
|
+
var _a;
|
|
260
|
+
const stackHeight = ((_a = positiveStackValues.get(x)) === null || _a === void 0 ? void 0 : _a.prev) || 0;
|
|
201
261
|
let acc = 0;
|
|
202
262
|
const ratio = plotHeight / stackHeight;
|
|
203
263
|
seriesStackData.forEach((item) => {
|