@gravity-ui/charts 1.11.3 → 1.12.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 (103) hide show
  1. package/dist/cjs/components/ChartInner/index.js +1 -1
  2. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +1 -0
  3. package/dist/cjs/components/ChartInner/useChartInnerProps.js +19 -12
  4. package/dist/cjs/components/Legend/index.d.ts +0 -1
  5. package/dist/cjs/components/Legend/index.js +13 -23
  6. package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +1 -0
  7. package/dist/cjs/components/Tooltip/ChartTooltipContent.js +3 -3
  8. package/dist/cjs/components/Tooltip/DefaultTooltipContent/Row.d.ts +9 -0
  9. package/dist/cjs/components/Tooltip/DefaultTooltipContent/Row.js +10 -0
  10. package/dist/cjs/components/Tooltip/DefaultTooltipContent/RowTotals.d.ts +9 -0
  11. package/dist/cjs/components/Tooltip/DefaultTooltipContent/RowTotals.js +23 -0
  12. package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.d.ts +11 -0
  13. package/dist/cjs/components/Tooltip/DefaultTooltipContent/index.js +102 -0
  14. package/dist/cjs/components/Tooltip/DefaultTooltipContent/utils.d.ts +30 -0
  15. package/dist/cjs/components/Tooltip/DefaultTooltipContent/utils.js +126 -0
  16. package/dist/cjs/components/Tooltip/index.js +1 -1
  17. package/dist/cjs/components/Tooltip/styles.css +14 -2
  18. package/dist/cjs/components/Tooltip/utils.d.ts +30 -0
  19. package/dist/cjs/components/Tooltip/utils.js +126 -0
  20. package/dist/cjs/constants/axis.d.ts +6 -0
  21. package/dist/cjs/constants/axis.js +6 -0
  22. package/dist/cjs/constants/index.d.ts +6 -4
  23. package/dist/cjs/constants/index.js +6 -4
  24. package/dist/cjs/constants/tooltip.d.ts +3 -0
  25. package/dist/cjs/constants/tooltip.js +3 -0
  26. package/dist/cjs/hooks/useAxisScales/index.d.ts +14 -3
  27. package/dist/cjs/hooks/useAxisScales/index.js +73 -22
  28. package/dist/cjs/hooks/useChartOptions/x-axis.js +1 -1
  29. package/dist/cjs/hooks/useChartOptions/y-axis.d.ts +4 -2
  30. package/dist/cjs/hooks/useChartOptions/y-axis.js +9 -3
  31. package/dist/cjs/hooks/useSeries/index.d.ts +9 -0
  32. package/dist/cjs/hooks/useSeries/index.js +59 -29
  33. package/dist/cjs/hooks/useSeries/prepare-legend.d.ts +2 -2
  34. package/dist/cjs/hooks/useSeries/prepare-legend.js +4 -6
  35. package/dist/cjs/hooks/useSeries/types.d.ts +1 -0
  36. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +1 -1
  37. package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +17 -62
  38. package/dist/cjs/hooks/useShapes/waterfall/prepare-data.js +1 -1
  39. package/dist/cjs/hooks/utils/bar-y.d.ts +27 -0
  40. package/dist/cjs/hooks/utils/bar-y.js +69 -0
  41. package/dist/cjs/hooks/utils/index.d.ts +1 -0
  42. package/dist/cjs/hooks/utils/index.js +1 -0
  43. package/dist/cjs/i18n/keysets/en.json +7 -1
  44. package/dist/cjs/i18n/keysets/ru.json +7 -1
  45. package/dist/cjs/types/chart/axis.d.ts +2 -2
  46. package/dist/cjs/types/chart/tooltip.d.ts +21 -0
  47. package/dist/cjs/validation/index.js +55 -1
  48. package/dist/esm/components/ChartInner/index.js +1 -1
  49. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +1 -0
  50. package/dist/esm/components/ChartInner/useChartInnerProps.js +19 -12
  51. package/dist/esm/components/Legend/index.d.ts +0 -1
  52. package/dist/esm/components/Legend/index.js +13 -23
  53. package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +1 -0
  54. package/dist/esm/components/Tooltip/ChartTooltipContent.js +3 -3
  55. package/dist/esm/components/Tooltip/DefaultTooltipContent/Row.d.ts +9 -0
  56. package/dist/esm/components/Tooltip/DefaultTooltipContent/Row.js +10 -0
  57. package/dist/esm/components/Tooltip/DefaultTooltipContent/RowTotals.d.ts +9 -0
  58. package/dist/esm/components/Tooltip/DefaultTooltipContent/RowTotals.js +23 -0
  59. package/dist/esm/components/Tooltip/DefaultTooltipContent/index.d.ts +11 -0
  60. package/dist/esm/components/Tooltip/DefaultTooltipContent/index.js +102 -0
  61. package/dist/esm/components/Tooltip/DefaultTooltipContent/utils.d.ts +30 -0
  62. package/dist/esm/components/Tooltip/DefaultTooltipContent/utils.js +126 -0
  63. package/dist/esm/components/Tooltip/index.js +1 -1
  64. package/dist/esm/components/Tooltip/styles.css +14 -2
  65. package/dist/esm/components/Tooltip/utils.d.ts +30 -0
  66. package/dist/esm/components/Tooltip/utils.js +126 -0
  67. package/dist/esm/constants/axis.d.ts +6 -0
  68. package/dist/esm/constants/axis.js +6 -0
  69. package/dist/esm/constants/index.d.ts +6 -4
  70. package/dist/esm/constants/index.js +6 -4
  71. package/dist/esm/constants/tooltip.d.ts +3 -0
  72. package/dist/esm/constants/tooltip.js +3 -0
  73. package/dist/esm/hooks/useAxisScales/index.d.ts +14 -3
  74. package/dist/esm/hooks/useAxisScales/index.js +73 -22
  75. package/dist/esm/hooks/useChartOptions/x-axis.js +1 -1
  76. package/dist/esm/hooks/useChartOptions/y-axis.d.ts +4 -2
  77. package/dist/esm/hooks/useChartOptions/y-axis.js +9 -3
  78. package/dist/esm/hooks/useSeries/index.d.ts +9 -0
  79. package/dist/esm/hooks/useSeries/index.js +59 -29
  80. package/dist/esm/hooks/useSeries/prepare-legend.d.ts +2 -2
  81. package/dist/esm/hooks/useSeries/prepare-legend.js +4 -6
  82. package/dist/esm/hooks/useSeries/types.d.ts +1 -0
  83. package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +1 -1
  84. package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +17 -62
  85. package/dist/esm/hooks/useShapes/waterfall/prepare-data.js +1 -1
  86. package/dist/esm/hooks/utils/bar-y.d.ts +27 -0
  87. package/dist/esm/hooks/utils/bar-y.js +69 -0
  88. package/dist/esm/hooks/utils/index.d.ts +1 -0
  89. package/dist/esm/hooks/utils/index.js +1 -0
  90. package/dist/esm/i18n/keysets/en.json +7 -1
  91. package/dist/esm/i18n/keysets/ru.json +7 -1
  92. package/dist/esm/types/chart/axis.d.ts +2 -2
  93. package/dist/esm/types/chart/tooltip.d.ts +21 -0
  94. package/dist/esm/validation/index.js +55 -1
  95. package/package.json +1 -1
  96. package/dist/cjs/components/Tooltip/DefaultContent.d.ts +0 -10
  97. package/dist/cjs/components/Tooltip/DefaultContent.js +0 -187
  98. package/dist/esm/components/Tooltip/DefaultContent.d.ts +0 -10
  99. package/dist/esm/components/Tooltip/DefaultContent.js +0 -187
  100. /package/dist/cjs/hooks/{useShapes/constants.d.ts → constants.d.ts} +0 -0
  101. /package/dist/cjs/hooks/{useShapes/constants.js → constants.js} +0 -0
  102. /package/dist/esm/hooks/{useShapes/constants.d.ts → constants.d.ts} +0 -0
  103. /package/dist/esm/hooks/{useShapes/constants.js → constants.js} +0 -0
