@gravity-ui/chartkit 4.5.0 → 4.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/build/plugins/d3/renderer/D3Widget.js +11 -1
  2. package/build/plugins/d3/renderer/components/AxisX.d.ts +1 -2
  3. package/build/plugins/d3/renderer/components/AxisX.js +39 -61
  4. package/build/plugins/d3/renderer/components/AxisY.js +28 -31
  5. package/build/plugins/d3/renderer/components/Chart.js +19 -7
  6. package/build/plugins/d3/renderer/components/Legend.d.ts +5 -6
  7. package/build/plugins/d3/renderer/components/Legend.js +139 -84
  8. package/build/plugins/d3/renderer/components/styles.css +27 -0
  9. package/build/plugins/d3/renderer/constants/defaults/axis.d.ts +5 -0
  10. package/build/plugins/d3/renderer/constants/defaults/axis.js +5 -0
  11. package/build/plugins/d3/renderer/constants/defaults/index.d.ts +2 -0
  12. package/build/plugins/d3/renderer/constants/defaults/index.js +2 -0
  13. package/build/plugins/d3/renderer/constants/defaults/legend.d.ts +4 -0
  14. package/build/plugins/d3/renderer/constants/defaults/legend.js +8 -0
  15. package/build/plugins/d3/renderer/{constants.d.ts → constants/index.d.ts} +1 -1
  16. package/build/plugins/d3/renderer/{constants.js → constants/index.js} +1 -1
  17. package/build/plugins/d3/renderer/hooks/useAxisScales/index.d.ts +3 -1
  18. package/build/plugins/d3/renderer/hooks/useAxisScales/index.js +64 -62
  19. package/build/plugins/d3/renderer/hooks/useChartDimensions/index.d.ts +7 -4
  20. package/build/plugins/d3/renderer/hooks/useChartDimensions/index.js +65 -7
  21. package/build/plugins/d3/renderer/hooks/useChartDimensions/utils.d.ts +6 -0
  22. package/build/plugins/d3/renderer/hooks/useChartDimensions/utils.js +7 -0
  23. package/build/plugins/d3/renderer/hooks/useChartOptions/chart.d.ts +1 -3
  24. package/build/plugins/d3/renderer/hooks/useChartOptions/chart.js +9 -68
  25. package/build/plugins/d3/renderer/hooks/useChartOptions/index.d.ts +3 -1
  26. package/build/plugins/d3/renderer/hooks/useChartOptions/index.js +3 -8
  27. package/build/plugins/d3/renderer/hooks/useChartOptions/types.d.ts +3 -6
  28. package/build/plugins/d3/renderer/hooks/useChartOptions/x-axis.js +4 -2
  29. package/build/plugins/d3/renderer/hooks/useChartOptions/y-axis.d.ts +3 -2
  30. package/build/plugins/d3/renderer/hooks/useChartOptions/y-axis.js +31 -4
  31. package/build/plugins/d3/renderer/hooks/useSeries/constants.d.ts +1 -1
  32. package/build/plugins/d3/renderer/hooks/useSeries/constants.js +1 -1
  33. package/build/plugins/d3/renderer/hooks/useSeries/index.d.ts +19 -7
  34. package/build/plugins/d3/renderer/hooks/useSeries/index.js +26 -8
  35. package/build/plugins/d3/renderer/hooks/useSeries/prepare-legend.d.ts +27 -0
  36. package/build/plugins/d3/renderer/hooks/useSeries/prepare-legend.js +92 -0
  37. package/build/plugins/d3/renderer/hooks/useSeries/prepareSeries.d.ts +1 -2
  38. package/build/plugins/d3/renderer/hooks/useSeries/types.d.ts +26 -1
  39. package/build/plugins/d3/renderer/hooks/useShapes/bar-x.js +2 -1
  40. package/build/plugins/d3/renderer/utils/axis-generators/bottom.d.ts +21 -0
  41. package/build/plugins/d3/renderer/utils/axis-generators/bottom.js +104 -0
  42. package/build/plugins/d3/renderer/utils/axis-generators/index.d.ts +1 -0
  43. package/build/plugins/d3/renderer/utils/axis-generators/index.js +1 -0
  44. package/build/plugins/d3/renderer/utils/axis.d.ts +22 -0
  45. package/build/plugins/d3/renderer/utils/axis.js +43 -0
  46. package/build/plugins/d3/renderer/utils/index.d.ts +7 -4
  47. package/build/plugins/d3/renderer/utils/index.js +16 -6
  48. package/build/plugins/d3/renderer/utils/text.d.ts +20 -2
  49. package/build/plugins/d3/renderer/utils/text.js +51 -1
  50. package/build/plugins/d3/renderer/utils/time.d.ts +3 -0
  51. package/build/plugins/d3/renderer/utils/time.js +34 -0
  52. package/build/plugins/highcharts/renderer/components/HighchartsComponent.js +3 -3
  53. package/build/plugins/shared/format-number/format-number.d.ts +1 -0
  54. package/build/plugins/shared/format-number/format-number.js +19 -20
  55. package/build/types/widget-data/axis.d.ts +13 -1
  56. package/build/types/widget-data/legend.d.ts +24 -7
  57. package/build/utils/common.d.ts +1 -0
  58. package/build/utils/common.js +1 -1
  59. package/build/utils/index.d.ts +1 -1
  60. package/build/utils/index.js +1 -1
  61. package/package.json +1 -1
  62. package/build/plugins/d3/renderer/hooks/useChartOptions/legend.d.ts +0 -6
  63. package/build/plugins/d3/renderer/hooks/useChartOptions/legend.js +0 -12
