@gravity-ui/charts 1.20.0 → 1.22.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 (87) hide show
  1. package/dist/cjs/components/AxisY/AxisY.js +8 -1
  2. package/dist/cjs/components/AxisY/prepare-axis-data.js +39 -12
  3. package/dist/cjs/components/AxisY/types.d.ts +3 -0
  4. package/dist/cjs/components/ChartInner/index.js +23 -8
  5. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +24 -13
  6. package/dist/cjs/components/ChartInner/useChartInnerProps.js +41 -107
  7. package/dist/cjs/components/ChartInner/useChartInnerState.d.ts +4 -2
  8. package/dist/cjs/components/ChartInner/useChartInnerState.js +9 -0
  9. package/dist/cjs/components/ChartInner/utils.d.ts +12 -3
  10. package/dist/cjs/components/ChartInner/utils.js +61 -1
  11. package/dist/cjs/components/Title/index.d.ts +0 -1
  12. package/dist/cjs/components/Title/index.js +6 -4
  13. package/dist/cjs/hooks/index.d.ts +7 -3
  14. package/dist/cjs/hooks/index.js +7 -3
  15. package/dist/cjs/hooks/useAxis/index.d.ts +19 -0
  16. package/dist/cjs/hooks/useAxis/index.js +63 -0
  17. package/dist/cjs/hooks/useChartOptions/chart.js +6 -1
  18. package/dist/cjs/hooks/useChartOptions/index.d.ts +1 -4
  19. package/dist/cjs/hooks/useChartOptions/index.js +2 -5
  20. package/dist/cjs/hooks/useChartOptions/title.js +4 -2
  21. package/dist/cjs/hooks/useChartOptions/types.d.ts +0 -1
  22. package/dist/cjs/hooks/useChartOptions/utils.d.ts +1 -4
  23. package/dist/cjs/hooks/useChartOptions/utils.js +29 -6
  24. package/dist/cjs/hooks/useChartOptions/x-axis.js +2 -2
  25. package/dist/cjs/hooks/useChartOptions/y-axis.js +10 -11
  26. package/dist/cjs/hooks/useNormalizedOriginalData/index.d.ts +40 -0
  27. package/dist/cjs/hooks/useNormalizedOriginalData/index.js +33 -0
  28. package/dist/cjs/hooks/useSeries/index.d.ts +0 -9
  29. package/dist/cjs/hooks/useSeries/index.js +0 -18
  30. package/dist/cjs/hooks/useSeries/types.d.ts +3 -0
  31. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +4 -0
  32. package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +4 -0
  33. package/dist/cjs/hooks/useShapes/scatter/prepare-data.d.ts +2 -2
  34. package/dist/cjs/hooks/useShapes/scatter/prepare-data.js +40 -5
  35. package/dist/cjs/types/chart/axis.d.ts +20 -2
  36. package/dist/cjs/types/chart/zoom.d.ts +29 -0
  37. package/dist/cjs/utils/chart/get-closest-data.js +1 -1
  38. package/dist/cjs/utils/chart/series/sorting.d.ts +2 -2
  39. package/dist/cjs/utils/chart/series/sorting.js +3 -3
  40. package/dist/cjs/utils/chart/text.js +24 -21
  41. package/dist/cjs/utils/chart/zoom.d.ts +7 -6
  42. package/dist/cjs/utils/chart/zoom.js +14 -6
  43. package/dist/esm/components/AxisY/AxisY.js +8 -1
  44. package/dist/esm/components/AxisY/prepare-axis-data.js +39 -12
  45. package/dist/esm/components/AxisY/types.d.ts +3 -0
  46. package/dist/esm/components/ChartInner/index.js +23 -8
  47. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +23 -12
  48. package/dist/esm/components/ChartInner/useChartInnerProps.js +41 -107
  49. package/dist/esm/components/ChartInner/useChartInnerState.d.ts +4 -2
  50. package/dist/esm/components/ChartInner/useChartInnerState.js +9 -0
  51. package/dist/esm/components/ChartInner/utils.d.ts +12 -3
  52. package/dist/esm/components/ChartInner/utils.js +61 -1
  53. package/dist/esm/components/Title/index.d.ts +0 -1
  54. package/dist/esm/components/Title/index.js +6 -4
  55. package/dist/esm/hooks/index.d.ts +7 -3
  56. package/dist/esm/hooks/index.js +7 -3
  57. package/dist/esm/hooks/useAxis/index.d.ts +19 -0
  58. package/dist/esm/hooks/useAxis/index.js +63 -0
  59. package/dist/esm/hooks/useChartOptions/chart.js +6 -1
  60. package/dist/esm/hooks/useChartOptions/index.d.ts +1 -4
  61. package/dist/esm/hooks/useChartOptions/index.js +2 -5
  62. package/dist/esm/hooks/useChartOptions/title.js +4 -2
  63. package/dist/esm/hooks/useChartOptions/types.d.ts +0 -1
  64. package/dist/esm/hooks/useChartOptions/utils.d.ts +1 -4
  65. package/dist/esm/hooks/useChartOptions/utils.js +29 -6
  66. package/dist/esm/hooks/useChartOptions/x-axis.js +2 -2
  67. package/dist/esm/hooks/useChartOptions/y-axis.js +10 -11
  68. package/dist/esm/hooks/useNormalizedOriginalData/index.d.ts +40 -0
  69. package/dist/esm/hooks/useNormalizedOriginalData/index.js +33 -0
  70. package/dist/esm/hooks/useSeries/index.d.ts +0 -9
  71. package/dist/esm/hooks/useSeries/index.js +0 -18
  72. package/dist/esm/hooks/useSeries/types.d.ts +3 -0
  73. package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +4 -0
  74. package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +4 -0
  75. package/dist/esm/hooks/useShapes/scatter/prepare-data.d.ts +2 -2
  76. package/dist/esm/hooks/useShapes/scatter/prepare-data.js +40 -5
  77. package/dist/esm/types/chart/axis.d.ts +20 -2
  78. package/dist/esm/types/chart/zoom.d.ts +29 -0
  79. package/dist/esm/utils/chart/get-closest-data.js +1 -1
  80. package/dist/esm/utils/chart/series/sorting.d.ts +2 -2
  81. package/dist/esm/utils/chart/series/sorting.js +3 -3
  82. package/dist/esm/utils/chart/text.js +24 -21
  83. package/dist/esm/utils/chart/zoom.d.ts +7 -6
  84. package/dist/esm/utils/chart/zoom.js +14 -6
  85. package/package.json +7 -16
  86. package/dist/cjs/components/Title/styles.css +0 -5
  87. package/dist/esm/components/Title/styles.css +0 -5
