@gravity-ui/charts 1.37.1 → 1.38.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 (43) hide show
  1. package/dist/cjs/components/ChartInner/index.js +3 -2
  2. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +24 -26
  3. package/dist/cjs/components/ChartInner/useChartInnerProps.js +58 -21
  4. package/dist/cjs/components/Legend/index.d.ts +2 -1
  5. package/dist/cjs/components/Legend/index.js +17 -16
  6. package/dist/cjs/hooks/useAxis/index.d.ts +2 -1
  7. package/dist/cjs/hooks/useAxis/index.js +9 -2
  8. package/dist/cjs/hooks/useChartDimensions/index.d.ts +2 -1
  9. package/dist/cjs/hooks/useChartDimensions/index.js +27 -13
  10. package/dist/cjs/hooks/useChartOptions/tooltip.d.ts +5 -0
  11. package/dist/cjs/hooks/useChartOptions/tooltip.js +2 -2
  12. package/dist/cjs/hooks/useRangeSlider/index.js +2 -1
  13. package/dist/cjs/hooks/useRangeSlider/types.d.ts +2 -1
  14. package/dist/cjs/hooks/useSeries/prepare-legend.d.ts +4 -2
  15. package/dist/cjs/hooks/useSeries/prepare-legend.js +76 -55
  16. package/dist/cjs/hooks/useSeries/types.d.ts +1 -13
  17. package/dist/cjs/index.d.ts +1 -0
  18. package/dist/cjs/index.js +1 -0
  19. package/dist/cjs/types/chart-ui.d.ts +15 -0
  20. package/dist/cjs/utils/chart/index.js +4 -2
  21. package/dist/cjs/utils/chart/text.js +4 -6
  22. package/dist/esm/components/ChartInner/index.js +3 -2
  23. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +17 -19
  24. package/dist/esm/components/ChartInner/useChartInnerProps.js +58 -21
  25. package/dist/esm/components/Legend/index.d.ts +2 -1
  26. package/dist/esm/components/Legend/index.js +17 -16
  27. package/dist/esm/hooks/useAxis/index.d.ts +2 -1
  28. package/dist/esm/hooks/useAxis/index.js +9 -2
  29. package/dist/esm/hooks/useChartDimensions/index.d.ts +2 -1
  30. package/dist/esm/hooks/useChartDimensions/index.js +27 -13
  31. package/dist/esm/hooks/useChartOptions/tooltip.d.ts +5 -0
  32. package/dist/esm/hooks/useChartOptions/tooltip.js +2 -2
  33. package/dist/esm/hooks/useRangeSlider/index.js +2 -1
  34. package/dist/esm/hooks/useRangeSlider/types.d.ts +2 -1
  35. package/dist/esm/hooks/useSeries/prepare-legend.d.ts +4 -2
  36. package/dist/esm/hooks/useSeries/prepare-legend.js +76 -55
  37. package/dist/esm/hooks/useSeries/types.d.ts +1 -13
  38. package/dist/esm/index.d.ts +1 -0
  39. package/dist/esm/index.js +1 -0
  40. package/dist/esm/types/chart-ui.d.ts +15 -0
  41. package/dist/esm/utils/chart/index.js +4 -2
  42. package/dist/esm/utils/chart/text.js +4 -6
  43. package/package.json +1 -1
@@ -66,7 +66,8 @@ export const ChartInner = (props) => {
66
66
  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,
67
67
  dispatcher,
68
68
  htmlLayout, plotNode: plotRef.current, preparedChart,
69
- rangeSliderState, svgContainer: svgRef.current, updateZoomState,
69
+ rangeSliderState,
70
+ updateZoomState,
70
71
  zoomState }));
71
72
  const debouncedBoundsWidth = useDebouncedValue({
72
73
  value: boundsWidth,
@@ -248,7 +249,7 @@ export const ChartInner = (props) => {
248
249
  React.createElement("g", { ref: plotBeforeRef }),
249
250
  shapes,
250
251
  React.createElement("g", { ref: plotAfterRef })),
251
- ((_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, ref: rangeSliderRef, width: width, xAxis: data.xAxis, yAxis: data.yAxis })),
252
+ ((_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, ref: rangeSliderRef, width: width, xAxis: data.xAxis, yAxis: data.yAxis, legendConfig: legendConfig })),
252
253
  (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 }))));