@@ -0,0 +1,126 @@
1
+ import get from 'lodash/get';
2
+ import { i18n } from '../../i18n';
3
+ import { getDataCategoryValue } from '../../utils';
4
+ import { getFormattedValue } from '../../utils/chart/format';
5
+ const DEFAULT_DATE_FORMAT = 'DD.MM.YY';
6
+ function getRowData(fieldName, data, axis) {
7
+ switch (axis === null || axis === void 0 ? void 0 : axis.type) {
8
+ case 'category': {
9
+ const categories = get(axis, 'categories', []);
10
+ return getDataCategoryValue({ axisDirection: fieldName, categories, data });
11
+ }
12
+ default: {
13
+ return get(data, fieldName);
14
+ }
15
+ }
16
+ }
17
+ export function getXRowData(data, xAxis) {
18
+ return getRowData('x', data, xAxis);
19
+ }
20
+ function getYRowData(data, yAxis) {
21
+ return getRowData('y', data, yAxis);
22
+ }
23
+ export function getDefaultValueFormat({ axis, }) {
24
+ switch (axis === null || axis === void 0 ? void 0 : axis.type) {
25
+ case 'linear':
26
+ case 'logarithmic': {
27
+ return {
28
+ type: 'number',
29
+ };
30
+ }
31
+ case 'datetime': {
32
+ return {
33
+ type: 'date',
34
+ format: DEFAULT_DATE_FORMAT,
35
+ };
36
+ }
37
+ default:
38
+ return undefined;
39
+ }
40
+ }
41
+ export const getMeasureValue = ({ data, xAxis, yAxis, valueFormat, }) => {
42
+ var _a, _b, _c, _d;
43
+ if (data.every((item) => ['pie', 'treemap', 'waterfall', 'sankey'].includes(item.series.type))) {
44
+ return null;
45
+ }
46
+ if (data.some((item) => item.series.type === 'radar')) {
47
+ return (_b = (_a = data[0].category) === null || _a === void 0 ? void 0 : _a.key) !== null && _b !== void 0 ? _b : null;
48
+ }
49
+ if (data.some((item) => item.series.type === 'bar-y')) {
50
+ const format = valueFormat !== null && valueFormat !== void 0 ? valueFormat : getDefaultValueFormat({ axis: yAxis });
51
+ return getFormattedValue({
52
+ value: getYRowData((_c = data[0]) === null || _c === void 0 ? void 0 : _c.data, yAxis),
53
+ format,
54
+ });
55
+ }
56
+ const format = valueFormat !== null && valueFormat !== void 0 ? valueFormat : getDefaultValueFormat({ axis: xAxis });
57
+ return getFormattedValue({
58
+ value: getXRowData((_d = data[0]) === null || _d === void 0 ? void 0 : _d.data, xAxis),
59
+ format,
60
+ });
61
+ };
62
+ export function getHoveredValues(args) {
63
+ const { hovered, xAxis, yAxis } = args;
64
+ return hovered.map((seriesItem) => {
65
+ var _a;
66
+ const { data, series } = seriesItem;
67
+ switch (series.type) {
68
+ case 'area':
69
+ case 'line':
70
+ case 'bar-x':
71
+ case 'scatter': {
72
+ return getYRowData(data, yAxis);
73
+ }
74
+ case 'bar-y': {
75
+ return getXRowData(data, xAxis);
76
+ }
77
+ case 'pie':
78
+ case 'radar':
79
+ case 'treemap': {
80
+ const seriesData = data;
81
+ return seriesData.value;
82
+ }
83
+ case 'sankey': {
84
+ const { target, data: source } = seriesItem;
85
+ return (_a = source.links.find((d) => d.name === (target === null || target === void 0 ? void 0 : target.name))) === null || _a === void 0 ? void 0 : _a.value;
86
+ }
87
+ case 'waterfall': {
88
+ return getYRowData(data, yAxis);
89
+ }
90
+ default: {
91
+ return undefined;
92
+ }
93
+ }
94
+ });
95
+ }
96
+ export function getBuiltInAggregatedValue(args) {
97
+ const { aggregation, values } = args;
98
+ switch (aggregation) {
99
+ case 'sum':
100
+ return values.reduce((acc, value) => {
101
+ return acc + (typeof value === 'number' ? value : 0);
102
+ }, 0);
103
+ default:
104
+ return undefined;
105
+ }
106
+ }
107
+ export function getBuiltInAggregationLabel(args) {
108
+ const { aggregation } = args;
109
+ switch (aggregation) {
110
+ case 'sum':
111
+ return i18n('tooltip', 'label_totals_sum');
112
+ default:
113
+ return '';
114
+ }
115
+ }
116
+ export function getPreparedAggregation(args) {
117
+ const { hovered, totals, xAxis, yAxis } = args;
118
+ const aggregation = totals === null || totals === void 0 ? void 0 : totals.aggregation;
119
+ if (typeof aggregation === 'string') {
120
+ return aggregation;
121
+ }
122
+ if (typeof aggregation === 'function') {
123
+ return () => aggregation({ hovered, xAxis, yAxis });
124
+ }
125
+ return 'sum';
126
+ }
@@ -0,0 +1,6 @@
1
+ export declare const AXIS_TYPE: {
2
+ readonly CATEGORY: "category";
3
+ readonly DATETIME: "datetime";
4
+ readonly LINEAR: "linear";
5
+ readonly LOGARITHMIC: "logarithmic";
6
+ };
@@ -0,0 +1,6 @@
1
+ export const AXIS_TYPE = {
2
+ CATEGORY: 'category',
3
+ DATETIME: 'datetime',
4
+ LINEAR: 'linear',
5
+ LOGARITHMIC: 'logarithmic',
6
+ };
@@ -1,8 +1,10 @@
1
- export * from './defaults';
2
- export * from './misc';
1
+ export * from './axis';
3
2
  export * from './chart-types';