@@ -1,12 +1,16 @@
1
+ export * from './useAxis';
2
+ export * from './useAxisScales';
1
3
  export * from './useChartDimensions';
2
4
  export * from './useChartOptions';
3
5
  export * from './useChartOptions/types';
4
- export * from './useAxisScales';
6
+ export * from './useCrosshair';
7
+ export * from './useNormalizedOriginalData';
5
8
  export * from './usePrevious';
6
9
  export * from './useSeries';
7
10
  export * from './useSeries/types';
8
11
  export * from './useShapes';
9
- export * from './useTooltip';
10
12
  export * from './useSplit';
11
13
  export * from './useSplit/types';
12
- export * from './useCrosshair';
14
+ export * from './useTooltip';
15
+ export * from './useZoom';
16
+ export * from './useZoom/types';
@@ -1,12 +1,16 @@
1
+ export * from './useAxis';
2
+ export * from './useAxisScales';
1
3
  export * from './useChartDimensions';
2
4
  export * from './useChartOptions';
3
5
  export * from './useChartOptions/types';
4
- export * from './useAxisScales';
6
+ export * from './useCrosshair';
7
+ export * from './useNormalizedOriginalData';
5
8
  export * from './usePrevious';
6
9
  export * from './useSeries';
7
10
  export * from './useSeries/types';
8
11
  export * from './useShapes';
9
- export * from './useTooltip';
10
12
  export * from './useSplit';
11
13
  export * from './useSplit/types';
