@gravity-ui/charts 0.7.0 → 0.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 (168) hide show
  1. package/README.md +1 -4
  2. package/dist/cjs/components/Axis/AxisX.d.ts +1 -0
  3. package/dist/cjs/components/Axis/AxisX.js +43 -6
  4. package/dist/cjs/components/Axis/AxisY.d.ts +1 -0
  5. package/dist/cjs/components/Axis/AxisY.js +63 -17
  6. package/dist/cjs/components/Axis/styles.css +5 -5
  7. package/dist/cjs/components/ChartInner/index.js +8 -6
  8. package/dist/cjs/components/ChartInner/styles.css +4 -4
  9. package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +1 -0
  10. package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +7 -4
  11. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +3 -2
  12. package/dist/cjs/components/Legend/index.js +2 -3
  13. package/dist/cjs/components/Legend/styles.css +14 -14
  14. package/dist/cjs/components/PlotTitle/index.js +1 -1
  15. package/dist/cjs/components/PlotTitle/styles.css +1 -1
  16. package/dist/cjs/components/Title/index.js +1 -1
  17. package/dist/cjs/components/Title/styles.css +1 -1
  18. package/dist/cjs/components/Tooltip/DefaultContent.js +19 -3
  19. package/dist/cjs/constants/index.d.ts +1 -0
  20. package/dist/cjs/constants/index.js +1 -0
  21. package/dist/cjs/hooks/useChartOptions/tooltip.js +2 -1
  22. package/dist/cjs/hooks/useChartOptions/types.d.ts +13 -2
  23. package/dist/cjs/hooks/useChartOptions/x-axis.js +9 -1
  24. package/dist/cjs/hooks/useChartOptions/y-axis.js +9 -1
  25. package/dist/cjs/hooks/useSeries/constants.js +1 -1
  26. package/dist/cjs/hooks/useSeries/prepare-bar-x.d.ts +2 -1
  27. package/dist/cjs/hooks/useSeries/prepare-bar-x.js +2 -1
  28. package/dist/cjs/hooks/useSeries/prepare-bar-y.d.ts +2 -1
  29. package/dist/cjs/hooks/useSeries/prepare-bar-y.js +3 -1
  30. package/dist/cjs/hooks/useSeries/prepare-pie.js +2 -2
  31. package/dist/cjs/hooks/useSeries/prepare-sankey.d.ts +11 -0
  32. package/dist/cjs/hooks/useSeries/prepare-sankey.js +38 -0
  33. package/dist/cjs/hooks/useSeries/prepareSeries.js +21 -2
  34. package/dist/cjs/hooks/useSeries/types.d.ts +12 -2
  35. package/dist/cjs/hooks/useSeries/utils.js +1 -1
  36. package/dist/cjs/hooks/useShapes/area/index.js +1 -1
  37. package/dist/cjs/hooks/useShapes/bar-x/index.js +16 -2
  38. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +2 -1
  39. package/dist/cjs/hooks/useShapes/bar-x/types.d.ts +1 -0
  40. package/dist/cjs/hooks/useShapes/bar-y/index.js +16 -2
  41. package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +2 -1
  42. package/dist/cjs/hooks/useShapes/bar-y/types.d.ts +1 -0
  43. package/dist/cjs/hooks/useShapes/index.d.ts +2 -1
  44. package/dist/cjs/hooks/useShapes/index.js +19 -0
  45. package/dist/cjs/hooks/useShapes/line/index.js +3 -3
  46. package/dist/cjs/hooks/useShapes/marker.js +1 -1
  47. package/dist/cjs/hooks/useShapes/pie/index.js +4 -4
  48. package/dist/cjs/hooks/useShapes/pie/prepare-data.js +37 -35
  49. package/dist/cjs/hooks/useShapes/pie/types.d.ts +1 -1
  50. package/dist/cjs/hooks/useShapes/sankey/index.d.ts +12 -0
  51. package/dist/cjs/hooks/useShapes/sankey/index.js +67 -0
  52. package/dist/cjs/hooks/useShapes/sankey/prepare-data.d.ts +7 -0
  53. package/dist/cjs/hooks/useShapes/sankey/prepare-data.js +72 -0
  54. package/dist/cjs/hooks/useShapes/sankey/types.d.ts +33 -0
  55. package/dist/cjs/hooks/useShapes/sankey/types.js +1 -0
  56. package/dist/cjs/hooks/useShapes/scatter/index.js +1 -1
  57. package/dist/cjs/hooks/useShapes/styles.css +7 -7
  58. package/dist/cjs/hooks/useShapes/treemap/index.js +1 -1
  59. package/dist/cjs/hooks/useShapes/utils.d.ts +7 -2
  60. package/dist/cjs/hooks/useShapes/utils.js +22 -17
  61. package/dist/cjs/hooks/useShapes/waterfall/index.js +2 -3
  62. package/dist/cjs/index.d.ts +1 -1
  63. package/dist/cjs/index.js +1 -0
  64. package/dist/cjs/types/chart/axis.d.ts +24 -0
  65. package/dist/cjs/types/chart/bar-x.d.ts +5 -0
  66. package/dist/cjs/types/chart/bar-y.d.ts +5 -0
  67. package/dist/cjs/types/chart/pie.d.ts +2 -0
  68. package/dist/cjs/types/chart/sankey.d.ts +22 -0
  69. package/dist/cjs/types/chart/sankey.js +1 -0
  70. package/dist/cjs/types/chart/series.d.ts +13 -2
  71. package/dist/cjs/types/chart/tooltip.d.ts +9 -1
  72. package/dist/cjs/types/index.d.ts +1 -0
  73. package/dist/cjs/types/index.js +1 -0
  74. package/dist/cjs/utils/chart/get-closest-data.d.ts +2 -0
  75. package/dist/cjs/utils/chart/get-closest-data.js +39 -3
  76. package/dist/cjs/utils/chart/index.js +1 -1
  77. package/dist/cjs/utils/chart/series/index.d.ts +1 -0
  78. package/dist/cjs/utils/chart/series/index.js +1 -0
  79. package/dist/cjs/utils/chart/series/line.d.ts +2 -0
  80. package/dist/cjs/utils/chart/series/line.js +17 -0
  81. package/dist/cjs/utils/{d3-dispatcher.d.ts → dispatcher.d.ts} +1 -1
  82. package/dist/cjs/utils/{d3-dispatcher.js → dispatcher.js} +1 -1
  83. package/dist/cjs/utils/index.d.ts +1 -1
  84. package/dist/cjs/utils/index.js +1 -1
  85. package/dist/esm/components/Axis/AxisX.d.ts +1 -0
  86. package/dist/esm/components/Axis/AxisX.js +43 -6
  87. package/dist/esm/components/Axis/AxisY.d.ts +1 -0
  88. package/dist/esm/components/Axis/AxisY.js +63 -17
  89. package/dist/esm/components/Axis/styles.css +5 -5
  90. package/dist/esm/components/ChartInner/index.js +8 -6
  91. package/dist/esm/components/ChartInner/styles.css +4 -4
  92. package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +1 -0
  93. package/dist/esm/components/ChartInner/useChartInnerHandlers.js +7 -4
  94. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +3 -2
  95. package/dist/esm/components/Legend/index.js +2 -3
  96. package/dist/esm/components/Legend/styles.css +14 -14
  97. package/dist/esm/components/PlotTitle/index.js +1 -1
  98. package/dist/esm/components/PlotTitle/styles.css +1 -1
  99. package/dist/esm/components/Title/index.js +1 -1
  100. package/dist/esm/components/Title/styles.css +1 -1
  101. package/dist/esm/components/Tooltip/DefaultContent.js +19 -3
  102. package/dist/esm/constants/index.d.ts +1 -0
  103. package/dist/esm/constants/index.js +1 -0
  104. package/dist/esm/hooks/useChartOptions/tooltip.js +2 -1
  105. package/dist/esm/hooks/useChartOptions/types.d.ts +13 -2
  106. package/dist/esm/hooks/useChartOptions/x-axis.js +9 -1
  107. package/dist/esm/hooks/useChartOptions/y-axis.js +9 -1
  108. package/dist/esm/hooks/useSeries/constants.js +1 -1
  109. package/dist/esm/hooks/useSeries/prepare-bar-x.d.ts +2 -1
  110. package/dist/esm/hooks/useSeries/prepare-bar-x.js +2 -1
  111. package/dist/esm/hooks/useSeries/prepare-bar-y.d.ts +2 -1
  112. package/dist/esm/hooks/useSeries/prepare-bar-y.js +3 -1
  113. package/dist/esm/hooks/useSeries/prepare-pie.js +2 -2
  114. package/dist/esm/hooks/useSeries/prepare-sankey.d.ts +11 -0
  115. package/dist/esm/hooks/useSeries/prepare-sankey.js +38 -0
  116. package/dist/esm/hooks/useSeries/prepareSeries.js +21 -2
  117. package/dist/esm/hooks/useSeries/types.d.ts +12 -2
  118. package/dist/esm/hooks/useSeries/utils.js +1 -1
  119. package/dist/esm/hooks/useShapes/area/index.js +1 -1
  120. package/dist/esm/hooks/useShapes/bar-x/index.js +16 -2
  121. package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +2 -1
  122. package/dist/esm/hooks/useShapes/bar-x/types.d.ts +1 -0
  123. package/dist/esm/hooks/useShapes/bar-y/index.js +16 -2
  124. package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +2 -1
  125. package/dist/esm/hooks/useShapes/bar-y/types.d.ts +1 -0
  126. package/dist/esm/hooks/useShapes/index.d.ts +2 -1
  127. package/dist/esm/hooks/useShapes/index.js +19 -0
  128. package/dist/esm/hooks/useShapes/line/index.js +3 -3
  129. package/dist/esm/hooks/useShapes/marker.js +1 -1
  130. package/dist/esm/hooks/useShapes/pie/index.js +4 -4
  131. package/dist/esm/hooks/useShapes/pie/prepare-data.js +37 -35
  132. package/dist/esm/hooks/useShapes/pie/types.d.ts +1 -1
  133. package/dist/esm/hooks/useShapes/sankey/index.d.ts +12 -0
  134. package/dist/esm/hooks/useShapes/sankey/index.js +67 -0
  135. package/dist/esm/hooks/useShapes/sankey/prepare-data.d.ts +7 -0
  136. package/dist/esm/hooks/useShapes/sankey/prepare-data.js +72 -0
  137. package/dist/esm/hooks/useShapes/sankey/types.d.ts +33 -0
  138. package/dist/esm/hooks/useShapes/sankey/types.js +1 -0
  139. package/dist/esm/hooks/useShapes/scatter/index.js +1 -1
  140. package/dist/esm/hooks/useShapes/styles.css +7 -7
  141. package/dist/esm/hooks/useShapes/treemap/index.js +1 -1
  142. package/dist/esm/hooks/useShapes/utils.d.ts +7 -2
  143. package/dist/esm/hooks/useShapes/utils.js +22 -17
  144. package/dist/esm/hooks/useShapes/waterfall/index.js +2 -3
  145. package/dist/esm/index.d.ts +1 -1
  146. package/dist/esm/index.js +1 -0
  147. package/dist/esm/types/chart/axis.d.ts +24 -0
  148. package/dist/esm/types/chart/bar-x.d.ts +5 -0
  149. package/dist/esm/types/chart/bar-y.d.ts +5 -0
  150. package/dist/esm/types/chart/pie.d.ts +2 -0
  151. package/dist/esm/types/chart/sankey.d.ts +22 -0
  152. package/dist/esm/types/chart/sankey.js +1 -0
  153. package/dist/esm/types/chart/series.d.ts +13 -2
  154. package/dist/esm/types/chart/tooltip.d.ts +9 -1
  155. package/dist/esm/types/index.d.ts +1 -0
  156. package/dist/esm/types/index.js +1 -0
  157. package/dist/esm/utils/chart/get-closest-data.d.ts +2 -0
  158. package/dist/esm/utils/chart/get-closest-data.js +39 -3
  159. package/dist/esm/utils/chart/index.js +1 -1
  160. package/dist/esm/utils/chart/series/index.d.ts +1 -0
  161. package/dist/esm/utils/chart/series/index.js +1 -0
  162. package/dist/esm/utils/chart/series/line.d.ts +2 -0
  163. package/dist/esm/utils/chart/series/line.js +17 -0
  164. package/dist/esm/utils/{d3-dispatcher.d.ts → dispatcher.d.ts} +1 -1
  165. package/dist/esm/utils/{d3-dispatcher.js → dispatcher.js} +1 -1
  166. package/dist/esm/utils/index.d.ts +1 -1
  167. package/dist/esm/utils/index.js +1 -1
  168. package/package.json +13 -2
