@gravity-ui/charts 1.11.0 → 1.11.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 (63) hide show
  1. package/dist/cjs/components/Axis/AxisY.js +3 -0
  2. package/dist/cjs/components/ChartInner/useChartInnerProps.js +37 -11
  3. package/dist/cjs/components/Legend/index.js +4 -1
  4. package/dist/cjs/components/Tooltip/DefaultContent.js +4 -4
  5. package/dist/cjs/hooks/useAxisScales/index.js +15 -6
  6. package/dist/cjs/hooks/useSeries/index.d.ts +1 -19
  7. package/dist/cjs/hooks/useSeries/index.js +7 -25
  8. package/dist/cjs/hooks/useSeries/prepare-legend.js +2 -2
  9. package/dist/cjs/hooks/useShapes/area/prepare-data.js +4 -3
  10. package/dist/cjs/hooks/useShapes/index.js +143 -139
  11. package/dist/cjs/hooks/useShapes/line/prepare-data.js +3 -2
  12. package/dist/cjs/hooks/useShapes/utils.d.ts +6 -0
  13. package/dist/cjs/hooks/useShapes/utils.js +29 -4
  14. package/dist/cjs/hooks/useShapes/waterfall/index.js +1 -1
  15. package/dist/cjs/libs/format-number/index.d.ts +7 -3
  16. package/dist/cjs/libs/format-number/index.js +8 -3
  17. package/dist/cjs/libs/format-number/types.d.ts +0 -1
  18. package/dist/cjs/types/chart/tooltip.d.ts +1 -0
  19. package/dist/cjs/types/formatter.d.ts +0 -1
  20. package/dist/cjs/utils/chart/get-closest-data.d.ts +1 -0
  21. package/dist/cjs/utils/chart/get-closest-data.js +2 -5
  22. package/dist/cjs/utils/chart/index.d.ts +1 -0
  23. package/dist/cjs/utils/chart/index.js +3 -2
  24. package/dist/cjs/utils/chart/series/index.d.ts +1 -0
  25. package/dist/cjs/utils/chart/series/index.js +1 -0
  26. package/dist/cjs/utils/chart/series/sorting.d.ts +2 -0
  27. package/dist/cjs/utils/chart/series/sorting.js +12 -0
  28. package/dist/{esm/hooks/hooks-utils → cjs/utils/chart}/zoom.d.ts +5 -2
  29. package/dist/{esm/hooks/hooks-utils → cjs/utils/chart}/zoom.js +36 -9
  30. package/dist/esm/components/Axis/AxisY.js +3 -0
  31. package/dist/esm/components/ChartInner/useChartInnerProps.js +37 -11
  32. package/dist/esm/components/Legend/index.js +4 -1
  33. package/dist/esm/components/Tooltip/DefaultContent.js +4 -4
  34. package/dist/esm/hooks/useAxisScales/index.js +15 -6
  35. package/dist/esm/hooks/useSeries/index.d.ts +1 -19
  36. package/dist/esm/hooks/useSeries/index.js +7 -25
  37. package/dist/esm/hooks/useSeries/prepare-legend.js +2 -2
  38. package/dist/esm/hooks/useShapes/area/prepare-data.js +4 -3
  39. package/dist/esm/hooks/useShapes/index.js +143 -139
  40. package/dist/esm/hooks/useShapes/line/prepare-data.js +3 -2
  41. package/dist/esm/hooks/useShapes/utils.d.ts +6 -0
  42. package/dist/esm/hooks/useShapes/utils.js +29 -4
  43. package/dist/esm/hooks/useShapes/waterfall/index.js +1 -1
  44. package/dist/esm/libs/format-number/index.d.ts +7 -3
  45. package/dist/esm/libs/format-number/index.js +8 -3
  46. package/dist/esm/libs/format-number/types.d.ts +0 -1
  47. package/dist/esm/types/chart/tooltip.d.ts +1 -0
  48. package/dist/esm/types/formatter.d.ts +0 -1
  49. package/dist/esm/utils/chart/get-closest-data.d.ts +1 -0
  50. package/dist/esm/utils/chart/get-closest-data.js +2 -5
  51. package/dist/esm/utils/chart/index.d.ts +1 -0
  52. package/dist/esm/utils/chart/index.js +3 -2
  53. package/dist/esm/utils/chart/series/index.d.ts +1 -0
  54. package/dist/esm/utils/chart/series/index.js +1 -0
  55. package/dist/esm/utils/chart/series/sorting.d.ts +2 -0
  56. package/dist/esm/utils/chart/series/sorting.js +12 -0
  57. package/dist/{cjs/hooks/hooks-utils → esm/utils/chart}/zoom.d.ts +5 -2
  58. package/dist/{cjs/hooks/hooks-utils → esm/utils/chart}/zoom.js +36 -9
  59. package/package.json +1 -1
  60. package/dist/cjs/hooks/hooks-utils/index.d.ts +0 -1
  61. package/dist/cjs/hooks/hooks-utils/index.js +0 -1
  62. package/dist/esm/hooks/hooks-utils/index.d.ts +0 -1
  63. package/dist/esm/hooks/hooks-utils/index.js +0 -1
