@gravity-ui/chartkit 4.8.0 → 4.9.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 (86) hide show
  1. package/build/plugins/d3/examples/bar-x/GroupedColumns.js +4 -2
  2. package/build/plugins/d3/examples/bar-y/Basic.d.ts +2 -0
  3. package/build/plugins/d3/examples/bar-y/Basic.js +43 -0
  4. package/build/plugins/d3/examples/bar-y/GroupedColumns.d.ts +2 -0
  5. package/build/plugins/d3/examples/bar-y/GroupedColumns.js +48 -0
  6. package/build/plugins/d3/examples/bar-y/StackedColumns.d.ts +2 -0
  7. package/build/plugins/d3/examples/bar-y/StackedColumns.js +47 -0
  8. package/build/plugins/d3/examples/combined/LineAndBarX.d.ts +2 -0
  9. package/build/plugins/d3/examples/combined/LineAndBarX.js +61 -0
  10. package/build/plugins/d3/examples/line/Basic.d.ts +2 -0
  11. package/build/plugins/d3/examples/line/Basic.js +66 -0
  12. package/build/plugins/d3/examples/nintendoGames.d.ts +40 -10
  13. package/build/plugins/d3/examples/nintendoGames.js +2416 -2189
  14. package/build/plugins/d3/renderer/D3Widget.js +27 -11
  15. package/build/plugins/d3/renderer/components/Chart.d.ts +0 -2
  16. package/build/plugins/d3/renderer/components/Chart.js +4 -6
  17. package/build/plugins/d3/renderer/components/Tooltip/DefaultContent.d.ts +2 -2
  18. package/build/plugins/d3/renderer/components/Tooltip/DefaultContent.js +42 -35
  19. package/build/plugins/d3/renderer/components/Tooltip/TooltipTriggerArea.d.ts +0 -2
  20. package/build/plugins/d3/renderer/components/Tooltip/TooltipTriggerArea.js +118 -48
  21. package/build/plugins/d3/renderer/components/Tooltip/index.d.ts +1 -0
  22. package/build/plugins/d3/renderer/components/Tooltip/index.js +5 -4
  23. package/build/plugins/d3/renderer/components/styles.css +1 -0
  24. package/build/plugins/d3/renderer/constants/defaults/series-options.d.ts +9 -2
  25. package/build/plugins/d3/renderer/constants/defaults/series-options.js +27 -0
  26. package/build/plugins/d3/renderer/hooks/useAxisScales/index.js +15 -1
  27. package/build/plugins/d3/renderer/hooks/useChartOptions/x-axis.js +3 -3
  28. package/build/plugins/d3/renderer/hooks/useChartOptions/y-axis.js +3 -3
  29. package/build/plugins/d3/renderer/hooks/useSeries/constants.d.ts +3 -0
  30. package/build/plugins/d3/renderer/hooks/useSeries/constants.js +5 -0
  31. package/build/plugins/d3/renderer/hooks/useSeries/index.d.ts +1 -1
  32. package/build/plugins/d3/renderer/hooks/useSeries/index.js +2 -1
  33. package/build/plugins/d3/renderer/hooks/useSeries/prepare-bar-x.d.ts +10 -0
  34. package/build/plugins/d3/renderer/hooks/useSeries/prepare-bar-x.js +38 -0
  35. package/build/plugins/d3/renderer/hooks/useSeries/prepare-bar-y.d.ts +10 -0
  36. package/build/plugins/d3/renderer/hooks/useSeries/prepare-bar-y.js +50 -0
  37. package/build/plugins/d3/renderer/hooks/useSeries/prepare-line-series.d.ts +11 -0
  38. package/build/plugins/d3/renderer/hooks/useSeries/prepare-line-series.js +32 -0
  39. package/build/plugins/d3/renderer/hooks/useSeries/prepareSeries.d.ts +2 -1
  40. package/build/plugins/d3/renderer/hooks/useSeries/prepareSeries.js +21 -60
  41. package/build/plugins/d3/renderer/hooks/useSeries/types.d.ts +24 -2
  42. package/build/plugins/d3/renderer/hooks/useSeries/utils.d.ts +3 -1
  43. package/build/plugins/d3/renderer/hooks/useSeries/utils.js +13 -0
  44. package/build/plugins/d3/renderer/hooks/useShapes/bar-x/prepare-data.js +4 -6
  45. package/build/plugins/d3/renderer/hooks/useShapes/bar-y/index.d.ts +11 -0
  46. package/build/plugins/d3/renderer/hooks/useShapes/bar-y/index.js +87 -0
  47. package/build/plugins/d3/renderer/hooks/useShapes/bar-y/prepare-data.d.ts +12 -0
  48. package/build/plugins/d3/renderer/hooks/useShapes/bar-y/prepare-data.js +114 -0
  49. package/build/plugins/d3/renderer/hooks/useShapes/bar-y/types.d.ts +10 -0
  50. package/build/plugins/d3/renderer/hooks/useShapes/bar-y/types.js +1 -0
  51. package/build/plugins/d3/renderer/hooks/useShapes/constants.d.ts +3 -0
  52. package/build/plugins/d3/renderer/hooks/useShapes/constants.js +3 -0
  53. package/build/plugins/d3/renderer/hooks/useShapes/index.d.ts +4 -4
  54. package/build/plugins/d3/renderer/hooks/useShapes/index.js +35 -5
  55. package/build/plugins/d3/renderer/hooks/useShapes/line/index.d.ts +11 -0
  56. package/build/plugins/d3/renderer/hooks/useShapes/line/index.js +98 -0
  57. package/build/plugins/d3/renderer/hooks/useShapes/line/prepare-data.d.ts +11 -0
  58. package/build/plugins/d3/renderer/hooks/useShapes/line/prepare-data.js +21 -0
  59. package/build/plugins/d3/renderer/hooks/useShapes/line/types.d.ts +16 -0
  60. package/build/plugins/d3/renderer/hooks/useShapes/line/types.js +1 -0
  61. package/build/plugins/d3/renderer/hooks/useShapes/pie.d.ts +0 -2
  62. package/build/plugins/d3/renderer/hooks/useShapes/pie.js +3 -3
  63. package/build/plugins/d3/renderer/hooks/useShapes/scatter/index.d.ts +0 -2
  64. package/build/plugins/d3/renderer/hooks/useShapes/scatter/index.js +6 -6
  65. package/build/plugins/d3/renderer/hooks/useShapes/scatter/prepare-data.d.ts +1 -1
  66. package/build/plugins/d3/renderer/hooks/useShapes/scatter/prepare-data.js +3 -34
  67. package/build/plugins/d3/renderer/hooks/useShapes/styles.css +6 -0
  68. package/build/plugins/d3/renderer/hooks/useShapes/utils.d.ts +17 -0
  69. package/build/plugins/d3/renderer/hooks/useShapes/utils.js +25 -0
  70. package/build/plugins/d3/renderer/utils/axis-generators/bottom.js +3 -3
  71. package/build/plugins/d3/renderer/utils/text.d.ts +5 -7
  72. package/build/plugins/d3/renderer/utils/text.js +4 -15
  73. package/build/types/widget-data/bar-y.d.ts +55 -0
  74. package/build/types/widget-data/bar-y.js +1 -0
  75. package/build/types/widget-data/base.d.ts +4 -0
  76. package/build/types/widget-data/index.d.ts +2 -0
  77. package/build/types/widget-data/index.js +2 -0
  78. package/build/types/widget-data/line.d.ts +37 -0
  79. package/build/types/widget-data/line.js +1 -0
  80. package/build/types/widget-data/series.d.ts +53 -3
  81. package/build/types/widget-data/tooltip.d.ts +15 -1
  82. package/build/utils/index.d.ts +1 -1
  83. package/build/utils/index.js +1 -1
  84. package/build/utils/performance.d.ts +3 -0
  85. package/build/utils/performance.js +8 -0
  86. package/package.json +3 -2
