@gravity-ui/chartkit 3.4.3 → 3.6.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 (62) hide show
  1. package/build/plugins/d3/renderer/D3Widget.js +3 -3
  2. package/build/plugins/d3/renderer/components/Chart.d.ts +3 -1
  3. package/build/plugins/d3/renderer/components/Chart.js +13 -12
  4. package/build/plugins/d3/renderer/components/Legend.d.ts +3 -2
  5. package/build/plugins/d3/renderer/components/Legend.js +101 -61
  6. package/build/plugins/d3/renderer/components/Tooltip/DefaultContent.js +12 -0
  7. package/build/plugins/d3/renderer/components/styles.css +4 -13
  8. package/build/plugins/d3/renderer/constants.d.ts +3 -0
  9. package/build/plugins/d3/renderer/constants.js +3 -0
  10. package/build/plugins/d3/renderer/hooks/index.d.ts +1 -1
  11. package/build/plugins/d3/renderer/hooks/index.js +1 -1
  12. package/build/plugins/d3/renderer/hooks/useAxisScales/index.d.ts +2 -2
  13. package/build/plugins/d3/renderer/hooks/useAxisScales/index.js +2 -2
  14. package/build/plugins/d3/renderer/hooks/useChartDimensions/index.d.ts +2 -2
  15. package/build/plugins/d3/renderer/hooks/useChartDimensions/index.js +2 -4
  16. package/build/plugins/d3/renderer/hooks/useChartOptions/chart.js +21 -15
  17. package/build/plugins/d3/renderer/hooks/useChartOptions/index.d.ts +3 -1
  18. package/build/plugins/d3/renderer/hooks/useChartOptions/legend.js +7 -2
  19. package/build/plugins/d3/renderer/hooks/useChartOptions/title.js +2 -2
  20. package/build/plugins/d3/renderer/hooks/useChartOptions/types.d.ts +3 -1
  21. package/build/plugins/d3/renderer/hooks/useChartOptions/x-axis.js +3 -3
  22. package/build/plugins/d3/renderer/hooks/useChartOptions/y-axis.js +3 -3
  23. package/build/plugins/d3/renderer/hooks/useSeries/constants.d.ts +1 -0
  24. package/build/plugins/d3/renderer/hooks/useSeries/constants.js +1 -0
  25. package/build/plugins/d3/renderer/hooks/useSeries/index.d.ts +10 -8
  26. package/build/plugins/d3/renderer/hooks/useSeries/index.js +43 -14
  27. package/build/plugins/d3/renderer/hooks/useSeries/prepareSeries.d.ts +9 -0
  28. package/build/plugins/d3/renderer/hooks/useSeries/prepareSeries.js +85 -0
  29. package/build/plugins/d3/renderer/hooks/useSeries/types.d.ts +29 -0
  30. package/build/plugins/d3/renderer/hooks/useSeries/types.js +1 -0
  31. package/build/plugins/d3/renderer/hooks/useSeries/utils.d.ts +3 -0
  32. package/build/plugins/d3/renderer/hooks/useSeries/utils.js +11 -0
  33. package/build/plugins/d3/renderer/hooks/useShapes/bar-x.d.ts +3 -0
  34. package/build/plugins/d3/renderer/hooks/useShapes/bar-x.js +7 -3
  35. package/build/plugins/d3/renderer/hooks/useShapes/index.d.ts +7 -2
  36. package/build/plugins/d3/renderer/hooks/useShapes/index.js +26 -2
  37. package/build/plugins/d3/renderer/hooks/useShapes/pie.d.ts +13 -0
  38. package/build/plugins/d3/renderer/hooks/useShapes/pie.js +126 -0
  39. package/build/plugins/d3/renderer/hooks/useShapes/scatter.d.ts +2 -1
  40. package/build/plugins/d3/renderer/hooks/useShapes/scatter.js +6 -3
  41. package/build/plugins/d3/renderer/hooks/useShapes/styles.css +22 -0
  42. package/build/plugins/d3/renderer/utils/index.d.ts +49 -7
  43. package/build/plugins/d3/renderer/utils/index.js +50 -18
  44. package/build/plugins/d3/renderer/utils/math.d.ts +23 -0
  45. package/build/plugins/d3/renderer/utils/math.js +43 -0
  46. package/build/plugins/highcharts/renderer/components/HighchartsComponent.js +1 -1
  47. package/build/plugins/highcharts/renderer/components/HighchartsReact.d.ts +18 -0
  48. package/build/plugins/highcharts/renderer/components/HighchartsReact.js +46 -0
  49. package/build/plugins/index.d.ts +1 -0
  50. package/build/plugins/index.js +1 -0
  51. package/build/types/widget-data/bar-x.d.ts +6 -1
  52. package/build/types/widget-data/base.d.ts +12 -0
  53. package/build/types/widget-data/legend.d.ts +32 -0
  54. package/build/types/widget-data/pie.d.ts +37 -1
  55. package/build/types/widget-data/scatter.d.ts +6 -1
  56. package/package.json +1 -3
  57. package/build/plugins/d3/renderer/hooks/useChartOptions/constants.d.ts +0 -3
  58. package/build/plugins/d3/renderer/hooks/useChartOptions/constants.js +0 -3
  59. package/build/plugins/d3/renderer/hooks/useChartOptions/utils.d.ts +0 -5
  60. package/build/plugins/d3/renderer/hooks/useChartOptions/utils.js +0 -18
  61. package/build/plugins/d3/renderer/hooks/useLegend/index.d.ts +0 -13
  62. package/build/plugins/d3/renderer/hooks/useLegend/index.js +0 -28