4
- export * from './line-styles';
5
- export * from './symbol-types';
3
+ export * from './defaults';
6
4
  export * from './layout-algorithms';
5
+ export * from './line-styles';
6
+ export * from './misc';
7
7
  export * from './palette';
8
+ export * from './symbol-types';
9
+ export * from './tooltip';
8
10
  export * from './typography';
@@ -1,8 +1,10 @@
1
- export * from './defaults';
2
- export * from './misc';
1
+ export * from './axis';
3
2
  export * from './chart-types';
4
- export * from './line-styles';
5
- export * from './symbol-types';
3
+ export * from './defaults';
6
4
  export * from './layout-algorithms';
5
+ export * from './line-styles';
6
+ export * from './misc';
7
7
  export * from './palette';
8
+ export * from './symbol-types';
9
+ export * from './tooltip';
8
10
  export * from './typography';
@@ -0,0 +1,3 @@
1
+ export declare const TOOLTIP_TOTALS_BUILT_IN_AGGREGATION: {
2
+ readonly SUM: "sum";
3
+ };
@@ -0,0 +1,3 @@
1
+ export const TOOLTIP_TOTALS_BUILT_IN_AGGREGATION = {
2
+ SUM: 'sum',
3
+ };
@@ -1,13 +1,14 @@
1
1
  import type { ScaleBand, ScaleLinear, ScaleTime } from 'd3';