@@ -1,5 +1,5 @@
1
1
  import get from 'lodash/get';
2
- import { DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_TYPE, axisLabelsDefaults, yAxisTitleDefaults, } from '../../constants';
2
+ import { DEFAULT_AXIS_LABEL_FONT_SIZE, DEFAULT_AXIS_TYPE, DashStyle, axisLabelsDefaults, yAxisTitleDefaults, } from '../../constants';
3
3
  import { CHART_SERIES_WITH_VOLUME_ON_Y_AXIS, formatAxisTickLabel, getClosestPointsRange, getHorisontalSvgTextHeight, getLabelsSize, getScaleTicks, getWaterfallPointSubtotal, wrapText, } from '../../utils';
4
4
  import { createYScale } from '../useAxisScales';
5
5
  const getAxisLabelMaxWidth = (args) => {
@@ -108,6 +108,14 @@ export const getPreparedYAxis = ({ series, yAxis, height, }) => {
108
108
  },
109
109
  position: get(axisItem, 'position', defaultAxisPosition),
110
110
  plotIndex: get(axisItem, 'plotIndex', 0),
111
+ plotLines: get(axisItem, 'plotLines', []).map((d) => ({
112
+ value: get(d, 'value', 0),
113
+ color: get(d, 'color', 'var(--g-color-base-brand)'),
114
+ width: get(d, 'width', 1),
115
+ dashStyle: get(d, 'dashStyle', DashStyle.Solid),
116
+ opacity: get(d, 'opacity', 1),
117
+ layerPlacement: get(d, 'layerPlacement', 'before'),
118
+ })),
111
119
  };