@@ -8,8 +8,8 @@ const D3Widget = React.forwardRef(function D3Widget(props, forwardedRef) {
8
8
  const [dimensions, setDimensions] = React.useState();
9
9
  const handleResize = React.useCallback(() => {
10
10
  if (ref.current) {
11
- const { width, height } = ref.current.getBoundingClientRect();
12
- setDimensions({ width, height });
11
+ const { top, left, width, height } = ref.current.getBoundingClientRect();
12
+ setDimensions({ top, left, width, height });
13
13
  }
14
14
  }, []);
15
15
  const debuncedHandleResize = React.useMemo(() => {
@@ -35,6 +35,6 @@ const D3Widget = React.forwardRef(function D3Widget(props, forwardedRef) {
35
35
  // dimensions initialize
36
36
  handleResize();
37
37
  }, [handleResize]);
38
- return (React.createElement("div", { ref: ref, style: { width: '100%', height: '100%' } }, (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) && (dimensions === null || dimensions === void 0 ? void 0 : dimensions.height) && (React.createElement(Chart, { width: dimensions.width, height: dimensions.height, data: props.data }))));
38
+ return (React.createElement("div", { ref: ref, style: { width: '100%', height: '100%', position: 'relative' } }, (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) && (dimensions === null || dimensions === void 0 ? void 0 : dimensions.height) && (React.createElement(Chart, { top: (dimensions === null || dimensions === void 0 ? void 0 : dimensions.top) || 0, left: dimensions.left || 0, width: dimensions.width, height: dimensions.height, data: props.data }))));
39
39
  });
40
40
  export default D3Widget;
@@ -2,9 +2,11 @@ import React from 'react';
2
2
  import type { ChartKitWidgetData } from '../../../../types/widget-data';
3
3
  import './styles.css';
4
4
  type Props = {
5
+ top: number;
6
+ left: number;
5
7
  width: number;
6
8
  height: number;
7
9
  data: ChartKitWidgetData;
8
10
  };
9
- export declare const Chart: ({ width, height, data }: Props) => React.JSX.Element;
11
+ export declare const Chart: (props: Props) => React.JSX.Element;
10
12
  export {};
@@ -5,18 +5,16 @@ import { AxisX } from './AxisX';
5
5
  import { Legend } from './Legend';
6
6
  import { Title } from './Title';
7
7
  import { Tooltip } from './Tooltip';
8
- import { useChartDimensions, useChartEvents, useChartOptions, useLegend, useAxisScales, useSeries, useShapes, useTooltip, } from '../hooks';
9
- import { isAxisRelatedSeries } from '../utils';
8
+ import { useChartDimensions, useChartEvents, useChartOptions, useAxisScales, useSeries, useShapes, useTooltip, } from '../hooks';
10
9
  import './styles.css';
11
10
  const b = block('d3');
12
- export const Chart = ({ width, height, data }) => {
11
+ export const Chart = (props) => {
12
+ const { top, left, width, height, data } = props;
13
13
  // FIXME: add data validation
14
- const { series } = data;
15
14
  const svgRef = React.createRef();
16
- const hasAxisRelatedSeries = series.data.some(isAxisRelatedSeries);
17
15
  const { chartHovered, handleMouseEnter, handleMouseLeave } = useChartEvents();
18
16
  const { chart, legend, title, tooltip, xAxis, yAxis } = useChartOptions(data);
19
- const { boundsWidth, boundsHeight, legendHeight } = useChartDimensions({
17
+ const { boundsWidth, boundsHeight } = useChartDimensions({
20
18
  width,
21
19
  height,
22
20
  margin: chart.margin,
@@ -25,12 +23,11 @@ export const Chart = ({ width, height, data }) => {
25
23
  xAxis,
26
24
  yAxis,
27
25
  });
28
- const { activeLegendItems, handleLegendItemClick } = useLegend({ series: series.data });
29
- const { chartSeries } = useSeries({ activeLegendItems, series: series.data });
26
+ const { preparedSeries, handleLegendItemClick } = useSeries({ series: data.series, legend });
30
27
  const { xScale, yScale } = useAxisScales({
31
28
  boundsWidth,
32
29
  boundsHeight,
33
- series: chartSeries,
30
+ series: preparedSeries,
34
31
  xAxis,
35
32
  yAxis,
36
33
  });
@@ -38,7 +35,11 @@ export const Chart = ({ width, height, data }) => {
38
35
  tooltip,
39
36
  });
40
37
  const { shapes } = useShapes({
41
- series: chartSeries,
38
+ top,
39
+ left,
40
+ boundsWidth,
41
+ boundsHeight,
42
+ series: preparedSeries,
42
43
  xAxis,
43
44
  xScale,
44
45
  yAxis,
@@ -54,11 +55,11 @@ export const Chart = ({ width, height, data }) => {
54
55
  chart.margin.left,
55
56
  chart.margin.top + ((title === null || title === void 0 ? void 0 : title.height) || 0),
56
57
  ].join(',')})` },
57
- hasAxisRelatedSeries && xScale && yScale && (React.createElement(React.Fragment, null,
58
+ xScale && yScale && (React.createElement(React.Fragment, null,
58
59
  React.createElement(AxisY, { axises: yAxis, width: boundsWidth, height: boundsHeight, scale: yScale }),
59
60
  React.createElement("g", { transform: `translate(0, ${boundsHeight})` },
60
61
  React.createElement(AxisX, { axis: xAxis, width: boundsWidth, height: boundsHeight, scale: xScale })))),
61
62
  shapes),
62
- legend.enabled && (React.createElement(Legend, { width: boundsWidth, offsetWidth: chart.margin.left, height: legendHeight, offsetHeight: height - legendHeight / 2, chartSeries: chartSeries, onItemClick: handleLegendItemClick }))),
63
+ legend.enabled && (React.createElement(Legend, { width: boundsWidth, offsetWidth: chart.margin.left, height: legend.height, legend: legend, offsetHeight: height - legend.height / 2, chartSeries: preparedSeries, onItemClick: handleLegendItemClick }))),
63
64
  React.createElement(Tooltip, { hovered: hovered, pointerPosition: pointerPosition, tooltip: tooltip, xAxis: xAxis, yAxis: yAxis[0] })));
64
65
  };
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
- import type { ChartSeries, OnLegendItemClick } from '../hooks';
2
+ import type { OnLegendItemClick, PreparedLegend, PreparedSeries } from '../hooks';
3
3
  type Props = {
4
4
  width: number;
5
5
  height: number;
6
+ legend: PreparedLegend;
6
7
  offsetWidth: number;
7
8
  offsetHeight: number;
8
- chartSeries: ChartSeries[];
9
+ chartSeries: PreparedSeries[];
9
10
  onItemClick: OnLegendItemClick;
10
11
  };
11
12
  export declare const Legend: (props: Props) => React.JSX.Element;
@@ -1,66 +1,106 @@
1
1
  import React from 'react';
2
- import { select } from 'd3';
2
+ import { select, sum } from 'd3';
3
+ import get from 'lodash/get';
3
4
  import { block } from '../../../../utils/cn';
4
5
  const b = block('d3-legend');
6
+ const getLegendItems = (series) => {
7
+ return series.reduce((acc, s) => {
8
+ const legendEnabled = get(s, 'legend.enabled', true);
9
+ if (legendEnabled) {
10
+ acc.push(Object.assign(Object.assign({}, s), { symbol: s.legend.symbol }));
11
+ }
12
+ return acc;
13
+ }, []);
14
+ };
15
+ function getLegendPosition(args) {
16
+ const { align, offsetWidth, width, contentWidth } = args;
17
+ const top = 0;
18
+ if (align === 'left') {
19
+ return { top, left: offsetWidth };
20
+ }
21
+ if (align === 'right') {
22
+ return { top, left: offsetWidth + width - contentWidth };
23
+ }
24
+ return { top, left: offsetWidth + width / 2 - contentWidth / 2 };
25
+ }
5
26
  export const Legend = (props) => {
6
- const { width, offsetWidth, height, offsetHeight, chartSeries, onItemClick } = props;
7
- return (React.createElement("g", { width: width, height: height, ref: (node) => {
8
- if (!node) {
9
- return;
10
- }
11
- const size = 10;
12
- const textWidths = [0];
13
- const svgElement = select(node);
14
- svgElement.selectAll('*').remove();
15
- const legendItemTemplate = svgElement
16
- .selectAll('legend-history')
17
- .data(chartSeries)
18
- .enter()
19
- .append('g')
20
- .attr('class', b('item'))
21
- .on('click', function (e, d) {
22
- onItemClick({ name: d.name, metaKey: e.metaKey });
23
- });
24
- svgElement
25
- .selectAll('*')
26
- .data(chartSeries)
27
- .append('text')
28
- .text(function (d) {
29
- return d.name;
30
- })
31
- .each(function () {
32
- textWidths.push(this.getComputedTextLength());
33
- })
34
- .remove();
35
- legendItemTemplate
36
- .append('rect')
37
- .attr('x', function (_d, i) {
38
- return (offsetWidth +
39
- i * size +
40
- textWidths.slice(0, i + 1).reduce((acc, tw) => acc + tw, 0));
41
- })
42
- .attr('y', offsetHeight - size / 2)
43
- .attr('width', size)
44
- .attr('height', size)
45
- .style('fill', function (d) {
46
- return d.color;
47
- });
48
- legendItemTemplate
49
- .append('text')
50
- .attr('x', function (_d, i) {
51
- return (offsetWidth +
52
- i * size +
53
- size +
54
- textWidths.slice(0, i + 1).reduce((acc, tw) => acc + tw, 0));
55
- })
56
- .attr('y', offsetHeight)
57
- .attr('class', function (d) {
58
- const mods = { selected: d.visible, unselected: !d.visible };
59
- return b('item-text', mods);
60
- })
61
- .text(function (d) {
62
- return ('name' in d && d.name);
63
- })
64
- .style('alignment-baseline', 'middle');
65
- } }));
27
+ const { width, offsetWidth, height, offsetHeight, chartSeries, legend, onItemClick } = props;
28
+ const ref = React.useRef(null);
29
+ React.useEffect(() => {
30
+ if (!ref.current) {
31
+ return;
32
+ }
33
+ const legendItems = getLegendItems(chartSeries);
34
+ const textWidths = [0];
35
+ const svgElement = select(ref.current);
36
+ svgElement.selectAll('*').remove();
37
+ const legendItemTemplate = svgElement
38
+ .selectAll('legend-history')
39
+ .data(legendItems)
40
+ .enter()
41
+ .append('g')
42
+ .attr('class', b('item'))
43
+ .on('click', function (e, d) {
44
+ onItemClick({ name: d.name, metaKey: e.metaKey });
45
+ });
46
+ svgElement
47
+ .selectAll('*')
48
+ .data(legendItems)
49
+ .append('text')
50
+ .text(function (d) {
51
+ return d.name;
52
+ })
53
+ .each(function () {
54
+ textWidths.push(this.getComputedTextLength());
55
+ })
56
+ .remove();
57
+ legendItemTemplate
58
+ .append('rect')
59
+ .attr('x', function (legendItem, i) {
60
+ return (i * legendItem.symbol.width +
61
+ i * legend.itemDistance +
62
+ i * legendItem.symbol.padding +
63
+ textWidths.slice(0, i + 1).reduce((acc, tw) => acc + tw, 0));
64
+ })
65
+ .attr('y', (legendItem) => offsetHeight - legendItem.symbol.height / 2)
66
+ .attr('width', (legendItem) => {
67
+ return legendItem.symbol.width;
68
+ })
69
+ .attr('height', (legendItem) => legendItem.symbol.height)
70
+ .attr('rx', (legendItem) => legendItem.symbol.radius)
71
+ .attr('class', b('item-shape'))
72
+ .style('fill', function (d) {
73
+ return d.color;
74
+ });
75
+ legendItemTemplate
76
+ .append('text')
77
+ .attr('x', function (legendItem, i) {
78
+ return (i * legendItem.symbol.width +
79
+ i * legend.itemDistance +
80
+ i * legendItem.symbol.padding +
81
+ legendItem.symbol.width +
82
+ legendItem.symbol.padding +
83
+ textWidths.slice(0, i + 1).reduce((acc, tw) => acc + tw, 0));
84
+ })
85
+ .attr('y', offsetHeight)
86
+ .attr('class', function (d) {
87
+ const mods = { selected: d.visible, unselected: !d.visible };
88
+ return b('item-text', mods);
89
+ })
90
+ .text(function (d) {
91
+ return ('name' in d && d.name);
92
+ })
93
+ .style('alignment-baseline', 'middle');
94
+ const contentWidth = sum(textWidths) +
95
+ sum(legendItems, (item) => item.symbol.width + item.symbol.padding) +
96
+ legend.itemDistance * (legendItems.length - 1);
97
+ const { left } = getLegendPosition({
98
+ align: legend.align,
99
+ width,
100
+ offsetWidth,
101
+ contentWidth,
102
+ });
103
+ svgElement.attr('transform', `translate(${[left, 0].join(',')})`);
104
+ }, [width, offsetWidth, height, offsetHeight, chartSeries, onItemClick, legend]);
105
+ return React.createElement("g", { ref: ref, width: width, height: height });
66
106
  };
@@ -14,6 +14,18 @@ export const DefaultContent = ({ hovered, xAxis, yAxis }) => {
14
14
  React.createElement("span", null, "Y:\u00A0"),
15
15
  React.createElement("b", null, yRow))));
16
16
  }
17
+ case 'bar-x': {
18
+ const barXData = data;
19
+ const xRow = xAxis.type === 'category' ? barXData.category : barXData.x;
20
+ const yRow = yAxis.type === 'category' ? barXData.category : barXData.y;
21
+ return (React.createElement("div", null,
22
+ React.createElement("div", null, xRow),
23
+ React.createElement("div", null,
24
+ React.createElement("span", null,
25
+ React.createElement("b", null, series.name),
26
+ ": ",
27
+ yRow))));
28
+ }
17
29
  default: {
18
30
  return null;
19
31
  }
@@ -19,6 +19,10 @@
19
19
  user-select: none;
20
20
  }
21
21
 
22
+ .chartkit-d3-legend__item-shape {
23
+ fill: var(--g-color-base-misc-medium);
24
+ }
25
+
22
26
  .chartkit-d3-legend__item-text {
23
27
  fill: var(--g-color-text-secondary);
24
28
  }
@@ -31,19 +35,6 @@
31
35
  fill: var(--g-color-text-complementary);
32
36
  }
33
37
 
34
- .chartkit-d3-scatter__point {
35
- stroke-width: 1px;
36
- }
37
-
38
- .chartkit-d3_hovered .chartkit-d3-scatter__point {
39
- opacity: 0.5;
40
- }
41
-
42
- .chartkit-d3-scatter__point:hover {
43
- stroke: #fff;
44
- opacity: 1;
45
- }
46
-
47
38
  .chartkit-d3-title {
48
39
  font-size: var(--g-text-subheader-2-font-size);
49
40
  font-weight: var(--g-text-subheader-font-weight);
@@ -1 +1,4 @@
1
1
  export declare const DEFAULT_PALETTE: string[];
2
+ export declare const DEFAULT_AXIS_LABEL_FONT_SIZE = "11px";
3
+ export declare const DEFAULT_AXIS_LABEL_PADDING = 10;
4
+ export declare const DEFAULT_AXIS_TITLE_FONT_SIZE = "14px";
@@ -20,3 +20,6 @@ export const DEFAULT_PALETTE = [
20
20
  '#FFB46C',
21
21
  '#DCA3D7',
22
22
  ];
23
+ export const DEFAULT_AXIS_LABEL_FONT_SIZE = '11px';
24
+ export const DEFAULT_AXIS_LABEL_PADDING = 10;
25
+ export const DEFAULT_AXIS_TITLE_FONT_SIZE = '14px';
@@ -2,9 +2,9 @@ export * from './useChartDimensions';
2
2
  export * from './useChartEvents';
3
3
  export * from './useChartOptions';
4
4
  export * from './useChartOptions/types';
5
- export * from './useLegend';
6
5
  export * from './useAxisScales';
7
6
  export * from './useSeries';
7
+ export * from './useSeries/types';
8
8
  export * from './useShapes';
9
9
  export * from './useTooltip';
10
10
  export * from './useTooltip/types';
@@ -2,9 +2,9 @@ export * from './useChartDimensions';
2
2
  export * from './useChartEvents';
3
3
  export * from './useChartOptions';
4
4
  export * from './useChartOptions/types';
5
- export * from './useLegend';
6
5
  export * from './useAxisScales';
7
6
  export * from './useSeries';
7
+ export * from './useSeries/types';
8
8
  export * from './useShapes';
9
9
  export * from './useTooltip';
10
10
  export * from './useTooltip/types';
@@ -1,11 +1,11 @@
1
1
  import type { ScaleBand, ScaleLinear, ScaleTime } from 'd3';
2
- import type { ChartKitWidgetSeries } from '../../../../../types/widget-data';
3
2
  import type { ChartOptions } from '../useChartOptions/types';
3
+ import { PreparedSeries } from '../useSeries/types';
4
4
  export type ChartScale = ScaleLinear<number, number> | ScaleBand<string> | ScaleTime<number, number>;
5
5
  type Args = {
6
6
  boundsWidth: number;
7
7
  boundsHeight: number;
8
- series: ChartKitWidgetSeries[];
8
+ series: PreparedSeries[];
9
9
  xAxis: ChartOptions['xAxis'];
10
10
  yAxis: ChartOptions['yAxis'];
11
11
  };
@@ -1,14 +1,14 @@
1
1
  import React from 'react';
2
2
  import { scaleBand, scaleLinear, scaleUtc, extent } from 'd3';
3
3
  import get from 'lodash/get';
4
- import { getOnlyVisibleSeries, getDomainDataXBySeries, getDomainDataYBySeries, isAxisRelatedSeries, } from '../../utils';
4
+ import { getOnlyVisibleSeries, getDomainDataYBySeries, isAxisRelatedSeries, getDomainDataXBySeries, isSeriesWithCategoryValues, } from '../../utils';
5
5
  const isNumericalArrayData = (data) => {
6
6
  return data.every((d) => typeof d === 'number' || d === null);
7
7
  };
8
8
  const filterCategoriesByVisibleSeries = (categories, series) => {
9
9
  return categories.filter((category) => {
10
10
  return series.some((s) => {
11
- return s.data.some((d) => 'category' in d && d.category === category);
11
+ return isSeriesWithCategoryValues(s) && s.data.some((d) => d.category === category);
12
12
  });
13
13
  });
14
14
  };
@@ -1,10 +1,10 @@
1
1
  import type { ChartMargin } from '../../../../../types/widget-data';
2
- import type { ChartOptions, PreparedAxis, PreparedTitle } from '../useChartOptions/types';
2
+ import type { PreparedAxis, PreparedLegend, PreparedTitle } from '../useChartOptions/types';
3
3
  type Args = {
4
4
  width: number;
5
5
  height: number;
6
6
  margin: ChartMargin;
7
- legend: ChartOptions['legend'];
7
+ legend: PreparedLegend;
8
8
  title?: PreparedTitle;
9
9
  xAxis?: PreparedAxis;
10
10
  yAxis?: PreparedAxis[];
@@ -1,13 +1,11 @@
1
- const LEGEND_LINE_HEIGHT = 15;
2
1
  export const useChartDimensions = (args) => {
3
2
  const { margin, legend, title, width, height, xAxis, yAxis } = args;
4
- const legendHeight = legend.enabled ? LEGEND_LINE_HEIGHT : 0;
5
3
  const titleHeight = (title === null || title === void 0 ? void 0 : title.height) || 0;
6
4
  const xAxisTitleHeight = (xAxis === null || xAxis === void 0 ? void 0 : xAxis.title.height) || 0;
7
5
  const yAxisTitleHeight = (yAxis === null || yAxis === void 0 ? void 0 : yAxis.reduce((acc, axis) => {
8
6
  return acc + (axis.title.height || 0);
9
7
  }, 0)) || 0;
10
8
  const boundsWidth = width - margin.right - margin.left - yAxisTitleHeight;
11
- const boundsHeight = height - margin.top - margin.bottom - legendHeight - titleHeight - xAxisTitleHeight;
12
- return { boundsWidth, boundsHeight, legendHeight };
9
+ const boundsHeight = height - margin.top - margin.bottom - legend.height - titleHeight - xAxisTitleHeight;
10
+ return { boundsWidth, boundsHeight, legendHeight: legend.height };
13
11
  };
@@ -1,7 +1,6 @@
1
1
  import { select, max } from 'd3';
2
2
  import get from 'lodash/get';
3
- import { formatAxisTickLabel, getDomainDataYBySeries } from '../../utils';
4
- import { getHorisontalSvgTextDimensions } from './utils';
3
+ import { formatAxisTickLabel, getDomainDataYBySeries, getHorisontalSvgTextHeight, isAxisRelatedSeries, } from '../../utils';
5
4
  const AXIS_WIDTH = 1;
6
5
  const getAxisLabelMaxWidth = (args) => {
7
6
  const { axis, series } = args;
@@ -9,8 +8,8 @@ const getAxisLabelMaxWidth = (args) => {
9
8
  let width = 0;
10
9
  switch (axis.type) {
11
10
  case 'category': {
12
- const yCatigories = get(axis, 'categories', []);
13
- maxDomainValue = [...yCatigories].sort((c1, c2) => c2.length - c1.length)[0];
11
+ const yCategories = get(axis, 'categories', []);
12
+ maxDomainValue = [...yCategories].sort((c1, c2) => c2.length - c1.length)[0];
14
13
  break;
15
14
  }
16
15
  case 'datetime': {
@@ -45,17 +44,24 @@ const getAxisLabelMaxWidth = (args) => {
45
44
  };
46
45
  export const getPreparedChart = (args) => {
47
46
  const { chart, series, preparedXAxis, preparedY1Axis } = args;
48
- const marginBottom = get(chart, 'margin.bottom', 0) +
49
- preparedXAxis.labels.padding +
50
- getHorisontalSvgTextDimensions({ text: 'Tmp', style: preparedXAxis.labels.style });
51
- const marginLeft = get(chart, 'margin.left', AXIS_WIDTH) +
52
- preparedY1Axis.labels.padding +
53
- getAxisLabelMaxWidth({ axis: preparedY1Axis, series: series.data }) +
54
- (preparedY1Axis.title.height || 0);
55
- const marginTop = get(chart, 'margin.top', 0) +
56
- getHorisontalSvgTextDimensions({ text: 'Tmp', style: preparedY1Axis.labels.style }) / 2;
57
- const marginRight = get(chart, 'margin.right', 0) +
58
- getAxisLabelMaxWidth({ axis: preparedXAxis, series: series.data }) / 2;
47
+ const hasAxisRelatedSeries = series.data.some(isAxisRelatedSeries);
48
+ let marginBottom = get(chart, 'margin.bottom', 0);
49
+ let marginLeft = get(chart, 'margin.left', 0);
50
+ let marginTop = get(chart, 'margin.top', 0);
51
+ let marginRight = get(chart, 'margin.right', 0);
52
+ if (hasAxisRelatedSeries) {
53
+ marginBottom +=
54
+ preparedXAxis.labels.padding +
55
+ getHorisontalSvgTextHeight({ text: 'Tmp', style: preparedXAxis.labels.style });
56
+ marginLeft +=
57
+ AXIS_WIDTH +
58
+ preparedY1Axis.labels.padding +
59
+ getAxisLabelMaxWidth({ axis: preparedY1Axis, series: series.data }) +
60
+ (preparedY1Axis.title.height || 0);
61
+ marginTop +=
62
+ getHorisontalSvgTextHeight({ text: 'Tmp', style: preparedY1Axis.labels.style }) / 2;
63
+ marginRight += getAxisLabelMaxWidth({ axis: preparedXAxis, series: series.data }) / 2;
64
+ }
59
65
  return {
60
66
  margin: {
61
67
  top: marginTop,
@@ -1,3 +1,5 @@
1
1
  import type { ChartKitWidgetData } from '../../../../../types/widget-data';
2
2
  import type { ChartOptions } from './types';
3
- export declare const useChartOptions: (args: ChartKitWidgetData) => ChartOptions;
3
+ type Args = ChartKitWidgetData;
4
+ export declare const useChartOptions: (args: Args) => ChartOptions;
5
+ export {};
@@ -1,7 +1,12 @@
1
+ const LEGEND_LINE_HEIGHT = 15;
1
2
  export const getPreparedLegend = (args) => {
2
3
  const { legend, series } = args;
3
- const enabled = legend === null || legend === void 0 ? void 0 : legend.enabled;
4
+ const enabled = typeof (legend === null || legend === void 0 ? void 0 : legend.enabled) === 'boolean' ? legend === null || legend === void 0 ? void 0 : legend.enabled : series.data.length > 1;
5
+ const height = enabled ? LEGEND_LINE_HEIGHT : 0;
4
6
  return {
5
- enabled: typeof enabled === 'boolean' ? enabled : series.data.length > 1,
7
+ align: (legend === null || legend === void 0 ? void 0 : legend.align) || 'center',
8
+ enabled,
9
+ itemDistance: (legend === null || legend === void 0 ? void 0 : legend.itemDistance) || 20,
10
+ height,
6
11
  };
7
12
  };
@@ -1,5 +1,5 @@
1
1
  import get from 'lodash/get';
2
- import { getHorisontalSvgTextDimensions } from './utils';
2
+ import { getHorisontalSvgTextHeight } from '../../utils';
3
3
  const DEFAULT_TITLE_FONT_SIZE = '15px';
4
4
  const TITLE_PADDINGS = 8 * 2;
5
5
  export const getPreparedTitle = ({ title, }) => {
@@ -8,7 +8,7 @@ export const getPreparedTitle = ({ title, }) => {
8
8
  fontSize: get(title, 'style.fontSize', DEFAULT_TITLE_FONT_SIZE),
9
9
  };
10
10
  const titleHeight = titleText
11
- ? getHorisontalSvgTextDimensions({ text: titleText, style: titleStyle }) + TITLE_PADDINGS
11
+ ? getHorisontalSvgTextHeight({ text: titleText, style: titleStyle }) + TITLE_PADDINGS
12
12
  : 0;
13
13
  const preparedTitle = titleText
14
14
  ? { text: titleText, style: titleStyle, height: titleHeight }
@@ -5,7 +5,9 @@ type PreparedAxisLabels = Omit<ChartKitWidgetAxisLabels, 'enabled' | 'padding' |
5
5
  export type PreparedChart = {
6
6
  margin: ChartMargin;
7
7
  };
8
- export type PreparedLegend = Required<ChartKitWidgetLegend>;
8
+ export type PreparedLegend = Required<ChartKitWidgetLegend> & {
9
+ height: number;
10
+ };
9
11
  export type PreparedAxis = Omit<ChartKitWidgetAxis, 'type' | 'labels'> & {
10
12
  type: ChartKitWidgetAxisType;
11
13
  labels: PreparedAxisLabels;
@@ -1,6 +1,6 @@
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 { getHorisontalSvgTextDimensions } from './utils';
2
+ import { DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_LABEL_PADDING, DEFAULT_AXIS_TITLE_FONT_SIZE, } from '../../constants';
3
+ import { getHorisontalSvgTextHeight } from '../../utils';
4
4
  export const getPreparedXAxis = ({ xAxis }) => {
5
5
  const titleText = get(xAxis, 'title.text', '');
6
6
  const titleStyle = {
@@ -21,7 +21,7 @@ export const getPreparedXAxis = ({ xAxis }) => {
21
21
  text: titleText,
22
22
  style: titleStyle,
23
23
  height: titleText
24
- ? getHorisontalSvgTextDimensions({ text: titleText, style: titleStyle })
24
+ ? getHorisontalSvgTextHeight({ text: titleText, style: titleStyle })
25
25
  : 0,
26
26
  },
27
27
  min: get(xAxis, 'min'),
@@ -1,6 +1,6 @@
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 { getHorisontalSvgTextDimensions } from './utils';
2
+ import { DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_LABEL_PADDING, DEFAULT_AXIS_TITLE_FONT_SIZE, } from '../../constants';
3
+ import { getHorisontalSvgTextHeight } from '../../utils';
4
4
  export const getPreparedYAxis = ({ yAxis }) => {
5
5
  // FIXME: add support for n axises
6
6
  const yAxis1 = yAxis === null || yAxis === void 0 ? void 0 : yAxis[0];
@@ -26,7 +26,7 @@ export const getPreparedYAxis = ({ yAxis }) => {
26
26
  text: y1TitleText,
27
27
  style: y1TitleStyle,
28
28
  height: y1TitleText
29
- ? getHorisontalSvgTextDimensions({ text: y1TitleText, style: y1TitleStyle })
29
+ ? getHorisontalSvgTextHeight({ text: y1TitleText, style: y1TitleStyle })
30
30
  : 0,
31
31
  },
32
32
  min: get(yAxis1, 'min'),
@@ -0,0 +1 @@
1
+ export declare const DEFAULT_LEGEND_SYMBOL_SIZE = 10;
@@ -0,0 +1 @@
1
+ export const DEFAULT_LEGEND_SYMBOL_SIZE = 10;
@@ -1,14 +1,16 @@
1
- import type { ChartKitWidgetSeries } from '../../../../../types/widget-data';
2
- export type ChartSeries = ChartKitWidgetSeries & {
3
- color: string;
1
+ import type { ChartKitWidgetData } from '../../../../../types/widget-data';
2
+ import { PreparedLegend } from '../useChartOptions/types';
3
+ import { PreparedSeries } from './types';
4
+ export type OnLegendItemClick = (data: {
4
5
  name: string;
5
- visible: boolean;
6
- };
6
+ metaKey: boolean;
7
+ }) => void;
7
8
  type Args = {
8
- activeLegendItems: string[];
9
- series: ChartKitWidgetSeries[];
9
+ legend: PreparedLegend;
10
+ series: ChartKitWidgetData['series'];
10
11
  };
11
12
  export declare const useSeries: (args: Args) => {
12
- chartSeries: ChartSeries[];
13
+ preparedSeries: PreparedSeries[];
14
+ handleLegendItemClick: OnLegendItemClick;
13
15
  };
14
16
  export {};