@gravity-ui/charts 1.24.0 → 1.24.2

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 (33) hide show
  1. package/dist/cjs/components/ChartInner/index.js +2 -1
  2. package/dist/cjs/components/ChartInner/useChartInnerProps.js +1 -2
  3. package/dist/cjs/hooks/useAxisScales/index.d.ts +4 -4
  4. package/dist/cjs/hooks/useAxisScales/index.js +95 -39
  5. package/dist/cjs/hooks/useAxisScales/utils.d.ts +19 -0
  6. package/dist/cjs/hooks/useAxisScales/utils.js +34 -0
  7. package/dist/cjs/hooks/useRangeSlider/index.js +2 -1
  8. package/dist/cjs/hooks/useRangeSlider/types.d.ts +2 -0
  9. package/dist/cjs/hooks/useShapes/area/prepare-data.d.ts +2 -0
  10. package/dist/cjs/hooks/useShapes/area/prepare-data.js +159 -158
  11. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.d.ts +2 -0
  12. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +87 -72
  13. package/dist/cjs/hooks/useShapes/index.js +2 -0
  14. package/dist/cjs/hooks/useShapes/line/prepare-data.js +1 -1
  15. package/dist/cjs/hooks/useShapes/styles.css +5 -13
  16. package/dist/cjs/utils/chart/index.js +1 -1
  17. package/dist/esm/components/ChartInner/index.js +2 -1
  18. package/dist/esm/components/ChartInner/useChartInnerProps.js +1 -2
  19. package/dist/esm/hooks/useAxisScales/index.d.ts +4 -4
  20. package/dist/esm/hooks/useAxisScales/index.js +95 -39
  21. package/dist/esm/hooks/useAxisScales/utils.d.ts +19 -0
  22. package/dist/esm/hooks/useAxisScales/utils.js +34 -0
  23. package/dist/esm/hooks/useRangeSlider/index.js +2 -1
  24. package/dist/esm/hooks/useRangeSlider/types.d.ts +2 -0
  25. package/dist/esm/hooks/useShapes/area/prepare-data.d.ts +2 -0
  26. package/dist/esm/hooks/useShapes/area/prepare-data.js +159 -158
  27. package/dist/esm/hooks/useShapes/bar-x/prepare-data.d.ts +2 -0
  28. package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +87 -72
  29. package/dist/esm/hooks/useShapes/index.js +2 -0
  30. package/dist/esm/hooks/useShapes/line/prepare-data.js +1 -1
  31. package/dist/esm/hooks/useShapes/styles.css +5 -13
  32. package/dist/esm/utils/chart/index.js +1 -1
  33. package/package.json +1 -1
@@ -1,33 +1,7 @@
1
1
  import { group } from 'd3';
2
- import { getDataCategoryValue, getLabelsSize, getLeftPosition } from '../../../utils';
2
+ import { getDataCategoryValue, getLabelsSize, getTextSizeFn } from '../../../utils';
3
3
  import { getFormattedValue } from '../../../utils/chart/format';
4
4
  import { getXValue, getYValue } from '../utils';