@@ -0,0 +1,10 @@
1
+ import type { ScaleOrdinal } from 'd3';
2
+ import type { BarXSeries } from '../../../../../types';
3
+ import type { PreparedLegend, PreparedSeries } from './types';
4
+ type PrepareBarXSeriesArgs = {
5
+ colorScale: ScaleOrdinal<string, string>;
6
+ series: BarXSeries[];
7
+ legend: PreparedLegend;
8
+ };
9
+ export declare function prepareBarXSeries(args: PrepareBarXSeriesArgs): PreparedSeries[];
10
+ export {};
@@ -0,0 +1,38 @@
1
+ import get from 'lodash/get';
2
+ import { getRandomCKId } from '../../../../../utils';
3
+ import { prepareLegendSymbol } from './utils';
4
+ import { DEFAULT_DATALABELS_STYLE } from './constants';
5
+ export function prepareBarXSeries(args) {
6
+ const { colorScale, series: seriesList, legend } = args;
7
+ const commonStackId = getRandomCKId();
8
+ return seriesList.map((series) => {
9
+ var _a, _b, _c, _d;
10
+ const name = series.name || '';
11
+ const color = series.color || colorScale(name);
12
+ let stackId = series.stackId;
13
+ if (!stackId) {
14
+ stackId = series.stacking === 'normal' ? commonStackId : getRandomCKId();
15
+ }
16
+ return {
17
+ type: series.type,
18
+ color,
19
+ name,
20
+ id: getRandomCKId(),
21
+ visible: get(series, 'visible', true),
22
+ legend: {
23
+ enabled: get(series, 'legend.enabled', legend.enabled),
24
+ symbol: prepareLegendSymbol(series),
25
+ },
26
+ data: series.data,
27
+ stacking: series.stacking,
28
+ stackId,
29
+ dataLabels: {
30
+ enabled: ((_a = series.dataLabels) === null || _a === void 0 ? void 0 : _a.enabled) || false,
31
+ inside: typeof ((_b = series.dataLabels) === null || _b === void 0 ? void 0 : _b.inside) === 'boolean'
32
+ ? (_c = series.dataLabels) === null || _c === void 0 ? void 0 : _c.inside
33
+ : false,
34
+ style: Object.assign({}, DEFAULT_DATALABELS_STYLE, (_d = series.dataLabels) === null || _d === void 0 ? void 0 : _d.style),
35
+ },
36
+ };
37
+ }, []);
38
+ }
@@ -0,0 +1,10 @@
1
+ import type { ScaleOrdinal } from 'd3';
2
+ import type { BarYSeries } from '../../../../../types';
3
+ import type { PreparedLegend, PreparedSeries } from './types';
4
+ type PrepareBarYSeriesArgs = {
5
+ colorScale: ScaleOrdinal<string, string>;
6
+ series: BarYSeries[];
7
+ legend: PreparedLegend;
8
+ };
9
+ export declare function prepareBarYSeries(args: PrepareBarYSeriesArgs): PreparedSeries[];
10
+ export {};
@@ -0,0 +1,50 @@
1
+ import get from 'lodash/get';
2
+ import { getRandomCKId } from '../../../../../utils';
3
+ import { prepareLegendSymbol } from './utils';
4
+ import { DEFAULT_DATALABELS_STYLE } from './constants';
5
+ import { getLabelsSize } from '../../utils';
6
+ function prepareDataLabels(series) {
7
+ var _a;
8
+ const enabled = get(series, 'dataLabels.enabled', false);
9
+ const style = Object.assign({}, DEFAULT_DATALABELS_STYLE, (_a = series.dataLabels) === null || _a === void 0 ? void 0 : _a.style);
10
+ const { maxHeight = 0, maxWidth = 0 } = enabled
11
+ ? getLabelsSize({
12
+ labels: series.data.map((d) => String(d.label || d.x)),
13
+ style,
14
+ })
15
+ : {};
16
+ return {
17
+ enabled,
18
+ inside: get(series, 'dataLabels.inside', false),
19
+ style,
20
+ maxHeight,
21
+ maxWidth,
22
+ };
23
+ }
24
+ export function prepareBarYSeries(args) {
25
+ const { colorScale, series: seriesList, legend } = args;
26
+ const commonStackId = getRandomCKId();
27
+ return seriesList.map((series) => {
28
+ const name = series.name || '';
29
+ const color = series.color || colorScale(name);
30
+ let stackId = series.stackId;
31
+ if (!stackId) {
32
+ stackId = series.stacking === 'normal' ? commonStackId : getRandomCKId();
33
+ }
34
+ return {
35
+ type: series.type,
36
+ color,
37
+ name,
38
+ id: getRandomCKId(),
39
+ visible: get(series, 'visible', true),
40
+ legend: {
41
+ enabled: get(series, 'legend.enabled', legend.enabled),
42
+ symbol: prepareLegendSymbol(series),
43
+ },
44
+ data: series.data,
45
+ stacking: series.stacking,
46
+ stackId,
47
+ dataLabels: prepareDataLabels(series),
48
+ };
49
+ }, []);
50
+ }
@@ -0,0 +1,11 @@
1
+ import { ScaleOrdinal } from 'd3';
2
+ import { ChartKitWidgetSeriesOptions, LineSeries } from '../../../../../types';
3
+ import { PreparedLegend, PreparedSeries } from './types';
4
+ type PrepareLineSeriesArgs = {
5
+ colorScale: ScaleOrdinal<string, string>;
6
+ series: LineSeries[];
7
+ seriesOptions?: ChartKitWidgetSeriesOptions;
8
+ legend: PreparedLegend;
9
+ };
10
+ export declare function prepareLineSeries(args: PrepareLineSeriesArgs): PreparedSeries[];
11
+ export {};
@@ -0,0 +1,32 @@
1
+ import get from 'lodash/get';
2
+ import { DEFAULT_DATALABELS_PADDING, DEFAULT_DATALABELS_STYLE } from './constants';
3
+ import { prepareLegendSymbol } from './utils';
4
+ import { getRandomCKId } from '../../../../../utils';
5
+ export function prepareLineSeries(args) {
6
+ const { colorScale, series: seriesList, seriesOptions, legend } = args;
7
+ const defaultLineWidth = get(seriesOptions, 'line.lineWidth', 1);
8
+ return seriesList.map((series) => {
9
+ var _a, _b;
10
+ const id = getRandomCKId();
11
+ const name = series.name || '';
12
+ const color = series.color || colorScale(name);
13
+ return {
14
+ type: series.type,
15
+ color,
16
+ lineWidth: get(series, 'lineWidth', defaultLineWidth),
17
+ name,
18
+ id,
19
+ visible: get(series, 'visible', true),
20
+ legend: {
21
+ enabled: get(series, 'legend.enabled', legend.enabled),
22
+ symbol: prepareLegendSymbol(series),
23
+ },
24
+ data: series.data,
25
+ dataLabels: {
26
+ enabled: ((_a = series.dataLabels) === null || _a === void 0 ? void 0 : _a.enabled) || false,
27
+ style: Object.assign({}, DEFAULT_DATALABELS_STYLE, (_b = series.dataLabels) === null || _b === void 0 ? void 0 : _b.style),
28
+ padding: get(series, 'dataLabels.padding', DEFAULT_DATALABELS_PADDING),
29
+ },
30
+ };
31
+ }, []);
32
+ }
@@ -1,9 +1,10 @@
1
1
  import type { ScaleOrdinal } from 'd3';