12
- export * from './useCrosshair';
14
+ export * from './useTooltip';
15
+ export * from './useZoom';
16
+ export * from './useZoom/types';
@@ -0,0 +1,19 @@
1
+ import type { ChartXAxis, ChartYAxis } from '../../types';
2
+ import type { PreparedAxis, PreparedChart } from '../useChartOptions/types';
3
+ import type { PreparedLegend, PreparedSeries, PreparedSeriesOptions } from '../useSeries/types';
4
+ interface UseAxesProps {
5
+ height: number;
6
+ preparedChart: PreparedChart;
7
+ preparedLegend: PreparedLegend | null;
8
+ preparedSeries: PreparedSeries[];
9
+ preparedSeriesOptions: PreparedSeriesOptions;
10
+ width: number;
11
+ boundsHeight?: number;
12
+ xAxis?: ChartXAxis;
13
+ yAxis?: ChartYAxis[];
14
+ }
15
+ export declare function useAxis(props: UseAxesProps): {
16
+ xAxis: PreparedAxis | null;
17
+ yAxis: PreparedAxis[];
18
+ };
19
+ export {};
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import isEqual from 'lodash/isEqual';
3
+ import { getPreparedXAxis } from '../useChartOptions/x-axis';
4
+ import { getPreparedYAxis } from '../useChartOptions/y-axis';
5
+ export function useAxis(props) {
6
+ const { boundsHeight, height, preparedChart, preparedLegend, preparedSeries, preparedSeriesOptions, width, xAxis, yAxis, } = props;
7
+ const [axesState, setValue] = React.useState({ xAxis: null, yAxis: [] });
8
+ const axesStateRunRef = React.useRef(0);
9
+ const prevAxesStateValue = React.useRef(axesState);
10
+ const axesStateReady = React.useRef(false);
11
+ React.useEffect(() => {
12
+ axesStateRunRef.current++;
13
+ axesStateReady.current = false;
14
+ (async function () {
15
+ const currentRun = axesStateRunRef.current;
16
+ const seriesData = preparedSeries.filter((s) => s.visible);
17
+ const preparedXAxis = await getPreparedXAxis({
18
+ xAxis,
19
+ width,
20
+ seriesData,
21
+ seriesOptions: preparedSeriesOptions,
22
+ });
23
+ let estimatedBoundsHeight = boundsHeight !== null && boundsHeight !== void 0 ? boundsHeight : height;
24
+ if (preparedXAxis && typeof boundsHeight !== 'number') {
25
+ estimatedBoundsHeight =
26
+ height -
27
+ (preparedXAxis.title.height +
28
+ preparedXAxis.title.margin +
29
+ preparedXAxis.labels.margin +
30
+ preparedXAxis.labels.height +
31
+ (preparedLegend ? preparedLegend.height + preparedLegend.margin : 0) +
32
+ preparedChart.margin.top +
33
+ preparedChart.margin.bottom);
34
+ }
35
+ const preparedYAxis = await getPreparedYAxis({
36
+ height,
37
+ boundsHeight: estimatedBoundsHeight,
38
+ width,
39
+ seriesData,
40
+ yAxis,
41
+ });
42
+ const newStateValue = { xAxis: preparedXAxis, yAxis: preparedYAxis };
43
+ if (axesStateRunRef.current === currentRun) {
44
+ if (!isEqual(prevAxesStateValue.current, newStateValue)) {
45
+ setValue(newStateValue);
46
+ prevAxesStateValue.current = newStateValue;
47
+ }
48
+ axesStateReady.current = true;
49
+ }
50
+ })();
51
+ }, [
52
+ boundsHeight,
53
+ height,
54
+ preparedChart.margin,
55
+ preparedLegend,
56
+ preparedSeries,
57
+ preparedSeriesOptions,
58
+ width,
59
+ xAxis,
60
+ yAxis,
61
+ ]);
62
+ return axesStateReady.current ? axesState : { xAxis: null, yAxis: [] };
63
+ }
@@ -72,7 +72,7 @@ function getZoomType(args) {
72
72
  return undefined;
73
73
  }