112
120
  if (labelsEnabled) {
113
121
  preparedAxis.labels.width = getAxisLabelMaxWidth({ axis: preparedAxis, series });
@@ -4,7 +4,7 @@ export const DEFAULT_DATALABELS_PADDING = 5;
4
4
  export const DEFAULT_DATALABELS_STYLE = {
5
5
  fontSize: '11px',
6
6
  fontWeight: 'bold',
7
- fontColor: 'var(--d3-data-labels)',
7
+ fontColor: 'var(--gcharts-data-labels)',
8
8
  };
9
9
  export const DEFAULT_HALO_OPTIONS = {
10
10
  enabled: true,
@@ -1,10 +1,11 @@
1
1
  import type { ScaleOrdinal } from 'd3';
2
- import type { BarXSeries } from '../../types';
2
+ import type { BarXSeries, ChartSeriesOptions } from '../../types';
3
3
  import type { PreparedLegend, PreparedSeries } from './types';
4
4
  type PrepareBarXSeriesArgs = {
5
5
  colorScale: ScaleOrdinal<string, string>;
6
6
  series: BarXSeries[];
7
7
  legend: PreparedLegend;
8
+ seriesOptions?: ChartSeriesOptions;
8
9
  };
9
10
  export declare function prepareBarXSeries(args: PrepareBarXSeriesArgs): PreparedSeries[];
10
11
  export {};
@@ -3,7 +3,7 @@ import { getUniqId } from '../../utils';
3
3
  import { DEFAULT_DATALABELS_PADDING, DEFAULT_DATALABELS_STYLE } from './constants';
4
4
  import { getSeriesStackId, prepareLegendSymbol } from './utils';
5
5
  export function prepareBarXSeries(args) {
6
- const { colorScale, series: seriesList, legend } = args;
6
+ const { colorScale, series: seriesList, seriesOptions, legend } = args;
7
7
  return seriesList.map((series) => {
8
8
  var _a, _b, _c, _d, _e;
9
9
  const name = series.name || '';
@@ -33,6 +33,7 @@ export function prepareBarXSeries(args) {
33
33
  },
34
34
  cursor: get(series, 'cursor', null),
35
35
  yAxis: get(series, 'yAxis', 0),
36
+ borderRadius: get(series, 'borderRadius', get(seriesOptions, 'bar-x.borderRadius', 0)),
36
37
  };
37
38
  }, []);
38
39
  }
@@ -1,10 +1,11 @@
1
1
  import type { ScaleOrdinal } from 'd3';
2
- import type { BarYSeries } from '../../types';
2
+ import type { BarYSeries, ChartSeriesOptions } from '../../types';
3
3
  import type { PreparedLegend, PreparedSeries } from './types';
4
4
  type PrepareBarYSeriesArgs = {
5
5
  colorScale: ScaleOrdinal<string, string>;
6
6
  series: BarYSeries[];
7
7
  legend: PreparedLegend;
8
+ seriesOptions?: ChartSeriesOptions;
8
9
  };
9
10
  export declare function prepareBarYSeries(args: PrepareBarYSeriesArgs): PreparedSeries[];
10
11
  export {};
@@ -24,8 +24,9 @@ function prepareDataLabels(series) {
24
24
  };
25
25
  }