@@ -0,0 +1,8 @@
1
+ export const legendDefaults = {
2
+ align: 'center',
3
+ itemDistance: 20,
4
+ margin: 15,
5
+ itemStyle: {
6
+ fontSize: '12px',
7
+ },
8
+ };
@@ -1,4 +1,4 @@
1
+ export * from './defaults';
1
2
  export declare const DEFAULT_PALETTE: string[];
2
3
  export declare const DEFAULT_AXIS_LABEL_FONT_SIZE = "11px";
3
- export declare const DEFAULT_AXIS_LABEL_PADDING = 10;
4
4
  export declare const DEFAULT_AXIS_TITLE_FONT_SIZE = "14px";
@@ -1,3 +1,4 @@
1
+ export * from './defaults';
1
2
  export const DEFAULT_PALETTE = [
2
3
  '#4DA2F1',
3
4
  '#FF3D64',
@@ -21,5 +22,4 @@ export const DEFAULT_PALETTE = [
21
22
  '#DCA3D7',
22
23
  ];
23
24
  export const DEFAULT_AXIS_LABEL_FONT_SIZE = '11px';
24
- export const DEFAULT_AXIS_LABEL_PADDING = 10;
25
25
  export const DEFAULT_AXIS_TITLE_FONT_SIZE = '14px';
@@ -1,5 +1,5 @@
1
1
  import type { ScaleBand, ScaleLinear, ScaleTime } from 'd3';
2
- import type { ChartOptions } from '../useChartOptions/types';
2
+ import type { ChartOptions, PreparedAxis } from '../useChartOptions/types';
3
3
  import { PreparedSeries } from '../useSeries/types';
4
4
  export type ChartScale = ScaleLinear<number, number> | ScaleBand<string> | ScaleTime<number, number>;
5
5
  type Args = {
@@ -13,6 +13,8 @@ type ReturnValue = {
13
13
  xScale?: ChartScale;
14
14
  yScale?: ChartScale;
15
15
  };
16
+ export declare function createYScale(axis: PreparedAxis, series: PreparedSeries[], boundsHeight: number): ScaleLinear<number, number, never> | ScaleBand<string> | ScaleTime<number, number, never>;
17
+ export declare function createXScale(axis: PreparedAxis, series: PreparedSeries[], boundsWidth: number): ScaleLinear<number, number, never> | ScaleBand<string> | ScaleTime<number, number, never>;
16
18
  /**
17
19
  * Uses to create scales for axis related series
18
20
  */
@@ -17,108 +17,110 @@ const filterCategoriesByVisibleSeries = (args) => {
17
17
  });
18
18
  return categories.filter((c) => visibleCategories.has(c));
19
19
  };