74
74
  function getPreparedZoom(args) {
75
- var _a;
75
+ var _a, _b, _c, _d;
76
76
  const { zoom, seriesData } = args;
77
77
  if (!(zoom === null || zoom === void 0 ? void 0 : zoom.enabled)) {
78
78
  return null;
@@ -86,6 +86,11 @@ function getPreparedZoom(args) {
86
86
  brush: {
87
87
  style: Object.assign({ fillOpacity: 1 }, (_a = zoom === null || zoom === void 0 ? void 0 : zoom.brush) === null || _a === void 0 ? void 0 : _a.style),
88
88
  },
89
+ resetButton: {
90
+ align: ((_b = zoom === null || zoom === void 0 ? void 0 : zoom.resetButton) === null || _b === void 0 ? void 0 : _b.align) || 'top-right',
91
+ offset: Object.assign({ x: 0, y: 0 }, (_c = zoom === null || zoom === void 0 ? void 0 : zoom.resetButton) === null || _c === void 0 ? void 0 : _c.offset),
92
+ relativeTo: ((_d = zoom === null || zoom === void 0 ? void 0 : zoom.resetButton) === null || _d === void 0 ? void 0 : _d.relativeTo) || 'chart-box',
93
+ },
89
94
  };
90
95
  }
91
96
  export const getPreparedChart = (args) => {
@@ -1,13 +1,10 @@
1
- import type { ChartSeries, ChartTitle, ChartTooltip, ChartXAxis, ChartYAxis, ChartOptions as GeneralChartOptions } from '../../types';
1
+ import type { ChartSeries, ChartTitle, ChartOptions as GeneralChartOptions } from '../../types';
2
2
  import type { ChartOptions } from './types';
3
3
  type Args = {
4
4
  seriesData: ChartSeries[];
5
5
  chart?: GeneralChartOptions;
6
6
  colors?: string[];
7
7
  title?: ChartTitle;
8
- tooltip?: ChartTooltip;
9
- yAxes?: ChartYAxis[];
10
- xAxis?: ChartXAxis;
11
8
  };
12
9
  export declare const useChartOptions: (args: Args) => ChartOptions;
13
10
  export {};
@@ -2,12 +2,10 @@ import React from 'react';
2
2
  import { DEFAULT_PALETTE } from '../../constants';
3
3
  import { getPreparedChart } from './chart';
4
4
  import { getPreparedTitle } from './title';
5
- import { getPreparedTooltip } from './tooltip';
6
5
  export const useChartOptions = (args) => {
7
- const { chart, colors, seriesData, title, tooltip, yAxes, xAxis } = args;
6
+ const { chart, colors, seriesData, title } = args;
8
7
  const options = React.useMemo(() => {
9
8
  const preparedTitle = getPreparedTitle({ title });
10
- const preparedTooltip = getPreparedTooltip({ tooltip, seriesData, yAxes, xAxis });
11
9
  const preparedChart = getPreparedChart({
12
10
  chart,
13
11
  preparedTitle,
@@ -17,8 +15,7 @@ export const useChartOptions = (args) => {
17
15
  colors: colors !== null && colors !== void 0 ? colors : DEFAULT_PALETTE,
18
16
  chart: preparedChart,
19
17
  title: preparedTitle,
20
- tooltip: preparedTooltip,
21
18
  };
22
- }, [chart, colors, seriesData, title, tooltip, xAxis, yAxes]);
19
+ }, [chart, colors, seriesData, title]);
23
20
  return options;
24
21
  };
@@ -3,10 +3,12 @@ import { getHorizontalSvgTextHeight } from '../../utils';
3
3
  const DEFAULT_TITLE_FONT_SIZE = '15px';
4
4
  const TITLE_PADDINGS = 8 * 2;
5
5
  export const getPreparedTitle = ({ title, }) => {
6
+ var _a, _b, _c, _d, _e, _f;
6
7
  const titleText = get(title, 'text');
7
8
  const titleStyle = {
8
- fontSize: get(title, 'style.fontSize', DEFAULT_TITLE_FONT_SIZE),
9
- fontWeight: get(title, 'style.fontWeight'),
9
+ fontSize: (_b = (_a = title === null || title === void 0 ? void 0 : title.style) === null || _a === void 0 ? void 0 : _a.fontSize) !== null && _b !== void 0 ? _b : DEFAULT_TITLE_FONT_SIZE,
10
+ fontWeight: (_d = (_c = title === null || title === void 0 ? void 0 : title.style) === null || _c === void 0 ? void 0 : _c.fontWeight) !== null && _d !== void 0 ? _d : 'var(--g-text-subheader-font-weight)',
11
+ fontColor: (_f = (_e = title === null || title === void 0 ? void 0 : title.style) === null || _e === void 0 ? void 0 : _e.fontColor) !== null && _f !== void 0 ? _f : 'var(--g-color-text-primary)',
10
12
  };
11
13
  const titleHeight = titleText
12
14
  ? getHorizontalSvgTextHeight({ text: titleText, style: titleStyle }) + TITLE_PADDINGS
@@ -69,7 +69,6 @@ export type PreparedTooltip = ChartData['tooltip'] & {
69
69
  };
70
70
  export type ChartOptions = {
71
71
  chart: PreparedChart;
72
- tooltip: PreparedTooltip;
73
72
  title?: PreparedTitle;
74
73
  colors: string[];
75
74
  };
@@ -8,7 +8,4 @@ export declare function prepareAxisPlotLabel(d: AxisPlot): {
8
8
  };
9
9
  padding: number;
10
10
  };
11
- export declare function getAxisCategories({ categories, order, }?: {
12
- categories?: string[];
13
- order?: ChartAxis['order'];
14
- }): string[] | undefined;
11
+ export declare function getAxisCategories({ categories: originalCategories, max, min, order, }?: Partial<ChartAxis>): string[] | undefined;
@@ -8,19 +8,42 @@ export function prepareAxisPlotLabel(d) {
8
8
  padding: (_e = (_d = d.label) === null || _d === void 0 ? void 0 : _d.padding) !== null && _e !== void 0 ? _e : 5,
9
9
  };
10
10
  }
11
- export function getAxisCategories({ categories, order, } = {}) {
12
- if (categories) {
11
+ function getNormalizedIndexMinMax(args) {
12
+ const { max, min } = args;
13
+ if (typeof min === 'number' && typeof max === 'number') {
14
+ return min > max ? [max, min] : [min, max];
15
+ }
16
+ return [min, max];
17
+ }
18
+ function getNormalizedStartEnd(args) {
19
+ const { length, max, min } = args;
20
+ const [normalizedMin, normalizedMax] = getNormalizedIndexMinMax({ max, min });
21
+ const start = typeof normalizedMin === 'number' && normalizedMin >= 0 ? normalizedMin : 0;
22
+ const end = typeof normalizedMax === 'number' && normalizedMax <= length ? normalizedMax + 1 : length;
23
+ return [start, end];
24
+ }
25
+ export function getAxisCategories({ categories: originalCategories, max, min, order, } = {}) {
26
+ if (originalCategories) {
27
+ let categories = originalCategories;
13
28
  switch (order) {
14
29
  case 'reverse': {
15
- return reverse(categories);
30
+ categories = reverse(originalCategories);
31
+ break;
16
32
  }
17
33
  case 'sortAsc': {
18
- return sort(categories, (a, b) => ascending(a, b));
34
+ categories = sort(originalCategories, (a, b) => ascending(a, b));
35
+ break;
19
36
  }
20
37
  case 'sortDesc': {
21
- return sort(categories, (a, b) => descending(a, b));
38
+ categories = sort(originalCategories, (a, b) => descending(a, b));
39
+ break;
22
40
  }
23
41
  }
42
+ if (typeof min === 'number' || typeof max === 'number') {
43
+ const [start, end] = getNormalizedStartEnd({ length: categories.length, max, min });
44
+ categories = categories.slice(start, end);
45
+ }
46
+ return categories;
24
47
  }
25
- return categories;
48
+ return originalCategories;
26
49
  }
@@ -2,7 +2,7 @@ import get from 'lodash/get';
2
2
  import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, SeriesType, axisCrosshairDefaults, axisLabelsDefaults, xAxisTitleDefaults, } from '../../constants';
3
3
  import { calculateCos, calculateNumericProperty, formatAxisTickLabel, getAxisItems, getClosestPointsRange, getDefaultDateFormat, getHorizontalHtmlTextHeight, getHorizontalSvgTextHeight, getLabelsSize, getMaxTickCount, getTicksCount, hasOverlappingLabels, isAxisRelatedSeries, wrapText, } from '../../utils';
4
4
  import { createXScale } from '../useAxisScales';
5
- import { getAxisCategories, prepareAxisPlotLabel } from './utils';
5
+ import { prepareAxisPlotLabel } from './utils';
6
6
  async function setLabelSettings({ axis, seriesData, seriesOptions, width, autoRotation = true, }) {
7
7
  const scale = createXScale({ axis, series: seriesData, seriesOptions, boundsWidth: width });
8
8
  if (!scale) {
@@ -98,7 +98,7 @@ export const getPreparedXAxis = async ({ xAxis, seriesData, seriesOptions, width
98
98
  html: labelsHtml,
99
99
  },
100
100
  lineColor: get(xAxis, 'lineColor'),
101
- categories: getAxisCategories(xAxis),
101
+ categories: xAxis === null || xAxis === void 0 ? void 0 : xAxis.categories,
102
102
  timestamps: get(xAxis, 'timestamps'),
103
103
  title: {
104
104
  text: titleText,
@@ -3,7 +3,7 @@ import { getTickValues } from '../../components/AxisY/utils';
3
3
  import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_TYPE, SeriesType, axisCrosshairDefaults, axisLabelsDefaults, yAxisTitleDefaults, } from '../../constants';
4
4
  import { calculateNumericProperty, formatAxisTickLabel, getDefaultDateFormat, getDefaultMinYAxisValue, getHorizontalHtmlTextHeight, getHorizontalSvgTextHeight, getLabelsSize, getMinSpaceBetween, getTextSizeFn, isAxisRelatedSeries, wrapText, } from '../../utils';
5
5
  import { createYScale } from '../useAxisScales';
6
- import { getAxisCategories, prepareAxisPlotLabel } from './utils';
6
+ import { prepareAxisPlotLabel } from './utils';
7
7
  const getAxisLabelMaxWidth = async (args) => {
8
8
  const { axis, seriesData, height } = args;
9
9
  if (!axis.labels.enabled) {
@@ -50,7 +50,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
50
50
  if (!hasAxisRelatedSeries) {
51
51
  return Promise.resolve([]);
52
52
  }
53
- return Promise.all(axisItems.map(async (axisItem) => {
53
+ return Promise.all(axisItems.map(async (axisItem, axisIndex) => {
54
54
  var _a, _b, _c, _d, _e, _f, _g;
55
55
  const plotIndex = get(axisItem, 'plotIndex', 0);
56
56
  const firstPlotAxis = !axisByPlot[plotIndex];
@@ -59,6 +59,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
59
59
  }
60
60
  axisByPlot[plotIndex].push(axisItem);
61
61
  const defaultAxisPosition = firstPlotAxis ? 'left' : 'right';
62
+ const axisSeriesData = seriesData.filter((s) => get(s, 'yAxis', 0) === axisIndex);
62
63
  const labelsEnabled = get(axisItem, 'labels.enabled', true);
63
64
  const labelsStyle = {
64
65
  fontSize: get(axisItem, 'labels.style.fontSize', DEFAULT_AXIS_LABEL_FONT_SIZE),
@@ -77,7 +78,8 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
77
78
  })).slice(0, titleMaxRowsCount);
78
79
  const titleSize = await getLabelsSize({ labels: [titleText], style: titleStyle });
79
80
  const axisType = get(axisItem, 'type', DEFAULT_AXIS_TYPE);
80
- const shouldHideGrid = axisItem.visible === false || seriesData.some((s) => s.type === SeriesType.Heatmap);
81
+ const shouldHideGrid = axisItem.visible === false ||
82
+ axisSeriesData.some((s) => s.type === SeriesType.Heatmap);
81
83
  const preparedAxis = {
82
84
  type: axisType,
83
85
  labels: {
@@ -97,7 +99,7 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
97
99
  html: labelsHtml,
98
100
  },
99
101
  lineColor: get(axisItem, 'lineColor'),
100
- categories: getAxisCategories(axisItem),
102
+ categories: axisItem.categories,
101
103
  timestamps: get(axisItem, 'timestamps'),
102
104
  title: {
103
105
  text: titleText,
@@ -108,9 +110,9 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
108
110
  align: get(axisItem, 'title.align', yAxisTitleDefaults.align),
109
111
  maxRowCount: titleMaxRowsCount,
110
112
  },
111
- min: (_c = get(axisItem, 'min')) !== null && _c !== void 0 ? _c : getDefaultMinYAxisValue(seriesData),
113
+ min: (_c = get(axisItem, 'min')) !== null && _c !== void 0 ? _c : getDefaultMinYAxisValue(axisSeriesData),
112
114
  max: get(axisItem, 'max'),
113
- maxPadding: get(axisItem, 'maxPadding', getMaxPaddingBySeries({ series: seriesData })),
115
+ maxPadding: get(axisItem, 'maxPadding', getMaxPaddingBySeries({ series: axisSeriesData })),
114
116
  grid: {
115
117
  enabled: shouldHideGrid
116
118
  ? false
@@ -159,14 +161,11 @@ export const getPreparedYAxis = ({ height, boundsHeight, width, seriesData, yAxi
159
161
  if (labelsEnabled) {
160
162
  const { height: labelsHeight, width: labelsWidth } = await getAxisLabelMaxWidth({
161
163
  axis: preparedAxis,
162
- seriesData,
164
+ seriesData: axisSeriesData,
163
165
  height: boundsHeight,
164
166
  });
165
167
  preparedAxis.labels.height = labelsHeight;
166
- preparedAxis.labels.width =
167
- labelsWidth > preparedAxis.labels.maxWidth
168
- ? preparedAxis.labels.maxWidth
169
- : labelsWidth;
168
+ preparedAxis.labels.width = Math.min(preparedAxis.labels.maxWidth, labelsWidth);
170
169
  }
171
170
  return preparedAxis;
172
171
  }));
@@ -0,0 +1,40 @@
1
+ import type { ChartData } from '../../types';
2
+ interface UseOriginalDataProps {
3
+ seriesData: ChartData['series']['data'];
4
+ xAxis: ChartData['xAxis'];
5
+ yAxis: ChartData['yAxis'];
6
+ }
7
+ export declare function useNormalizedOriginalData(props: UseOriginalDataProps): {
8
+ normalizedSeriesData: import("../../types").ChartSeries[];
9
+ normalizedXAxis: {
10
+ categories: string[] | undefined;
11
+ crosshair?: import("../../types").AxisCrosshair;
12
+ timestamps?: number[];
13
+ type?: import("../../types").ChartAxisType;
14
+ labels?: import("../../types").ChartAxisLabels;
15
+ lineColor?: string;
16
+ title?: {
17
+ text?: string;
18
+ style?: Partial<import("../../types").BaseTextStyle>;
19
+ margin?: number;
20
+ align?: import("../../types").ChartAxisTitleAlignment;
21
+ maxRowCount?: number;
22
+ };
23
+ min?: number;
24
+ max?: number;
25
+ grid?: {
26
+ enabled?: boolean;
27
+ };
28
+ ticks?: {
29
+ pixelInterval?: number;
30
+ interval?: number | string;
31
+ };
32
+ maxPadding?: number;
33
+ plotLines?: import("../../types").AxisPlotLine[];
34
+ plotBands?: import("../../types").AxisPlotBand[];
35
+ visible?: boolean;
36
+ order?: "sortAsc" | "sortDesc" | "reverse";
37
+ };
38
+ normalizedYAxis: import("../../types").ChartYAxis[] | undefined;
39
+ };
40
+ export {};
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import { getSortedSeriesData } from '../../utils';
3
+ import { getAxisCategories } from '../useChartOptions/utils';
4
+ export function useNormalizedOriginalData(props) {
5
+ const normalizedSeriesData = React.useMemo(() => {
6
+ return getSortedSeriesData({
7
+ seriesData: props.seriesData,
8
+ xAxis: props.xAxis,
9
+ yAxis: props.yAxis,
10
+ });
11
+ }, [props.seriesData, props.xAxis, props.yAxis]);
12
+ const normalizedXAxis = React.useMemo(() => {
13
+ var _a;
14
+ let categories = (_a = props.xAxis) === null || _a === void 0 ? void 0 : _a.categories;
15
+ if (props.xAxis && props.xAxis.categories) {
16
+ categories = getAxisCategories(props.xAxis);
17
+ }
18
+ return Object.assign(Object.assign({}, props.xAxis), { categories });
19
+ }, [props.xAxis]);
20
+ const normalizedYAxis = React.useMemo(() => {
21
+ if (Array.isArray(props.yAxis) && props.yAxis.some((axis) => axis.categories)) {
22
+ return props.yAxis.map((axis) => {
23
+ let categories = axis.categories;
24
+ if (axis.categories) {
25
+ categories = getAxisCategories(axis);
26
+ }
27
+ return Object.assign(Object.assign({}, axis), { categories });
28
+ });
29
+ }
30
+ return props.yAxis;
31
+ }, [props.yAxis]);
32
+ return { normalizedSeriesData, normalizedXAxis, normalizedYAxis };
33
+ }
@@ -13,13 +13,4 @@ export declare const useSeries: (args: Args) => {
13
13
  preparedSeries: PreparedSeries[];
14
14
  handleLegendItemClick: OnLegendItemClick;
15
15
  };
16
- export declare const useShapeSeries: ({ seriesData, seriesOptions, colors, preparedLegend, activeLegendItems, }: {
17
- colors: string[];
18
- seriesData: ChartData["series"]["data"];
19
- seriesOptions: ChartData["series"]["options"];
20
- activeLegendItems: string[];
21
- preparedLegend?: PreparedLegend | null;
22
- }) => {
23
- preparedSeries: PreparedSeries[];
24
- };
25
16
  export {};
@@ -93,21 +93,3 @@ export const useSeries = (args) => {
93
93
  handleLegendItemClick,
94
94
  };
95
95
  };
96
- export const useShapeSeries = ({ seriesData, seriesOptions, colors, preparedLegend, activeLegendItems, }) => {
97
- const [preparedSeries, setPreparedSeries] = React.useState([]);
98
- React.useEffect(() => {
99
- (async () => {
100
- const items = await getPreparedSeries({
101
- seriesData,
102
- seriesOptions,
103
- preparedLegend,
104
- colors,
105
- });
106
- setPreparedSeries(items);
107
- })();
108
- }, [seriesData, seriesOptions, preparedLegend, colors]);
109
- const chartSeries = useVisibleSeries({ preparedSeries, activeLegendItems });
110
- return {
111
- preparedSeries: chartSeries,
112
- };
113
- };
@@ -326,6 +326,9 @@ export type PreparedRadarSeries = {
326
326
  };
327
327
  } & BasePreparedSeries;
328
328
  export type PreparedSeries = PreparedScatterSeries | PreparedBarXSeries | PreparedBarYSeries | PreparedPieSeries | PreparedLineSeries | PreparedAreaSeries | PreparedTreemapSeries | PreparedWaterfallSeries | PreparedSankeySeries | PreparedRadarSeries | PreparedHeatmapSeries;
329
+ export type PreparedZoomableSeries = Extract<PreparedSeries, {
330
+ data: Array<unknown>;
331
+ }>;
329
332
  export type PreparedSeriesOptions = SeriesOptionsDefaults;
330
333
  export type StackedSeries = BarXSeries | AreaSeries | BarYSeries;
331
334
  export {};
@@ -118,6 +118,10 @@ export const prepareBarXData = async (args) => {
118
118
  let xCenter;
119
119
  if (xAxis.type === 'category') {
120
120
  const xBandScale = xScale;
121
+ const xBandScaleDomain = xBandScale.domain();
122
+ if (xBandScaleDomain.indexOf(xValue) === -1) {
123
+ continue;
124
+ }
121
125
  xCenter = (xBandScale(xValue) || 0) + xBandScale.bandwidth() / 2;
122
126
  }
123
127
  else {
@@ -67,6 +67,10 @@ export async function prepareBarYData(args) {
67
67
  let center;
68
68
  if (yAxis[0].type === 'category') {
69
69
  const bandScale = yScale;
70
+ const bandScaleDomain = bandScale.domain();
71
+ if (bandScaleDomain.indexOf(yValue) === -1) {
72
+ return;
73
+ }
70
74
  center = (bandScale(yValue) || 0) + bandSize / 2;
71
75
  }
72
76
  else {
@@ -2,11 +2,11 @@ import type { ChartScale } from '../../useAxisScales';
2
2
  import type { PreparedAxis } from '../../useChartOptions/types';
3
3
  import type { PreparedScatterSeries } from '../../useSeries/types';
4
4
  import type { PreparedScatterData } from './types';
5
- export declare const prepareScatterData: (args: {
5
+ export declare function prepareScatterData(args: {
6
6
  series: PreparedScatterSeries[];
7
7
  xAxis: PreparedAxis;
8
8
  xScale: ChartScale;
9
9
  yAxis: PreparedAxis[];
10
10
  yScale: (ChartScale | undefined)[];
11
11
  isOutsideBounds: (x: number, y: number) => boolean;
12
- }) => PreparedScatterData[];
12
+ }): PreparedScatterData[];
@@ -1,9 +1,38 @@
1
1
  import get from 'lodash/get';
2
+ import { getDataCategoryValue } from '../../../utils';
2
3
  import { getXValue, getYValue } from '../utils';
3
- const getFilteredLinearScatterData = (data) => {
4
+ function getFilteredLinearScatterData(data) {
4
5
  return data.filter((d) => typeof d.x === 'number' && typeof d.y === 'number');
5
- };
6
- export const prepareScatterData = (args) => {
6
+ }
7
+ function getFilteredCategoryScatterData(args) {
8
+ const { data, xAxis, xScale, yAxis, yScale } = args;
9
+ const xDomain = xScale.domain();
10
+ const xCategories = get(xAxis, 'categories', []);
11
+ const yDomain = yScale.domain();
12
+ const yCategories = get(yAxis, 'categories', []);
13
+ return data.filter((d) => {
14
+ let xInRange = true;
15
+ let yInRange = true;
16
+ if (xAxis.type === 'category') {
17
+ const dataCategory = getDataCategoryValue({
18
+ axisDirection: 'x',
19
+ categories: xCategories,
20
+ data: d,
21
+ });
22
+ xInRange = xDomain.indexOf(dataCategory) !== -1;
23
+ }
24
+ if (yAxis.type === 'category') {
25
+ const dataCategory = getDataCategoryValue({
26
+ axisDirection: 'y',
27
+ categories: yCategories,
28
+ data: d,
29
+ });
30
+ yInRange = yDomain.indexOf(dataCategory) !== -1;
31
+ }
32
+ return xInRange && yInRange;
33
+ });
34
+ }
35
+ export function prepareScatterData(args) {
7
36
  const { series, xAxis, xScale, yAxis, yScale, isOutsideBounds } = args;
8
37
  return series.reduce((acc, s) => {
9
38
  const yAxisIndex = get(s, 'yAxis', 0);
@@ -13,7 +42,13 @@ export const prepareScatterData = (args) => {
13
42
  return acc;
14
43
  }
15
44
  const filteredData = xAxis.type === 'category' || seriesYAxis.type === 'category'
16
- ? s.data
45
+ ? getFilteredCategoryScatterData({
46
+ data: s.data,
47
+ xAxis,
48
+ xScale,
49
+ yAxis: seriesYAxis,
50
+ yScale: seriesYScale,
51
+ })
17
52
  : getFilteredLinearScatterData(s.data);
18
53
  filteredData.forEach((d) => {
19
54
  var _a;
@@ -39,4 +74,4 @@ export const prepareScatterData = (args) => {
39
74
  });
40
75
  return acc;
41
76
  }, []);
42
- };
77
+ }
@@ -65,9 +65,27 @@ export interface ChartAxis {
65
65
  */
66
66
  maxRowCount?: number;
67
67
  };
68
- /** The minimum value of the axis. If undefined the min value is automatically calculate. */
68
+ /**
69
+ * The minimum value of the axis. If undefined the min value is automatically calculated.
70
+ *
71
+ * The value type depends on the axis scale:
72
+ * - For `linear` and `logarithmic` axes: numeric value
73
+ * - For `datetime` axes: timestamp (milliseconds since Unix epoch)
74
+ * - For `category` axes: index of the element in the categories array (which has been processed according to the specified `order` property)
75
+ *
76
+ * Note: min/max is not supported for category axes in waterfall and heatmap visualizations.
77
+ */
69
78
  min?: number;
70
- /** The maximum value of the axis. If undefined the max value is automatically calculate. */
79
+ /**
80
+ * The maximum value of the axis. If undefined the max value is automatically calculated.
81
+ *
82
+ * The value type depends on the axis scale:
83
+ * - For `linear` and `logarithmic` axes: numeric value
84
+ * - For `datetime` axes: timestamp (milliseconds since Unix epoch)
85
+ * - For `category` axes: index of the element in the categories array (which has been processed according to the specified `order` property)
86
+ *
87
+ * Note: min/max is not supported for category axes in waterfall and heatmap visualizations.
88
+ */
71
89
  max?: number;
72
90
  /** The grid lines settings.
73
91
  * Unavailable for some visualizations, such as a heatmap.
@@ -33,4 +33,33 @@ export interface ChartZoom {
33
33
  fillOpacity?: number;
34
34
  };
35
35
  };
36
+ /**
37
+ * Reset zoom button configuration.
38
+ * The button appears only after the zoom has been applied.
39
+ */
40
+ resetButton?: {
41
+ /**
42
+ * The alignment of the button.
43
+ *
44
+ * @default 'top-right'
45
+ */
46
+ align?: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
47
+ /**
48
+ * The offset of the button.
49
+ *
50
+ * @default {x: 0, y: 0}
51
+ */
52
+ offset?: {
53
+ x?: number;
54
+ y?: number;
55
+ };
56
+ /**
57
+ * The box to which the button is positioned relative to.
58
+ * - `chart-box` refers to the entire chart area, including titles and legends.
59
+ * - `plot-box` refers to the area where the series are drawn.
60
+ *
61
+ * @default 'chart-box'
62
+ */
63
+ relativeTo?: 'chart-box' | 'plot-box';
64
+ };
36
65
  }