@@ -23,160 +23,167 @@ export const useShapes = (args) => {
23
23
  const { boundsWidth, boundsHeight, dispatcher, series, seriesOptions, xAxis, xScale, yAxis, yScale, split, htmlLayout, clipPathId, isOutsideBounds, } = args;
24
24
  const [shapesElemens, setShapesElements] = React.useState([]);
25
25
  const [shapesElemensData, setShapesElemensData] = React.useState([]);
26
- const setShapes = React.useCallback(async () => {
27
- const visibleSeries = getOnlyVisibleSeries(series);
28
- const groupedSeries = group(visibleSeries, (item) => item.type);
29
- const shapesData = [];
30
- const shapes = [];
31
- await Promise.all(
32
- // eslint-disable-next-line complexity
33
- Array.from(groupedSeries).map(async (item) => {
34
- const [seriesType, chartSeries] = item;
35
- switch (seriesType) {
36
- case 'bar-x': {
37
- if (xAxis && xScale && yScale) {
38
- const preparedData = await prepareBarXData({
39
- series: chartSeries,
40
- seriesOptions,
41
- xAxis,
42
- xScale,
43
- yAxis,
44
- yScale,
45
- boundsHeight,
46
- });
47
- shapes.push(React.createElement(BarXSeriesShapes, { key: "bar-x", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
48
- shapesData.push(...preparedData);
26
+ const countedRef = React.useRef(0);
27
+ React.useEffect(() => {
28
+ countedRef.current++;
29
+ (async () => {
30
+ const currentRun = countedRef.current;
31
+ const visibleSeries = getOnlyVisibleSeries(series);
32
+ const groupedSeries = group(visibleSeries, (item) => item.type);
33
+ const shapesData = [];
34
+ const shapes = [];
35
+ await Promise.all(
36
+ // eslint-disable-next-line complexity
37
+ Array.from(groupedSeries).map(async (item) => {
38
+ const [seriesType, chartSeries] = item;
39
+ switch (seriesType) {
40
+ case 'bar-x': {
41
+ if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
42
+ const preparedData = await prepareBarXData({
43
+ series: chartSeries,
44
+ seriesOptions,
45
+ xAxis,
46
+ xScale,
47
+ yAxis,
48
+ yScale,
49
+ boundsHeight,
50
+ });
51
+ shapes.push(React.createElement(BarXSeriesShapes, { key: "bar-x", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
52
+ shapesData.push(...preparedData);
53
+ }
54
+ break;
49
55
  }
50
- break;
51
- }
52
- case 'bar-y': {
53
- if (xAxis && xScale && yScale) {
54
- const preparedData = await prepareBarYData({
56
+ case 'bar-y': {
57
+ if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
58
+ const preparedData = await prepareBarYData({
59
+ series: chartSeries,
60
+ seriesOptions,
61
+ xAxis,
62
+ xScale,
63
+ yAxis,
64
+ yScale,
65
+ });
66
+ shapes.push(React.createElement(BarYSeriesShapes, { key: "bar-y", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
67
+ shapesData.push(...preparedData);
68
+ }
69
+ break;
70
+ }
71
+ case 'waterfall': {
72
+ if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
73
+ const preparedData = await prepareWaterfallData({
74
+ series: chartSeries,
75
+ seriesOptions,
76
+ xAxis,
77
+ xScale,
78
+ yAxis,
79
+ yScale,
80
+ });
81
+ shapes.push(React.createElement(WaterfallSeriesShapes, { key: "waterfall", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
82
+ shapesData.push(...preparedData);
83
+ }
84
+ break;
85
+ }
86
+ case 'line': {
87
+ if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
88
+ const preparedData = await prepareLineData({
89
+ series: chartSeries,
90
+ xAxis,
91
+ xScale,
92
+ yAxis,
93
+ yScale,
94
+ split,
95
+ isOutsideBounds,
96
+ });
97
+ shapes.push(React.createElement(LineSeriesShapes, { key: "line", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
98
+ shapesData.push(...preparedData);
99
+ }
100
+ break;
101
+ }
102
+ case 'area': {
103
+ if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
104
+ const preparedData = await prepareAreaData({
105
+ series: chartSeries,
106
+ xAxis,
107
+ xScale,
108
+ yAxis,
109
+ yScale,
110
+ boundsHeight,
111
+ isOutsideBounds,
112
+ });
113
+ shapes.push(React.createElement(AreaSeriesShapes, { key: "area", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
114
+ shapesData.push(...preparedData);
115
+ }
116
+ break;
117
+ }
118
+ case 'scatter': {
119
+ if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
120
+ const preparedData = prepareScatterData({
121
+ series: chartSeries,
122
+ xAxis,
123
+ xScale,
124
+ yAxis,
125
+ yScale,
126
+ isOutsideBounds,
127
+ });
128
+ shapes.push(React.createElement(ScatterSeriesShape, { key: "scatter", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
129
+ shapesData.push(...preparedData);
130
+ }
131
+ break;
132
+ }
133
+ case 'pie': {
134
+ const preparedData = await preparePieData({
55
135
  series: chartSeries,
56
- seriesOptions,
57
- xAxis,
58
- xScale,
59
- yAxis,
60
- yScale,
136
+ boundsWidth,
137
+ boundsHeight,
61
138
  });
62
- shapes.push(React.createElement(BarYSeriesShapes, { key: "bar-y", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
139
+ shapes.push(React.createElement(PieSeriesShapes, { key: "pie", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
63
140
  shapesData.push(...preparedData);
141
+ break;
64
142
  }
65
- break;
66
- }
67
- case 'waterfall': {
68
- if (xAxis && xScale && yScale) {
69
- const preparedData = await prepareWaterfallData({
70
- series: chartSeries,
71
- seriesOptions,
72
- xAxis,
73
- xScale,
74
- yAxis,
75
- yScale,
143
+ case 'treemap': {
144
+ const preparedData = await prepareTreemapData({
145
+ // We should have exactly one series with "treemap" type
146
+ // Otherwise data validation should emit an error
147
+ series: chartSeries[0],
148
+ width: boundsWidth,
149
+ height: boundsHeight,
76
150
  });
77
- shapes.push(React.createElement(WaterfallSeriesShapes, { key: "waterfall", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
78
- shapesData.push(...preparedData);
151
+ shapes.push(React.createElement(TreemapSeriesShape, { key: "treemap", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
152
+ shapesData.push(preparedData);
153
+ break;
79
154
  }
80
- break;
81
- }
82
- case 'line': {
83
- if (xAxis && xScale && yScale) {
84
- const preparedData = await prepareLineData({
85
- series: chartSeries,
86
- xAxis,
87
- xScale,
88
- yAxis,
89
- yScale,
90
- split,
91
- isOutsideBounds,
155
+ case 'sankey': {
156
+ const preparedData = prepareSankeyData({
157
+ series: chartSeries[0],
158
+ width: boundsWidth,
159
+ height: boundsHeight,
92
160
  });
93
- shapes.push(React.createElement(LineSeriesShapes, { key: "line", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
94
- shapesData.push(...preparedData);
161
+ shapes.push(React.createElement(SankeySeriesShape, { key: "sankey", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
162
+ shapesData.push(preparedData);
163
+ break;
95
164
  }
96
- break;
97
- }
98
- case 'area': {
99
- if (xAxis && xScale && yScale) {
100
- const preparedData = await prepareAreaData({
165
+ case 'radar': {
166
+ const preparedData = await prepareRadarData({
101
167
  series: chartSeries,
102
- xAxis,
103
- xScale,
104
- yAxis,
105
- yScale,
168
+ boundsWidth,
106
169
  boundsHeight,
107
- isOutsideBounds,
108
170
  });
109
- shapes.push(React.createElement(AreaSeriesShapes, { key: "area", dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
171
+ shapes.push(React.createElement(RadarSeriesShapes, { key: "radar", dispatcher: dispatcher, series: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
110
172
  shapesData.push(...preparedData);
173
+ break;
111
174
  }
112
- break;
113
- }
114
- case 'scatter': {
115
- if (xAxis && xScale && yScale) {
116
- const preparedData = prepareScatterData({
117
- series: chartSeries,
118
- xAxis,
119
- xScale,
120
- yAxis,
121
- yScale,
122
- isOutsideBounds,
175
+ default: {
176
+ throw new ChartError({
177
+ message: `The display method is not defined for a series with type "${seriesType}"`,
123
178
  });
124
- shapes.push(React.createElement(ScatterSeriesShape, { key: "scatter", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
125
- shapesData.push(...preparedData);
126
179
  }
127
- break;
128
- }
129
- case 'pie': {
130
- const preparedData = await preparePieData({
131
- series: chartSeries,
132
- boundsWidth,
133
- boundsHeight,
134
- });
135
- shapes.push(React.createElement(PieSeriesShapes, { key: "pie", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
136
- shapesData.push(...preparedData);
137
- break;
138
- }
139
- case 'treemap': {
140
- const preparedData = await prepareTreemapData({
141
- // We should have exactly one series with "treemap" type
142
- // Otherwise data validation should emit an error
143
- series: chartSeries[0],
144
- width: boundsWidth,
145
- height: boundsHeight,
146
- });
147
- shapes.push(React.createElement(TreemapSeriesShape, { key: "treemap", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
148
- shapesData.push(preparedData);
149
- break;
150
- }
151
- case 'sankey': {
152
- const preparedData = prepareSankeyData({
153
- series: chartSeries[0],
154
- width: boundsWidth,
155
- height: boundsHeight,
156
- });
157
- shapes.push(React.createElement(SankeySeriesShape, { key: "sankey", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
158
- shapesData.push(preparedData);
159
- break;
160
- }
161
- case 'radar': {
162
- const preparedData = await prepareRadarData({
163
- series: chartSeries,
164
- boundsWidth,
165
- boundsHeight,
166
- });
167
- shapes.push(React.createElement(RadarSeriesShapes, { key: "radar", dispatcher: dispatcher, series: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
168
- shapesData.push(...preparedData);
169
- break;
170
- }
171
- default: {
172
- throw new ChartError({
173
- message: `The display method is not defined for a series with type "${seriesType}"`,
174
- });
175
180
  }
181
+ }));
182
+ if (countedRef.current === currentRun) {
183
+ setShapesElements(shapes);
184
+ setShapesElemensData(shapesData);
176
185
  }
177
- }));
178
- setShapesElements(shapes);
179
- setShapesElemensData(shapesData);
186
+ })();
180
187
  }, [
181
188
  boundsHeight,
182
189
  boundsWidth,
@@ -192,8 +199,5 @@ export const useShapes = (args) => {
192
199
  clipPathId,
193
200
  isOutsideBounds,
194
201
  ]);
195
- React.useEffect(() => {
196
- setShapes();
197
- }, [setShapes]);
198
202
  return { shapes: shapesElemens, shapesData: shapesElemensData };
199
203
  };
@@ -51,8 +51,9 @@ export const prepareLineData = async (args) => {
51
51
  const yAxisTop = ((_a = split.plots[seriesYAxis.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
52
52
  const seriesYScale = yScale[s.yAxis];
53
53
  const points = s.data.map((d) => ({
54
- x: getXValue({ point: d, xAxis, xScale }),
55
- y: yAxisTop + getYValue({ point: d, yAxis: seriesYAxis, yScale: seriesYScale }),
54
+ x: getXValue({ point: d, points: s.data, xAxis, xScale }),
55
+ y: yAxisTop +
56
+ getYValue({ point: d, points: s.data, yAxis: seriesYAxis, yScale: seriesYScale }),
56
57
  active: true,
57
58
  data: d,
58
59
  series: s,
@@ -6,6 +6,9 @@ export declare function getXValue(args: {
6
6
  point: {
7
7
  x?: number | string;
8
8
  };
9
+ points?: {
10
+ x?: number | string;
11
+ }[];
9
12
  xAxis: PreparedAxis;
10
13
  xScale: ChartScale;
11
14
  }): number;
@@ -13,6 +16,9 @@ export declare function getYValue(args: {
13
16
  point: {
14
17
  y?: number | string;
15
18
  };
19
+ points?: {
20
+ y?: number | string;
21
+ }[];
16
22
  yAxis: PreparedAxis;
17
23
  yScale: ChartScale;
18
24
  }): number;
@@ -1,26 +1,51 @@
1
1
  import { path, select } from 'd3';
2
2
  import get from 'lodash/get';
3
3
  import { getDataCategoryValue } from '../../utils';
4
+ const ONE_POINT_DOMAIN_DATA_CAPACITY = 3;
4
5
  export function getXValue(args) {
5
- const { point, xAxis, xScale } = args;
6
+ const { point, points, xAxis, xScale } = args;
6
7
  if (xAxis.type === 'category') {
7
8
  const xBandScale = xScale;
8
9
  const categories = get(xAxis, 'categories', []);
9
10
  const dataCategory = getDataCategoryValue({ axisDirection: 'x', categories, data: point });
10
11
  return (xBandScale(dataCategory) || 0) + xBandScale.step() / 2;
11
12
  }
12
- const xLinearScale = xScale;
13
+ let xLinearScale = xScale;
14
+ const [xMinDomain, xMaxDomain] = xLinearScale.domain();
15
+ if (Number(xMinDomain) === Number(xMaxDomain) &&
16
+ (points === null || points === void 0 ? void 0 : points.length) === ONE_POINT_DOMAIN_DATA_CAPACITY) {
17
+ const x1 = points[0].x;
18
+ const xTarget = points[1].x;
19
+ const x3 = points[2].x;
20
+ const xMin = Math.min(x1, xTarget, x3);
21
+ const xMax = Math.max(x1, xTarget, x3);
22
+ xLinearScale = xLinearScale
23
+ .copy()
24
+ .domain([xMin + (xTarget - xMin) / 2, xMax - (xMax - xTarget) / 2]);
25
+ }
13
26
  return xLinearScale(point.x);
14
27
  }
15
28
  export function getYValue(args) {
16
- const { point, yAxis, yScale } = args;
29
+ const { point, points, yAxis, yScale } = args;
17
30
  if (yAxis.type === 'category') {
18
31
  const yBandScale = yScale;
19
32
  const categories = get(yAxis, 'categories', []);
20
33
  const dataCategory = getDataCategoryValue({ axisDirection: 'y', categories, data: point });
21
34
  return (yBandScale(dataCategory) || 0) + yBandScale.step() / 2;
22
35
  }
23
- const yLinearScale = yScale;
36
+ let yLinearScale = yScale;
37
+ const [yMinDomain, yMaxDomain] = yLinearScale.domain();
38
+ if (Number(yMinDomain) === Number(yMaxDomain) &&
39
+ (points === null || points === void 0 ? void 0 : points.length) === ONE_POINT_DOMAIN_DATA_CAPACITY) {
40
+ const y1 = points[0].y;
41
+ const yTarget = points[1].y;
42
+ const y2 = points[2].y;
43
+ const yMin = Math.min(y1, yTarget, y2);
44
+ const yMax = Math.max(y1, yTarget, y2);
45
+ yLinearScale = yLinearScale
46
+ .copy()
47
+ .domain([yMin + (yTarget - yMin) / 2, yMax - (yMax - yTarget) / 2]);
48
+ }
24
49
  return yLinearScale(point.y);
25
50
  }
26
51
  export function shapeKey(d) {
@@ -125,7 +125,7 @@ export const WaterfallSeriesShapes = (args) => {
125
125
  return () => {
126
126
  dispatcher.on('hover-shape.waterfall', null);
127
127
  };
128
- }, [dispatcher, preparedData, seriesOptions]);
128
+ }, [connectorSelector, dispatcher, preparedData, seriesOptions]);
129
129
  return (React.createElement(React.Fragment, null,
130
130
  React.createElement("g", { ref: ref, className: b(), clipPath: `url(#${clipPathId})` }),
131
131
  React.createElement(HtmlLayer, { preparedData: preparedData, htmlLayout: htmlLayout })));
@@ -1,5 +1,9 @@
1
1
  import type { FormatNumberOptions, FormatOptions } from './types';
2
- export declare const formatBytes: (value: number, options?: FormatOptions) => string;
3
- export declare const formatDuration: (value: number, options?: FormatOptions) => string;
4
- export declare const getNumberUnitRate: (value: number) => number;
2
+ export declare const formatBytes: (value: number, options?: FormatOptions & {
3
+ unitRate?: number;
4
+ }) => string;
5
+ export declare const formatDuration: (value: number, options?: FormatOptions & {
6
+ unitRate?: number;
7
+ }) => string;
8
+ export declare const getDefaultUnit: (value: number) => string | undefined;
5
9
  export declare const formatNumber: (value: number | string, options?: FormatNumberOptions) => string;
@@ -59,7 +59,6 @@ const baseFormatNumber = unitFormatter({
59
59
  unitDelimiterI18nKey: 'value_number-delimiter',
60
60
  unitsI18nKeys: BASE_NUMBER_FORMAT_UNIT_KEYS,
61
61
  });
62
- export const getNumberUnitRate = (value) => getUnitRate(value, 1000, BASE_NUMBER_FORMAT_UNIT_KEYS);
63
62
  const NUMBER_UNIT_RATE_BY_UNIT = {
64
63
  default: 0,
65
64
  auto: undefined,
@@ -68,11 +67,17 @@ const NUMBER_UNIT_RATE_BY_UNIT = {
68
67
  b: 3,
69
68
  t: 4,
70
69
  };
70
+ export const getDefaultUnit = (value) => {
71
+ var _a;
72
+ const unitRate = getUnitRate(value, 1000, BASE_NUMBER_FORMAT_UNIT_KEYS);
73
+ const [unit] = (_a = Object.entries(NUMBER_UNIT_RATE_BY_UNIT).find(([_key, val]) => val === unitRate)) !== null && _a !== void 0 ? _a : [];
74
+ return unit;
75
+ };
71
76
  export const formatNumber = (value, options = {}) => {
72
77
  if (Number.isNaN(value) || Number.isNaN(Number(value))) {
73
78
  return new Intl.NumberFormat('en').format(Number(value));
74
79
  }
75
- const { format = 'number', multiplier = 1, prefix = '', postfix = '', unit, unitRate, labelMode, } = options;
80
+ const { format = 'number', multiplier = 1, prefix = '', postfix = '', unit, labelMode } = options;
76
81
  let changedMultiplier = multiplier;
77
82
  let prePostfix = '';
78
83
  if (format === 'percent') {
@@ -82,6 +87,6 @@ export const formatNumber = (value, options = {}) => {
82
87
  if (labelMode === 'percent') {
83
88
  prePostfix = '%';
84
89
  }
85
- const formattedValue = baseFormatNumber(Number(value) * changedMultiplier, Object.assign(Object.assign({}, options), { unitRate: unitRate !== null && unitRate !== void 0 ? unitRate : NUMBER_UNIT_RATE_BY_UNIT[unit !== null && unit !== void 0 ? unit : 'default'] }));
90
+ const formattedValue = baseFormatNumber(Number(value) * changedMultiplier, Object.assign(Object.assign({}, options), { unitRate: NUMBER_UNIT_RATE_BY_UNIT[unit !== null && unit !== void 0 ? unit : 'default'] }));
86
91
  return `${prefix}${formattedValue}${prePostfix}${postfix}`;
87
92
  };
@@ -1,6 +1,5 @@
1
1
  export type FormatOptions = {
2
2
  precision?: number | 'auto';
3
- unitRate?: number;
4
3
  showRankDelimiter?: boolean;
5
4
  lang?: string;
6
5
  labelMode?: string;
@@ -63,6 +63,7 @@ export interface TooltipDataChunkSankey<T = MeaningfulAny> {
63
63
  export interface TooltipDataChunkWaterfall<T = MeaningfulAny> {
64
64
  data: WaterfallSeriesData<T>;
65
65
  series: WaterfallSeries<T>;
66
+ subTotal?: number;
66
67
  }
67
68
  export interface TooltipDataChunkRadar<T = MeaningfulAny> {
68
69
  data: RadarSeriesData<T>;
@@ -1,6 +1,5 @@
1
1
  export interface FormatOptions {
2
2
  precision?: number | 'auto';
3
- unitRate?: number;
4
3
  showRankDelimiter?: boolean;
5
4
  lang?: string;
6
5
  labelMode?: string;
@@ -12,6 +12,7 @@ export type ShapePoint = {
12
12
  y1: number;
13
13
  data: ChartSeriesData;
14
14
  series: ChartSeries;
15
+ subTotal?: number;
15
16
  };
16
17
  export declare function getClosestPoints(args: GetClosestPointsArgs): TooltipDataChunk[];
17
18
  export {};
@@ -35,11 +35,7 @@ function getClosestPointsByXValue(x, y, points) {
35
35
  });
36
36
  const closestPoints = sort(groupedBySeries, (p) => p.y0);
37
37
  const closestYIndex = getClosestYIndex(closestPoints, y);
38
- return closestPoints.map((p, i) => ({
39
- data: p.data,
40
- series: p.series,
41
- closest: i === closestYIndex,
42
- }));
38
+ return closestPoints.map((p, i) => (Object.assign(Object.assign({}, p), { closest: i === closestYIndex })));
43
39
  }
44
40
  function getSeriesType(shapeData) {
45
41
  return (get(shapeData, 'series.type') ||
@@ -73,6 +69,7 @@ export function getClosestPoints(args) {
73
69
  x: d.x + d.width / 2,
74
70
  y0: d.y,
75
71
  y1: d.y + d.height,
72
+ subTotal: d.subTotal,
76
73
  }));
77
74
  result.push(...getClosestPointsByXValue(pointerX, pointerY, points));
78
75
  break;
@@ -11,6 +11,7 @@ export * from './legend';
11
11
  export * from './symbol';
12
12
  export * from './series';
13
13
  export * from './color';
14
+ export * from './zoom';
14
15
  export declare const CHART_SERIES_WITH_VOLUME_ON_Y_AXIS: ChartSeries['type'][];
15
16
  export declare const CHART_SERIES_WITH_VOLUME_ON_X_AXIS: ChartSeries['type'][];
16
17
  type UnknownSeries = {
@@ -5,7 +5,7 @@ import isNil from 'lodash/isNil';
5
5
  import sortBy from 'lodash/sortBy';
6
6
  import { DEFAULT_AXIS_LABEL_FONT_SIZE } from '../../constants';
7
7
  import { getSeriesStackId } from '../../hooks/useSeries/utils';
8
- import { formatNumber, getNumberUnitRate } from '../../libs/format-number';
8
+ import { formatNumber, getDefaultUnit } from '../../libs/format-number';
9
9
  import { getWaterfallPointSubtotal } from './series/waterfall';
10
10
  import { getDefaultDateFormat } from './time';
11
11
  export * from './math';
@@ -17,6 +17,7 @@ export * from './legend';
17
17
  export * from './symbol';
18
18
  export * from './series';
19
19
  export * from './color';
20
+ export * from './zoom';
20
21
  const CHARTS_WITHOUT_AXIS = ['pie', 'treemap', 'sankey', 'radar'];
21
22
  export const CHART_SERIES_WITH_VOLUME_ON_Y_AXIS = [
22
23
  'bar-x',
@@ -184,7 +185,7 @@ export const formatAxisTickLabel = (args) => {
184
185
  }
185
186
  case 'linear':
186
187
  default: {
187
- const numberFormat = Object.assign({ unitRate: value && step ? getNumberUnitRate(step) : undefined }, axis.labels.numberFormat);
188
+ const numberFormat = Object.assign({ unit: value && step ? getDefaultUnit(step) : undefined }, axis.labels.numberFormat);
188
189
  return formatNumber(value, numberFormat);
189
190
  }
190
191
  }
@@ -1,2 +1,3 @@
1
1
  export * from './line';
2
+ export * from './sorting';
2
3
  export * from './waterfall';
@@ -1,2 +1,3 @@
1
1
  export * from './line';
2
+ export * from './sorting';
2
3
  export * from './waterfall';
@@ -0,0 +1,2 @@
1
+ import type { ChartSeries } from '../../../types';
2
+ export declare function getSortedSeriesData(seriesData: ChartSeries[]): ChartSeries[];
@@ -0,0 +1,12 @@
1
+ import { sort } from 'd3';
2
+ import { SeriesType } from '../../../constants';
3
+ export function getSortedSeriesData(seriesData) {
4
+ return seriesData.map((s) => {
5
+ switch (s.type) {
6
+ case SeriesType.Area: {
7
+ s.data = sort(s.data, (d) => d.x);
8
+ }
9
+ }
10
+ return s;
11
+ });
12
+ }
@@ -1,8 +1,11 @@
1
+ import type { ZoomState } from '../../hooks/useZoom/types';
1
2
  import type { ChartSeries, ChartXAxis, ChartYAxis } from '../../types';
2
- import type { ZoomState } from '../useZoom/types';
3
3
  export declare function getZoomedSeriesData(args: {
4
4
  seriesData: ChartSeries[];
5
5
  zoomState: Partial<ZoomState>;
6
6
  xAxis?: ChartXAxis;
7
7
  yAxes?: ChartYAxis[];
8
- }): ChartSeries[];
8
+ }): {
9
+ zoomedSeriesData: ChartSeries[];
10
+ zoomedShapesSeriesData: ChartSeries[];
11
+ };