20
- const createScales = (args) => {
21
- const { boundsWidth, boundsHeight, series, xAxis, yAxis } = args;
22
- const xMin = get(xAxis, 'min');
23
- const xType = get(xAxis, 'type', 'linear');
24
- const xCategories = get(xAxis, 'categories');
25
- const xTimestamps = get(xAxis, 'timestamps');
26
- const yType = get(yAxis[0], 'type', 'linear');
27
- const yMin = get(yAxis[0], 'min');
28
- const yCategories = get(yAxis[0], 'categories');
29
- const yTimestamps = get(xAxis, 'timestamps');
30
- let visibleSeries = getOnlyVisibleSeries(series);
31
- // Reassign to all series in case of all series unselected,
32
- // otherwise we will get an empty space without grid
33
- visibleSeries = visibleSeries.length === 0 ? series : visibleSeries;
34
- let xScale;
35
- let yScale;
36
- const xAxisMinPadding = boundsWidth * xAxis.maxPadding;
37
- const xRange = [0, boundsWidth - xAxisMinPadding];
38
- switch (xType) {
20
+ export function createYScale(axis, series, boundsHeight) {
21
+ const yType = get(axis, 'type', 'linear');
22
+ const yMin = get(axis, 'min');
23
+ const yCategories = get(axis, 'categories');
24
+ const yTimestamps = get(axis, 'timestamps');
25
+ switch (yType) {
39
26
  case 'linear': {
40
- const domain = getDomainDataXBySeries(visibleSeries);
27
+ const domain = getDomainDataYBySeries(series);
28
+ const range = [boundsHeight, boundsHeight * axis.maxPadding];
41
29
  if (isNumericalArrayData(domain)) {
42
- const [domainXMin, xMax] = extent(domain);
43
- const xMinValue = typeof xMin === 'number' ? xMin : domainXMin;
44
- xScale = scaleLinear().domain([xMinValue, xMax]).range(xRange).nice();
30
+ const [domainYMin, yMax] = extent(domain);
31
+ const yMinValue = typeof yMin === 'number' ? yMin : domainYMin;
32
+ return scaleLinear().domain([yMinValue, yMax]).range(range).nice();
45
33
  }
46
34
  break;
47
35
  }
48
36
  case 'category': {
49
- if (xCategories) {
37
+ if (yCategories) {
50
38
  const filteredCategories = filterCategoriesByVisibleSeries({
51
- axisDirection: 'x',
52
- categories: xCategories,
53
- series: visibleSeries,
39
+ axisDirection: 'y',
40
+ categories: yCategories,
41
+ series: series,
54
42
  });
55
- xScale = scaleBand().domain(filteredCategories).range([0, boundsWidth]);
56
- if (xScale.step() / 2 < xAxisMinPadding) {
57
- xScale.range(xRange);
58
- }
43
+ return scaleBand().domain(filteredCategories).range([boundsHeight, 0]);
59
44
  }
60
45
  break;
61
46
  }
62
47
  case 'datetime': {
63
- if (xTimestamps) {
64
- const [xMin, xMax] = extent(xTimestamps);
65
- xScale = scaleUtc().domain([xMin, xMax]).range(xRange).nice();
48
+ const range = [boundsHeight, boundsHeight * axis.maxPadding];
49
+ if (yTimestamps) {
50
+ const [yMin, yMax] = extent(yTimestamps);
51
+ return scaleUtc().domain([yMin, yMax]).range(range).nice();
66
52
  }
67
53
  else {
68
- const domain = getDomainDataXBySeries(visibleSeries);
54
+ const domain = getDomainDataYBySeries(series);
69
55
  if (isNumericalArrayData(domain)) {
70
- const [xMin, xMax] = extent(domain);
71
- xScale = scaleUtc().domain([xMin, xMax]).range(xRange).nice();
56
+ const [yMin, yMax] = extent(domain);
57
+ return scaleUtc().domain([yMin, yMax]).range(range).nice();
72
58
  }
73
59
  }
74
60
  break;
75
61
  }
76
62
  }
77
- if (!xScale) {
78
- throw new Error('Failed to create xScale');
79
- }
80
- switch (yType) {
63
+ throw new Error('Failed to create yScale');
64
+ }
65
+ export function createXScale(axis, series, boundsWidth) {
66
+ const xMin = get(axis, 'min');
67
+ const xType = get(axis, 'type', 'linear');
68
+ const xCategories = get(axis, 'categories');
69
+ const xTimestamps = get(axis, 'timestamps');
70
+ const xAxisMinPadding = boundsWidth * axis.maxPadding;
71
+ const xRange = [0, boundsWidth - xAxisMinPadding];
72
+ switch (xType) {
81
73
  case 'linear': {
82
- const domain = getDomainDataYBySeries(visibleSeries);
83
- const range = [boundsHeight, boundsHeight * yAxis[0].maxPadding];
74
+ const domain = getDomainDataXBySeries(series);
84
75
  if (isNumericalArrayData(domain)) {
85
- const [domainYMin, yMax] = extent(domain);
86
- const yMinValue = typeof yMin === 'number' ? yMin : domainYMin;
87
- yScale = scaleLinear().domain([yMinValue, yMax]).range(range).nice();
76
+ const [domainXMin, xMax] = extent(domain);
77
+ const xMinValue = typeof xMin === 'number' ? xMin : domainXMin;
78
+ return scaleLinear().domain([xMinValue, xMax]).range(xRange).nice();
88
79
  }
89
80
  break;
90
81
  }
91
82
  case 'category': {
92
- if (yCategories) {
83
+ if (xCategories) {
93
84
  const filteredCategories = filterCategoriesByVisibleSeries({
94
- axisDirection: 'y',
95
- categories: yCategories,
96
- series: visibleSeries,
85
+ axisDirection: 'x',
86
+ categories: xCategories,
87
+ series: series,
97
88
  });
98
- yScale = scaleBand().domain(filteredCategories).range([boundsHeight, 0]);
89
+ const xScale = scaleBand().domain(filteredCategories).range([0, boundsWidth]);
90
+ if (xScale.step() / 2 < xAxisMinPadding) {
91
+ xScale.range(xRange);
92
+ }
93
+ return xScale;
99
94
  }
100
95
  break;
101
96
  }
102
97
  case 'datetime': {
103
- const range = [boundsHeight, boundsHeight * yAxis[0].maxPadding];
104
- if (yTimestamps) {
105
- const [yMin, yMax] = extent(yTimestamps);
106
- yScale = scaleUtc().domain([yMin, yMax]).range(range).nice();
98
+ if (xTimestamps) {
99
+ const [xMin, xMax] = extent(xTimestamps);
100
+ return scaleUtc().domain([xMin, xMax]).range(xRange).nice();
107
101
  }
108
102
  else {
109
- const domain = getDomainDataYBySeries(visibleSeries);
103
+ const domain = getDomainDataXBySeries(series);
110
104
  if (isNumericalArrayData(domain)) {
111
- const [yMin, yMax] = extent(domain);
112
- yScale = scaleUtc().domain([yMin, yMax]).range(range).nice();
105
+ const [xMin, xMax] = extent(domain);
106
+ return scaleUtc().domain([xMin, xMax]).range(xRange).nice();
113
107
  }
114
108
  }
115
109
  break;
116
110
  }
117
111
  }
118
- if (!yScale) {
119
- throw new Error('Failed to create yScale');
120
- }
121
- return { xScale, yScale };
112
+ throw new Error('Failed to create xScale');
113
+ }
114
+ const createScales = (args) => {
115
+ const { boundsWidth, boundsHeight, series, xAxis, yAxis } = args;
116
+ let visibleSeries = getOnlyVisibleSeries(series);
117
+ // Reassign to all series in case of all series unselected,
118
+ // otherwise we will get an empty space without grid
119
+ visibleSeries = visibleSeries.length === 0 ? series : visibleSeries;
120
+ return {
121
+ xScale: createXScale(xAxis, visibleSeries, boundsWidth),
122
+ yScale: createYScale(yAxis[0], visibleSeries, boundsHeight),
123
+ };
122
124
  };
123
125
  /**
124
126
  * Uses to create scales for axis related series
@@ -1,13 +1,16 @@
1
- import type { ChartMargin } from '../../../../../types/widget-data';
2
- import type { PreparedAxis } from '../useChartOptions/types';
1
+ import type { ChartMargin } from '../../../../../types';
2
+ import type { PreparedAxis, PreparedLegend, PreparedSeries } from '../../hooks';
3
+ export { getBoundsWidth } from './utils';
3
4
  type Args = {
4
5
  width: number;
5
6
  height: number;
6
7
  margin: ChartMargin;
7
- yAxis?: PreparedAxis[];
8
+ preparedLegend: PreparedLegend;
9
+ preparedXAxis: PreparedAxis;
10
+ preparedYAxis: PreparedAxis[];
11
+ preparedSeries: PreparedSeries[];
8
12
  };
9
13
  export declare const useChartDimensions: (args: Args) => {
10
14
  boundsWidth: number;
11
15
  boundsHeight: number;
12
16
  };
13
- export {};
@@ -1,9 +1,67 @@
1
+ import React from 'react';
2
+ import { createXScale } from '../../hooks';
3
+ import { formatAxisTickLabel, getClosestPointsRange, getHorisontalSvgTextHeight, getLabelsMaxHeight, getMaxTickCount, getTicksCount, getXAxisItems, hasOverlappingLabels, isAxisRelatedSeries, } from '../../utils';
4
+ import { getBoundsWidth } from './utils';
5
+ export { getBoundsWidth } from './utils';
6
+ const getHeightOccupiedByXAxis = ({ preparedXAxis, preparedSeries, width, }) => {
7
+ let height = preparedXAxis.title.height;
8
+ if (preparedXAxis.labels.enabled) {
9
+ const scale = createXScale(preparedXAxis, preparedSeries, width);
10
+ const tickCount = getTicksCount({ axis: preparedXAxis, range: width });
11
+ const ticks = getXAxisItems({
12
+ scale: scale,
13
+ count: tickCount,
14
+ maxCount: getMaxTickCount({ width, axis: preparedXAxis }),
15
+ });
16
+ const step = getClosestPointsRange(preparedXAxis, ticks);
17
+ const labels = ticks.map((value) => {
18
+ return formatAxisTickLabel({
19
+ axis: preparedXAxis,
20
+ value,
21
+ step,
22
+ });
23
+ });
24
+ const overlapping = hasOverlappingLabels({
25
+ width,
26
+ labels,
27
+ padding: preparedXAxis.labels.padding,
28
+ style: preparedXAxis.labels.style,
29
+ });
30
+ const labelsHeight = overlapping
31
+ ? getLabelsMaxHeight({
32
+ labels,
33
+ style: preparedXAxis.labels.style,
34
+ transform: 'rotate(-45)',
35
+ })
36
+ : getHorisontalSvgTextHeight({ text: 'Tmp', style: preparedXAxis.labels.style });
37
+ height += preparedXAxis.labels.margin + labelsHeight;
38
+ }
39
+ return height;
40
+ };
41
+ const getBottomOffset = (args) => {
42
+ const { hasAxisRelatedSeries, preparedLegend, preparedXAxis, preparedSeries, width } = args;
43
+ let result = 0;
44
+ if (preparedLegend.enabled) {
45
+ result += preparedLegend.height + preparedLegend.margin;
46
+ }
47
+ if (hasAxisRelatedSeries) {
48
+ result += getHeightOccupiedByXAxis({ preparedXAxis, preparedSeries, width });
49
+ }
50
+ return result;
51
+ };
1
52
  export const useChartDimensions = (args) => {
2
- const { margin, width, height, yAxis } = args;
3
- const yAxisTitleHeight = (yAxis === null || yAxis === void 0 ? void 0 : yAxis.reduce((acc, axis) => {
4
- return acc + (axis.title.height || 0);
5
- }, 0)) || 0;
6
- const boundsWidth = width - margin.right - margin.left - yAxisTitleHeight;
7
- const boundsHeight = height - margin.top - margin.bottom;
8
- return { boundsWidth, boundsHeight };
53
+ const { margin, width, height, preparedLegend, preparedXAxis, preparedYAxis, preparedSeries } = args;
54
+ return React.useMemo(() => {
55
+ const hasAxisRelatedSeries = preparedSeries.some(isAxisRelatedSeries);
56
+ const boundsWidth = getBoundsWidth({ chartWidth: width, chartMargin: margin, preparedYAxis });
57
+ const bottomOffset = getBottomOffset({
58
+ hasAxisRelatedSeries,
59
+ preparedLegend,
60
+ preparedXAxis,
61
+ preparedSeries,
62
+ width: boundsWidth,
63
+ });
64
+ const boundsHeight = height - margin.top - margin.bottom - bottomOffset;
65
+ return { boundsWidth, boundsHeight };
66
+ }, [margin, width, height, preparedLegend, preparedXAxis, preparedYAxis, preparedSeries]);
9
67
  };
@@ -0,0 +1,6 @@
1
+ import type { PreparedAxis, PreparedChart } from '../../hooks';
2
+ export declare const getBoundsWidth: (args: {
3
+ chartWidth: number;
4
+ chartMargin: PreparedChart['margin'];
5
+ preparedYAxis: PreparedAxis[];
6
+ }) => number;
@@ -0,0 +1,7 @@
1
+ export const getBoundsWidth = (args) => {
2
+ const { chartWidth, chartMargin, preparedYAxis } = args;
3
+ const yAxisTitleHeight = preparedYAxis.reduce((acc, axis) => {
4
+ return acc + (axis.title.height || 0);
5
+ }, 0) || 0;
6
+ return chartWidth - chartMargin.right - chartMargin.left - yAxisTitleHeight;
7
+ };
@@ -1,10 +1,8 @@
1
1
  import type { ChartKitWidgetData } from '../../../../../types/widget-data';
2
- import type { PreparedAxis, PreparedChart, PreparedTitle, PreparedLegend } from './types';
2
+ import type { PreparedAxis, PreparedChart, PreparedTitle } from './types';
3
3
  export declare const getPreparedChart: (args: {
4
4
  chart: ChartKitWidgetData['chart'];
5
5
  series: ChartKitWidgetData['series'];
6
- preparedLegend: PreparedLegend;
7
- preparedXAxis: PreparedAxis;
8
6
  preparedY1Axis: PreparedAxis;
9
7
  preparedTitle?: PreparedTitle;
10
8
  }) => PreparedChart;
@@ -1,47 +1,6 @@
1
- import { select, max } from 'd3';
2
1
  import get from 'lodash/get';
3
- import { formatAxisTickLabel, getDomainDataYBySeries, getHorisontalSvgTextHeight, isAxisRelatedSeries, } from '../../utils';
4
- const AXIS_WIDTH = 1;
5
- const getAxisLabelMaxWidth = (args) => {
6
- const { axis, series } = args;
7
- let maxDomainValue;
8
- let width = 0;
9
- switch (axis.type) {
10
- case 'category': {
11
- const yCategories = get(axis, 'categories', []);
12
- maxDomainValue = [...yCategories].sort((c1, c2) => c2.length - c1.length)[0];
13
- break;
14
- }
15
- case 'datetime': {
16
- const yTimestamps = get(axis, 'timestamps');
17
- const domain = yTimestamps || getDomainDataYBySeries(series);
18
- maxDomainValue = max(domain);
19
- break;
20
- }
21
- case 'linear': {
22
- const domain = getDomainDataYBySeries(series);
23
- maxDomainValue = max(domain);
24
- }
25
- }
26
- let formattedValue = '';
27
- if (axis.labels.enabled) {
28
- formattedValue = formatAxisTickLabel({
29
- axisType: axis.type,
30
- value: maxDomainValue,
31
- dateFormat: axis.labels['dateFormat'],
32
- numberFormat: axis.labels['numberFormat'],
33
- });
34
- }
35
- select(document.body)
36
- .append('text')
37
- .style('font-size', axis.labels.style.fontSize)
38
- .text(formattedValue)
39
- .each(function () {
40
- width = this.getBoundingClientRect().width;
41
- })
42
- .remove();
43
- return width;
44
- };
2
+ import { isAxisRelatedSeries, getHorisontalSvgTextHeight } from '../../utils';
3
+ const AXIS_LINE_WIDTH = 1;
45
4
  const getMarginTop = (args) => {
46
5
  const { chart, hasAxisRelatedSeries, preparedY1Axis, preparedTitle } = args;
47
6
  let marginTop = get(chart, 'margin.top', 0);
@@ -54,27 +13,14 @@ const getMarginTop = (args) => {
54
13
  }
55
14
  return marginTop;
56
15
  };
57
- const getMarginBottom = (args) => {
58
- const { chart, hasAxisRelatedSeries, preparedLegend, preparedXAxis } = args;
59
- let marginBottom = get(chart, 'margin.bottom', 0) + preparedLegend.height;
60
- if (hasAxisRelatedSeries) {
61
- marginBottom +=
62
- preparedXAxis.title.height +
63
- getHorisontalSvgTextHeight({ text: 'Tmp', style: preparedXAxis.labels.style });
64
- if (preparedXAxis.labels.enabled) {
65
- marginBottom += preparedXAxis.labels.padding;
66
- }
67
- }
68
- return marginBottom;
69
- };
70
16
  const getMarginLeft = (args) => {
71
- const { chart, hasAxisRelatedSeries, series, preparedY1Axis } = args;
17
+ const { chart, hasAxisRelatedSeries, preparedY1Axis } = args;
72
18
  let marginLeft = get(chart, 'margin.left', 0);
73
19
  if (hasAxisRelatedSeries) {
74
20
  marginLeft +=
75
- AXIS_WIDTH +
76
- preparedY1Axis.labels.padding +
77
- getAxisLabelMaxWidth({ axis: preparedY1Axis, series: series.data }) +
21
+ AXIS_LINE_WIDTH +
22
+ preparedY1Axis.labels.margin +
23
+ (preparedY1Axis.labels.maxWidth || 0) +
78
24
  preparedY1Axis.title.height;
79
25
  }
80
26
  return marginLeft;
@@ -84,16 +30,11 @@ const getMarginRight = (args) => {
84
30
  return get(chart, 'margin.right', 0);
85
31
  };
86
32
  export const getPreparedChart = (args) => {
87
- const { chart, series, preparedLegend, preparedXAxis, preparedY1Axis, preparedTitle } = args;
33
+ const { chart, series, preparedY1Axis, preparedTitle } = args;
88
34
  const hasAxisRelatedSeries = series.data.some(isAxisRelatedSeries);
89
35
  const marginTop = getMarginTop({ chart, hasAxisRelatedSeries, preparedY1Axis, preparedTitle });
90
- const marginBottom = getMarginBottom({
91
- chart,
92
- hasAxisRelatedSeries,
93
- preparedLegend,
94
- preparedXAxis,
95
- });
96
- const marginLeft = getMarginLeft({ chart, hasAxisRelatedSeries, series, preparedY1Axis });
36
+ const marginBottom = get(chart, 'margin.bottom', 0);
37
+ const marginLeft = getMarginLeft({ chart, hasAxisRelatedSeries, preparedY1Axis });
97
38
  const marginRight = getMarginRight({ chart });
98
39
  return {
99
40
  margin: {
@@ -1,5 +1,7 @@
1
1
  import type { ChartKitWidgetData } from '../../../../../types/widget-data';
2
2
  import type { ChartOptions } from './types';
3
- type Args = ChartKitWidgetData;
3
+ type Args = {
4
+ data: ChartKitWidgetData;
5
+ };
4
6
  export declare const useChartOptions: (args: Args) => ChartOptions;
5
7
  export {};
@@ -1,34 +1,29 @@
1
1
  import React from 'react';
2
2
  import { getPreparedChart } from './chart';
3
- import { getPreparedLegend } from './legend';
4
3
  import { getPreparedTitle } from './title';
5
4
  import { getPreparedTooltip } from './tooltip';
6
5
  import { getPreparedXAxis } from './x-axis';
7
6
  import { getPreparedYAxis } from './y-axis';
8
7
  export const useChartOptions = (args) => {
9
- const { chart, series, legend, title, tooltip, xAxis, yAxis } = args;
8
+ const { data: { chart, series, title, tooltip, xAxis, yAxis }, } = args;
10
9
  const options = React.useMemo(() => {
11
10
  const preparedTitle = getPreparedTitle({ title });
12
11
  const preparedTooltip = getPreparedTooltip({ tooltip });
13
- const preparedLegend = getPreparedLegend({ legend, series });
14
- const preparedYAxis = getPreparedYAxis({ yAxis });
12
+ const preparedYAxis = getPreparedYAxis({ series: series.data, yAxis });
15
13
  const preparedXAxis = getPreparedXAxis({ xAxis });
16
14
  const preparedChart = getPreparedChart({
17
15
  chart,
18
16
  series,
19
17
  preparedTitle,
20
- preparedLegend,
21
- preparedXAxis,
22
18
  preparedY1Axis: preparedYAxis[0],
23
19
  });
24
20
  return {
25
21
  chart: preparedChart,
26
- legend: preparedLegend,
27
22
  title: preparedTitle,
28
23
  tooltip: preparedTooltip,
29
24
  xAxis: preparedXAxis,
30
25
  yAxis: preparedYAxis,
31
26
  };
32
- }, [chart, legend, title, tooltip, series, xAxis, yAxis]);
27
+ }, [chart, title, tooltip, series, xAxis, yAxis]);
33
28
  return options;
34
29
  };
@@ -1,13 +1,11 @@
1
- import type { BaseTextStyle, ChartKitWidgetData, ChartKitWidgetAxis, ChartKitWidgetAxisType, ChartKitWidgetAxisLabels, ChartKitWidgetLegend, ChartMargin } from '../../../../../types/widget-data';
2
- type PreparedAxisLabels = Omit<ChartKitWidgetAxisLabels, 'enabled' | 'padding' | 'style'> & Required<Pick<ChartKitWidgetAxisLabels, 'enabled' | 'padding'>> & {
1
+ import type { BaseTextStyle, ChartKitWidgetData, ChartKitWidgetAxis, ChartKitWidgetAxisType, ChartKitWidgetAxisLabels, ChartMargin } from '../../../../../types/widget-data';
2
+ type PreparedAxisLabels = Omit<ChartKitWidgetAxisLabels, 'enabled' | 'padding' | 'style'> & Required<Pick<ChartKitWidgetAxisLabels, 'enabled' | 'padding' | 'margin'>> & {
3
3
  style: BaseTextStyle;
4
+ maxWidth?: number;
4
5
  };
5
6
  export type PreparedChart = {
6
7
  margin: ChartMargin;
7
8
  };
8
- export type PreparedLegend = Required<ChartKitWidgetLegend> & {
9
- height: number;
10
- };
11
9
  export type PreparedAxis = Omit<ChartKitWidgetAxis, 'type' | 'labels'> & {
12
10
  type: ChartKitWidgetAxisType;
13
11
  labels: PreparedAxisLabels;
@@ -33,7 +31,6 @@ export type PreparedTooltip = ChartKitWidgetData['tooltip'] & {
33
31
  };
34
32
  export type ChartOptions = {
35
33
  chart: PreparedChart;
36
- legend: PreparedLegend;
37
34
  tooltip: PreparedTooltip;
38
35
  xAxis: PreparedAxis;
39
36
  yAxis: PreparedAxis[];
@@ -1,5 +1,5 @@
1
1
  import get from 'lodash/get';
2
- import { DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_LABEL_PADDING, DEFAULT_AXIS_TITLE_FONT_SIZE, } from '../../constants';
2
+ import { axisLabelsDefaults, DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_TITLE_FONT_SIZE, } from '../../constants';
3
3
  import { getHorisontalSvgTextHeight } from '../../utils';
4
4
  export const getPreparedXAxis = ({ xAxis }) => {
5
5
  const titleText = get(xAxis, 'title.text', '');
@@ -10,9 +10,11 @@ export const getPreparedXAxis = ({ xAxis }) => {
10
10
  type: get(xAxis, 'type', 'linear'),
11
11
  labels: {
12
12
  enabled: get(xAxis, 'labels.enabled', true),
13
- padding: get(xAxis, 'labels.padding', DEFAULT_AXIS_LABEL_PADDING),
13
+ margin: get(xAxis, 'labels.margin', axisLabelsDefaults.margin),
14
+ padding: get(xAxis, 'labels.padding', axisLabelsDefaults.padding),
14
15
  dateFormat: get(xAxis, 'labels.dateFormat'),
15
16
  numberFormat: get(xAxis, 'labels.numberFormat'),
17
+ autoRotation: get(xAxis, 'labels.autoRotation', true),
16
18
  style: { fontSize: get(xAxis, 'labels.style.fontSize', DEFAULT_AXIS_LABEL_FONT_SIZE) },
17
19
  },
18
20
  lineColor: get(xAxis, 'lineColor'),
@@ -1,5 +1,6 @@
1
- import type { ChartKitWidgetData } from '../../../../../types/widget-data';
1
+ import type { ChartKitWidgetData, ChartKitWidgetSeries } from '../../../../../types/widget-data';
2
2
  import type { PreparedAxis } from './types';
3
- export declare const getPreparedYAxis: ({ yAxis }: {
3
+ export declare const getPreparedYAxis: ({ series, yAxis, }: {
4
+ series: ChartKitWidgetSeries[];
4
5
  yAxis: ChartKitWidgetData['yAxis'];
5
6
  }) => PreparedAxis[];
@@ -1,7 +1,31 @@
1
1
  import get from 'lodash/get';
2
- import { DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_LABEL_PADDING, DEFAULT_AXIS_TITLE_FONT_SIZE, } from '../../constants';
3
- import { getHorisontalSvgTextHeight } from '../../utils';
4
- export const getPreparedYAxis = ({ yAxis }) => {
2
+ import { axisLabelsDefaults, DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_TITLE_FONT_SIZE, } from '../../constants';
3
+ import { getHorisontalSvgTextHeight, formatAxisTickLabel, getClosestPointsRange, getScaleTicks, getLabelsMaxWidth, } from '../../utils';
4
+ import { createYScale } from '../useAxisScales';
5
+ const getAxisLabelMaxWidth = (args) => {
6
+ const { axis, series } = args;
7
+ if (!axis.labels.enabled) {
8
+ return 0;
9
+ }
10
+ const scale = createYScale(axis, series, 1);
11
+ const ticks = getScaleTicks(scale);
12
+ // FIXME: it is necessary to filter data, since we do not draw overlapping ticks
13
+ const step = getClosestPointsRange(axis, ticks);
14
+ const labels = ticks.map((tick) => formatAxisTickLabel({
15
+ axis,
16
+ value: tick,
17
+ step,
18
+ }));
19
+ return getLabelsMaxWidth({
20
+ labels,
21
+ style: axis.labels.style,
22
+ });
23
+ };
24
+ const applyLabelsMaxWidth = (args) => {
25
+ const { series, preparedYAxis } = args;
26
+ preparedYAxis.labels.maxWidth = getAxisLabelMaxWidth({ axis: preparedYAxis, series });
27
+ };
28
+ export const getPreparedYAxis = ({ series, yAxis, }) => {
5
29
  // FIXME: add support for n axises
6
30
  const yAxis1 = yAxis === null || yAxis === void 0 ? void 0 : yAxis[0];
7
31
  const y1LabelsStyle = {
@@ -15,7 +39,9 @@ export const getPreparedYAxis = ({ yAxis }) => {
15
39
  type: get(yAxis1, 'type', 'linear'),
16
40
  labels: {
17
41
  enabled: get(yAxis1, 'labels.enabled', true),
18
- padding: get(yAxis1, 'labels.padding', DEFAULT_AXIS_LABEL_PADDING),
42
+ margin: get(yAxis1, 'labels.margin', axisLabelsDefaults.margin),
43
+ padding: get(yAxis1, 'labels.padding', axisLabelsDefaults.padding),
44
+ autoRotation: get(yAxis1, 'labels.autoRotation', false),
19
45
  dateFormat: get(yAxis1, 'labels.dateFormat'),
20
46
  numberFormat: get(yAxis1, 'labels.numberFormat'),
21
47
  style: y1LabelsStyle,
@@ -39,5 +65,6 @@ export const getPreparedYAxis = ({ yAxis }) => {
39
65
  pixelInterval: get(yAxis1, 'ticks.pixelInterval'),
40
66
  },
41
67
  };
68
+ applyLabelsMaxWidth({ series, preparedYAxis: preparedY1Axis });
42
69
  return [preparedY1Axis];
43
70
  };
@@ -1 +1 @@
1
- export declare const DEFAULT_LEGEND_SYMBOL_SIZE = 10;
1
+ export declare const DEFAULT_LEGEND_SYMBOL_SIZE = 8;
@@ -1 +1 @@
1
- export const DEFAULT_LEGEND_SYMBOL_SIZE = 10;
1
+ export const DEFAULT_LEGEND_SYMBOL_SIZE = 8;
@@ -1,15 +1,27 @@
1
1
  import type { ChartKitWidgetData } from '../../../../../types/widget-data';
2
- import { PreparedLegend } from '../useChartOptions/types';
3
- import { PreparedSeries } from './types';
4
- export type OnLegendItemClick = (data: {
5
- name: string;
6
- metaKey: boolean;
7
- }) => void;
2
+ import type { PreparedAxis, PreparedChart } from '../useChartOptions/types';
3
+ import type { PreparedSeries, OnLegendItemClick } from './types';
8
4
  type Args = {
9
- legend: PreparedLegend;
5
+ chartWidth: number;
6
+ chartHeight: number;
7
+ chartMargin: PreparedChart['margin'];
8
+ legend: ChartKitWidgetData['legend'];
10
9
  series: ChartKitWidgetData['series'];
10
+ preparedYAxis: PreparedAxis[];
11
11
  };
12
12
  export declare const useSeries: (args: Args) => {
13
+ legendItems: import("./types").LegendItem[][];
14
+ legendConfig: {
15
+ offset: {
16
+ left: number;
17
+ top: number;
18
+ };
19
+ pagination: {
20
+ limit: number;
21
+ maxPage: number;
22
+ } | undefined;
23
+ };
24
+ preparedLegend: import("./types").PreparedLegend;
13
25
  preparedSeries: PreparedSeries[];
14
26
  handleLegendItemClick: OnLegendItemClick;
15
27
  };