@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.
Files changed (43) hide show
  1. package/dist/cjs/components/AxisX/prepare-axis-data.d.ts +6 -5
  2. package/dist/cjs/components/AxisX/prepare-axis-data.js +29 -3
  3. package/dist/cjs/components/AxisY/utils.js +3 -3
  4. package/dist/cjs/components/ChartInner/index.js +18 -8
  5. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +1 -0
  6. package/dist/cjs/components/ChartInner/useChartInnerProps.js +2 -1
  7. package/dist/cjs/hooks/useAxis/x-axis.js +2 -2
  8. package/dist/cjs/hooks/useShapes/area/prepare-data.js +85 -25
  9. package/dist/cjs/hooks/useShapes/index.d.ts +1 -0
  10. package/dist/cjs/hooks/useShapes/index.js +32 -26
  11. package/dist/cjs/setup-jsdom.d.ts +0 -0
  12. package/dist/cjs/setup-jsdom.js +19 -0
  13. package/dist/cjs/types/chart/axis.d.ts +4 -1
  14. package/dist/cjs/utils/chart/axis/common.d.ts +2 -2
  15. package/dist/cjs/utils/chart/axis/common.js +2 -2
  16. package/dist/cjs/utils/chart/axis/x-axis.d.ts +11 -10
  17. package/dist/cjs/utils/chart/axis/x-axis.js +24 -3
  18. package/dist/cjs/utils/chart/index.d.ts +2 -29
  19. package/dist/cjs/utils/chart/index.js +2 -19
  20. package/dist/cjs/utils/chart/series-type-guards.d.ts +30 -0
  21. package/dist/cjs/utils/chart/series-type-guards.js +19 -0
  22. package/dist/esm/components/AxisX/prepare-axis-data.d.ts +6 -5
  23. package/dist/esm/components/AxisX/prepare-axis-data.js +29 -3
  24. package/dist/esm/components/AxisY/utils.js +3 -3
  25. package/dist/esm/components/ChartInner/index.js +18 -8
  26. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +1 -0
  27. package/dist/esm/components/ChartInner/useChartInnerProps.js +2 -1
  28. package/dist/esm/hooks/useAxis/x-axis.js +2 -2
  29. package/dist/esm/hooks/useShapes/area/prepare-data.js +85 -25
  30. package/dist/esm/hooks/useShapes/index.d.ts +1 -0
  31. package/dist/esm/hooks/useShapes/index.js +32 -26
  32. package/dist/esm/setup-jsdom.d.ts +0 -0
  33. package/dist/esm/setup-jsdom.js +19 -0
  34. package/dist/esm/types/chart/axis.d.ts +4 -1
  35. package/dist/esm/utils/chart/axis/common.d.ts +2 -2
  36. package/dist/esm/utils/chart/axis/common.js +2 -2
  37. package/dist/esm/utils/chart/axis/x-axis.d.ts +11 -10
  38. package/dist/esm/utils/chart/axis/x-axis.js +24 -3
  39. package/dist/esm/utils/chart/index.d.ts +2 -29
  40. package/dist/esm/utils/chart/index.js +2 -19
  41. package/dist/esm/utils/chart/series-type-guards.d.ts +30 -0
  42. package/dist/esm/utils/chart/series-type-guards.js +19 -0
  43. 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, yAxis, scale, boundsWidth, boundsOffsetLeft, boundsOffsetRight, height, split, }: {
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, yAxis, scale, boundsWidth, boundsOffsetLeft, boundsOffsetRight, height, split, }) {
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
- const values = getXAxisTickValues({ scale, axis, labelLineHeight });
99
- const tickStep = getMinSpaceBetween(values, (d) => Number(d.value));
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, getTicksCount, isBandScale, thinOut, } from '../../utils';
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 = getTicksCount({ axis, range: height })) !== null && _a !== void 0 ? _a : domainData.length;
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 = getTicksCount({ axis, range: height });
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
- }, [xAxis, xScale, yAxis, boundsWidth, boundsOffsetLeft, width, boundsHeight, preparedSplit]);
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 (areShapesReady) {
222
+ if (shapesReady) {
213
223
  onReady === null || onReady === void 0 ? void 0 : onReady({ dimensions: { width, height } });
214
224
  }
215
- }, [height, areShapesReady, onReady, width]);
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 : true;
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
- for (let j = 0; j < seriesStack.length; j++) {
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 positiveStackHeight = positiveStackValues.get(x) || 0;
139
- y = yAxisTop + yValue - positiveStackHeight;
140
- y0 -= positiveStackHeight;
141
- positiveStackValues.set(x, positiveStackHeight + (yMin - yValue));
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 negativeStackHeight = negativeStackValues.get(x) || 0;
145
- y = yAxisTop + yValue + negativeStackHeight;
146
- y0 += negativeStackHeight;
147
- negativeStackValues.set(x, negativeStackHeight + (yValue - yMin));
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
- if (s.nullMode === 'connect' && yDataValue === null) {
151
- return pointsAcc;
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
- const stackHeight = positiveStackValues.get(x) || 0;
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) => {
@@ -43,4 +43,5 @@ type Args = {
43
43
  export declare const useShapes: (args: Args) => {
44
44
  shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
45
45
  shapesData: ShapeData[];
46
+ shapesReady: boolean;
46
47
  };