@gravity-ui/charts 1.44.0 → 1.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/cjs/components/ChartInner/index.js +2 -2
  2. package/dist/cjs/components/ChartInner/styles.css +2 -2
  3. package/dist/cjs/components/ChartInner/useChartInnerProps.js +1 -1
  4. package/dist/cjs/components/ChartInner/utils/title.d.ts +2 -1
  5. package/dist/cjs/components/ChartInner/utils/title.js +51 -14
  6. package/dist/cjs/components/Title/index.d.ts +4 -2
  7. package/dist/cjs/components/Title/index.js +9 -2
  8. package/dist/cjs/core/constants/defaults/annotation.d.ts +12 -0
  9. package/dist/cjs/core/constants/defaults/annotation.js +12 -0
  10. package/dist/cjs/core/constants/defaults/index.d.ts +1 -0
  11. package/dist/cjs/core/constants/defaults/index.js +1 -0
  12. package/dist/cjs/core/series/constants.d.ts +1 -1
  13. package/dist/cjs/core/series/constants.js +1 -1
  14. package/dist/cjs/core/series/prepare-annotation.d.ts +12 -0
  15. package/dist/cjs/core/series/prepare-annotation.js +31 -0
  16. package/dist/cjs/core/series/types.d.ts +16 -0
  17. package/dist/cjs/core/types/chart/annotation.d.ts +45 -0
  18. package/dist/cjs/core/types/chart/annotation.js +1 -0
  19. package/dist/cjs/core/types/chart/area.d.ts +8 -0
  20. package/dist/cjs/core/types/chart/bar-x.d.ts +6 -0
  21. package/dist/cjs/core/types/chart/line.d.ts +8 -0
  22. package/dist/cjs/core/types/chart/marker.d.ts +6 -4
  23. package/dist/cjs/core/types/chart/series.d.ts +7 -0
  24. package/dist/cjs/core/types/chart/title.d.ts +18 -0
  25. package/dist/cjs/core/types/chart/tooltip.d.ts +1 -0
  26. package/dist/cjs/core/types/index.d.ts +1 -0
  27. package/dist/cjs/core/types/index.js +1 -0
  28. package/dist/cjs/core/utils/text.d.ts +8 -0
  29. package/dist/cjs/core/utils/text.js +9 -1
  30. package/dist/cjs/hooks/types.d.ts +6 -3
  31. package/dist/cjs/hooks/useShapes/HtmlLayer.js +4 -3
  32. package/dist/cjs/hooks/useShapes/annotation/index.d.ts +14 -0
  33. package/dist/cjs/hooks/useShapes/annotation/index.js +200 -0
  34. package/dist/cjs/hooks/useShapes/area/index.d.ts +2 -0
  35. package/dist/cjs/hooks/useShapes/area/index.js +21 -2
  36. package/dist/cjs/hooks/useShapes/area/prepare-data.d.ts +2 -1
  37. package/dist/cjs/hooks/useShapes/area/prepare-data.js +38 -20
  38. package/dist/cjs/hooks/useShapes/area/types.d.ts +4 -0
  39. package/dist/cjs/hooks/useShapes/bar-x/index.d.ts +2 -0
  40. package/dist/cjs/hooks/useShapes/bar-x/index.js +30 -2
  41. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +10 -2
  42. package/dist/cjs/hooks/useShapes/bar-x/types.d.ts +2 -0
  43. package/dist/cjs/hooks/useShapes/index.js +5 -3
  44. package/dist/cjs/hooks/useShapes/line/index.d.ts +2 -0
  45. package/dist/cjs/hooks/useShapes/line/index.js +18 -4
  46. package/dist/cjs/hooks/useShapes/line/prepare-data.d.ts +2 -1
  47. package/dist/cjs/hooks/useShapes/line/prepare-data.js +28 -10
  48. package/dist/cjs/hooks/useShapes/line/types.d.ts +4 -0
  49. package/dist/cjs/types/chart-ui.d.ts +2 -0
  50. package/dist/esm/components/ChartInner/index.js +2 -2
  51. package/dist/esm/components/ChartInner/styles.css +2 -2
  52. package/dist/esm/components/ChartInner/useChartInnerProps.js +1 -1
  53. package/dist/esm/components/ChartInner/utils/title.d.ts +2 -1
  54. package/dist/esm/components/ChartInner/utils/title.js +51 -14
  55. package/dist/esm/components/Title/index.d.ts +4 -2
  56. package/dist/esm/components/Title/index.js +9 -2
  57. package/dist/esm/core/constants/defaults/annotation.d.ts +12 -0
  58. package/dist/esm/core/constants/defaults/annotation.js +12 -0
  59. package/dist/esm/core/constants/defaults/index.d.ts +1 -0
  60. package/dist/esm/core/constants/defaults/index.js +1 -0
  61. package/dist/esm/core/series/constants.d.ts +1 -1
  62. package/dist/esm/core/series/constants.js +1 -1
  63. package/dist/esm/core/series/prepare-annotation.d.ts +12 -0
  64. package/dist/esm/core/series/prepare-annotation.js +31 -0
  65. package/dist/esm/core/series/types.d.ts +16 -0
  66. package/dist/esm/core/types/chart/annotation.d.ts +45 -0
  67. package/dist/esm/core/types/chart/annotation.js +1 -0
  68. package/dist/esm/core/types/chart/area.d.ts +8 -0
  69. package/dist/esm/core/types/chart/bar-x.d.ts +6 -0
  70. package/dist/esm/core/types/chart/line.d.ts +8 -0
  71. package/dist/esm/core/types/chart/marker.d.ts +6 -4
  72. package/dist/esm/core/types/chart/series.d.ts +7 -0
  73. package/dist/esm/core/types/chart/title.d.ts +18 -0
  74. package/dist/esm/core/types/chart/tooltip.d.ts +1 -0
  75. package/dist/esm/core/types/index.d.ts +1 -0
  76. package/dist/esm/core/types/index.js +1 -0
  77. package/dist/esm/core/utils/text.d.ts +8 -0
  78. package/dist/esm/core/utils/text.js +9 -1
  79. package/dist/esm/hooks/types.d.ts +6 -3
  80. package/dist/esm/hooks/useShapes/HtmlLayer.js +4 -3
  81. package/dist/esm/hooks/useShapes/annotation/index.d.ts +14 -0
  82. package/dist/esm/hooks/useShapes/annotation/index.js +200 -0
  83. package/dist/esm/hooks/useShapes/area/index.d.ts +2 -0
  84. package/dist/esm/hooks/useShapes/area/index.js +21 -2
  85. package/dist/esm/hooks/useShapes/area/prepare-data.d.ts +2 -1
  86. package/dist/esm/hooks/useShapes/area/prepare-data.js +38 -20
  87. package/dist/esm/hooks/useShapes/area/types.d.ts +4 -0
  88. package/dist/esm/hooks/useShapes/bar-x/index.d.ts +2 -0
  89. package/dist/esm/hooks/useShapes/bar-x/index.js +30 -2
  90. package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +10 -2
  91. package/dist/esm/hooks/useShapes/bar-x/types.d.ts +2 -0
  92. package/dist/esm/hooks/useShapes/index.js +5 -3
  93. package/dist/esm/hooks/useShapes/line/index.d.ts +2 -0
  94. package/dist/esm/hooks/useShapes/line/index.js +18 -4
  95. package/dist/esm/hooks/useShapes/line/prepare-data.d.ts +2 -1
  96. package/dist/esm/hooks/useShapes/line/prepare-data.js +28 -10
  97. package/dist/esm/hooks/useShapes/line/types.d.ts +4 -0
  98. package/dist/esm/types/chart-ui.d.ts +2 -0
  99. package/package.json +2 -2