2
2
  import type { ChartAxis, ChartSeries } from '../../types';
3
3
  import type { PreparedAxis } from '../useChartOptions/types';
4
- import type { PreparedSeries } from '../useSeries/types';
4
+ import type { PreparedSeries, PreparedSeriesOptions } from '../useSeries/types';
5
5
  import type { PreparedSplit } from '../useSplit/types';
6
6
  export type ChartScale = ScaleLinear<number, number> | ScaleBand<string> | ScaleTime<number, number>;
7
7
  type Args = {
8
8
  boundsWidth: number;
9
9
  boundsHeight: number;
10
10
  series: PreparedSeries[];
11
+ seriesOptions: PreparedSeriesOptions;
11
12
  xAxis: PreparedAxis | null;
12
13
  yAxis: PreparedAxis[];
13
14
  split: PreparedSplit;
@@ -18,8 +19,18 @@ type ReturnValue = {
18
19
  xScale?: ChartScale;
19
20
  yScale?: ChartScale[];
20
21
  };
21
- export declare function createYScale(axis: PreparedAxis, series: PreparedSeries[], boundsHeight: number): ScaleBand<string> | ScaleLinear<number, number, never> | ScaleTime<number, number, never>;
22
- export declare function createXScale(axis: PreparedAxis | ChartAxis, series: (PreparedSeries | ChartSeries)[], boundsWidth: number, hasZoomX?: boolean): ScaleBand<string> | ScaleLinear<number, number, never> | ScaleTime<number, number, never>;
22
+ export declare function createYScale(args: {
23
+ axis: PreparedAxis;
24
+ boundsHeight: number;
25
+ series: (PreparedSeries | ChartSeries)[];
26
+ seriesOptions: PreparedSeriesOptions;
27
+ }): ScaleBand<string> | ScaleLinear<number, number, never> | ScaleTime<number, number, never>;
28
+ export declare function createXScale(args: {
29
+ axis: PreparedAxis | ChartAxis;
30
+ boundsWidth: number;
31
+ series: (PreparedSeries | ChartSeries)[];
32
+ hasZoomX?: boolean;
33
+ }): ScaleBand<string> | ScaleLinear<number, number, never> | ScaleTime<number, number, never>;
23
34
  /**
24
35
  * Uses to create scales for axis related series
25
36
  */
@@ -1,13 +1,14 @@
1
1
  import React from 'react';
2
2
  import { extent, scaleBand, scaleLinear, scaleLog, scaleUtc } from 'd3';
3
3
  import get from 'lodash/get';
4
- import { DEFAULT_AXIS_TYPE } from '../../constants';
4
+ import { DEFAULT_AXIS_TYPE, SeriesType } from '../../constants';
5
5
  import { CHART_SERIES_WITH_VOLUME_ON_Y_AXIS, getAxisHeight, getDataCategoryValue, getDefaultMaxXAxisValue, getDefaultMinXAxisValue, getDomainDataXBySeries, getDomainDataYBySeries, getOnlyVisibleSeries, isAxisRelatedSeries, isSeriesWithCategoryValues, } from '../../utils';
6
+ import { getBarYLayoutForNumericScale } from '../utils';
6
7
  const X_AXIS_ZOOM_PADDING = 0.02;
7
- const isNumericalArrayData = (data) => {
8
+ function isNumericalArrayData(data) {
8
9
  return data.every((d) => typeof d === 'number' || d === null);
9
- };
10
- const filterCategoriesByVisibleSeries = (args) => {
10
+ }
11
+ function filterCategoriesByVisibleSeries(args) {
11
12
  const { axisDirection, categories, series } = args;
12
13
  const visibleCategories = new Set();
13
14
  series.forEach((s) => {
@@ -18,18 +19,61 @@ const filterCategoriesByVisibleSeries = (args) => {
18
19
  }
19
20
  });
20
21
  return categories.filter((c) => visibleCategories.has(c));
21
- };
22
- export function createYScale(axis, series, boundsHeight) {
23
- const yType = get(axis, 'type', DEFAULT_AXIS_TYPE);
22
+ }
23
+ // axis is validated in `validation/index.ts`, so the value of `axis.type` is definitely valid.
24
+ // eslint-disable-next-line consistent-return
25
+ function getYScaleRange(args) {
26
+ const { axis, boundsHeight, series, seriesOptions } = args;
27
+ switch (axis.type) {
28
+ case 'datetime':
29
+ case 'linear':
30
+ case 'logarithmic': {
31
+ const barYSeries = series.filter((s) => s.type === SeriesType.BarY);
32
+ if (barYSeries.length) {
33
+ const { barSize, dataLength } = getBarYLayoutForNumericScale({
34
+ plotHeight: boundsHeight - boundsHeight * axis.maxPadding,
35
+ series: barYSeries,
36
+ seriesOptions: seriesOptions,
37
+ });
38
+ if (dataLength > 1) {
39
+ const alreadyCountedStackingIds = new Set();
40
+ const offsetMultiplier = barYSeries.reduce((acc, s) => {
41
+ let count = 0;
42
+ if (s.stackId) {
43
+ if (!alreadyCountedStackingIds.has(s.stackId)) {
44
+ alreadyCountedStackingIds.add(s.stackId);
45
+ count = 1;
46
+ }
47
+ }
48
+ else {
49
+ count = 1;
50
+ }
51
+ return acc + count;
52
+ }, 0);
53
+ const offset = (barSize * Math.max(offsetMultiplier, 1)) / 2;
54
+ const start = boundsHeight - offset;
55
+ const end = boundsHeight * axis.maxPadding + offset;
56
+ return [start, end];
57
+ }
58
+ }
59
+ return [boundsHeight, boundsHeight * axis.maxPadding];
60
+ }
61
+ case 'category': {
62
+ return [boundsHeight, 0];
63
+ }
64
+ }
65
+ }
66
+ export function createYScale(args) {
67
+ const { axis, boundsHeight, series, seriesOptions } = args;
24
68
  const yMinProps = get(axis, 'min');
25
69
  const yMaxProps = get(axis, 'max');
26
70
  const yCategories = get(axis, 'categories');
27
71
  const yTimestamps = get(axis, 'timestamps');
28
- switch (yType) {
72
+ const range = getYScaleRange({ axis, boundsHeight, series, seriesOptions });
73
+ switch (axis.type) {
29
74
  case 'linear':
30
75
  case 'logarithmic': {
31
76
  const domain = getDomainDataYBySeries(series);
32
- const range = [boundsHeight, boundsHeight * axis.maxPadding];
33
77
  if (isNumericalArrayData(domain)) {
34
78
  const [yMinDomain, yMaxDomain] = extent(domain);
35
79
  const yMin = typeof yMinProps === 'number' ? yMinProps : yMinDomain;
@@ -41,7 +85,7 @@ export function createYScale(axis, series, boundsHeight) {
41
85
  const hasSeriesWithVolumeOnYAxis = series.some((s) => CHART_SERIES_WITH_VOLUME_ON_Y_AXIS.includes(s.type));
42
86
  yMax = hasSeriesWithVolumeOnYAxis ? Math.max(yMaxDomain, 0) : yMaxDomain;
43
87
  }
44
- const scaleFn = yType === 'logarithmic' ? scaleLog : scaleLinear;
88
+ const scaleFn = axis.type === 'logarithmic' ? scaleLog : scaleLinear;
45
89
  return scaleFn().domain([yMin, yMax]).range(range).nice();
46
90
  }
47
91
  break;
@@ -53,12 +97,11 @@ export function createYScale(axis, series, boundsHeight) {
53
97
  categories: yCategories,
54
98
  series: series,
55
99
  });
56
- return scaleBand().domain(filteredCategories).range([boundsHeight, 0]);
100
+ return scaleBand().domain(filteredCategories).range(range);
57
101
  }
58
102
  break;
59
103
  }
60
104
  case 'datetime': {
61
- const range = [boundsHeight, boundsHeight * axis.maxPadding];
62
105
  if (yTimestamps) {
63
106
  const [yMinTimestamp, yMaxTimestamp] = extent(yTimestamps);
64
107
  const yMin = typeof yMinProps === 'number' ? yMinProps : yMinTimestamp;
@@ -74,7 +117,6 @@ export function createYScale(axis, series, boundsHeight) {
74
117
  return scaleUtc().domain([yMin, yMax]).range(range).nice();
75
118
  }
76
119
  }
77
- break;
78
120
  }
79
121
  }
80
122
  throw new Error('Failed to create yScale');
@@ -97,7 +139,8 @@ function calculateXAxisPadding(series) {
97
139
  return result;
98
140
  }
99
141
  // eslint-disable-next-line complexity
100
- export function createXScale(axis, series, boundsWidth, hasZoomX) {
142
+ export function createXScale(args) {
143
+ const { axis, boundsWidth, series, hasZoomX } = args;
101
144
  const xMinProps = get(axis, 'min');
102
145
  const xMaxProps = get(axis, 'max');
103
146
  const xType = get(axis, 'type', DEFAULT_AXIS_TYPE);
@@ -193,13 +236,15 @@ export function createXScale(axis, series, boundsWidth, hasZoomX) {
193
236
  throw new Error('Failed to create xScale');
194
237
  }
195
238
  const createScales = (args) => {
196
- const { boundsWidth, boundsHeight, series, xAxis, yAxis, split, hasZoomX } = args;
239
+ const { boundsWidth, boundsHeight, hasZoomX, series, seriesOptions, split, xAxis, yAxis } = args;
197
240
  let visibleSeries = getOnlyVisibleSeries(series);
198
241
  // Reassign to all series in case of all series unselected,
199
242
  // otherwise we will get an empty space without grid
200
243
  visibleSeries = visibleSeries.length === 0 ? series : visibleSeries;
201
244
  return {
202
- xScale: xAxis ? createXScale(xAxis, visibleSeries, boundsWidth, hasZoomX) : undefined,
245
+ xScale: xAxis
246
+ ? createXScale({ axis: xAxis, boundsWidth, series: visibleSeries, hasZoomX })
247
+ : undefined,
203
248
  yScale: yAxis.map((axis, index) => {
204
249
  const axisSeries = series.filter((s) => {
205
250
  const seriesAxisIndex = get(s, 'yAxis', 0);
@@ -207,7 +252,12 @@ const createScales = (args) => {
207
252
  });
208
253
  const visibleAxisSeries = getOnlyVisibleSeries(axisSeries);
209
254
  const axisHeight = getAxisHeight({ boundsHeight, split });
210
- return createYScale(axis, visibleAxisSeries.length ? visibleAxisSeries : axisSeries, axisHeight);
255
+ return createYScale({
256
+ axis,
257
+ boundsHeight: axisHeight,
258
+ series: visibleAxisSeries.length ? visibleAxisSeries : axisSeries,
259
+ seriesOptions,
260
+ });
211
261
  }),
212
262
  };
213
263
  };
@@ -215,7 +265,7 @@ const createScales = (args) => {
215
265
  * Uses to create scales for axis related series
216
266
  */
217
267
  export const useAxisScales = (args) => {
218
- const { boundsWidth, boundsHeight, series, xAxis, yAxis, split, hasZoomX, hasZoomY } = args;
268
+ const { boundsWidth, boundsHeight, hasZoomX, hasZoomY, series, seriesOptions, split, xAxis, yAxis, } = args;
219
269
  return React.useMemo(() => {
220
270
  let xScale;
221
271
  let yScale;
@@ -224,14 +274,15 @@ export const useAxisScales = (args) => {
224
274
  ({ xScale, yScale } = createScales({
225
275
  boundsWidth,
226
276
  boundsHeight,
277
+ hasZoomX,
278
+ hasZoomY,
227
279
  series,
280
+ seriesOptions,
281
+ split,
228
282
  xAxis,
229
283
  yAxis,
230
- split,
231
- hasZoomX,
232
- hasZoomY,
233
284
  }));
234
285
  }
235
286
  return { xScale, yScale };
236
- }, [boundsWidth, boundsHeight, series, xAxis, yAxis, split, hasZoomX, hasZoomY]);
287
+ }, [boundsWidth, boundsHeight, hasZoomX, hasZoomY, series, seriesOptions, split, xAxis, yAxis]);
237
288
  };
@@ -3,7 +3,7 @@ import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, axisCrosshairDefaults, axisLa
3
3
  import { calculateCos, formatAxisTickLabel, getClosestPointsRange, getHorisontalSvgTextHeight, getLabelsSize, getMaxTickCount, getTicksCount, getXAxisItems, hasOverlappingLabels, wrapText, } from '../../utils';
4
4
  import { createXScale } from '../useAxisScales';
5
5
  async function getLabelSettings({ axis, seriesData, width, autoRotation = true, }) {
6
- const scale = createXScale(axis, seriesData, width);
6
+ const scale = createXScale({ axis, series: seriesData, boundsWidth: width });
7
7
  const tickCount = getTicksCount({ axis, range: width });
8
8
  const ticks = getXAxisItems({
9
9
  scale: scale,
@@ -1,7 +1,9 @@
1
1
  import type { ChartSeries, ChartYAxis } from '../../types';
2
+ import type { PreparedSeriesOptions } from '../useSeries/types';
2
3
  import type { PreparedAxis } from './types';
3
- export declare const getPreparedYAxis: ({ seriesData, yAxis, height, }: {
4
+ export declare const getPreparedYAxis: ({ height, seriesData, seriesOptions, yAxis, }: {
5
+ height: number;
4
6
  seriesData: ChartSeries[];
7
+ seriesOptions: PreparedSeriesOptions;
5
8
  yAxis: ChartYAxis[] | undefined;
6
- height: number;
7
9
  }) => Promise<PreparedAxis[]>;
@@ -3,11 +3,16 @@ import { DASH_STYLE, DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_TYPE, axisCrossh
3
3
  import { formatAxisTickLabel, getClosestPointsRange, getDefaultMinYAxisValue, getHorisontalSvgTextHeight, getLabelsSize, getScaleTicks, isAxisRelatedSeries, wrapText, } from '../../utils';
4
4
  import { createYScale } from '../useAxisScales';
5
5
  const getAxisLabelMaxWidth = async (args) => {
6
- const { axis, seriesData } = args;
6
+ const { axis, seriesData, seriesOptions } = args;
7
7
  if (!axis.labels.enabled) {
8
8
  return 0;
9
9
  }
10
- const scale = createYScale(axis, seriesData, 1);
10
+ const scale = createYScale({
11
+ axis,
12
+ boundsHeight: 1,
13
+ series: seriesData,
14
+ seriesOptions,
15
+ });
11
16
  const ticks = getScaleTicks(scale);
12
17
  // FIXME: it is necessary to filter data, since we do not draw overlapping ticks
13
18
  const step = getClosestPointsRange(axis, ticks);
@@ -23,7 +28,7 @@ const getAxisLabelMaxWidth = async (args) => {
23
28
  });
24
29
  return size.maxWidth;
25
30
  };
26
- export const getPreparedYAxis = ({ seriesData, yAxis, height, }) => {
31
+ export const getPreparedYAxis = ({ height, seriesData, seriesOptions, yAxis, }) => {
27
32
  const axisByPlot = [];
28
33
  const axisItems = yAxis || [{}];
29
34
  const hasAxisRelatedSeries = seriesData.some(isAxisRelatedSeries);
@@ -126,6 +131,7 @@ export const getPreparedYAxis = ({ seriesData, yAxis, height, }) => {
126
131
  preparedAxis.labels.width = await getAxisLabelMaxWidth({
127
132
  axis: preparedAxis,
128
133
  seriesData,
134
+ seriesOptions,
129
135
  });
130
136
  }
131
137
  return preparedAxis;
@@ -13,4 +13,13 @@ 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
+ };
16
25
  export {};
@@ -5,6 +5,38 @@ import { usePrevious } from '../usePrevious';
5
5
  import { getPreparedLegend } from './prepare-legend';
6
6
  import { prepareSeries } from './prepareSeries';
7
7
  import { getActiveLegendItems, getAllLegendItems } from './utils';
8
+ const useVisibleSeries = ({ preparedSeries, activeLegendItems, }) => {
9
+ return React.useMemo(() => {
10
+ return preparedSeries.map((singleSeries) => {
11
+ if (singleSeries.legend.enabled) {
12
+ return Object.assign(Object.assign({}, singleSeries), { visible: activeLegendItems.includes(singleSeries.name) });
13
+ }
14
+ return singleSeries;
15
+ });
16
+ }, [preparedSeries, activeLegendItems]);
17
+ };
18
+ const getPreparedSeries = async ({ seriesData, seriesOptions, colors, preparedLegend, }) => {
19
+ const seriesNames = getSeriesNames(seriesData);
20
+ const colorScale = scaleOrdinal(seriesNames, colors);
21
+ const groupedSeries = group(seriesData, (item) => item.type);
22
+ const acc = [];
23
+ if (!preparedLegend) {
24
+ return acc;
25
+ }
26
+ const list = Array.from(groupedSeries);
27
+ for (let i = 0; i < list.length; i++) {
28
+ const [seriesType, seriesList] = list[i];
29
+ acc.push(...(await prepareSeries({
30
+ type: seriesType,
31
+ series: seriesList,
32
+ seriesOptions,
33
+ legend: preparedLegend,
34
+ colorScale,
35
+ colors,
36
+ })));
37
+ }
38
+ return acc;
39
+ };
8
40
  export const useSeries = (args) => {
9
41
  const { legend, originalSeriesData, seriesData, seriesOptions, colors, preparedLegend: preparedLegendProps = null, } = args;
10
42
  const [preparedLegend, setPreparedLegend] = React.useState(preparedLegendProps);
@@ -17,38 +49,18 @@ export const useSeries = (args) => {
17
49
  const [activeLegendItems, setActiveLegendItems] = React.useState(getActiveLegendItems(preparedSeries));
18
50
  React.useEffect(() => {
19
51
  (async () => {
20
- const seriesNames = getSeriesNames(seriesData);
21
- const colorScale = scaleOrdinal(seriesNames, colors);
22
- const groupedSeries = group(seriesData, (item) => item.type);
23
- const acc = [];
24
- if (!preparedLegend) {
25
- return;
26
- }
27
- const list = Array.from(groupedSeries);
28
- for (let i = 0; i < list.length; i++) {
29
- const [seriesType, seriesList] = list[i];
30
- acc.push(...(await prepareSeries({
31
- type: seriesType,
32
- series: seriesList,
33
- seriesOptions,
34
- legend: preparedLegend,
35
- colorScale,
36
- colors,
37
- })));
38
- }
39
- setPreparedSeries(acc);
40
- setActiveLegendItems(getActiveLegendItems(acc));
52
+ const items = await getPreparedSeries({
53
+ seriesData,
54
+ seriesOptions,
55
+ preparedLegend,
56
+ colors,
57
+ });
58
+ setPreparedSeries(items);
59
+ setActiveLegendItems(getActiveLegendItems(items));
41
60
  })();
42
61
  }, [seriesData, seriesOptions, preparedLegend, colors]);
43
62
  const prevOriginalSeriesData = usePrevious(originalSeriesData);
44
- const chartSeries = React.useMemo(() => {
45
- return preparedSeries.map((singleSeries) => {
46
- if (singleSeries.legend.enabled) {
47
- return Object.assign(Object.assign({}, singleSeries), { visible: activeLegendItems.includes(singleSeries.name) });
48
- }
49
- return singleSeries;
50
- });
51
- }, [preparedSeries, activeLegendItems]);
63
+ const chartSeries = useVisibleSeries({ preparedSeries, activeLegendItems });
52
64
  const handleLegendItemClick = React.useCallback(({ name, metaKey }) => {
53
65
  const allItems = getAllLegendItems(preparedSeries);
54
66
  const onlyItemSelected = activeLegendItems.length === 1 && activeLegendItems.includes(name);
@@ -81,3 +93,21 @@ export const useSeries = (args) => {
81
93
  handleLegendItemClick,
82
94
  };
83
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
+ };
@@ -1,5 +1,5 @@
1
1
  import type { ChartData } from '../../types';
2
- import type { PreparedAxis, PreparedChart } from '../useChartOptions/types';
2
+ import type { PreparedChart } from '../useChartOptions/types';
3
3
  import type { LegendItem, PreparedLegend, PreparedSeries } from './types';
4
4
  export declare function getPreparedLegend(args: {
5
5
  legend: ChartData['legend'];
@@ -11,7 +11,6 @@ export declare function getLegendComponents(args: {
11
11
  chartMargin: PreparedChart['margin'];
12
12
  series: PreparedSeries[];
13
13
  preparedLegend: PreparedLegend;
14
- preparedYAxis: PreparedAxis[];
15
14
  }): {
16
15
  legendConfig: {
17
16
  offset: {
@@ -24,6 +23,7 @@ export declare function getLegendComponents(args: {
24
23
  end: number;
25
24
  }[];
26
25
  } | undefined;
26
+ maxWidth: number;
27
27
  };
28
28
  legendItems: LegendItem[][];
29
29
  };
@@ -4,8 +4,6 @@ import get from 'lodash/get';
4
4
  import merge from 'lodash/merge';
5
5
  import { CONTINUOUS_LEGEND_SIZE, legendDefaults } from '../../constants';
6
6
  import { getDefaultColorStops, getDomainForContinuousColorScale, getLabelsSize } from '../../utils';
7
- import { getBoundsWidth } from '../useChartDimensions';
8
- import { getYAxisWidth } from '../useChartDimensions/utils';
9
7
  export async function getPreparedLegend(args) {
10
8
  var _a, _b, _c, _d, _e, _f, _g;
11
9
  const { legend, series } = args;
@@ -168,8 +166,8 @@ function getPagination(args) {
168
166
  return { pages };
169
167
  }
170
168
  export function getLegendComponents(args) {
171
- const { chartWidth, chartHeight, chartMargin, series, preparedLegend, preparedYAxis } = args;
172
- const maxLegendWidth = getBoundsWidth({ chartWidth, chartMargin, preparedYAxis });
169
+ const { chartWidth, chartHeight, chartMargin, series, preparedLegend } = args;
170
+ const maxLegendWidth = chartWidth - chartMargin.right - chartMargin.left;
173
171
  const maxLegendHeight = (chartHeight - chartMargin.top - chartMargin.bottom - preparedLegend.margin) / 2;
174
172
  const flattenLegendItems = getFlattenLegendItems(series, preparedLegend);
175
173
  const items = getGroupedLegendItems({
@@ -199,8 +197,8 @@ export function getLegendComponents(args) {
199
197
  }
200
198
  const top = chartHeight - chartMargin.bottom - preparedLegend.height;
201
199
  const offset = {
202
- left: chartMargin.left + getYAxisWidth(preparedYAxis[0]),
200
+ left: chartMargin.left,
203
201
  top,
204
202
  };
205
- return { legendConfig: { offset, pagination }, legendItems: items };
203
+ return { legendConfig: { offset, pagination, maxWidth: maxLegendWidth }, legendItems: items };
206
204
  }
@@ -53,6 +53,7 @@ export type LegendConfig = {
53
53
  left: number;
54
54
  top: number;
55
55
  };
56
+ maxWidth: number;
56
57
  pagination?: {
57
58
  pages: {
58
59
  start: number;
@@ -2,7 +2,7 @@ import { ascending, descending, max, sort } from 'd3';
2
2
  import get from 'lodash/get';
3
3
  import { getDataCategoryValue, getLabelsSize } from '../../../utils';
4
4
  import { getFormattedValue } from '../../../utils/chart/format';
5
- import { MIN_BAR_GAP, MIN_BAR_GROUP_GAP, MIN_BAR_WIDTH } from '../constants';
5
+ import { MIN_BAR_GAP, MIN_BAR_GROUP_GAP, MIN_BAR_WIDTH } from '../../constants';
6
6
  async function getLabelData(d) {
7
7
  if (!d.series.dataLabels.enabled) {
8
8
  return undefined;