5
- async function getLabelData(point, series, xMax) {
6
- const text = getFormattedValue(Object.assign({ value: point.data.label || point.data.y }, series.dataLabels));
7
- const style = series.dataLabels.style;
8
- const size = await getLabelsSize({ labels: [text], style, html: series.dataLabels.html });
9
- const labelData = {
10
- text,
11
- x: point.x,
12
- y: point.y - series.dataLabels.padding,
13
- style,
14
- size: { width: size.maxWidth, height: size.maxHeight },
15
- textAnchor: 'middle',
16
- series: series,
17
- active: true,
18
- };
19
- const left = getLeftPosition(labelData);
20
- if (left < 0) {
21
- labelData.x = labelData.x + Math.abs(left);
22
- }
23
- else {
24
- const right = left + labelData.size.width;
25
- if (right > xMax) {
26
- labelData.x = labelData.x - (right - xMax);
27
- }
28
- }
29
- return labelData;
30
- }
31
5
  function getXValues(series, xAxis, xScale) {
32
6
  const categories = xAxis.categories || [];
33
7
  const xValues = series.reduce((acc, s) => {
@@ -53,148 +27,175 @@ function getXValues(series, xAxis, xScale) {
53
27
  }
54
28
  return Array.from(xValues);
55
29
  }
30
+ async function prepareDataLabels({ series, points, xMax, yAxisTop, }) {
31
+ const svgLabels = [];
32
+ const htmlLabels = [];
33
+ const getTextSize = getTextSizeFn({ style: series.dataLabels.style });
34
+ for (let pointsIndex = 0; pointsIndex < points.length; pointsIndex++) {
35
+ const point = points[pointsIndex];
36
+ if (point.y === null) {
37
+ continue;
38
+ }
39
+ const text = getFormattedValue(Object.assign({ value: point.data.label || point.data.y }, series.dataLabels));
40
+ if (series.dataLabels.html) {
41
+ const size = await getLabelsSize({
42
+ labels: [text],
43
+ style: series.dataLabels.style,
44
+ html: series.dataLabels.html,
45
+ });
46
+ const labelSize = { width: size.maxWidth, height: size.maxHeight };
47
+ const x = Math.min(xMax - labelSize.width, Math.max(0, point.x - labelSize.width / 2));
48
+ const y = Math.max(yAxisTop, point.y - series.dataLabels.padding - labelSize.height);
49
+ htmlLabels.push({
50
+ x,
51
+ y,
52
+ content: text,
53
+ size: labelSize,
54
+ style: series.dataLabels.style,
55
+ });
56
+ }
57
+ else {
58
+ const labelSize = await getTextSize(text);
59
+ const x = Math.min(xMax - labelSize.width, Math.max(0, point.x - labelSize.width / 2));
60
+ const y = Math.max(yAxisTop, point.y - series.dataLabels.padding - labelSize.height);
61
+ svgLabels.push({
62
+ text,
63
+ x,
64
+ y,
65
+ style: series.dataLabels.style,
66
+ size: labelSize,
67
+ textAnchor: 'start',
68
+ series,
69
+ active: true,
70
+ });
71
+ }
72
+ }
73
+ return { svgLabels, htmlLabels };
74
+ }
56
75
  export const prepareAreaData = async (args) => {
57
- var _a;
58
- const { series, xAxis, xScale, yAxis, yScale, boundsHeight: plotHeight, isOutsideBounds } = args;
76
+ var _a, _b;
77
+ const { series, xAxis, xScale, yAxis, yScale, boundsHeight: plotHeight, split, isOutsideBounds, } = args;
59
78
  const [_xMin, xRangeMax] = xScale.range();
60
- const xMax = xRangeMax / (1 - xAxis.maxPadding);
79
+ const xMax = xRangeMax;
61
80
  const result = [];
62
- const list = Array.from(group(series, (s) => s.stackId));
63
- for (let i = 0; i < list.length; i++) {
64
- const [_stackId, seriesStack] = list[i];
65
- const xValues = getXValues(seriesStack, xAxis, xScale);
66
- const accumulatedYValues = new Map();
67
- xValues.forEach(([key]) => {
68
- accumulatedYValues.set(key, 0);
69
- });
70
- const seriesStackData = [];
71
- for (let j = 0; j < seriesStack.length; j++) {
72
- const s = seriesStack[j];
73
- const yAxisIndex = s.yAxis;
74
- const seriesYAxis = yAxis[yAxisIndex];
75
- const seriesYScale = yScale[yAxisIndex];
76
- if (!seriesYScale) {
77
- continue;
78
- }
79
- const yMin = (_a = getYValue({
80
- point: { y: 0 },
81
- points: s.data,
82
- yAxis: seriesYAxis,
83
- yScale: seriesYScale,
84
- })) !== null && _a !== void 0 ? _a : 0;
85
- const seriesData = s.data.reduce((m, d) => {
86
- const key = String(xAxis.type === 'category'
87
- ? getDataCategoryValue({
88
- axisDirection: 'x',
89
- categories: xAxis.categories || [],
90
- data: d,
91
- })
92
- : d.x);
93
- return m.set(key, d);
94
- }, new Map());
95
- const points = xValues.reduce((pointsAcc, [x, xValue]) => {
96
- var _a;
97
- const accumulatedYValue = accumulatedYValues.get(x) || 0;
98
- const d = (_a = seriesData.get(x)) !== null && _a !== void 0 ? _a : {
99
- x,
100
- y: 0,
101
- };
102
- const yValue = getYValue({ point: d, yAxis: seriesYAxis, yScale: seriesYScale });
103
- const yPointValue = yValue === null ? null : yValue - accumulatedYValue;
104
- if (yPointValue !== null) {
105
- accumulatedYValues.set(x, yMin - yPointValue);
81
+ const dataByPlots = Array.from(group(series, (s) => {
82
+ const yAxisIndex = s.yAxis;
83
+ const seriesYAxis = yAxis[yAxisIndex];
84
+ const plotIndex = seriesYAxis.plotIndex;
85
+ return plotIndex;
86
+ }, (s) => s.stackId));
87
+ const plotIndexes = Object.keys(dataByPlots);
88
+ for (let plotDataIndex = 0; plotDataIndex < plotIndexes.length; plotDataIndex++) {
89
+ const [plotIndex, stackItems] = dataByPlots[plotDataIndex];
90
+ const list = Array.from(stackItems);
91
+ for (let i = 0; i < list.length; i++) {
92
+ const [_stackId, seriesStack] = list[i];
93
+ const xValues = getXValues(seriesStack, xAxis, xScale);
94
+ const accumulatedYValues = new Map();
95
+ xValues.forEach(([key]) => {
96
+ accumulatedYValues.set(key, 0);
97
+ });
98
+ const seriesStackData = [];
99
+ for (let j = 0; j < seriesStack.length; j++) {
100
+ const s = seriesStack[j];
101
+ const yAxisIndex = s.yAxis;
102
+ const seriesYAxis = yAxis[yAxisIndex];
103
+ const seriesYScale = yScale[yAxisIndex];
104
+ if (!seriesYScale) {
105
+ continue;
106
106
  }
107
- pointsAcc.push({
108
- y0: yMin - accumulatedYValue,
109
- x: xValue,
110
- y: yPointValue,
111
- data: d,
112
- series: s,
113
- });
114
- return pointsAcc;
115
- }, []);
116
- let labels = [];
117
- const htmlElements = [];
118
- if (s.dataLabels.enabled) {
119
- const labelItems = await Promise.all(points.reduce((labelItemsAcc, p) => {
120
- if (p.y === null) {
121
- return labelItemsAcc;
107
+ const yAxisTop = ((_a = split.plots[plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
108
+ const yMin = (_b = getYValue({
109
+ point: { y: 0 },
110
+ points: s.data,
111
+ yAxis: seriesYAxis,
112
+ yScale: seriesYScale,
113
+ })) !== null && _b !== void 0 ? _b : 0;
114
+ const seriesData = s.data.reduce((m, d) => {
115
+ const key = String(xAxis.type === 'category'
116
+ ? getDataCategoryValue({
117
+ axisDirection: 'x',
118
+ categories: xAxis.categories || [],
119
+ data: d,
120
+ })
121
+ : d.x);
122
+ return m.set(key, d);
123
+ }, new Map());
124
+ const points = xValues.reduce((pointsAcc, [x, xValue]) => {
125
+ var _a;
126
+ const accumulatedYValue = accumulatedYValues.get(x) || 0;
127
+ const d = (_a = seriesData.get(x)) !== null && _a !== void 0 ? _a : {
128
+ x,
129
+ y: 0,
130
+ };
131
+ const yValue = getYValue({ point: d, yAxis: seriesYAxis, yScale: seriesYScale });
132
+ const yPointValue = yValue === null ? null : yValue - accumulatedYValue;
133
+ if (yPointValue !== null) {
134
+ accumulatedYValues.set(x, yMin - yPointValue);
122
135
  }
123
- labelItemsAcc.push(getLabelData(p, s, xMax));
124
- return labelItemsAcc;
125
- }, []));
126
- if (s.dataLabels.html) {
127
- const htmlLabels = await Promise.all(labelItems.map(async (l) => {
128
- var _a;
129
- const style = (_a = l.style) !== null && _a !== void 0 ? _a : s.dataLabels.style;
130
- const labelSize = await getLabelsSize({
131
- labels: [l.text],
132
- style,
133
- html: true,
134
- });
135
- return {
136
- x: l.x - l.size.width / 2,
137
- y: l.y,
138
- content: l.text,
139
- size: {
140
- width: labelSize.maxWidth,
141
- height: labelSize.maxHeight,
142
- },
143
- style,
144
- };
145
- }));
146
- htmlElements.push(...htmlLabels);
136
+ pointsAcc.push({
137
+ y0: yAxisTop + yMin - accumulatedYValue,
138
+ x: xValue,
139
+ y: yPointValue === null ? null : yAxisTop + (yPointValue !== null && yPointValue !== void 0 ? yPointValue : 0),
140
+ data: d,
141
+ series: s,
142
+ });
143
+ return pointsAcc;
144
+ }, []);
145
+ const labels = [];
146
+ const htmlElements = [];
147
+ if (s.dataLabels.enabled) {
148
+ const labelsData = await prepareDataLabels({ series: s, points, xMax, yAxisTop });
149
+ labels.push(...labelsData.svgLabels);
150
+ htmlElements.push(...labelsData.htmlLabels);
147
151
  }
148
- else {
149
- labels = labelItems;
152
+ let markers = [];
153
+ if (s.marker.states.normal.enabled || s.marker.states.hover.enabled) {
154
+ markers = points.reduce((markersAcc, p) => {
155
+ if (p.y === null) {
156
+ return markersAcc;
157
+ }
158
+ markersAcc.push({
159
+ point: p,
160
+ active: true,
161
+ hovered: false,
162
+ clipped: isOutsideBounds(p.x, p.y),
163
+ });
164
+ return markersAcc;
165
+ }, []);
150
166
  }
167
+ seriesStackData.push({
168
+ points,
169
+ markers,
170
+ labels,
171
+ color: s.color,
172
+ opacity: s.opacity,
173
+ width: s.lineWidth,
174
+ series: s,
175
+ hovered: false,
176
+ active: true,
177
+ id: s.id,
178
+ htmlElements,
179
+ });
151
180
  }
152
- let markers = [];
153
- if (s.marker.states.normal.enabled || s.marker.states.hover.enabled) {
154
- markers = points.reduce((markersAcc, p) => {
155
- if (p.y === null) {
156
- return markersAcc;
157
- }
158
- markersAcc.push({
159
- point: p,
160
- active: true,
161
- hovered: false,
162
- clipped: isOutsideBounds(p.x, p.y),
181
+ if (series.some((s) => s.stacking === 'percent')) {
182
+ xValues.forEach(([x], index) => {
183
+ const stackHeight = accumulatedYValues.get(x) || 0;
184
+ let acc = 0;
185
+ const ratio = plotHeight / stackHeight;
186
+ seriesStackData.forEach((item) => {
187
+ const point = item.points[index];
188
+ if (point.y !== null && point.y !== undefined) {
189
+ const height = (point.y0 - point.y) * ratio;
190
+ point.y0 = plotHeight - height - acc;
191
+ point.y = point.y0 + height;
192
+ acc += height;
193
+ }
163
194
  });
164
- return markersAcc;
165
- }, []);
166
- }
167
- seriesStackData.push({
168
- points,
169
- markers,
170
- labels,
171
- color: s.color,
172
- opacity: s.opacity,
173
- width: s.lineWidth,
174
- series: s,
175
- hovered: false,
176
- active: true,
177
- id: s.id,
178
- htmlElements,
179
- });
180
- }
181
- if (series.some((s) => s.stacking === 'percent')) {
182
- xValues.forEach(([x], index) => {
183
- const stackHeight = accumulatedYValues.get(x) || 0;
184
- let acc = 0;
185
- const ratio = plotHeight / stackHeight;
186
- seriesStackData.forEach((item) => {
187
- const point = item.points[index];
188
- if (point.y !== null && point.y !== undefined) {
189
- const height = (point.y0 - point.y) * ratio;
190
- point.y0 = plotHeight - height - acc;
191
- point.y = point.y0 + height;
192
- acc += height;
193
- }
194
195
  });
195
- });
196
+ }
197
+ result.push(...seriesStackData);
196
198
  }
197
- result.push(...seriesStackData);
198
199
  }
199
200
  return result;
200
201
  };
@@ -1,6 +1,7 @@
1
1
  import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
2
2
  import type { ChartScale } from '../../useAxisScales';
3
3
  import type { PreparedBarXSeries, PreparedSeriesOptions } from '../../useSeries/types';
4
+ import type { PreparedSplit } from '../../useSplit/types';
4
5
  import type { PreparedBarXData } from './types';
5
6
  export declare const prepareBarXData: (args: {
6
7
  series: PreparedBarXSeries[];
@@ -10,4 +11,5 @@ export declare const prepareBarXData: (args: {
10
11
  yAxis: PreparedYAxis[];
11
12
  yScale: (ChartScale | undefined)[];
12
13
  boundsHeight: number;
14
+ split: PreparedSplit;
13
15
  }) => Promise<PreparedBarXData[]>;
@@ -33,8 +33,8 @@ async function getLabelData(d) {
33
33
  }
34
34
  // eslint-disable-next-line complexity
35
35
  export const prepareBarXData = async (args) => {
36
- var _a;
37
- const { series, seriesOptions, xAxis, xScale, yScale, boundsHeight: plotHeight } = args;
36
+ var _a, _b, _c;
37
+ const { series, seriesOptions, xAxis, xScale, yAxis, yScale, boundsHeight: plotHeight, split, } = args;
38
38
  const stackGap = seriesOptions['bar-x'].stackGap;
39
39
  const categories = get(xAxis, 'categories', []);
40
40
  const barMaxWidth = get(seriesOptions, 'bar-x.barMaxWidth');
@@ -55,8 +55,17 @@ export const prepareBarXData = async (args) => {
55
55
  }
56
56
  }
57
57
  })();
58
- const data = {};
58
+ // series grouped by plotIndex > xValue > data[];
59
+ const dataByPlots = new Map();
59
60
  series.forEach((s) => {
61
+ var _a;
62
+ const yAxisIndex = s.yAxis;
63
+ const seriesYAxis = yAxis[yAxisIndex];
64
+ const plotIndex = seriesYAxis.plotIndex;
65
+ if (!dataByPlots.has(plotIndex)) {
66
+ dataByPlots.set(plotIndex, {});
67
+ }
68
+ const data = (_a = dataByPlots.get(plotIndex)) !== null && _a !== void 0 ? _a : {};
60
69
  s.data.forEach((d) => {
61
70
  if (!isSeriesDataValid(d)) {
62
71
  return;
@@ -96,81 +105,87 @@ export const prepareBarXData = async (args) => {
96
105
  }
97
106
  });
98
107
  }
99
- const maxGroupSize = max(Object.values(data), (d) => Object.values(d).length) || 1;
100
- const groupGap = Math.max(bandWidth * groupPadding, MIN_BAR_GROUP_GAP);
101
- const groupWidth = bandWidth - groupGap;
102
- const rectGap = Math.max(bandWidth * barPadding, MIN_BAR_GAP);
103
- const rectWidth = Math.max(MIN_BAR_WIDTH, Math.min(groupWidth / maxGroupSize - rectGap, barMaxWidth));
104
108
  const result = [];
105
- const groupedData = Object.entries(data);
106
- for (let groupedDataIndex = 0; groupedDataIndex < groupedData.length; groupedDataIndex++) {
107
- const [xValue, val] = groupedData[groupedDataIndex];
108
- const stacks = Object.values(val);
109
- const currentGroupWidth = rectWidth * stacks.length + rectGap * (stacks.length - 1);
110
- for (let groupItemIndex = 0; groupItemIndex < stacks.length; groupItemIndex++) {
111
- const yValues = stacks[groupItemIndex];
112
- let stackHeight = 0;
113
- const stackItems = [];
114
- const sortedData = sortKey
115
- ? sort(yValues, (a, b) => comparator(get(a, sortKey), get(b, sortKey)))
116
- : yValues;
117
- for (let yValueIndex = 0; yValueIndex < sortedData.length; yValueIndex++) {
118
- const yValue = sortedData[yValueIndex];
119
- const yAxisIndex = yValue.series.yAxis;
120
- const seriesYScale = yScale[yAxisIndex];
121
- if (!seriesYScale) {
122
- continue;
123
- }
124
- let xCenter;
125
- if (xAxis.type === 'category') {
126
- const xBandScale = xScale;
127
- const xBandScaleDomain = xBandScale.domain();
128
- if (xBandScaleDomain.indexOf(xValue) === -1) {
109
+ const plotIndexes = Array.from(dataByPlots.keys());
110
+ for (let plotDataIndex = 0; plotDataIndex < plotIndexes.length; plotDataIndex++) {
111
+ const data = (_a = dataByPlots.get(plotIndexes[plotDataIndex])) !== null && _a !== void 0 ? _a : {};
112
+ const maxGroupSize = max(Object.values(data), (d) => Object.values(d).length) || 1;
113
+ const groupGap = Math.max(bandWidth * groupPadding, MIN_BAR_GROUP_GAP);
114
+ const groupWidth = bandWidth - groupGap;
115
+ const rectGap = Math.max(bandWidth * barPadding, MIN_BAR_GAP);
116
+ const rectWidth = Math.max(MIN_BAR_WIDTH, Math.min(groupWidth / maxGroupSize - rectGap, barMaxWidth));
117
+ const groupedData = Object.entries(data);
118
+ for (let groupedDataIndex = 0; groupedDataIndex < groupedData.length; groupedDataIndex++) {
119
+ const [xValue, val] = groupedData[groupedDataIndex];
120
+ const stacks = Object.values(val);
121
+ const currentGroupWidth = rectWidth * stacks.length + rectGap * (stacks.length - 1);
122
+ for (let groupItemIndex = 0; groupItemIndex < stacks.length; groupItemIndex++) {
123
+ const yValues = stacks[groupItemIndex];
124
+ let stackHeight = 0;
125
+ const stackItems = [];
126
+ const sortedData = sortKey
127
+ ? sort(yValues, (a, b) => comparator(get(a, sortKey), get(b, sortKey)))
128
+ : yValues;
129
+ for (let yValueIndex = 0; yValueIndex < sortedData.length; yValueIndex++) {
130
+ const yValue = sortedData[yValueIndex];
131
+ const yAxisIndex = yValue.series.yAxis;
132
+ const seriesYScale = yScale[yAxisIndex];
133
+ if (!seriesYScale) {
129
134
  continue;
130
135
  }
131
- xCenter = (xBandScale(xValue) || 0) + xBandScale.bandwidth() / 2;
132
- }
133
- else {
134
- const xLinearScale = xScale;
135
- xCenter = xLinearScale(Number(xValue));
136
- }
137
- const x = xCenter - currentGroupWidth / 2 + (rectWidth + rectGap) * groupItemIndex;
138
- const yDataValue = ((_a = yValue.data.y) !== null && _a !== void 0 ? _a : 0);
139
- const y = seriesYScale(yDataValue);
140
- const base = seriesYScale(0);
141
- const isLastStackItem = yValueIndex === sortedData.length - 1;
142
- const height = yDataValue > 0 ? base - y : y - base;
143
- let shapeHeight = height - (stackItems.length ? stackGap : 0);
144
- if (shapeHeight < 0) {
145
- shapeHeight = height;
136
+ const seriesYAxis = yAxis[yAxisIndex];
137
+ const yAxisTop = ((_b = split.plots[seriesYAxis.plotIndex]) === null || _b === void 0 ? void 0 : _b.top) || 0;
138
+ let xCenter;
139
+ if (xAxis.type === 'category') {
140
+ const xBandScale = xScale;
141
+ const xBandScaleDomain = xBandScale.domain();
142
+ if (xBandScaleDomain.indexOf(xValue) === -1) {
143
+ continue;
144
+ }
145
+ xCenter = (xBandScale(xValue) || 0) + xBandScale.bandwidth() / 2;
146
+ }
147
+ else {
148
+ const xLinearScale = xScale;
149
+ xCenter = xLinearScale(Number(xValue));
150
+ }
151
+ const x = xCenter - currentGroupWidth / 2 + (rectWidth + rectGap) * groupItemIndex;
152
+ const yDataValue = ((_c = yValue.data.y) !== null && _c !== void 0 ? _c : 0);
153
+ const y = seriesYScale(yDataValue);
154
+ const base = seriesYScale(0);
155
+ const isLastStackItem = yValueIndex === sortedData.length - 1;
156
+ const height = Math.abs(base - y);
157
+ let shapeHeight = height - (stackItems.length ? stackGap : 0);
158
+ if (shapeHeight < 0) {
159
+ shapeHeight = height;
160
+ }
161
+ if (shapeHeight < 0) {
162
+ continue;
163
+ }
164
+ const barData = {
165
+ x,
166
+ y: yAxisTop + (yDataValue > 0 ? y - stackHeight : base),
167
+ width: rectWidth,
168
+ height: shapeHeight,
169
+ opacity: get(yValue.data, 'opacity', null),
170
+ data: yValue.data,
171
+ series: yValue.series,
172
+ htmlElements: [],
173
+ isLastStackItem,
174
+ };
175
+ stackItems.push(barData);
176
+ stackHeight += height;
146
177
  }
147
- if (shapeHeight < 0) {
148
- continue;
178
+ if (series.some((s) => s.stacking === 'percent')) {
179
+ let acc = 0;
180
+ const ratio = plotHeight / (stackHeight - stackItems.length);
181
+ stackItems.forEach((item) => {
182
+ item.height = item.height * ratio;
183
+ item.y = plotHeight - item.height - acc;
184
+ acc += item.height + 1;
185
+ });
149
186
  }
150
- const barData = {
151
- x,
152
- y: yDataValue > 0 ? y - stackHeight : seriesYScale(0),
153
- width: rectWidth,
154
- height: shapeHeight,
155
- opacity: get(yValue.data, 'opacity', null),
156
- data: yValue.data,
157
- series: yValue.series,
158
- htmlElements: [],
159
- isLastStackItem,
160
- };
161
- stackItems.push(barData);
162
- stackHeight += height;
163
- }
164
- if (series.some((s) => s.stacking === 'percent')) {
165
- let acc = 0;
166
- const ratio = plotHeight / (stackHeight - stackItems.length);
167
- stackItems.forEach((item) => {
168
- item.height = item.height * ratio;
169
- item.y = plotHeight - item.height - acc;
170
- acc += item.height + 1;
171
- });
187
+ result.push(...stackItems);
172
188
  }
173
- result.push(...stackItems);
174
189
  }
175
190
  }
176
191
  for (let i = 0; i < result.length; i++) {
@@ -57,6 +57,7 @@ export const useShapes = (args) => {
57
57
  yAxis,
58
58
  yScale,
59
59
  boundsHeight,
60
+ split,
60
61
  });
61
62
  shapes.push(React.createElement(BarXSeriesShapes, { key: SERIES_TYPE.BarX, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
62
63
  shapesData.push(...preparedData);
@@ -120,6 +121,7 @@ export const useShapes = (args) => {
120
121
  yAxis,
121
122
  yScale,
122
123
  boundsHeight,
124
+ split,
123
125
  isOutsideBounds,
124
126
  });
125
127
  shapes.push(React.createElement(AreaSeriesShapes, { key: SERIES_TYPE.Area, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
@@ -16,7 +16,7 @@ export const prepareLineData = async (args) => {
16
16
  var _a;
17
17
  const { series, xAxis, yAxis, xScale, yScale, split, isOutsideBounds } = args;
18
18
  const [_xMin, xRangeMax] = xScale.range();
19
- const xMax = xRangeMax / (1 - xAxis.maxPadding);
19
+ const xMax = xRangeMax;
20
20
  const acc = [];
21
21
  for (let i = 0; i < series.length; i++) {
22
22
  const s = series[i];
@@ -1,4 +1,8 @@
1
- .gcharts-line__label {
1
+ .gcharts-line__label,
2
+ .gcharts-area__label,
3
+ .gcharts-radar__label,
4
+ .gcharts-heatmap__label,
5
+ .gcharts-funnel__label {
2
6
  dominant-baseline: text-before-edge;
3
7
  }
4
8
 
@@ -16,10 +20,6 @@
16
20
  dominant-baseline: text-before-edge;
17
21
  }
18
22
 
19
- .gcharts-radar__label {
20
- dominant-baseline: text-before-edge;
21
- }
22
-
23
23
  .gcharts-bar-x__label {
24
24
  user-select: none;
25
25
  fill: var(--g-color-text-complementary);
@@ -40,12 +40,4 @@
40
40
 
41
41
  .gcharts-waterfall__connector {
42
42
  stroke: var(--g-color-line-generic-active);
43
- }
44
-
45
- .gcharts-heatmap__label {
46
- dominant-baseline: text-before-edge;
47
- }
48
-
49
- .gcharts-funnel__label {
50
- dominant-baseline: text-before-edge;
51
43
  }
@@ -129,7 +129,7 @@ export const getDomainDataYBySeries = (series) => {
129
129
  switch (type) {
130
130
  case 'area':
131
131
  case 'bar-x': {
132
- acc.push(...getDomainDataForStackedSeries(seriesList));
132
+ acc.push(0, ...getDomainDataForStackedSeries(seriesList));
133
133
  break;
134
134
  }
135
135
  case 'waterfall': {
@@ -177,6 +177,7 @@ export const ChartInner = (props) => {
177
177
  }, [
178
178
  initialized,
179
179
  preparedRangeSlider.defaultRange,
180
+ preparedSeries,
180
181
  setInitialized,
181
182
  updateRangeSliderState,
182
183
  xScale,
@@ -201,7 +202,7 @@ export const ChartInner = (props) => {
201
202
  React.createElement("g", { ref: plotBeforeRef }),
202
203
  shapes,
203
204
  React.createElement("g", { ref: plotAfterRef })),
204
- ((_e = xAxis === null || xAxis === void 0 ? void 0 : xAxis.rangeSlider) === null || _e === void 0 ? void 0 : _e.enabled) && (React.createElement(RangeSlider, { boundsOffsetLeft: debouncedOffsetLeft, boundsWidth: debouncedBoundsWidth, height: height, htmlLayout: htmlLayout, onUpdate: updateRangeSliderState, preparedChart: preparedChart, preparedLegend: preparedLegend, preparedSeries: debouncedAllPreparedSeries, preparedSeriesOptions: preparedSeriesOptions, preparedRangeSlider: xAxis.rangeSlider, rangeSliderState: rangeSliderState, width: width, xAxis: data.xAxis, yAxis: data.yAxis })),
205
+ ((_e = xAxis === null || xAxis === void 0 ? void 0 : xAxis.rangeSlider) === null || _e === void 0 ? void 0 : _e.enabled) && (React.createElement(RangeSlider, { boundsOffsetLeft: debouncedOffsetLeft, boundsWidth: debouncedBoundsWidth, height: height, htmlLayout: htmlLayout, onUpdate: updateRangeSliderState, preparedChart: preparedChart, preparedLegend: preparedLegend, preparedSeries: debouncedAllPreparedSeries, preparedSeriesOptions: preparedSeriesOptions, preparedRangeSlider: xAxis.rangeSlider, rangeSliderState: rangeSliderState, width: width, xAxis: data.xAxis, yAxis: data.yAxis, zoomState: zoomState })),
205
206
  (preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && legendConfig && (React.createElement(Legend, { chartSeries: preparedSeries, legend: preparedLegend, items: legendItems, config: legendConfig, onItemClick: handleLegendItemClick, onUpdate: unpinTooltip, htmlLayout: htmlLayout }))));
206
207
  return (React.createElement("div", { className: b() },
207
208
  React.createElement("svg", { ref: svgRef, width: width, height: height,
@@ -79,14 +79,13 @@ export function useChartInnerProps(props) {
79
79
  const { xScale, yScale } = useAxisScales({
80
80
  boundsWidth,
81
81
  boundsHeight,
82
- hasZoomX: Boolean(zoomState.x),
83
- hasZoomY: Boolean(zoomState.y),
84
82
  rangeSliderState,
85
83
  series: preparedSeries,
86
84
  seriesOptions: preparedSeriesOptions,
87
85
  split: preparedSplit,
88
86
  xAxis,
89
87
  yAxis,
88
+ zoomState,
90
89
  });
91
90
  const isOutsideBounds = React.useCallback((x, y) => {
92
91
  return x < 0 || x > boundsWidth || y < 0 || y > boundsHeight;