@@ -5,6 +5,8 @@ import type { PreparedBarXData } from './types';
5
5
  export { prepareBarXData } from './prepare-data';
6
6
  export * from './types';
7
7
  type Args = {
8
+ boundsHeight: number;
9
+ boundsWidth: number;
8
10
  clipPathId: string;
9
11
  htmlLayout: HTMLElement | null;
10
12
  preparedData: PreparedBarXData[];
@@ -5,14 +5,16 @@ import get from 'lodash/get';
5
5
  import { filterOverlappingLabels } from '../../../core/utils';
6
6
  import { block } from '../../../utils';
7
7
  import { HtmlLayer } from '../HtmlLayer';
8
+ import { renderAnnotations } from '../annotation';
8
9
  import { getRectPath } from '../utils';
9
10
  export { prepareBarXData } from './prepare-data';
10
11
  export * from './types';
11
12
  const b = block('bar-x');
12
13
  export const BarXSeriesShapes = (args) => {
13
- const { dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId } = args;
14
+ const { boundsHeight, boundsWidth, dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId, } = args;
14
15
  const hoveredDataRef = React.useRef(null);
15
16
  const ref = React.useRef(null);
17
+ const annotationsRef = React.useRef(null);
16
18
  const allowOverlapDataLabels = React.useMemo(() => {
17
19
  return preparedData.some((d) => d === null || d === void 0 ? void 0 : d.series.dataLabels.allowOverlap);
18
20
  }, [preparedData]);
@@ -65,6 +67,24 @@ export const BarXSeriesShapes = (args) => {
65
67
  .style('font-size', (d) => d.style.fontSize)
66
68
  .style('font-weight', (d) => d.style.fontWeight || null)
67
69
  .style('fill', (d) => d.style.fontColor || null);
70
+ if (annotationsRef.current) {
71
+ const anchors = [];
72
+ for (const d of preparedData) {
73
+ if (d.annotation) {
74
+ anchors.push({
75
+ annotation: d.annotation,
76
+ x: d.x + d.width / 2,
77
+ y: d.y,
78
+ });
79
+ }
80
+ }
81
+ renderAnnotations({
82
+ anchors,
83
+ container: select(annotationsRef.current),
84
+ plotHeight: boundsHeight,
85
+ plotWidth: boundsWidth,
86
+ });
87
+ }
68
88
  function handleShapeHover(data) {
69
89
  hoveredDataRef.current = data;
70
90
  const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
@@ -112,7 +132,14 @@ export const BarXSeriesShapes = (args) => {
112
132
  return () => {
113
133
  dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on('hover-shape.bar-x', null);
114
134
  };
115
- }, [allowOverlapDataLabels, dispatcher, preparedData, seriesOptions]);
135
+ }, [
136
+ allowOverlapDataLabels,
137
+ boundsHeight,
138
+ boundsWidth,
139
+ dispatcher,
140
+ preparedData,
141
+ seriesOptions,
142
+ ]);
116
143
  const htmlLayerData = React.useMemo(() => {
117
144
  const items = preparedData.map((d) => d === null || d === void 0 ? void 0 : d.htmlLabels).flat();
118
145
  if (allowOverlapDataLabels) {
@@ -122,5 +149,6 @@ export const BarXSeriesShapes = (args) => {
122
149
  }, [allowOverlapDataLabels, preparedData]);
123
150
  return (React.createElement(React.Fragment, null,
124
151
  React.createElement("g", { ref: ref, className: b(), clipPath: `url(#${clipPathId})` }),
152
+ React.createElement("g", { ref: annotationsRef }),
125
153
  React.createElement(HtmlLayer, { preparedData: htmlLayerData, htmlLayout: htmlLayout })));
126
154
  };
@@ -1,5 +1,6 @@
1
1
  import { ascending, descending, max, min, reverse, sort } from 'd3-array';
2
2
  import get from 'lodash/get';
3
+ import { prepareAnnotation } from '../../../core/series/prepare-annotation';
3
4
  import { getDataCategoryValue, getLabelsSize } from '../../../core/utils';
4
5
  import { getFormattedValue } from '../../../core/utils/format';
5
6
  import { MIN_BAR_GAP, MIN_BAR_GROUP_GAP, MIN_BAR_WIDTH } from '../../constants';
@@ -35,7 +36,7 @@ async function getLabelData(d, xMax) {
35
36
  };
36
37
  }
37
38
  export const prepareBarXData = async (args) => {
38
- var _a, _b, _c, _d, _e, _f;
39
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
39
40
  const { series, seriesOptions, xAxis, xScale, yAxis, yScale, boundsHeight: plotHeight, split, isRangeSlider, } = args;
40
41
  const stackGap = seriesOptions['bar-x'].stackGap;
41
42
  const categories = (_a = xAxis === null || xAxis === void 0 ? void 0 : xAxis.categories) !== null && _a !== void 0 ? _a : [];
@@ -178,6 +179,13 @@ export const prepareBarXData = async (args) => {
178
179
  continue;
179
180
  }
180
181
  const barData = {
182
+ annotation: yValue.data.annotation && !isRangeSlider
183
+ ? await prepareAnnotation({
184
+ annotation: yValue.data.annotation,
185
+ optionsLabel: (_g = (_f = seriesOptions['bar-x']) === null || _f === void 0 ? void 0 : _f.annotation) === null || _g === void 0 ? void 0 : _g.label,
186
+ optionsPopup: (_j = (_h = seriesOptions['bar-x']) === null || _h === void 0 ? void 0 : _h.annotation) === null || _j === void 0 ? void 0 : _j.popup,
187
+ })
188
+ : undefined,
181
189
  x,
182
190
  y: barPositionY,
183
191
  width: rectWidth,
@@ -220,7 +228,7 @@ export const prepareBarXData = async (args) => {
220
228
  barData.x >= xMax ||
221
229
  barData.y + barData.height <= 0 ||
222
230
  barData.y >= plotHeight;
223
- const isZeroValue = ((_f = barData.data.y) !== null && _f !== void 0 ? _f : 0) === 0;
231
+ const isZeroValue = ((_k = barData.data.y) !== null && _k !== void 0 ? _k : 0) === 0;
224
232
  if (barData.series.dataLabels.enabled &&
225
233
  !isRangeSlider &&
226
234
  (!isBarOutsideBounds || isZeroValue)) {
@@ -1,6 +1,8 @@
1
+ import type { PreparedAnnotation } from '../../../core/series/types';
1
2
  import type { HtmlItem, LabelData, TooltipDataChunkBarX } from '../../../types';
2
3
  import type { PreparedBarXSeries } from '../../useSeries/types';
3
4
  export type PreparedBarXData = Omit<TooltipDataChunkBarX, 'series'> & {
5
+ annotation?: PreparedAnnotation;
4
6
  x: number;
5
7
  y: number;
6
8
  width: number;
@@ -62,7 +62,7 @@ export async function getShapes(args) {
62
62
  split,
63
63
  isRangeSlider,
64
64
  });
65
- shapes[index] = (React.createElement(BarXSeriesShapes, { key: SERIES_TYPE.BarX, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
65
+ shapes[index] = (React.createElement(BarXSeriesShapes, { key: SERIES_TYPE.BarX, boundsHeight: boundsHeight, boundsWidth: boundsWidth, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
66
66
  shapesData.splice(index, 0, ...preparedData);
67
67
  layers.push(...preparedData);
68
68
  }
@@ -104,6 +104,7 @@ export async function getShapes(args) {
104
104
  if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
105
105
  const preparedData = await prepareLineData({
106
106
  series: chartSeries,
107
+ seriesOptions,
107
108
  xAxis,
108
109
  xScale,
109
110
  yAxis,
@@ -118,7 +119,7 @@ export async function getShapes(args) {
118
119
  yAxis,
119
120
  zoomState,
120
121
  });
121
- shapes[index] = (React.createElement(LineSeriesShapes, { key: groupId, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: resultClipPathId }));
122
+ shapes[index] = (React.createElement(LineSeriesShapes, { key: groupId, boundsHeight: boundsHeight, boundsWidth: boundsWidth, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: resultClipPathId }));
122
123
  shapesData.splice(index, 0, ...preparedData);
123
124
  layers.push(...preparedData);
124
125
  }
@@ -128,6 +129,7 @@ export async function getShapes(args) {
128
129
  if (xAxis && xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length)) {
129
130
  const preparedData = await prepareAreaData({
130
131
  series: chartSeries,
132
+ seriesOptions,
131
133
  xAxis,
132
134
  xScale,
133
135
  yAxis,
@@ -136,7 +138,7 @@ export async function getShapes(args) {
136
138
  isOutsideBounds,
137
139
  isRangeSlider,
138
140
  });
139
- shapes[index] = (React.createElement(AreaSeriesShapes, { key: SERIES_TYPE.Area, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
141
+ shapes[index] = (React.createElement(AreaSeriesShapes, { key: SERIES_TYPE.Area, boundsHeight: boundsHeight, boundsWidth: boundsWidth, dispatcher: dispatcher, seriesOptions: seriesOptions, preparedData: preparedData, htmlLayout: htmlLayout, clipPathId: clipPathId }));
140
142
  shapesData.splice(index, 0, ...preparedData);
141
143
  layers.push(...preparedData);
142
144
  }
@@ -3,6 +3,8 @@ import type { Dispatch } from 'd3-dispatch';
3
3
  import type { PreparedSeriesOptions } from '../../useSeries/types';
4
4
  import type { PreparedLineData } from './types';
5
5
  type Args = {
6
+ boundsHeight: number;
7
+ boundsWidth: number;
6
8
  clipPathId: string;
7
9
  htmlLayout: HTMLElement | null;
8
10
  preparedData: PreparedLineData[];
@@ -6,16 +6,19 @@ import get from 'lodash/get';
6
6
  import { getLineDashArray } from '../../../core/utils';
7
7
  import { block } from '../../../utils';
8
8
  import { HtmlLayer } from '../HtmlLayer';
9
+ import { renderAnnotations } from '../annotation';
9
10
  import { getMarkerHaloVisibility, getMarkerVisibility, renderMarker, selectMarkerHalo, selectMarkerSymbol, setMarker, } from '../marker';
10
11
  import { setActiveState } from '../utils';
11
12
  const b = block('line');
12
13
  export const LineSeriesShapes = (args) => {
13
- const { dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId } = args;
14
+ const { boundsHeight, boundsWidth, dispatcher, preparedData, seriesOptions, htmlLayout, clipPathId, } = args;
14
15
  const hoveredDataRef = React.useRef(null);
15
16
  const plotRef = React.useRef(null);
16
17
  const markersRef = React.useRef(null);
17
18
  const hoverMarkersRef = React.useRef(null);
19
+ const annotationsRef = React.useRef(null);
18
20
  React.useEffect(() => {
21
+ var _a, _b;
19
22
  if (!plotRef.current || !markersRef.current) {
20
23
  return () => { };
21
24
  }
@@ -64,6 +67,15 @@ export const LineSeriesShapes = (args) => {
64
67
  .data(markers)
65
68
  .join('g')
66
69
  .call(renderMarker);
70
+ if (annotationsRef.current) {
71
+ const anchors = preparedData.flatMap((d) => d.annotations);
72
+ renderAnnotations({
73
+ anchors,
74
+ container: select(annotationsRef.current),
75
+ plotHeight: boundsHeight,
76
+ plotWidth: boundsWidth,
77
+ });
78
+ }
67
79
  const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
68
80
  const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
69
81
  function handleShapeHover(data) {
@@ -165,11 +177,12 @@ export const LineSeriesShapes = (args) => {
165
177
  if (hoveredDataRef.current !== null) {
166
178
  handleShapeHover(hoveredDataRef.current);
167
179
  }
168
- dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on('hover-shape.line', handleShapeHover);
180
+ const eventName = `hover-shape.line-${(_b = (_a = preparedData[0]) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : 'unknown'}`;
181
+ dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on(eventName, handleShapeHover);
169
182
  return () => {
170
- dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on('hover-shape.line', null);
183
+ dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on(eventName, null);
171
184
  };
172
- }, [dispatcher, preparedData, seriesOptions]);
185
+ }, [boundsHeight, boundsWidth, dispatcher, preparedData, seriesOptions]);
173
186
  const htmlLayerData = React.useMemo(() => {
174
187
  const items = preparedData.map((d) => d === null || d === void 0 ? void 0 : d.htmlLabels).flat();
175
188
  return { htmlElements: items };
@@ -178,5 +191,6 @@ export const LineSeriesShapes = (args) => {
178
191
  React.createElement("g", { ref: plotRef, className: b(), clipPath: `url(#${clipPathId})` }),
179
192
  React.createElement("g", { ref: markersRef }),
180
193
  React.createElement("g", { ref: hoverMarkersRef }),
194
+ React.createElement("g", { ref: annotationsRef }),
181
195
  React.createElement(HtmlLayer, { preparedData: htmlLayerData, htmlLayout: htmlLayout })));
182
196
  };
@@ -2,10 +2,11 @@ import type { PreparedSplit } from '../../../core/layout/split-types';
2
2
  import type { ChartScale } from '../../../core/scales/types';
3
3
  import type { ShapeDataWithLabels } from '../../../types';
4
4
  import type { PreparedXAxis, PreparedYAxis } from '../../useAxis/types';
5
- import type { PreparedLineSeries } from '../../useSeries/types';
5
+ import type { PreparedLineSeries, PreparedSeriesOptions } from '../../useSeries/types';
6
6
  import type { PreparedLineData } from './types';
7
7
  export declare const prepareLineData: (args: {
8
8
  series: PreparedLineSeries[];
9
+ seriesOptions?: PreparedSeriesOptions;
9
10
  xAxis: PreparedXAxis;
10
11
  xScale: ChartScale;
11
12
  yAxis: PreparedYAxis[];
@@ -1,3 +1,4 @@
1
+ import { prepareAnnotation } from '../../../core/series/prepare-annotation';
1
2
  import { filterOverlappingLabels, getLabelsSize, getTextSizeFn } from '../../../core/utils';
2
3
  import { getFormattedValue } from '../../../core/utils/format';
3
4
  import { getXValue, getYValue } from '../utils';
@@ -15,8 +16,8 @@ async function getHtmlLabel(point, series, xMax) {
15
16
  };
16
17
  }
17
18
  export const prepareLineData = async (args) => {
18
- var _a, _b, _c, _d;
19
- const { series, xAxis, yAxis, xScale, yScale, split, isOutsideBounds, isRangeSlider, otherLayers, } = args;
19
+ var _a, _b, _c, _d, _e, _f, _g;
20
+ const { series, seriesOptions, xAxis, yAxis, xScale, yScale, split, isOutsideBounds, isRangeSlider, otherLayers, } = args;
20
21
  const [_xMin, xRangeMax] = xScale.range();
21
22
  const xMax = xRangeMax;
22
23
  const acc = [];
@@ -29,21 +30,31 @@ export const prepareLineData = async (args) => {
29
30
  if (!seriesYScale) {
30
31
  continue;
31
32
  }
32
- const points = s.data.map((d) => {
33
+ const annotationOpts = (_b = seriesOptions === null || seriesOptions === void 0 ? void 0 : seriesOptions.line) === null || _b === void 0 ? void 0 : _b.annotation;
34
+ const points = [];
35
+ for (let j = 0; j < s.data.length; j++) {
36
+ const d = s.data[j];
33
37
  const yValue = getYValue({
34
38
  point: d,
35
39
  points: s.data,
36
40
  yAxis: seriesYAxis,
37
41
  yScale: seriesYScale,
38
42
  });
39
- return {
43
+ points.push({
40
44
  x: getXValue({ point: d, points: s.data, xAxis, xScale }),
41
45
  y: yValue === null ? null : yAxisTop + yValue,
42
- active: true,
46
+ color: (_d = (_c = d.marker) === null || _c === void 0 ? void 0 : _c.color) !== null && _d !== void 0 ? _d : d.color,
43
47
  data: d,
44
48
  series: s,
45
- };
46
- });
49
+ annotation: d.annotation && !isRangeSlider
50
+ ? await prepareAnnotation({
51
+ annotation: d.annotation,
52
+ optionsLabel: annotationOpts === null || annotationOpts === void 0 ? void 0 : annotationOpts.label,
53
+ optionsPopup: annotationOpts === null || annotationOpts === void 0 ? void 0 : annotationOpts.popup,
54
+ })
55
+ : undefined,
56
+ });
57
+ }
47
58
  let htmlElements = [];
48
59
  let svgLabels = [];
49
60
  if (s.dataLabels.enabled && !isRangeSlider) {
@@ -64,7 +75,7 @@ export const prepareLineData = async (args) => {
64
75
  if (point.y !== null &&
65
76
  point.x !== null &&
66
77
  !isOutsideBounds(point.x, point.y)) {
67
- const labelValue = (_b = point.data.label) !== null && _b !== void 0 ? _b : point.data.y;
78
+ const labelValue = (_e = point.data.label) !== null && _e !== void 0 ? _e : point.data.y;
68
79
  const text = getFormattedValue(Object.assign({ value: labelValue }, s.dataLabels));
69
80
  const labelSize = await getTextSize(text);
70
81
  const style = s.dataLabels.style;
@@ -112,7 +123,14 @@ export const prepareLineData = async (args) => {
112
123
  return result;
113
124
  }, []);
114
125
  }
126
+ const annotations = points.reduce((result, p) => {
127
+ if (p.annotation && p.x !== null && p.y !== null) {
128
+ result.push({ annotation: p.annotation, x: p.x, y: p.y });
129
+ }
130
+ return result;
131
+ }, []);
115
132
  const result = {
133
+ annotations,
116
134
  points,
117
135
  markers,
118
136
  svgLabels: svgLabels,
@@ -122,11 +140,11 @@ export const prepareLineData = async (args) => {
122
140
  id: s.id,
123
141
  htmlLabels: htmlElements,
124
142
  color: s.color,
125
- lineWidth: (_c = (isRangeSlider ? s.rangeSlider.lineWidth : undefined)) !== null && _c !== void 0 ? _c : s.lineWidth,
143
+ lineWidth: (_f = (isRangeSlider ? s.rangeSlider.lineWidth : undefined)) !== null && _f !== void 0 ? _f : s.lineWidth,
126
144
  dashStyle: s.dashStyle,
127
145
  linecap: s.linecap,
128
146
  linejoin: s.linejoin,
129
- opacity: (_d = (isRangeSlider ? s.rangeSlider.opacity : undefined)) !== null && _d !== void 0 ? _d : s.opacity,
147
+ opacity: (_g = (isRangeSlider ? s.rangeSlider.opacity : undefined)) !== null && _g !== void 0 ? _g : s.opacity,
130
148
  };
131
149
  acc.push(result);
132
150
  }
@@ -1,11 +1,14 @@
1
1
  import type { DashStyle, LineCap, LineJoin } from '../../../core/constants';
2
+ import type { PreparedAnnotation } from '../../../core/series/types';
2
3
  import type { HtmlItem, LabelData, LineSeriesData, LineSeriesLineBaseStyle } from '../../../types';
3
4
  import type { PreparedLineSeries } from '../../useSeries/types';
5
+ import type { AnnotationAnchor } from '../annotation';
4
6
  export type PointData = {
5
7
  x: number | null;
6
8
  y: number | null;
7
9
  data: LineSeriesData;
8
10
  series: PreparedLineSeries;
11
+ annotation?: PreparedAnnotation;
9
12
  color?: string;
10
13
  };
11
14
  export type MarkerPointData = PointData & {
@@ -19,6 +22,7 @@ export type MarkerData = {
19
22
  clipped: boolean;
20
23
  };
21
24
  export type PreparedLineData = {
25
+ annotations: AnnotationAnchor[];
22
26
  id: string;
23
27
  points: PointData[];
24
28
  markers: MarkerData[];
@@ -24,6 +24,8 @@ export interface HtmlItem {
24
24
  height: number;
25
25
  };
26
26
  style?: BaseTextStyle & React.CSSProperties;
27
+ /** Coordinate space for positioning: 'plot' uses the plot area origin, 'chart' uses the full chart origin. Defaults to 'plot'. */
28
+ scope?: 'plot' | 'chart';
27
29
  }
28
30
  export interface ShapeDataWithLabels {
29
31
  svgLabels: LabelData[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/charts",
3
- "version": "1.44.0",
3
+ "version": "1.46.0",
4
4
  "description": "A flexible JavaScript library for data visualization and chart rendering using React",
5
5
  "license": "MIT",
6
6
  "main": "dist/cjs/index.js",
@@ -96,7 +96,7 @@
96
96
  "@gravity-ui/prettier-config": "^1.1.0",
97
97
  "@gravity-ui/stylelint-config": "^4.0.1",
98
98
  "@gravity-ui/tsconfig": "^1.0.0",
99
- "@gravity-ui/uikit": "^7.4.0",
99
+ "@gravity-ui/uikit": "^7.18.0",
100
100
  "@playwright/experimental-ct-react": "^1.56.1",
101
101
  "@playwright/test": "^1.56.1",
102
102
  "@storybook/addon-a11y": "^10.2.16",