2
- import type { ChartKitWidgetSeries } from '../../../../../types/widget-data';
2
+ import type { ChartKitWidgetSeries, ChartKitWidgetSeriesOptions } from '../../../../../types';
3
3
  import type { PreparedLegend, PreparedSeries } from './types';
4
4
  export declare function prepareSeries(args: {
5
5
  type: ChartKitWidgetSeries['type'];
6
6
  series: ChartKitWidgetSeries[];
7
+ seriesOptions?: ChartKitWidgetSeriesOptions;
7
8
  legend: PreparedLegend;
8
9
  colorScale: ScaleOrdinal<string, string>;
9
10
  }): PreparedSeries[];
@@ -3,33 +3,16 @@ import get from 'lodash/get';
3
3
  import { scaleOrdinal } from 'd3';
4
4
  import { getRandomCKId } from '../../../../../utils';
5
5
  import { DEFAULT_PALETTE } from '../../constants';
6
- import { DEFAULT_LEGEND_SYMBOL_SIZE } from './constants';
7
- const DEFAULT_DATALABELS_STYLE = {
8
- fontSize: '11px',
9
- fontWeight: 'bold',
10
- };
11
- function prepareLegendSymbol(series) {
12
- var _a;
13
- switch (series.type) {
14
- default: {
15
- const symbolOptions = ((_a = series.legend) === null || _a === void 0 ? void 0 : _a.symbol) || {};
16
- const symbolHeight = (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.height) || DEFAULT_LEGEND_SYMBOL_SIZE;
17
- return {
18
- shape: 'rect',
19
- width: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.width) || DEFAULT_LEGEND_SYMBOL_SIZE,
20
- height: symbolHeight,
21
- radius: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.radius) || symbolHeight / 2,
22
- padding: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.padding) || 5,
23
- };
24
- }
25
- }
26
- }
6
+ import { prepareLineSeries } from './prepare-line-series';
7
+ import { prepareBarXSeries } from './prepare-bar-x';
8
+ import { prepareBarYSeries } from './prepare-bar-y';
9
+ import { prepareLegendSymbol } from './utils';
10
+ import { ChartKitError } from '../../../../../libs';
27
11
  function prepareAxisRelatedSeries(args) {
28
12
  const { colorScale, series, legend } = args;
29
13
  const preparedSeries = cloneDeep(series);
30
14
  const name = 'name' in series && series.name ? series.name : '';
31
- const color = 'color' in series && series.color ? series.color : colorScale(name);
32
- preparedSeries.color = color;
15
+ preparedSeries.color = 'color' in series && series.color ? series.color : colorScale(name);
33
16
  preparedSeries.name = name;
34
17
  preparedSeries.visible = get(preparedSeries, 'visible', true);
35
18
  preparedSeries.legend = {
@@ -38,40 +21,6 @@ function prepareAxisRelatedSeries(args) {
38
21
  };
39
22
  return [preparedSeries];
40
23
  }
41
- function prepareBarXSeries(args) {
42
- const { colorScale, series: seriesList, legend } = args;
43
- const commonStackId = getRandomCKId();
44
- return seriesList.map((series) => {
45
- var _a, _b, _c, _d;
46
- const name = series.name || '';
47
- const color = series.color || colorScale(name);
48
- let stackId = series.stackId;
49
- if (!stackId) {
50
- stackId = series.stacking === 'normal' ? commonStackId : getRandomCKId();
51
- }
52
- return {
53
- type: series.type,
54
- color: color,
55
- name: name,
56
- id: '',
57
- visible: get(series, 'visible', true),
58
- legend: {
59
- enabled: get(series, 'legend.enabled', legend.enabled),
60
- symbol: prepareLegendSymbol(series),
61
- },
62
- data: series.data,
63
- stacking: series.stacking,
64
- stackId,
65
- dataLabels: {
66
- enabled: ((_a = series.dataLabels) === null || _a === void 0 ? void 0 : _a.enabled) || false,
67
- inside: typeof ((_b = series.dataLabels) === null || _b === void 0 ? void 0 : _b.inside) === 'boolean'
68
- ? (_c = series.dataLabels) === null || _c === void 0 ? void 0 : _c.inside
69
- : false,
70
- style: Object.assign({}, DEFAULT_DATALABELS_STYLE, (_d = series.dataLabels) === null || _d === void 0 ? void 0 : _d.style),
71
- },
72
- };
73
- }, []);
74
- }
75
24
  function preparePieSeries(args) {
76
25
  const { series, legend } = args;
77
26
  const dataNames = series.data.map((d) => d.name);
@@ -108,7 +57,7 @@ function preparePieSeries(args) {
108
57
  return preparedSeries;
109
58
  }
110
59
  export function prepareSeries(args) {
111
- const { type, series, legend, colorScale } = args;
60
+ const { type, series, seriesOptions, legend, colorScale } = args;
112
61
  switch (type) {
113
62
  case 'pie': {
114
63
  return series.reduce((acc, singleSeries) => {
@@ -119,15 +68,27 @@ export function prepareSeries(args) {
119
68
  case 'bar-x': {
120
69
  return prepareBarXSeries({ series: series, legend, colorScale });
121
70
  }
71
+ case 'bar-y': {
72
+ return prepareBarYSeries({ series: series, legend, colorScale });
73
+ }
122
74
  case 'scatter': {
123
75
  return series.reduce((acc, singleSeries) => {
124
76
  acc.push(...prepareAxisRelatedSeries({ series: singleSeries, legend, colorScale }));
125
77
  return acc;
126
78
  }, []);
127
79
  }
80
+ case 'line': {
81
+ return prepareLineSeries({
82
+ series: series,
83
+ seriesOptions,
84
+ legend,
85
+ colorScale,
86
+ });
87
+ }
128
88
  default: {
129
- const seriesType = get(series, 'type');
130
- throw new Error(`Series type ${seriesType} does not support data preparation for series that do not support the presence of axes`);
89
+ throw new ChartKitError({
90
+ message: `Series type "${type}" does not support data preparation for series that do not support the presence of axes`,
91
+ });
131
92
  }
132
93
  }
133
94
  }
@@ -1,4 +1,4 @@
1
- import { BarXSeries, BarXSeriesData, BaseTextStyle, ChartKitWidgetLegend, PieSeries, PieSeriesData, RectLegendSymbolOptions, ScatterSeries, ScatterSeriesData } from '../../../../../types/widget-data';
1
+ import { BarXSeries, BarXSeriesData, BaseTextStyle, ChartKitWidgetLegend, PieSeries, PieSeriesData, RectLegendSymbolOptions, ScatterSeries, ScatterSeriesData, BarYSeries, BarYSeriesData, LineSeries, LineSeriesData } from '../../../../../types';
2
2
  import type { SeriesOptionsDefaults } from '../../constants';
3
3
  export type RectLegendSymbol = {
4
4
  shape: 'rect';
@@ -53,12 +53,34 @@ export type PreparedBarXSeries = {
53
53
  style: BaseTextStyle;
54
54
  };
55
55
  } & BasePreparedSeries;
56
+ export type PreparedBarYSeries = {
57
+ type: BarYSeries['type'];
58
+ data: BarYSeriesData[];
59
+ stackId: string;
60
+ dataLabels: {
61
+ enabled: boolean;
62
+ inside: boolean;
63
+ style: BaseTextStyle;
64
+ maxHeight: number;
65
+ maxWidth: number;
66
+ };
67
+ } & BasePreparedSeries;
56
68
  export type PreparedPieSeries = BasePreparedSeries & Required<Omit<PieSeries, 'data'>> & {
57
69
  data: PieSeriesData;
58
70
  value: PieSeriesData['value'];
59
71
  stackId: string;
60
72
  label?: PieSeriesData['label'];
61
73
  };
62
- export type PreparedSeries = PreparedScatterSeries | PreparedBarXSeries | PreparedPieSeries;
74
+ export type PreparedLineSeries = {
75
+ type: LineSeries['type'];
76
+ data: LineSeriesData[];
77
+ lineWidth: number;
78
+ dataLabels: {
79
+ enabled: boolean;
80
+ style: BaseTextStyle;
81
+ padding: number;
82
+ };
83
+ } & BasePreparedSeries;
84
+ export type PreparedSeries = PreparedScatterSeries | PreparedBarXSeries | PreparedBarYSeries | PreparedPieSeries | PreparedLineSeries;
63
85
  export type PreparedSeriesOptions = SeriesOptionsDefaults;
64
86
  export {};
@@ -1,3 +1,5 @@
1
- import { PreparedSeries } from './types';
1
+ import { PreparedLegendSymbol, PreparedSeries } from './types';
2
+ import { ChartKitWidgetSeries } from '../../../../../types';
2
3
  export declare const getActiveLegendItems: (series: PreparedSeries[]) => string[];
3
4
  export declare const getAllLegendItems: (series: PreparedSeries[]) => string[];
5
+ export declare function prepareLegendSymbol(series: ChartKitWidgetSeries): PreparedLegendSymbol;
@@ -1,3 +1,4 @@
1
+ import { DEFAULT_LEGEND_SYMBOL_SIZE } from './constants';
1
2
  export const getActiveLegendItems = (series) => {
2
3
  return series.reduce((acc, s) => {
3
4
  if (s.legend.enabled && s.visible) {
@@ -9,3 +10,15 @@ export const getActiveLegendItems = (series) => {
9
10
  export const getAllLegendItems = (series) => {
10
11
  return series.map((s) => s.name);
11
12
  };
13
+ export function prepareLegendSymbol(series) {
14
+ var _a;
15
+ const symbolOptions = ((_a = series.legend) === null || _a === void 0 ? void 0 : _a.symbol) || {};
16
+ const symbolHeight = (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.height) || DEFAULT_LEGEND_SYMBOL_SIZE;
17
+ return {
18
+ shape: 'rect',
19
+ width: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.width) || DEFAULT_LEGEND_SYMBOL_SIZE,
20
+ height: symbolHeight,
21
+ radius: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.radius) || symbolHeight / 2,
22
+ padding: (symbolOptions === null || symbolOptions === void 0 ? void 0 : symbolOptions.padding) || 5,
23
+ };
24
+ }
@@ -1,9 +1,7 @@
1
1
  import { ascending, descending, max, sort } from 'd3';
2
2
  import get from 'lodash/get';
3
3
  import { getDataCategoryValue } from '../../../utils';
4
- const MIN_RECT_WIDTH = 1;
5
- const MIN_RECT_GAP = 1;
6
- const MIN_GROUP_GAP = 1;
4
+ import { MIN_BAR_GAP, MIN_BAR_GROUP_GAP, MIN_BAR_WIDTH } from '../constants';
7
5
  export const prepareBarXData = (args) => {
8
6
  const { series, seriesOptions, xAxis, xScale, yScale } = args;
9
7
  const categories = get(xAxis, 'categories', []);
@@ -64,10 +62,10 @@ export const prepareBarXData = (args) => {
64
62
  });
65
63
  }
66
64
  const maxGroupSize = max(Object.values(data), (d) => Object.values(d).length) || 1;
67
- const groupGap = Math.max(bandWidth * groupPadding, MIN_GROUP_GAP);
65
+ const groupGap = Math.max(bandWidth * groupPadding, MIN_BAR_GROUP_GAP);
68
66
  const groupWidth = bandWidth - groupGap;
69
- const rectGap = Math.max(bandWidth * barPadding, MIN_RECT_GAP);
70
- const rectWidth = Math.max(MIN_RECT_WIDTH, Math.min(groupWidth / maxGroupSize - rectGap, barMaxWidth));
67
+ const rectGap = Math.max(bandWidth * barPadding, MIN_BAR_GAP);
68
+ const rectWidth = Math.max(MIN_BAR_WIDTH, Math.min(groupWidth / maxGroupSize - rectGap, barMaxWidth));
71
69
  const result = [];
72
70
  Object.entries(data).forEach(([xValue, val]) => {
73
71
  const stacks = Object.values(val);
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import type { Dispatch } from 'd3';
3
+ import type { PreparedSeriesOptions } from '../../useSeries/types';
4
+ import type { PreparedBarYData } from './types';
5
+ export { prepareBarYData } from './prepare-data';
6
+ type Args = {
7
+ dispatcher: Dispatch<object>;
8
+ preparedData: PreparedBarYData[];
9
+ seriesOptions: PreparedSeriesOptions;
10
+ };
11
+ export declare const BarYSeriesShapes: (args: Args) => React.JSX.Element;
@@ -0,0 +1,87 @@
1
+ import React from 'react';
2
+ import get from 'lodash/get';
3
+ import { color, select } from 'd3';
4
+ import { block } from '../../../../../../utils/cn';
5
+ export { prepareBarYData } from './prepare-data';
6
+ const DEFAULT_LABEL_PADDING = 7;
7
+ const b = block('d3-bar-y');
8
+ export const BarYSeriesShapes = (args) => {
9
+ const { dispatcher, preparedData, seriesOptions } = args;
10
+ const ref = React.useRef(null);
11
+ React.useEffect(() => {
12
+ if (!ref.current) {
13
+ return () => { };
14
+ }
15
+ const svgElement = select(ref.current);
16
+ svgElement.selectAll('*').remove();
17
+ const rectSelection = svgElement
18
+ .selectAll('rect')
19
+ .data(preparedData)
20
+ .join('rect')
21
+ .attr('class', b('segment'))
22
+ .attr('x', (d) => d.x)
23
+ .attr('y', (d) => d.y)
24
+ .attr('height', (d) => d.height)
25
+ .attr('width', (d) => d.width)
26
+ .attr('fill', (d) => d.color);
27
+ const dataLabels = preparedData.filter((d) => d.series.dataLabels.enabled);
28
+ const labelSelection = svgElement
29
+ .selectAll('text')
30
+ .data(dataLabels)
31
+ .join('text')
32
+ .text((d) => String(d.data.label || d.data.x))
33
+ .attr('class', b('label'))
34
+ .attr('x', (d) => {
35
+ if (d.series.dataLabels.inside) {
36
+ return d.x + d.width / 2;
37
+ }
38
+ return d.x + d.width + DEFAULT_LABEL_PADDING;
39
+ })
40
+ .attr('y', (d) => {
41
+ return d.y + d.height / 2 + d.series.dataLabels.maxHeight / 2;
42
+ })
43
+ .attr('text-anchor', (d) => {
44
+ if (d.series.dataLabels.inside) {
45
+ return 'middle';
46
+ }
47
+ return 'right';
48
+ })
49
+ .style('font-size', (d) => d.series.dataLabels.style.fontSize)
50
+ .style('font-weight', (d) => d.series.dataLabels.style.fontWeight || null)
51
+ .style('fill', (d) => d.series.dataLabels.style.fontColor || null);
52
+ const hoverOptions = get(seriesOptions, 'bar-y.states.hover');
53
+ const inactiveOptions = get(seriesOptions, 'bar-y.states.inactive');
54
+ dispatcher.on('hover-shape.bar-y', (data) => {
55
+ if (hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled) {
56
+ const hovered = data === null || data === void 0 ? void 0 : data.reduce((acc, d) => {
57
+ acc.add(d.data.y);
58
+ return acc;
59
+ }, new Set());
60
+ rectSelection.attr('fill', (d) => {
61
+ var _a;
62
+ const fillColor = d.color;
63
+ if (hovered === null || hovered === void 0 ? void 0 : hovered.has(d.data.y)) {
64
+ return (((_a = color(fillColor)) === null || _a === void 0 ? void 0 : _a.brighter(hoverOptions.brightness).toString()) ||
65
+ fillColor);
66
+ }
67
+ return fillColor;
68
+ });
69
+ }
70
+ if (inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled) {
71
+ const hoveredSeries = data === null || data === void 0 ? void 0 : data.map((d) => d.series.id);
72
+ const newOpacity = (d) => {
73
+ if ((hoveredSeries === null || hoveredSeries === void 0 ? void 0 : hoveredSeries.length) && !hoveredSeries.includes(d.series.id)) {
74
+ return inactiveOptions.opacity || null;
75
+ }
76
+ return null;
77
+ };
78
+ rectSelection.attr('opacity', newOpacity);
79
+ labelSelection.attr('opacity', newOpacity);
80
+ }
81
+ });
82
+ return () => {
83
+ dispatcher.on('hover-shape.bar-y', null);
84
+ };
85
+ }, [dispatcher, preparedData, seriesOptions]);
86
+ return React.createElement("g", { ref: ref, className: b() });
87
+ };
@@ -0,0 +1,12 @@
1
+ import type { ChartScale } from '../../useAxisScales';
2
+ import type { PreparedAxis } from '../../useChartOptions/types';
3
+ import type { PreparedBarYSeries, PreparedSeriesOptions } from '../../useSeries/types';
4
+ import type { PreparedBarYData } from './types';
5
+ export declare const prepareBarYData: (args: {
6
+ series: PreparedBarYSeries[];
7
+ seriesOptions: PreparedSeriesOptions;
8
+ xAxis: PreparedAxis;
9
+ xScale: ChartScale;
10
+ yAxis: PreparedAxis[];
11
+ yScale: ChartScale;
12
+ }) => PreparedBarYData[];
@@ -0,0 +1,114 @@
1
+ import { ascending, descending, max, sort } from 'd3';
2
+ import get from 'lodash/get';
3
+ import { getDataCategoryValue } from '../../../utils';
4
+ import { MIN_BAR_GAP, MIN_BAR_GROUP_GAP, MIN_BAR_WIDTH } from '../constants';
5
+ function groupByYValue(series, yAxis) {
6
+ const data = {};
7
+ series.forEach((s) => {
8
+ s.data.forEach((d) => {
9
+ const axisIndex = get(s, 'yAxis', 0);
10
+ const seriesYAxis = yAxis[axisIndex];
11
+ const categories = get(seriesYAxis, 'categories', []);
12
+ const key = seriesYAxis.type === 'category'
13
+ ? getDataCategoryValue({ axisDirection: 'y', categories, data: d })
14
+ : d.y;
15
+ if (key) {
16
+ if (!data[key]) {
17
+ data[key] = {};
18
+ }
19
+ if (!data[key][s.stackId]) {
20
+ data[key][s.stackId] = [];
21
+ }
22
+ data[key][s.stackId].push({ data: d, series: s });
23
+ }
24
+ });
25
+ });
26
+ return data;
27
+ }
28
+ function getBandWidth(series, yAxis, yScale) {
29
+ let bandWidth = Infinity;
30
+ if (yAxis[0].type === 'category') {
31
+ bandWidth = yScale.bandwidth();
32
+ }
33
+ else {
34
+ const scale = yScale;
35
+ const axisValues = series.reduce((acc, s) => {
36
+ s.data.forEach((dataItem) => acc.push(Number(dataItem.y)));
37
+ return acc;
38
+ }, []);
39
+ axisValues.sort().forEach((value, index) => {
40
+ if (index > 0 && value !== axisValues[index - 1]) {
41
+ const dist = scale(value) - scale(axisValues[index - 1]);
42
+ if (dist < bandWidth) {
43
+ bandWidth = dist;
44
+ }
45
+ }
46
+ });
47
+ }
48
+ return bandWidth;
49
+ }
50
+ export const prepareBarYData = (args) => {
51
+ const { series, seriesOptions, yAxis, xScale, yScale } = args;
52
+ const barMaxWidth = get(seriesOptions, 'bar-y.barMaxWidth');
53
+ const barPadding = get(seriesOptions, 'bar-y.barPadding');
54
+ const groupPadding = get(seriesOptions, 'bar-y.groupPadding');
55
+ const sortingOptions = get(seriesOptions, 'bar-y.dataSorting');
56
+ const comparator = (sortingOptions === null || sortingOptions === void 0 ? void 0 : sortingOptions.direction) === 'desc' ? descending : ascending;
57
+ const sortKey = (() => {
58
+ switch (sortingOptions === null || sortingOptions === void 0 ? void 0 : sortingOptions.key) {
59
+ case 'x': {
60
+ return 'data.x';
61
+ }
62
+ case 'name': {
63
+ return 'series.name';
64
+ }
65
+ default: {
66
+ return undefined;
67
+ }
68
+ }
69
+ })();
70
+ const groupedData = groupByYValue(series, yAxis);
71
+ const bandWidth = getBandWidth(series, yAxis, yScale);
72
+ const maxGroupSize = max(Object.values(groupedData), (d) => Object.values(d).length) || 1;
73
+ const groupGap = Math.max(bandWidth * groupPadding, MIN_BAR_GROUP_GAP);
74
+ const groupWidth = bandWidth - groupGap;
75
+ const rectGap = Math.max(bandWidth * barPadding, MIN_BAR_GAP);
76
+ const barHeight = Math.max(MIN_BAR_WIDTH, Math.min(groupWidth / maxGroupSize - rectGap, barMaxWidth));
77
+ const result = [];
78
+ Object.entries(groupedData).forEach(([yValue, val]) => {
79
+ const stacks = Object.values(val);
80
+ const currentBarHeight = barHeight * stacks.length + rectGap * (stacks.length - 1);
81
+ stacks.forEach((measureValues, groupItemIndex) => {
82
+ let stackSum = 0;
83
+ const sortedData = sortKey
84
+ ? sort(measureValues, (a, b) => comparator(get(a, sortKey), get(b, sortKey)))
85
+ : measureValues;
86
+ sortedData.forEach(({ data, series: s }) => {
87
+ let center;
88
+ if (yAxis[0].type === 'category') {
89
+ const bandScale = yScale;
90
+ center = (bandScale(yValue) || 0) + bandWidth / 2;
91
+ }
92
+ else {
93
+ const scale = yScale;
94
+ center = scale(Number(yValue));
95
+ }
96
+ const y = center - currentBarHeight / 2 + (barHeight + rectGap) * groupItemIndex;
97
+ const xLinearScale = xScale;
98
+ const x = xLinearScale(data.x);
99
+ const width = x - xLinearScale(xLinearScale.domain()[0]);
100
+ result.push({
101
+ x: stackSum,
102
+ y,
103
+ width,
104
+ height: barHeight,
105
+ color: data.color || s.color,
106
+ data,
107
+ series: s,
108
+ });
109
+ stackSum += width + 1;
110
+ });
111
+ });
112
+ });
113
+ return result;
114
+ };
@@ -0,0 +1,10 @@
1
+ import { TooltipDataChunkBarX } from '../../../../../../types';
2
+ import { PreparedBarYSeries } from '../../useSeries/types';
3
+ export type PreparedBarYData = Omit<TooltipDataChunkBarX, 'series'> & {
4
+ x: number;
5
+ y: number;
6
+ width: number;
7
+ height: number;
8
+ color: string;
9
+ series: PreparedBarYSeries;
10
+ };
@@ -0,0 +1,3 @@
1
+ export declare const MIN_BAR_WIDTH = 1;
2
+ export declare const MIN_BAR_GAP = 1;
3
+ export declare const MIN_BAR_GROUP_GAP = 1;
@@ -0,0 +1,3 @@
1
+ export const MIN_BAR_WIDTH = 1;
2
+ export const MIN_BAR_GAP = 1;
3
+ export const MIN_BAR_GROUP_GAP = 1;
@@ -5,13 +5,13 @@ import type { ChartScale } from '../useAxisScales';
5
5
  import type { PreparedSeries, PreparedSeriesOptions } from '../';
6
6
  import type { PreparedBarXData } from './bar-x';
7
7
  import type { PreparedScatterData } from './scatter';
8
- import './styles.css';
8
+ import type { PreparedLineData } from './line/types';
9
+ import type { PreparedBarYData } from './bar-y/types';
9
10
  export type { PreparedBarXData } from './bar-x';
10
11
  export type { PreparedScatterData } from './scatter';
11
- export type ShapeData = PreparedBarXData | PreparedScatterData;
12
+ import './styles.css';
13
+ export type ShapeData = PreparedBarXData | PreparedBarYData | PreparedScatterData | PreparedLineData;
12
14
  type Args = {
13
- top: number;
14
- left: number;
15
15
  boundsWidth: number;
16
16
  boundsHeight: number;
17
17
  dispatcher: Dispatch<object>;