26
26
  export function prepareBarYSeries(args) {
27
- const { colorScale, series: seriesList, legend } = args;
27
+ const { colorScale, series: seriesList, seriesOptions, legend } = args;
28
28
  return seriesList.map((series) => {
29
+ var _a, _b, _c;
29
30
  const name = series.name || '';
30
31
  const color = series.color || colorScale(name);
31
32
  return {
@@ -43,6 +44,7 @@ export function prepareBarYSeries(args) {
43
44
  stackId: getSeriesStackId(series),
44
45
  dataLabels: prepareDataLabels(series),
45
46
  cursor: get(series, 'cursor', null),
47
+ borderRadius: (_c = (_a = series.borderRadius) !== null && _a !== void 0 ? _a : (_b = seriesOptions === null || seriesOptions === void 0 ? void 0 : seriesOptions['bar-y']) === null || _b === void 0 ? void 0 : _b.borderRadius) !== null && _c !== void 0 ? _c : 0,
46
48
  };
47
49
  }, []);
48
50
  }
@@ -11,7 +11,7 @@ export function preparePieSeries(args) {
11
11
  const stackId = getUniqId();
12
12
  const seriesHoverState = get(seriesOptions, 'pie.states.hover');
13
13
  const preparedSeries = series.data.map((dataItem, i) => {
14
- var _a, _b, _c;
14
+ var _a, _b, _c, _d, _e;
15
15
  const result = {
16
16
  type: 'pie',
17
17
  data: dataItem,
@@ -40,7 +40,7 @@ export function preparePieSeries(args) {
40
40
  borderColor: series.borderColor || '',
41
41
  borderRadius: (_b = series.borderRadius) !== null && _b !== void 0 ? _b : 0,
42
42
  borderWidth: (_c = series.borderWidth) !== null && _c !== void 0 ? _c : 1,
43
- radius: series.radius || '100%',
43
+ radius: (_e = (_d = dataItem.radius) !== null && _d !== void 0 ? _d : series.radius) !== null && _e !== void 0 ? _e : '100%',
44
44
  innerRadius: series.innerRadius || 0,
45
45
  stackId,
46
46
  states: {
@@ -0,0 +1,11 @@
1
+ import type { ScaleOrdinal } from 'd3';
2
+ import type { ChartSeriesOptions, SankeySeries } from '../../types';
3
+ import type { PreparedLegend, PreparedSankeySeries } from './types';
4
+ type PrepareSankeySeriesArgs = {
5
+ colorScale: ScaleOrdinal<string, string>;
6
+ legend: PreparedLegend;
7
+ series: SankeySeries[];
8
+ seriesOptions?: ChartSeriesOptions;
9
+ };
10
+ export declare function prepareSankeySeries(args: PrepareSankeySeriesArgs): PreparedSankeySeries[];
11
+ export {};
@@ -0,0 +1,38 @@
1
+ import get from 'lodash/get';
2
+ import { getUniqId } from '../../utils';
3
+ import { DEFAULT_DATALABELS_STYLE } from './constants';
4
+ import { prepareLegendSymbol } from './utils';
5
+ export function prepareSankeySeries(args) {
6
+ const { colorScale, legend, series } = args;
7
+ return series.map((s) => {
8
+ var _a;
9
+ const id = getUniqId();
10
+ const name = s.name || '';
11
+ const color = colorScale(name);
12
+ const preparedSeries = {
13
+ color,
14
+ data: s.data.map((d) => {
15
+ var _a;
16
+ return ({
17
+ name: d.name,
18
+ color: (_a = d.color) !== null && _a !== void 0 ? _a : colorScale(d.name),
19
+ links: d.links,
20
+ });
21
+ }),
22
+ dataLabels: {
23
+ enabled: get(s, 'dataLabels.enabled', true),
24
+ style: Object.assign({}, DEFAULT_DATALABELS_STYLE, (_a = s.dataLabels) === null || _a === void 0 ? void 0 : _a.style),
25
+ },
26
+ id,
27
+ type: s.type,
28
+ name,
29
+ visible: get(s, 'visible', true),
30
+ legend: {
31
+ enabled: get(s, 'legend.enabled', legend.enabled),
32
+ symbol: prepareLegendSymbol(s),
33
+ },
34
+ cursor: get(s, 'cursor', null),
35
+ };
36
+ return preparedSeries;
37
+ });
38
+ }
@@ -4,6 +4,7 @@ import { prepareBarXSeries } from './prepare-bar-x';
4
4
  import { prepareBarYSeries } from './prepare-bar-y';
5
5
  import { prepareLineSeries } from './prepare-line';
6
6
  import { preparePieSeries } from './prepare-pie';
7
+ import { prepareSankeySeries } from './prepare-sankey';
7
8
  import { prepareScatterSeries } from './prepare-scatter';
8
9
  import { prepareTreemap } from './prepare-treemap';
9
10
  import { prepareWaterfallSeries } from './prepare-waterfall';
@@ -17,10 +18,20 @@ export function prepareSeries(args) {
17
18
  }, []);
18
19
  }
19
20
  case 'bar-x': {
20
- return prepareBarXSeries({ series: series, legend, colorScale });
21
+ return prepareBarXSeries({
22
+ series: series,
23
+ legend,
24
+ colorScale,
25
+ seriesOptions,
26
+ });
21
27
  }
22
28
  case 'bar-y': {
23
- return prepareBarYSeries({ series: series, legend, colorScale });
29
+ return prepareBarYSeries({
30
+ series: series,
31
+ legend,
32
+ colorScale,
33
+ seriesOptions,
34
+ });
24
35
  }
25
36
  case 'scatter': {
26
37
  return prepareScatterSeries({ series: series, legend, colorScale });
@@ -56,6 +67,14 @@ export function prepareSeries(args) {
56
67
  colorScale,
57
68
  });
58
69
  }
70
+ case 'sankey': {
71
+ return prepareSankeySeries({
72
+ series: series,
73
+ seriesOptions,
74
+ colorScale,
75
+ legend,
76
+ });
77
+ }
59
78
  default: {
60
79
  throw new ChartError({
61
80
  message: `Series type "${type}" does not support data preparation for series that do not support the presence of axes`,
@@ -1,5 +1,5 @@
1
1
  import type { DashStyle, LayoutAlgorithm, LineCap, SeriesOptionsDefaults, SymbolType } from '../../constants';
2
- import type { AreaSeries, AreaSeriesData, BarXSeries, BarXSeriesData, BarYSeries, BarYSeriesData, BaseTextStyle, ChartLegend, ConnectorCurve, ConnectorShape, LineSeries, LineSeriesData, PathLegendSymbolOptions, PieSeries, PieSeriesData, RectLegendSymbolOptions, ScatterSeries, ScatterSeriesData, SymbolLegendSymbolOptions, TreemapSeries, TreemapSeriesData, WaterfallSeries, WaterfallSeriesData } from '../../types';
2
+ import type { AreaSeries, AreaSeriesData, BarXSeries, BarXSeriesData, BarYSeries, BarYSeriesData, BaseTextStyle, ChartLegend, ConnectorCurve, ConnectorShape, LineSeries, LineSeriesData, PathLegendSymbolOptions, PieSeries, PieSeriesData, RectLegendSymbolOptions, SankeySeries, SankeySeriesData, ScatterSeries, ScatterSeriesData, SymbolLegendSymbolOptions, TreemapSeries, TreemapSeriesData, WaterfallSeries, WaterfallSeriesData } from '../../types';
3
3
  export type RectLegendSymbol = {
4
4
  shape: 'rect';
5
5
  } & Required<RectLegendSymbolOptions>;
@@ -107,6 +107,7 @@ export type PreparedBarXSeries = {
107
107
  padding: number;
108
108
  html: boolean;
109
109
  };
110
+ borderRadius: number;
110
111
  yAxis: number;
111
112
  } & BasePreparedSeries;
112
113
  export type PreparedBarYSeries = {
@@ -122,6 +123,7 @@ export type PreparedBarYSeries = {
122
123
  maxWidth: number;
123
124
  html: boolean;
124
125
  };
126
+ borderRadius: number;
125
127
  } & BasePreparedSeries;
126
128
  export type PreparedPieSeries = {
127
129
  type: PieSeries['type'];
@@ -248,7 +250,15 @@ export type PreparedWaterfallSeries = {
248
250
  positiveColor: string;
249
251
  negativeColor: string;
250
252
  } & BasePreparedSeries;
251
- export type PreparedSeries = PreparedScatterSeries | PreparedBarXSeries | PreparedBarYSeries | PreparedPieSeries | PreparedLineSeries | PreparedAreaSeries | PreparedTreemapSeries | PreparedWaterfallSeries;
253
+ export type PreparedSankeySeries = {
254
+ type: SankeySeries['type'];
255
+ data: SankeySeriesData[];
256
+ dataLabels: {
257
+ enabled: boolean;
258
+ style: BaseTextStyle;
259
+ };
260
+ } & BasePreparedSeries & Omit<SankeySeries, keyof BasePreparedSeries>;
261
+ export type PreparedSeries = PreparedScatterSeries | PreparedBarXSeries | PreparedBarYSeries | PreparedPieSeries | PreparedLineSeries | PreparedAreaSeries | PreparedTreemapSeries | PreparedWaterfallSeries | PreparedSankeySeries;
252
262
  export type PreparedSeriesOptions = SeriesOptionsDefaults;
253
263
  export type StackedSeries = BarXSeries | AreaSeries | BarYSeries;
254
264
  export {};
@@ -1,6 +1,6 @@
1
1
  import memoize from 'lodash/memoize';
2
2
  import { SymbolType } from '../../constants';
3
- import { getUniqId } from '../../utils';
3
+ import { getUniqId } from '../../utils/misc';
4
4
  import { DEFAULT_LEGEND_SYMBOL_PADDING, DEFAULT_LEGEND_SYMBOL_SIZE } from './constants';
5
5
  export const getActiveLegendItems = (series) => {
6
6
  return series.reduce((acc, s) => {
@@ -5,7 +5,7 @@ import { block, filterOverlappingLabels } from '../../..//utils';
5
5
  import { HtmlLayer } from '../HtmlLayer';
6
6
  import { getMarkerHaloVisibility, getMarkerVisibility, renderMarker, selectMarkerHalo, selectMarkerSymbol, setMarker, } from '../marker';
7
7
  import { setActiveState } from '../utils';
8
- const b = block('d3-area');
8
+ const b = block('area');
9
9
  export const AreaSeriesShapes = (args) => {
10
10
  const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
11
11
  const hoveredDataRef = React.useRef(null);
@@ -3,9 +3,10 @@ import { color, select } from 'd3';
3
3
  import get from 'lodash/get';
4
4
  import { block, filterOverlappingLabels } from '../../../utils';
5
5
  import { HtmlLayer } from '../HtmlLayer';
6
+ import { getRectPath } from '../utils';
6
7
  export { prepareBarXData } from './prepare-data';
7
8
  export * from './types';
8
- const b = block('d3-bar-x');
9
+ const b = block('bar-x');
9
10
  export const BarXSeriesShapes = (args) => {
10
11
  const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
11
12
  const hoveredDataRef = React.useRef(null);
@@ -22,7 +23,20 @@ export const BarXSeriesShapes = (args) => {
22
23
  const rectSelection = svgElement
23
24
  .selectAll('allRects')
24
25
  .data(preparedData)
25
- .join('rect')
26
+ .join('path')
27
+ .attr('d', (d) => {
28
+ const borderRadius = d.isLastStackItem
29
+ ? Math.min(d.height, d.width / 2, d.series.borderRadius)
30
+ : 0;
31
+ const p = getRectPath({
32
+ x: d.x,
33
+ y: d.y,
34
+ width: d.width,
35
+ height: d.height,
36
+ borderRadius: [borderRadius, borderRadius, 0, 0],
37
+ });
38
+ return p.toString();
39
+ })
26
40
  .attr('class', b('segment'))
27
41
  .attr('x', (d) => d.x)
28
42
  .attr('y', (d) => d.y)
@@ -103,7 +103,7 @@ export const prepareBarXData = (args) => {
103
103
  const sortedData = sortKey
104
104
  ? sort(yValues, (a, b) => comparator(get(a, sortKey), get(b, sortKey)))
105
105
  : yValues;
106
- sortedData.forEach((yValue) => {
106
+ sortedData.forEach((yValue, yValueIndex) => {
107
107
  const yAxisIndex = yValue.series.yAxis;
108
108
  const seriesYScale = yScale[yAxisIndex];
109
109
  let xCenter;
@@ -129,6 +129,7 @@ export const prepareBarXData = (args) => {
129
129
  data: yValue.data,
130
130
  series: yValue.series,
131
131
  htmlElements: [],
132
+ isLastStackItem: yValueIndex === sortedData.length - 1,
132
133
  };
133
134
  const label = getLabelData(barData);
134
135
  if (yValue.series.dataLabels.html && label) {
@@ -9,4 +9,5 @@ export type PreparedBarXData = Omit<TooltipDataChunkBarX, 'series'> & {
9
9
  series: PreparedBarXSeries;
10
10
  label?: LabelData;
11
11
  htmlElements: HtmlItem[];
12
+ isLastStackItem: boolean;
12
13
  };
@@ -3,8 +3,9 @@ import { color, select } from 'd3';
3
3
  import get from 'lodash/get';
4
4
  import { block } from '../../../utils';
5
5
  import { HtmlLayer } from '../HtmlLayer';
6
+ import { getRectPath } from '../utils';
6
7
  export { prepareBarYData } from './prepare-data';
7
- const b = block('d3-bar-y');
8
+ const b = block('bar-y');
8
9
  export const BarYSeriesShapes = (args) => {
9
10
  const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
10
11
  const hoveredDataRef = React.useRef(null);
@@ -18,7 +19,20 @@ export const BarYSeriesShapes = (args) => {
18
19
  const rectSelection = svgElement
19
20
  .selectAll('rect')
20
21
  .data(preparedData)
21
- .join('rect')
22
+ .join('path')
23
+ .attr('d', (d) => {
24
+ const borderRadius = d.isLastStackItem
25
+ ? Math.min(d.height, d.width / 2, d.series.borderRadius)
26
+ : 0;
27
+ const p = getRectPath({
28
+ x: d.x,
29
+ y: d.y,
30
+ width: d.width,
31
+ height: d.height,
32
+ borderRadius: [0, borderRadius, borderRadius, 0],
33
+ });
34
+ return p.toString();
35
+ })
22
36
  .attr('class', b('segment'))
23
37
  .attr('x', (d) => d.x)
24
38
  .attr('y', (d) => d.y)
@@ -124,7 +124,7 @@ export const prepareBarYData = (args) => {
124
124
  const sortedData = sortKey
125
125
  ? sort(measureValues, (a, b) => comparator(get(a, sortKey), get(b, sortKey)))
126
126
  : measureValues;
127
- sortedData.forEach(({ data, series: s }) => {
127
+ sortedData.forEach(({ data, series: s }, xValueIndex) => {
128
128
  let center;
129
129
  if (yAxis[0].type === 'category') {
130
130
  const bandScale = yScale;
@@ -147,6 +147,7 @@ export const prepareBarYData = (args) => {
147
147
  data,
148
148
  series: s,
149
149
  htmlElements: [],
150
+ isLastStackItem: xValueIndex === sortedData.length - 1,
150
151
  };
151
152
  stackItems.push(item);
152
153
  stackSum += width + 1;
@@ -10,4 +10,5 @@ export type PreparedBarYData = Omit<TooltipDataChunkBarX, 'series'> & {
10
10
  series: PreparedBarYSeries;
11
11
  label?: LabelData;
12
12
  htmlElements: HtmlItem[];
13
+ isLastStackItem: boolean;
13
14
  };
@@ -8,12 +8,13 @@ import type { PreparedBarXData } from './bar-x';
8
8
  import type { PreparedBarYData } from './bar-y/types';
9
9
  import type { PreparedLineData } from './line/types';
10
10
  import type { PreparedPieData } from './pie/types';
11
+ import type { PreparedSankeyData } from './sankey/types';
11
12
  import type { PreparedScatterData } from './scatter/types';
12
13
  export type { PreparedBarXData } from './bar-x';
13
14
  export type { PreparedScatterData } from './scatter/types';
14
15
  import type { PreparedWaterfallData } from './waterfall';
15
16
  import './styles.css';
16
- export type ShapeData = PreparedBarXData | PreparedBarYData | PreparedScatterData | PreparedLineData | PreparedPieData | PreparedAreaData | PreparedWaterfallData;
17
+ export type ShapeData = PreparedBarXData | PreparedBarYData | PreparedScatterData | PreparedLineData | PreparedPieData | PreparedAreaData | PreparedWaterfallData | PreparedSankeyData;
17
18
  type Args = {
18
19
  boundsWidth: number;
19
20
  boundsHeight: number;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { group } from 'd3';
3
+ import { ChartError } from '../../libs';
3
4
  import { getOnlyVisibleSeries } from '../../utils';
4
5
  import { AreaSeriesShapes } from './area';
5
6
  import { prepareAreaData } from './area/prepare-data';
@@ -9,6 +10,8 @@ import { LineSeriesShapes } from './line';
9
10
  import { prepareLineData } from './line/prepare-data';
10
11
  import { PieSeriesShapes } from './pie';
11
12
  import { preparePieData } from './pie/prepare-data';
13
+ import { SankeySeriesShape } from './sankey';
14
+ import { prepareSankeyData } from './sankey/prepare-data';
12
15
  import { ScatterSeriesShape, prepareScatterData } from './scatter';
13
16
  import { TreemapSeriesShape } from './treemap';
14
17
  import { prepareTreemapData } from './treemap/prepare-data';
@@ -134,6 +137,22 @@ export const useShapes = (args) => {
134
137
  });
135
138
  acc.push(React.createElement(TreemapSeriesShape, { key: "treemap", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
136
139
  shapesData.push(preparedData);
140
+ break;
141
+ }
142
+ case 'sankey': {
143
+ const preparedData = prepareSankeyData({
144
+ series: chartSeries[0],
145
+ width: boundsWidth,
146
+ height: boundsHeight,
147
+ });
148
+ acc.push(React.createElement(SankeySeriesShape, { key: "sankey", dispatcher: dispatcher, preparedData: preparedData, seriesOptions: seriesOptions, htmlLayout: htmlLayout }));
149
+ shapesData.push(preparedData);
150
+ break;
151
+ }
152
+ default: {
153
+ throw new ChartError({
154
+ message: `The display method is not defined for a series with type "${seriesType}"`,
155
+ });
137
156
  }
138
157
  }
139
158
  return acc;
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
2
  import { color, line as lineGenerator, select } from 'd3';
3
3
  import get from 'lodash/get';
4
- import { block, filterOverlappingLabels } from '../../../utils';
4
+ import { block, filterOverlappingLabels, getLineDashArray } from '../../../utils';
5
5
  import { HtmlLayer } from '../HtmlLayer';
6
6
  import { getMarkerHaloVisibility, getMarkerVisibility, renderMarker, selectMarkerHalo, selectMarkerSymbol, setMarker, } from '../marker';
7
- import { getLineDashArray, setActiveState } from '../utils';
8
- const b = block('d3-line');
7
+ import { setActiveState } from '../utils';
8
+ const b = block('line');
9
9
  export const LineSeriesShapes = (args) => {
10
10
  const { dispatcher, preparedData, seriesOptions, htmlLayout } = args;
11
11
  const hoveredDataRef = React.useRef(null);
@@ -2,7 +2,7 @@ import { symbol } from 'd3';
2
2
  import get from 'lodash/get';
3
3
  import { SymbolType } from '../../constants';
4
4
  import { block, getSymbol } from '../../utils';
5
- const b = block('d3-marker');
5
+ const b = block('marker');
6
6
  const haloClassName = b('halo');
7
7
  const symbolClassName = b('symbol');
8
8
  export function renderMarker(selection) {
@@ -4,7 +4,7 @@ import get from 'lodash/get';
4
4
  import { block, setEllipsisForOverflowTexts } from '../../../utils';
5
5
  import { HtmlLayer } from '../HtmlLayer';
6
6
  import { setActiveState } from '../utils';
7
- const b = block('d3-pie');
7
+ const b = block('pie');
8
8
  export function getHaloVisibility(d) {
9
9
  const enabled = d.data.pie.halo.enabled && d.data.hovered;
10
10
  return enabled ? '' : 'hidden';
@@ -30,7 +30,6 @@ export function PieSeriesShapes(args) {
30
30
  const [x, y] = pieData.center;
31
31
  return `translate(${x}, ${y})`;
32
32
  })
33
- .style('stroke', (pieData) => pieData.borderColor)
34
33
  .style('stroke-width', (pieData) => pieData.borderWidth)
35
34
  .attr('cursor', (pieData) => pieData.series.cursor);
36
35
  // Render halo appearing outside the hovered slice
@@ -46,7 +45,7 @@ export function PieSeriesShapes(args) {
46
45
  .attr('d', (d) => {
47
46
  const arcGenerator = arc()
48
47
  .innerRadius(d.data.pie.innerRadius)
49
- .outerRadius(d.data.pie.radius + d.data.pie.halo.size)
48
+ .outerRadius(d.data.radius + d.data.pie.halo.size)
50
49
  .cornerRadius(d.data.pie.borderRadius);
51
50
  return arcGenerator(d);
52
51
  })
@@ -63,11 +62,12 @@ export function PieSeriesShapes(args) {
63
62
  .attr('d', (d) => {
64
63
  const arcGenerator = arc()
65
64
  .innerRadius(d.data.pie.innerRadius)
66
- .outerRadius(d.data.pie.radius)
65
+ .outerRadius(d.data.radius)
67
66
  .cornerRadius(d.data.pie.borderRadius);
68
67
  return arcGenerator(d);
69
68
  })
70
69
  .attr('class', b('segment'))
70
+ .style('stroke', (d) => d.data.series.borderColor)
71
71
  .attr('fill', (d) => d.data.color)
72
72
  .attr('opacity', (d) => d.data.opacity);
73
73
  // render Labels
@@ -19,15 +19,13 @@ export function preparePieData(args) {
19
19
  const maxRadius = Math.min(boundsWidth, boundsHeight) / 2;
20
20
  const groupedPieSeries = group(preparedSeries, (pieSeries) => pieSeries.stackId);
21
21
  const prepareItem = (stackId, items) => {
22
- var _a, _b, _c;
22
+ var _a;
23
23
  const series = items[0];
24
- const { center, borderWidth, borderColor, borderRadius, radius: seriesRadius, innerRadius: seriesInnerRadius, dataLabels, } = series;
25
- const radius = (_a = calculateNumericProperty({ value: seriesRadius, base: maxRadius })) !== null && _a !== void 0 ? _a : maxRadius;
24
+ const { center, borderWidth, borderColor, borderRadius, innerRadius: seriesInnerRadius, dataLabels, } = series;
26
25
  const data = {
27
26
  id: stackId,
28
27
  center: getCenter(boundsWidth, boundsHeight, center),
29
- innerRadius: (_b = calculateNumericProperty({ value: seriesInnerRadius, base: radius })) !== null && _b !== void 0 ? _b : 0,
30
- radius,
28
+ innerRadius: 0,
31
29
  segments: [],
32
30
  labels: [],
33
31
  htmlLabels: [],
@@ -43,7 +41,19 @@ export function preparePieData(args) {
43
41
  size: series.states.hover.halo.size,
44
42
  },
45
43
  };
44
+ const { maxHeight: labelHeight } = getLabelsSize({
45
+ labels: ['Some Label'],
46
+ style: dataLabels.style,
47
+ });
48
+ let segmentMaxRadius = 0;
46
49
  const segments = items.map((item) => {
50
+ var _a;
51
+ let maxSegmentRadius = maxRadius;
52
+ if (dataLabels.enabled) {
53
+ maxSegmentRadius -= dataLabels.distance + dataLabels.connectorPadding + labelHeight;
54
+ }
55
+ const segmentRadius = (_a = calculateNumericProperty({ value: item.radius, base: maxSegmentRadius })) !== null && _a !== void 0 ? _a : maxSegmentRadius;
56
+ segmentMaxRadius = Math.max(segmentMaxRadius, segmentRadius);
47
57
  return {
48
58
  value: item.value,
49
59
  color: item.color,
@@ -52,19 +62,12 @@ export function preparePieData(args) {
52
62
  hovered: false,
53
63
  active: true,
54
64
  pie: data,
65
+ radius: segmentRadius,
55
66
  };
56
67
  });
57
68
  data.segments = pieGenerator(segments);
58
- if (dataLabels.enabled) {
59
- const { style, connectorPadding, distance } = dataLabels;
60
- const { maxHeight: labelHeight } = getLabelsSize({ labels: ['Some Label'], style });
61
- const minSegmentRadius = maxRadius - distance - connectorPadding - labelHeight;
62
- if (data.radius > minSegmentRadius) {
63
- data.radius = minSegmentRadius;
64
- data.innerRadius =
65
- (_c = calculateNumericProperty({ value: seriesInnerRadius, base: data.radius })) !== null && _c !== void 0 ? _c : 0;
66
- }
67
- }
69
+ data.innerRadius =
70
+ (_a = calculateNumericProperty({ value: seriesInnerRadius, base: segmentMaxRadius })) !== null && _a !== void 0 ? _a : 0;
68
71
  return data;
69
72
  };
70
73
  const prepareLabels = (prepareLabelsArgs) => {
@@ -84,20 +87,17 @@ export function preparePieData(args) {
84
87
  const { style, connectorPadding, distance } = dataLabels;
85
88
  const { maxHeight: labelHeight } = getLabelsSize({ labels: ['Some Label'], style });
86
89
  const connectorStartPointGenerator = arc()
87
- .innerRadius(data.radius)
88
- .outerRadius(data.radius);
89
- const connectorMidPointRadius = data.radius + distance / 2;
90
+ .innerRadius((d) => d.data.radius)
91
+ .outerRadius((d) => d.data.radius);
90
92
  const connectorMidPointGenerator = arc()
91
- .innerRadius(connectorMidPointRadius)
92
- .outerRadius(connectorMidPointRadius);
93
- const connectorArcRadius = data.radius + distance;
93
+ .innerRadius((d) => d.data.radius + distance / 2)
94
+ .outerRadius((d) => d.data.radius + distance / 2);
94
95
  const connectorEndPointGenerator = arc()
95
- .innerRadius(connectorArcRadius)
96
- .outerRadius(connectorArcRadius);
97
- const labelArcRadius = connectorArcRadius + connectorPadding;
96
+ .innerRadius((d) => d.data.radius + distance)
97
+ .outerRadius((d) => d.data.radius + distance);
98
98
  const labelArcGenerator = arc()
99
- .innerRadius(labelArcRadius)
100
- .outerRadius(labelArcRadius);
99
+ .innerRadius((d) => d.data.radius + distance + connectorPadding)
100
+ .outerRadius((d) => d.data.radius + distance + connectorPadding);
101
101
  series.forEach((d, index) => {
102
102
  const prevLabel = labels[labels.length - 1];
103
103
  const text = String(d.data.label || d.data.value);
@@ -179,8 +179,8 @@ export function preparePieData(args) {
179
179
  }
180
180
  if (shouldUseHtml) {
181
181
  htmlLabels.push({
182
- x: boundsWidth / 2 + label.x,
183
- y: boundsHeight / 2 + label.y,
182
+ x: data.center[0] + label.x,
183
+ y: Math.max(0, data.center[1] + label.y),
184
184
  content: label.text,
185
185
  size: label.size,
186
186
  });
@@ -207,19 +207,21 @@ export function preparePieData(args) {
207
207
  data,
208
208
  series: items,
209
209
  });
210
- const allPreparedLabels = [...preparedLabels.labels, ...preparedLabels.htmlLabels];
211
- const top = Math.min(data.center[1] - data.radius, ...allPreparedLabels.map((l) => l.y + data.center[1]));
212
- const bottom = Math.max(data.center[1] + data.radius, ...allPreparedLabels.map((l) => data.center[1] + l.y + l.size.height));
210
+ const segmentMaxRadius = Math.max(...data.segments.map((s) => s.data.radius));
211
+ const top = Math.min(data.center[1] - segmentMaxRadius, ...preparedLabels.labels.map((l) => l.y + data.center[1]), ...preparedLabels.htmlLabels.map((l) => l.y));
212
+ const bottom = Math.max(data.center[1] + segmentMaxRadius, ...preparedLabels.labels.map((l) => l.y + data.center[1] + l.size.height), ...preparedLabels.htmlLabels.map((l) => l.y + l.size.height));
213
213
  const topAdjustment = Math.floor(top - data.halo.size);
214
214
  if (topAdjustment > 0) {
215
- // should adjust top position and height
216
- data.radius += topAdjustment / 2;
215
+ data.segments.forEach((s) => {
216
+ s.data.radius += topAdjustment / 2;
217
+ });
217
218
  data.center[1] -= topAdjustment / 2;
218
219
  }
219
220
  const bottomAdjustment = Math.floor(boundsHeight - bottom - data.halo.size);
220
221
  if (bottomAdjustment > 0) {
221
- // should adjust position and radius
222
- data.radius += bottomAdjustment / 2;
222
+ data.segments.forEach((s) => {
223
+ s.data.radius += bottomAdjustment / 2;
224
+ });
223
225
  data.center[1] += bottomAdjustment / 2;
224
226
  }
225
227
  const { labels, htmlLabels, connectors } = prepareLabels({