253
254
  return (React.createElement("div", { className: b() },
254
255
  React.createElement("svg", { ref: svgRef, width: width, height: height,
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { Dispatch } from 'd3';
3
- import type { PreparedChart, PreparedLegend, RangeSliderState, ZoomState } from '../../hooks';
3
+ import type { LegendItem, PreparedChart, PreparedLegend, PreparedSeries, RangeSliderState, ZoomState } from '../../hooks';
4
+ import type { LegendConfig } from '../../types';
4
5
  import type { ChartInnerProps } from './types';
5
6
  type Props = ChartInnerProps & {
6
7
  clipPathId: string;
@@ -8,35 +9,33 @@ type Props = ChartInnerProps & {
8
9
  htmlLayout: HTMLElement | null;
9
10
  plotNode: SVGGElement | null;
10
11
  preparedChart: PreparedChart;
11
- svgContainer: SVGGElement | null;
12
12
  updateZoomState: (nextZoomState: Partial<ZoomState>) => void;
13
13
  zoomState: Partial<ZoomState>;
14
14
  rangeSliderState?: RangeSliderState;
15
15
  };
16
+ type LegendState = {
17
+ legendConfig?: LegendConfig;
18
+ legendItems: LegendItem[][];
19
+ };
20
+ export declare function useLegend({ preparedLegend, preparedChart, preparedSeries, width, height, }: {
21
+ preparedLegend: PreparedLegend | null;
22
+ preparedChart: PreparedChart;
23
+ preparedSeries: PreparedSeries[];
24
+ width: number;
25
+ height: number;
26
+ }): LegendState;
16
27
  export declare function useChartInnerProps(props: Props): {
17
- allPreparedSeries: import("../../hooks").PreparedSeries[];
28
+ allPreparedSeries: PreparedSeries[];
18
29
  boundsHeight: number;
19
30
  boundsOffsetLeft: number;
20
31
  boundsOffsetTop: number;
21
32
  boundsWidth: number;
22
33
  handleLegendItemClick: import("../../hooks").OnLegendItemClick;
23
34
  isOutsideBounds: (x: number, y: number) => boolean;
24
- legendConfig: {
25
- offset: {
26
- left: number;
27
- top: number;
28
- };
29
- pagination: {
30
- pages: {
31
- start: number;
32
- end: number;
33
- }[];
34
- } | undefined;
35
- maxWidth: number;
36
- } | undefined;
37
- legendItems: never[] | import("../../hooks").LegendItem[][];
35
+ legendConfig: LegendConfig | undefined;
36
+ legendItems: LegendItem[][];
38
37
  preparedLegend: PreparedLegend | null;
39
- preparedSeries: import("../../hooks").PreparedSeries[];
38
+ preparedSeries: PreparedSeries[];
40
39
  preparedSeriesOptions: import("../../constants").SeriesOptionsDefaults;
41
40
  preparedSplit: import("../../hooks").PreparedSplit;
42
41
  prevHeight: number | undefined;
@@ -44,13 +43,12 @@ export declare function useChartInnerProps(props: Props): {
44
43
  shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
45
44
  shapesData: import("../../hooks").ShapeData[];
46
45
  shapesReady: boolean;
47
- svgXPos: number | undefined;
48
46
  xAxis: import("../../hooks").PreparedXAxis | null;
49
47
  xScale: import("../../hooks").ChartScale | undefined;
50
- yAxis: (Omit<import("../..").ChartAxis, "type" | "labels" | "plotLines" | "plotBands"> & {
51
- type: import("../..").ChartAxisType;
52
- labels: Omit<import("../..").ChartAxisLabels, "enabled" | "style" | "padding" | "autoRotation"> & Required<Pick<import("../..").ChartAxisLabels, "margin" | "html" | "enabled" | "rotation" | "padding">> & {
53
- style: import("../..").BaseTextStyle;
48
+ yAxis: (Omit<import("../../types").ChartAxis, "type" | "labels" | "plotLines" | "plotBands"> & {
49
+ type: import("../../types").ChartAxisType;
50
+ labels: Omit<import("../../types").ChartAxisLabels, "enabled" | "style" | "padding" | "autoRotation"> & Required<Pick<import("../../types").ChartAxisLabels, "margin" | "html" | "enabled" | "rotation" | "padding">> & {
51
+ style: import("../../types").BaseTextStyle;
54
52
  rotation: number;
55
53
  height: number;
56
54
  width: number;
@@ -62,8 +60,8 @@ export declare function useChartInnerProps(props: Props): {
62
60
  width: number;
63
61
  text: string;
64
62
  margin: number;
65
- style: import("../..").BaseTextStyle;
66
- align: import("../..").ChartAxisTitleAlignment;
63
+ style: import("../../types").BaseTextStyle;
64
+ align: import("../../types").ChartAxisTitleAlignment;
67
65
  maxRowCount: number;
68
66
  rotation: number;
69
67
  maxWidth: number;
@@ -82,7 +80,7 @@ export declare function useChartInnerProps(props: Props): {
82
80
  plotIndex: number;
83
81
  plotLines: import("../../hooks").PreparedAxisPlotLine[];
84
82
  plotBands: import("../../hooks").PreparedAxisPlotBand[];
85
- crosshair: Required<import("../..").AxisCrosshair>;
83
+ crosshair: Required<import("../../types").AxisCrosshair>;
86
84
  })[];
87
85
  yScale: (import("../../hooks").ChartScale | undefined)[] | undefined;
88
86
  };
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import isEqual from 'lodash/isEqual';
2
3
  import { DEFAULT_PALETTE, SERIES_TYPE } from '../../constants';
3
4
  import { useAxis, useAxisScales, useChartDimensions, useNormalizedOriginalData, usePrevious, useSeries, useShapes, useSplit, useYAxisLabelWidth, useZoom, } from '../../hooks';
4
5
  import { getYAxisWidth } from '../../hooks/useChartDimensions/utils';
@@ -9,17 +10,18 @@ import { hasAtLeastOneSeriesDataPerPlot } from './utils';
9
10
  const CLIP_PATH_BY_SERIES_TYPE = {
10
11
  [SERIES_TYPE.Scatter]: false,
11
12
  };
12
- function getBoundsOffsetTop(args) {
13
- const { chartMarginTop, preparedLegend } = args;
13
+ function getBoundsOffsetTop({ chartMarginTop, preparedLegend, legendConfig, }) {
14
+ var _a;
14
15
  return (chartMarginTop +
15
16
  ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'top'
16
- ? preparedLegend.height + preparedLegend.margin
17
+ ? ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.height) !== null && _a !== void 0 ? _a : 0) + preparedLegend.margin
17
18
  : 0));
18
19
  }
19
20
  function getBoundsOffsetLeft(args) {
20
- const { chartMarginLeft, preparedLegend, yAxis, getYAxisWidth: getAxisWidth } = args;
21
+ var _a;
22
+ const { chartMarginLeft, preparedLegend, yAxis, getYAxisWidth: getAxisWidth, legendConfig, } = args;
21
23
  const legendOffset = (preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'left'
22
- ? preparedLegend.width + preparedLegend.margin
24
+ ? ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.width) !== null && _a !== void 0 ? _a : 0) + preparedLegend.margin
23
25
  : 0;
24
26
  const leftAxisWidth = yAxis.reduce((acc, axis) => {
25
27
  if (axis.position !== 'left') {
@@ -33,9 +35,47 @@ function getBoundsOffsetLeft(args) {
33
35
  }, 0);
34
36
  return chartMarginLeft + legendOffset + leftAxisWidth;
35
37
  }
38
+ export function useLegend({ preparedLegend, preparedChart, preparedSeries, width, height, }) {
39
+ const [legendState, setLegend] = React.useState({
40
+ legendConfig: undefined,
41
+ legendItems: [],
42
+ });
43
+ const legendStateRunRef = React.useRef(0);
44
+ const prevLegendStateValue = React.useRef(legendState);
45
+ const legendStateReady = React.useRef(false);
46
+ React.useEffect(() => {
47
+ legendStateRunRef.current++;
48
+ legendStateReady.current = false;
49
+ (async function () {
50
+ const currentRun = legendStateRunRef.current;
51
+ if (!preparedLegend) {
52
+ return;
53
+ }
54
+ const newStateValue = await getLegendComponents({
55
+ chartWidth: width,
56
+ chartHeight: height,
57
+ chartMargin: preparedChart.margin,
58
+ series: preparedSeries,
59
+ preparedLegend,
60
+ });
61
+ if (legendStateRunRef.current === currentRun) {
62
+ if (!isEqual(prevLegendStateValue.current, newStateValue)) {
63
+ setLegend(newStateValue);
64
+ prevLegendStateValue.current = newStateValue;
65
+ }
66
+ legendStateReady.current = true;
67
+ }
68
+ })();
69
+ }, [height, preparedChart.margin, preparedLegend, preparedSeries, width]);
70
+ return legendStateReady.current
71
+ ? legendState
72
+ : {
73
+ legendConfig: undefined,
74
+ legendItems: [],
75
+ };
76
+ }
36
77
  export function useChartInnerProps(props) {
37
- var _a;
38
- const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, preparedChart, rangeSliderState, svgContainer, width, updateZoomState, zoomState, } = props;
78
+ const { clipPathId, data, dispatcher, height, htmlLayout, plotNode, preparedChart, rangeSliderState, width, updateZoomState, zoomState, } = props;
39
79
  const prevWidth = usePrevious(width);
40
80
  const prevHeight = usePrevious(height);
41
81
  const colors = React.useMemo(() => {
@@ -76,21 +116,17 @@ export function useChartInnerProps(props) {
76
116
  zoomState: effectiveZoomState,
77
117
  });
78
118
  }, [allPreparedSeries, normalizedXAxis, normalizedYAxis, effectiveZoomState]);
79
- const { legendConfig, legendItems } = React.useMemo(() => {
80
- if (!preparedLegend) {
81
- return { legendConfig: undefined, legendItems: [] };
82
- }
83
- return getLegendComponents({
84
- chartWidth: width,
85
- chartHeight: height,
86
- chartMargin: preparedChart.margin,
87
- series: preparedSeries,
88
- preparedLegend,
89
- });
90
- }, [width, height, preparedChart.margin, preparedSeries, preparedLegend]);
119
+ const { legendConfig, legendItems } = useLegend({
120
+ width,
121
+ height,
122
+ preparedChart,
123
+ preparedSeries,
124
+ preparedLegend,
125
+ });
91
126
  const { xAxis, yAxis, setAxes } = useAxis({
92
127
  height,
93
128
  preparedChart,
129
+ legendConfig,
94
130
  preparedLegend,
95
131
  preparedSeries,
96
132
  preparedSeriesOptions,
@@ -106,6 +142,7 @@ export function useChartInnerProps(props) {
106
142
  preparedYAxis: yAxis,
107
143
  preparedXAxis: xAxis,
108
144
  width,
145
+ legendConfig,
109
146
  });
110
147
  const preparedSplit = useSplit({ split: data.split, boundsHeight, chartWidth: width });
111
148
  const { xScale, yScale } = useAxisScales({
@@ -166,6 +203,7 @@ export function useChartInnerProps(props) {
166
203
  const boundsOffsetTop = getBoundsOffsetTop({
167
204
  chartMarginTop: preparedChart.margin.top,
168
205
  preparedLegend,
206
+ legendConfig,
169
207
  });
170
208
  // We need to calculate the width of each left axis because the first axis can be hidden
171
209
  const boundsOffsetLeft = getBoundsOffsetLeft({
@@ -173,8 +211,8 @@ export function useChartInnerProps(props) {
173
211
  preparedLegend,
174
212
  yAxis,
175
213
  getYAxisWidth,
214
+ legendConfig,
176
215
  });
177
- const { x } = (_a = svgContainer === null || svgContainer === void 0 ? void 0 : svgContainer.getBoundingClientRect()) !== null && _a !== void 0 ? _a : {};
178
216
  return {
179
217
  allPreparedSeries,
180
218
  boundsHeight,
@@ -194,7 +232,6 @@ export function useChartInnerProps(props) {
194
232
  shapes,
195
233
  shapesData,
196
234
  shapesReady,
197
- svgXPos: x,
198
235
  xAxis,
199
236
  xScale,
200
237
  yAxis,
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
- import type { LegendConfig, LegendItem, OnLegendItemClick, PreparedLegend, PreparedSeries } from '../../hooks';
2
+ import type { LegendItem, OnLegendItemClick, PreparedLegend, PreparedSeries } from '../../hooks';
3
+ import type { LegendConfig } from '../../types';
3
4
  import './styles.css';
4
5
  type Props = {
5
6
  chartSeries: PreparedSeries[];
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { scaleLinear, select, symbol } from 'd3';
3
3
  import { CONTINUOUS_LEGEND_SIZE } from '../../constants';
4
4
  import { formatNumber } from '../../libs';
5
- import { block, createGradientRect, getContinuesColorFn, getLabelsSize, getSymbol, getUniqId, handleOverflowingText, } from '../../utils';
5
+ import { block, createGradientRect, getContinuesColorFn, getLabelsSize, getSymbol, getUniqId, } from '../../utils';
6
6
  import { axisBottom } from '../../utils/chart/axis-generators';
7
7
  import { appendLinePathElement } from '../utils';
8
8
  import './styles.css';
@@ -163,7 +163,6 @@ export const Legend = (props) => {
163
163
  : items;
164
164
  const legendLineHeights = [];
165
165
  pageItems.forEach((line) => {
166
- var _a;
167
166
  const legendLine = svgElement.append('g').attr('class', b('line'));
168
167
  const htmlLegendLine = htmlContainer === null || htmlContainer === void 0 ? void 0 : htmlContainer.append('div').style('position', 'absolute');
169
168
  const legendItemTemplate = legendLine
@@ -214,9 +213,8 @@ export const Legend = (props) => {
214
213
  .on('click', function (e, d) {
215
214
  onItemClick({ id: d.id, name: d.name, metaKey: e.metaKey });
216
215
  onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate();
217
- })[legend.html ? 'html' : 'text'](function (d) {
218
- return d.name;
219
- });
216
+ })
217
+ .html((d) => d.text);
220
218
  }
221
219
  else {
222
220
  legendItemTemplate
@@ -231,19 +229,22 @@ export const Legend = (props) => {
231
229
  const mods = { selected: d.visible, unselected: !d.visible };
232
230
  return b('item-text', mods);
233
231
  })
234
- .html(function (d) {
235
- return ('name' in d && d.name);
236
- })
237
- .style('font-size', legend.itemStyle.fontSize)
238
- .each((d, index, nodes) => {
239
- if (d.overflowed) {
240
- handleOverflowingText(nodes[index], d.textWidth);
232
+ .html((d) => d.text)
233
+ .style('font-size', legend.itemStyle.fontSize);
234
+ }
235
+ let contentWidth = 0;
236
+ if (legend.html) {
237
+ contentWidth = getXPosition(line.length) - legend.itemDistance;
238
+ }
239
+ else {
240
+ contentWidth = line.reduce((sum, l, index) => {
241
+ sum += l.textWidth + l.symbol.width + l.symbol.padding;
242
+ if (index > 0) {
243
+ sum += legend.itemDistance;
241
244
  }
242
- });
245
+ return sum;
246
+ }, 0);
243
247
  }
244
- const contentWidth = (legend.html
245
- ? getXPosition(line.length) - legend.itemDistance
246
- : (_a = legendLine.node()) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect().width) || 0;
247
248
  let left = 0;
248
249
  switch (legend.justifyContent) {
249
250
  case 'center': {
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
- import type { ChartXAxis, ChartYAxis } from '../../types';
2
+ import type { ChartXAxis, ChartYAxis, LegendConfig } from '../../types';
3
3
  import type { PreparedChart } from '../useChartOptions/types';
4
4
  import type { PreparedLegend, PreparedSeries, PreparedSeriesOptions } from '../useSeries/types';
5
5
  import type { AxesState } from './types';
6
6
  interface UseAxesProps {
7
7
  height: number;
8
8
  preparedChart: PreparedChart;
9
+ legendConfig: LegendConfig | undefined;
9
10
  preparedLegend: PreparedLegend | null;
10
11
  preparedSeries: PreparedSeries[];
11
12
  preparedSeriesOptions: PreparedSeriesOptions;
@@ -4,15 +4,20 @@ import { getWidthOccupiedByYAxis } from '../useChartDimensions/utils';
4
4
  import { getPreparedXAxis } from './x-axis';
5
5
  import { getPreparedYAxis } from './y-axis';
6
6
  export function useAxis(props) {
7
- const { boundsHeight, height, preparedChart, preparedLegend, preparedSeries, preparedSeriesOptions, width, xAxis, yAxis, } = props;
7
+ const { boundsHeight, height, preparedChart, legendConfig, preparedLegend, preparedSeries, preparedSeriesOptions, width, xAxis, yAxis, } = props;
8
8
  const [axesState, setAxes] = React.useState({ xAxis: null, yAxis: [] });
9
9
  const axesStateRunRef = React.useRef(0);
10
10
  const prevAxesStateValue = React.useRef(axesState);
11
11
  const axesStateReady = React.useRef(false);
12
12
  React.useEffect(() => {
13
+ const shouldWaitForLegendReady = !preparedLegend || ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && !legendConfig);
14
+ if (shouldWaitForLegendReady) {
15
+ return;
16
+ }
13
17
  axesStateRunRef.current++;
14
18
  axesStateReady.current = false;
15
19
  (async function () {
20
+ var _a, _b;
16
21
  const currentRun = axesStateRunRef.current;
17
22
  const seriesData = preparedSeries.filter((s) => s.visible);
18
23
  const estimatedPreparedYAxis = await getPreparedYAxis({
@@ -41,7 +46,8 @@ export function useAxis(props) {
41
46
  (preparedXAxis.rangeSlider.enabled
42
47
  ? preparedXAxis.rangeSlider.height + preparedXAxis.rangeSlider.margin
43
48
  : 0) +
44
- (preparedLegend ? preparedLegend.height + preparedLegend.margin : 0) +
49
+ ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.height) !== null && _a !== void 0 ? _a : 0) +
50
+ ((_b = preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.margin) !== null && _b !== void 0 ? _b : 0) +
45
51
  preparedChart.margin.top +
46
52
  preparedChart.margin.bottom);
47
53
  }
@@ -65,6 +71,7 @@ export function useAxis(props) {
65
71
  boundsHeight,
66
72
  height,
67
73
  preparedChart.margin,
74
+ legendConfig,
68
75
  preparedLegend,
69
76
  preparedSeries,
70
77
  preparedSeriesOptions,
@@ -1,5 +1,5 @@
1
1
  import type { PreparedLegend, PreparedSeries, PreparedXAxis, PreparedYAxis } from '../../hooks';
2
- import type { ChartMargin } from '../../types';
2
+ import type { ChartMargin, LegendConfig } from '../../types';
3
3
  export { getBoundsWidth } from './utils';
4
4
  type Args = {
5
5
  height: number;
@@ -9,6 +9,7 @@ type Args = {
9
9
  preparedXAxis: PreparedXAxis | null;
10
10
  preparedYAxis: PreparedYAxis[] | null;
11
11
  width: number;
12
+ legendConfig: LegendConfig | undefined;
12
13
  };
13
14
  export declare const useChartDimensions: (args: Args) => {
14
15
  boundsWidth: number;
@@ -3,10 +3,11 @@ import { isAxisRelatedSeries } from '../../utils';
3
3
  import { getBoundsWidth } from './utils';
4
4
  export { getBoundsWidth } from './utils';
5
5
  const getBottomOffset = (args) => {
6
- const { hasAxisRelatedSeries, preparedLegend, preparedXAxis } = args;
6
+ var _a;
7
+ const { hasAxisRelatedSeries, preparedLegend, legendConfig, preparedXAxis } = args;
7
8
  let result = 0;
8
9
  if ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'bottom') {
9
- result += preparedLegend.height + preparedLegend.margin;
10
+ result += ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.height) !== null && _a !== void 0 ? _a : 0) + preparedLegend.margin;
10
11
  }
11
12
  if (!(preparedXAxis === null || preparedXAxis === void 0 ? void 0 : preparedXAxis.visible)) {
12
13
  return result;
@@ -24,26 +25,29 @@ const getBottomOffset = (args) => {
24
25
  }
25
26
  return result;
26
27
  };
27
- const getTopOffset = ({ preparedLegend }) => {
28
+ const getTopOffset = ({ preparedLegend, legendConfig, }) => {
29
+ var _a;
28
30
  if ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'top') {
29
- return preparedLegend.height + preparedLegend.margin;
31
+ return ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.height) !== null && _a !== void 0 ? _a : 0) + preparedLegend.margin;
30
32
  }
31
33
  return 0;
32
34
  };
33
- const getRightOffset = ({ preparedLegend }) => {
35
+ const getRightOffset = ({ preparedLegend, legendConfig, }) => {
36
+ var _a;
34
37
  if ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'right') {
35
- return preparedLegend.width + preparedLegend.margin;
38
+ return ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.width) !== null && _a !== void 0 ? _a : 0) + preparedLegend.margin;
36
39
  }
37
40
  return 0;
38
41
  };
39
- const getLeftOffset = ({ preparedLegend }) => {
42
+ const getLeftOffset = ({ preparedLegend, legendConfig, }) => {
43
+ var _a;
40
44
  if ((preparedLegend === null || preparedLegend === void 0 ? void 0 : preparedLegend.enabled) && preparedLegend.position === 'left') {
41
- return preparedLegend.width + preparedLegend.margin;
45
+ return ((_a = legendConfig === null || legendConfig === void 0 ? void 0 : legendConfig.width) !== null && _a !== void 0 ? _a : 0) + preparedLegend.margin;
42
46
  }
43
47
  return 0;
44
48
  };
45
49
  export const useChartDimensions = (args) => {
46
- const { height, margin, preparedLegend, preparedSeries, preparedXAxis, preparedYAxis, width } = args;
50
+ const { height, margin, preparedLegend, preparedSeries, preparedXAxis, preparedYAxis, width, legendConfig, } = args;
47
51
  return React.useMemo(() => {
48
52
  const hasAxisRelatedSeries = preparedSeries.some(isAxisRelatedSeries);
49
53
  const boundsWidth = getBoundsWidth({ chartWidth: width, chartMargin: margin, preparedYAxis });
@@ -51,12 +55,22 @@ export const useChartDimensions = (args) => {
51
55
  hasAxisRelatedSeries,
52
56
  preparedLegend,
53
57
  preparedXAxis,
58
+ legendConfig,
54
59
  });
55
- const topOffset = getTopOffset({ preparedLegend });
56
- const rightOffset = getRightOffset({ preparedLegend });
57
- const leftOffset = getLeftOffset({ preparedLegend });
60
+ const topOffset = getTopOffset({ preparedLegend, legendConfig });
61
+ const rightOffset = getRightOffset({ preparedLegend, legendConfig });
62
+ const leftOffset = getLeftOffset({ preparedLegend, legendConfig });
58
63
  const boundsHeight = height - margin.top - margin.bottom - bottomOffset - topOffset;
59
64
  const adjustedBoundsWidth = boundsWidth - rightOffset - leftOffset;
60
65
  return { boundsWidth: adjustedBoundsWidth, boundsHeight };
61
- }, [height, margin, preparedLegend, preparedSeries, preparedXAxis, preparedYAxis, width]);
66
+ }, [
67
+ height,
68
+ margin,
69
+ preparedLegend,
70
+ legendConfig,
71
+ preparedSeries,
72
+ preparedXAxis,
73
+ preparedYAxis,
74
+ width,
75
+ ]);
62
76
  };
@@ -1,5 +1,10 @@
1
1
  import type { ChartData, ChartSeries, ChartXAxis, ChartYAxis } from '../../types';
2
2
  import type { PreparedTooltip } from './types';
3
+ export declare function getDefaultTooltipHeaderFormat({ seriesData, yAxes, xAxis, }: {
4
+ seriesData: ChartSeries[];
5
+ yAxes?: ChartYAxis[];
6
+ xAxis?: ChartXAxis;
7
+ }): import("../../types").ValueFormat | undefined;
3
8
  export declare const getPreparedTooltip: (args: {
4
9
  tooltip: ChartData["tooltip"];
5
10
  seriesData: ChartSeries[];
@@ -1,7 +1,7 @@
1
1
  import get from 'lodash/get';
2
2
  import { getDefaultValueFormat } from '../../components/Tooltip/DefaultTooltipContent/utils';
3
3
  import { getDomainDataXBySeries, getDomainDataYBySeries, getMinSpaceBetween } from '../../utils';
4
- function getDefaultHeaderFormat({ seriesData, yAxes, xAxis, }) {
4
+ export function getDefaultTooltipHeaderFormat({ seriesData, yAxes, xAxis, }) {
5
5
  if (seriesData.every((item) => ['pie', 'treemap', 'waterfall', 'sankey', 'radar', 'heatmap', 'funnel'].includes(item.type))) {
6
6
  return undefined;
7
7
  }
@@ -17,5 +17,5 @@ function getDefaultHeaderFormat({ seriesData, yAxes, xAxis, }) {
17
17
  export const getPreparedTooltip = (args) => {
18
18
  var _a, _b;
19
19
  const { tooltip, seriesData, yAxes, xAxis } = args;
20
- return Object.assign(Object.assign({}, tooltip), { enabled: get(tooltip, 'enabled', true), throttle: (_a = tooltip === null || tooltip === void 0 ? void 0 : tooltip.throttle) !== null && _a !== void 0 ? _a : 0, headerFormat: (_b = tooltip === null || tooltip === void 0 ? void 0 : tooltip.headerFormat) !== null && _b !== void 0 ? _b : getDefaultHeaderFormat({ seriesData, yAxes, xAxis }) });
20
+ return Object.assign(Object.assign({}, tooltip), { enabled: get(tooltip, 'enabled', true), throttle: (_a = tooltip === null || tooltip === void 0 ? void 0 : tooltip.throttle) !== null && _a !== void 0 ? _a : 0, headerFormat: (_b = tooltip === null || tooltip === void 0 ? void 0 : tooltip.headerFormat) !== null && _b !== void 0 ? _b : getDefaultTooltipHeaderFormat({ seriesData, yAxes, xAxis }) });
21
21
  };
@@ -17,7 +17,7 @@ const CLIP_PATH_BY_SERIES_TYPE = {
17
17
  [SERIES_TYPE.Scatter]: true,
18
18
  };
19
19
  export function useRangeSlider(props) {
20
- const { boundsWidth, boundsOffsetLeft, clipPathId, height, htmlLayout, onUpdate, preparedChart, preparedLegend, preparedSeries, preparedSeriesOptions, preparedRangeSlider, rangeSliderState, width, xAxis, yAxis, } = props;
20
+ const { boundsWidth, boundsOffsetLeft, clipPathId, height, htmlLayout, onUpdate, preparedChart, preparedLegend, legendConfig, preparedSeries, preparedSeriesOptions, preparedRangeSlider, rangeSliderState, width, xAxis, yAxis, } = props;
21
21
  const filteredPreparedSeries = React.useMemo(() => {
22
22
  return preparedSeries.filter((s) => {
23
23
  if ('rangeSlider' in s && !s.rangeSlider.visible) {
@@ -31,6 +31,7 @@ export function useRangeSlider(props) {
31
31
  height,
32
32
  preparedChart,
33
33
  preparedLegend,
34
+ legendConfig,
34
35
  preparedSeries,
35
36
  preparedSeriesOptions,
36
37
  width,
@@ -1,4 +1,4 @@
1
- import type { ChartXAxis, ChartYAxis } from '../../types';
1
+ import type { ChartXAxis, ChartYAxis, LegendConfig } from '../../types';
2
2
  import type { PreparedRangeSlider, PreparedXAxis, PreparedYAxis } from '../useAxis/types';
3
3
  import type { ChartScale } from '../useAxisScales/types';
4
4
  import type { BrushSelection, UseBrushProps } from '../useBrush/types';
@@ -16,6 +16,7 @@ export interface RangeSliderProps {
16
16
  onUpdate: (nextRangeSliderState?: RangeSliderState) => void;
17
17
  preparedChart: PreparedChart;
18
18
  preparedLegend: PreparedLegend | null;
19
+ legendConfig: LegendConfig | undefined;
19
20
  preparedRangeSlider: PreparedRangeSlider;
20
21
  preparedSeries: PreparedSeries[];
21
22
  preparedSeriesOptions: PreparedSeriesOptions;
@@ -11,7 +11,7 @@ export declare function getLegendComponents(args: {
11
11
  chartMargin: PreparedChart['margin'];
12
12
  series: PreparedSeries[];
13
13
  preparedLegend: PreparedLegend;
14
- }): {
14
+ }): Promise<{
15
15
  legendConfig: {
16
16
  offset: {
17
17
  left: number;
@@ -24,6 +24,8 @@ export declare function getLegendComponents(args: {
24
24
  }[];
25
25
  } | undefined;
26
26
  maxWidth: number;
27
+ height: number;
28
+ width: number;
27
29
  };
28
30
  legendItems: LegendItem[][];
29
- };
31
+ }>;