@gravity-ui/charts 0.6.0 → 0.6.1-beta.2

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 (178) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/components/Axis/AxisY.d.ts +1 -0
  3. package/dist/cjs/components/Axis/AxisY.js +55 -13
  4. package/dist/cjs/components/ChartInner/index.js +3 -2
  5. package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +4 -0
  6. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +2 -2
  7. package/dist/cjs/components/Legend/index.js +1 -2
  8. package/dist/cjs/components/PlotTitle/index.js +1 -1
  9. package/dist/cjs/components/PlotTitle/styles.css +1 -1
  10. package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +2 -2
  11. package/dist/cjs/components/Tooltip/DefaultContent.js +19 -3
  12. package/dist/cjs/components/Tooltip/index.js +2 -2
  13. package/dist/cjs/components/Tooltip/styles.css +11 -9
  14. package/dist/cjs/components/index.d.ts +10 -9
  15. package/dist/cjs/constants/index.d.ts +1 -0
  16. package/dist/cjs/constants/index.js +1 -0
  17. package/dist/cjs/hooks/useChartOptions/types.d.ts +11 -1
  18. package/dist/cjs/hooks/useChartOptions/x-axis.js +1 -0
  19. package/dist/cjs/hooks/useChartOptions/y-axis.js +9 -1
  20. package/dist/cjs/hooks/useSeries/prepare-area.d.ts +1 -1
  21. package/dist/cjs/hooks/useSeries/prepare-bar-x.d.ts +2 -1
  22. package/dist/cjs/hooks/useSeries/prepare-bar-x.js +2 -1
  23. package/dist/cjs/hooks/useSeries/prepare-bar-y.d.ts +2 -1
  24. package/dist/cjs/hooks/useSeries/prepare-bar-y.js +3 -1
  25. package/dist/cjs/hooks/useSeries/prepare-line.d.ts +1 -1
  26. package/dist/cjs/hooks/useSeries/prepare-pie.js +2 -2
  27. package/dist/cjs/hooks/useSeries/prepare-sankey.d.ts +11 -0
  28. package/dist/cjs/hooks/useSeries/prepare-sankey.js +38 -0
  29. package/dist/cjs/hooks/useSeries/prepareSeries.js +21 -2
  30. package/dist/cjs/hooks/useSeries/types.d.ts +12 -2
  31. package/dist/cjs/hooks/useSeries/utils.js +1 -1
  32. package/dist/cjs/hooks/useShapes/area/prepare-data.js +4 -0
  33. package/dist/cjs/hooks/useShapes/bar-x/index.js +16 -2
  34. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +3 -1
  35. package/dist/cjs/hooks/useShapes/bar-x/types.d.ts +1 -0
  36. package/dist/cjs/hooks/useShapes/bar-y/index.js +16 -2
  37. package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +3 -1
  38. package/dist/cjs/hooks/useShapes/bar-y/types.d.ts +1 -0
  39. package/dist/cjs/hooks/useShapes/index.d.ts +2 -1
  40. package/dist/cjs/hooks/useShapes/index.js +19 -0
  41. package/dist/cjs/hooks/useShapes/line/index.js +2 -2
  42. package/dist/cjs/hooks/useShapes/line/prepare-data.js +1 -0
  43. package/dist/cjs/hooks/useShapes/pie/index.js +5 -4
  44. package/dist/cjs/hooks/useShapes/pie/prepare-data.js +168 -118
  45. package/dist/cjs/hooks/useShapes/pie/types.d.ts +2 -2
  46. package/dist/cjs/hooks/useShapes/sankey/index.d.ts +12 -0
  47. package/dist/cjs/hooks/useShapes/sankey/index.js +67 -0
  48. package/dist/cjs/hooks/useShapes/sankey/prepare-data.d.ts +7 -0
  49. package/dist/cjs/hooks/useShapes/sankey/prepare-data.js +72 -0
  50. package/dist/cjs/hooks/useShapes/sankey/types.d.ts +33 -0
  51. package/dist/cjs/hooks/useShapes/sankey/types.js +1 -0
  52. package/dist/cjs/hooks/useShapes/styles.css +2 -2
  53. package/dist/cjs/hooks/useShapes/treemap/prepare-data.js +1 -0
  54. package/dist/cjs/hooks/useShapes/utils.d.ts +7 -2
  55. package/dist/cjs/hooks/useShapes/utils.js +22 -17
  56. package/dist/cjs/hooks/useShapes/waterfall/index.js +1 -2
  57. package/dist/cjs/index.d.ts +1 -1
  58. package/dist/cjs/index.js +1 -0
  59. package/dist/cjs/types/chart/area.d.ts +6 -6
  60. package/dist/cjs/types/chart/axis.d.ts +32 -7
  61. package/dist/cjs/types/chart/bar-x.d.ts +9 -4
  62. package/dist/cjs/types/chart/bar-y.d.ts +10 -6
  63. package/dist/cjs/types/chart/base.d.ts +6 -6
  64. package/dist/cjs/types/chart/chart.d.ts +4 -4
  65. package/dist/cjs/types/chart/halo.d.ts +2 -2
  66. package/dist/cjs/types/chart/legend.d.ts +10 -10
  67. package/dist/cjs/types/chart/line.d.ts +4 -4
  68. package/dist/cjs/types/chart/marker.d.ts +2 -2
  69. package/dist/cjs/types/chart/pie.d.ts +6 -4
  70. package/dist/cjs/types/chart/sankey.d.ts +22 -0
  71. package/dist/cjs/types/chart/sankey.js +1 -0
  72. package/dist/cjs/types/chart/scatter.d.ts +4 -4
  73. package/dist/cjs/types/chart/series.d.ts +21 -10
  74. package/dist/cjs/types/chart/split.d.ts +4 -4
  75. package/dist/cjs/types/chart/title.d.ts +2 -2
  76. package/dist/cjs/types/chart/tooltip.d.ts +27 -21
  77. package/dist/cjs/types/chart/treemap.d.ts +4 -4
  78. package/dist/cjs/types/chart/waterfall.d.ts +4 -4
  79. package/dist/cjs/types/chart-ui.d.ts +10 -6
  80. package/dist/cjs/types/formatter.d.ts +4 -4
  81. package/dist/cjs/types/index.d.ts +35 -4
  82. package/dist/cjs/types/index.js +1 -0
  83. package/dist/cjs/utils/chart/get-closest-data.d.ts +2 -0
  84. package/dist/cjs/utils/chart/get-closest-data.js +39 -3
  85. package/dist/cjs/utils/chart/index.js +1 -1
  86. package/dist/cjs/utils/chart/series/index.d.ts +1 -0
  87. package/dist/cjs/utils/chart/series/index.js +1 -0
  88. package/dist/cjs/utils/chart/series/line.d.ts +2 -0
  89. package/dist/cjs/utils/chart/series/line.js +17 -0
  90. package/dist/esm/components/Axis/AxisY.d.ts +1 -0
  91. package/dist/esm/components/Axis/AxisY.js +55 -13
  92. package/dist/esm/components/ChartInner/index.js +3 -2
  93. package/dist/esm/components/ChartInner/useChartInnerHandlers.js +4 -0
  94. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +2 -2
  95. package/dist/esm/components/Legend/index.js +1 -2
  96. package/dist/esm/components/PlotTitle/index.js +1 -1
  97. package/dist/esm/components/PlotTitle/styles.css +1 -1
  98. package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +2 -2
  99. package/dist/esm/components/Tooltip/DefaultContent.js +19 -3
  100. package/dist/esm/components/Tooltip/index.js +2 -2
  101. package/dist/esm/components/Tooltip/styles.css +11 -9
  102. package/dist/esm/components/index.d.ts +10 -9
  103. package/dist/esm/constants/index.d.ts +1 -0
  104. package/dist/esm/constants/index.js +1 -0
  105. package/dist/esm/hooks/useChartOptions/types.d.ts +11 -1
  106. package/dist/esm/hooks/useChartOptions/x-axis.js +1 -0
  107. package/dist/esm/hooks/useChartOptions/y-axis.js +9 -1
  108. package/dist/esm/hooks/useSeries/prepare-area.d.ts +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-line.d.ts +1 -1
  114. package/dist/esm/hooks/useSeries/prepare-pie.js +2 -2
  115. package/dist/esm/hooks/useSeries/prepare-sankey.d.ts +11 -0
  116. package/dist/esm/hooks/useSeries/prepare-sankey.js +38 -0
  117. package/dist/esm/hooks/useSeries/prepareSeries.js +21 -2
  118. package/dist/esm/hooks/useSeries/types.d.ts +12 -2
  119. package/dist/esm/hooks/useSeries/utils.js +1 -1
  120. package/dist/esm/hooks/useShapes/area/prepare-data.js +4 -0
  121. package/dist/esm/hooks/useShapes/bar-x/index.js +16 -2
  122. package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +3 -1
  123. package/dist/esm/hooks/useShapes/bar-x/types.d.ts +1 -0
  124. package/dist/esm/hooks/useShapes/bar-y/index.js +16 -2
  125. package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +3 -1
  126. package/dist/esm/hooks/useShapes/bar-y/types.d.ts +1 -0
  127. package/dist/esm/hooks/useShapes/index.d.ts +2 -1
  128. package/dist/esm/hooks/useShapes/index.js +19 -0
  129. package/dist/esm/hooks/useShapes/line/index.js +2 -2
  130. package/dist/esm/hooks/useShapes/line/prepare-data.js +1 -0
  131. package/dist/esm/hooks/useShapes/pie/index.js +5 -4
  132. package/dist/esm/hooks/useShapes/pie/prepare-data.js +168 -118
  133. package/dist/esm/hooks/useShapes/pie/types.d.ts +2 -2
  134. package/dist/esm/hooks/useShapes/sankey/index.d.ts +12 -0
  135. package/dist/esm/hooks/useShapes/sankey/index.js +67 -0
  136. package/dist/esm/hooks/useShapes/sankey/prepare-data.d.ts +7 -0
  137. package/dist/esm/hooks/useShapes/sankey/prepare-data.js +72 -0
  138. package/dist/esm/hooks/useShapes/sankey/types.d.ts +33 -0
  139. package/dist/esm/hooks/useShapes/sankey/types.js +1 -0
  140. package/dist/esm/hooks/useShapes/styles.css +2 -2
  141. package/dist/esm/hooks/useShapes/treemap/prepare-data.js +1 -0
  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 +1 -2
  145. package/dist/esm/index.d.ts +1 -1
  146. package/dist/esm/index.js +1 -0
  147. package/dist/esm/types/chart/area.d.ts +6 -6
  148. package/dist/esm/types/chart/axis.d.ts +32 -7
  149. package/dist/esm/types/chart/bar-x.d.ts +9 -4
  150. package/dist/esm/types/chart/bar-y.d.ts +10 -6
  151. package/dist/esm/types/chart/base.d.ts +6 -6
  152. package/dist/esm/types/chart/chart.d.ts +4 -4
  153. package/dist/esm/types/chart/halo.d.ts +2 -2
  154. package/dist/esm/types/chart/legend.d.ts +10 -10
  155. package/dist/esm/types/chart/line.d.ts +4 -4
  156. package/dist/esm/types/chart/marker.d.ts +2 -2
  157. package/dist/esm/types/chart/pie.d.ts +6 -4
  158. package/dist/esm/types/chart/sankey.d.ts +22 -0
  159. package/dist/esm/types/chart/sankey.js +1 -0
  160. package/dist/esm/types/chart/scatter.d.ts +4 -4
  161. package/dist/esm/types/chart/series.d.ts +21 -10
  162. package/dist/esm/types/chart/split.d.ts +4 -4
  163. package/dist/esm/types/chart/title.d.ts +2 -2
  164. package/dist/esm/types/chart/tooltip.d.ts +27 -21
  165. package/dist/esm/types/chart/treemap.d.ts +4 -4
  166. package/dist/esm/types/chart/waterfall.d.ts +4 -4
  167. package/dist/esm/types/chart-ui.d.ts +10 -6
  168. package/dist/esm/types/formatter.d.ts +4 -4
  169. package/dist/esm/types/index.d.ts +35 -4
  170. package/dist/esm/types/index.js +1 -0
  171. package/dist/esm/utils/chart/get-closest-data.d.ts +2 -0
  172. package/dist/esm/utils/chart/get-closest-data.js +39 -3
  173. package/dist/esm/utils/chart/index.js +1 -1
  174. package/dist/esm/utils/chart/series/index.d.ts +1 -0
  175. package/dist/esm/utils/chart/series/index.js +1 -0
  176. package/dist/esm/utils/chart/series/line.d.ts +2 -0
  177. package/dist/esm/utils/chart/series/line.js +17 -0
  178. package/package.json +7 -2
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @gravity-ui/charts · [![npm package](https://img.shields.io/npm/v/@gravity-ui/charts)](https://www.npmjs.com/package/@gravity-ui/charts) [![CI](https://img.shields.io/github/actions/workflow/status/gravity-ui/charts/.github/workflows/ci.yml?label=CI&logo=github)](https://github.com/gravity-ui/charts/actions/workflows/ci.yml?query=branch:main) [![storybook](https://img.shields.io/badge/Storybook-deployed-ff4685)](https://preview.gravity-ui.com/charts/)
1
+ # Gravity Charts · [![npm package](https://img.shields.io/npm/v/@gravity-ui/charts)](https://www.npmjs.com/package/@gravity-ui/charts) [![CI](https://img.shields.io/github/actions/workflow/status/gravity-ui/charts/.github/workflows/ci.yml?label=CI&logo=github)](https://github.com/gravity-ui/charts/actions/workflows/ci.yml?query=branch:main) [![storybook](https://img.shields.io/badge/Storybook-deployed-ff4685)](https://preview.gravity-ui.com/charts/)
2
2
 
3
3
  > [!WARNING]
4
4
  > The library may have major changes in minor releases while it is on version `0.*.*`.
@@ -6,7 +6,7 @@
6
6
  ## Install
7
7
 
8
8
  ```shell
9
- npm install --save-dev @gravity-ui/uikit @gravity-ui/charts
9
+ npm install @gravity-ui/uikit @gravity-ui/charts
10
10
  ```
11
11
 
12
12
  ## Development
@@ -7,6 +7,7 @@ type Props = {
7
7
  width: number;
8
8
  height: number;
9
9
  split: PreparedSplit;
10
+ plotRef?: React.MutableRefObject<SVGGElement | null>;
10
11
  };
11
12
  export declare const AxisY: (props: Props) => React.JSX.Element;
12
13
  export {};
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { axisLeft, axisRight, line, select } from 'd3';
3
- import { block, calculateCos, calculateSin, formatAxisTickLabel, getAxisHeight, getAxisTitleRows, getClosestPointsRange, getScaleTicks, getTicksCount, handleOverflowingText, parseTransformStyle, setEllipsisForOverflowTexts, wrapText, } from '../../utils';
3
+ import { block, calculateCos, calculateSin, formatAxisTickLabel, getAxisHeight, getAxisTitleRows, getClosestPointsRange, getLineDashArray, getScaleTicks, getTicksCount, handleOverflowingText, parseTransformStyle, setEllipsisForOverflowTexts, wrapText, } from '../../utils';
4
4
  import './styles.css';
5
5
  const b = block('d3-axis');
6
6
  function transformLabel(args) {
@@ -79,7 +79,7 @@ function getTitlePosition(args) {
79
79
  return { x, y };
80
80
  }
81
81
  export const AxisY = (props) => {
82
- const { axes, width, height: totalHeight, scale, split } = props;
82
+ const { axes, width, height: totalHeight, scale, split, plotRef } = props;
83
83
  const height = getAxisHeight({ split, boundsHeight: totalHeight });
84
84
  const ref = React.useRef(null);
85
85
  React.useEffect(() => {
@@ -88,26 +88,34 @@ export const AxisY = (props) => {
88
88
  }
89
89
  const svgElement = select(ref.current);
90
90
  svgElement.selectAll('*').remove();
91
+ const getAxisPosition = (axis) => {
92
+ var _a;
93
+ const top = ((_a = split.plots[axis.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
94
+ if (axis.position === 'left') {
95
+ return `translate(0, ${top}px)`;
96
+ }
97
+ return `translate(${width}px, 0)`;
98
+ };
99
+ const plotLines = axes.reduce((acc, axis) => {
100
+ if (axis.plotLines.length) {
101
+ acc.push(...axis.plotLines.map((plotLine) => {
102
+ return Object.assign(Object.assign({}, plotLine), { transform: getAxisPosition(axis) });
103
+ }));
104
+ }
105
+ return acc;
106
+ }, []);
91
107
  const axisSelection = svgElement
92
108
  .selectAll('axis')
93
109
  .data(axes)
94
110
  .join('g')
95
111
  .attr('class', b())
96
- .style('transform', (d) => {
97
- var _a;
98
- const top = ((_a = split.plots[d.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
99
- if (d.position === 'left') {
100
- return `translate(0, ${top}px)`;
101
- }
102
- return `translate(${width}px, 0)`;
103
- });
112
+ .style('transform', (d) => getAxisPosition(d));
104
113
  axisSelection.each((d, index, node) => {
105
114
  const seriesScale = scale[index];
106
115
  const axisItem = select(node[index]);
116
+ const axisScale = seriesScale;
107
117
  const yAxisGenerator = getAxisGenerator({
108
- axisGenerator: d.position === 'left'
109
- ? axisLeft(seriesScale)
110
- : axisRight(seriesScale),
118
+ axisGenerator: d.position === 'left' ? axisLeft(axisScale) : axisRight(axisScale),
111
119
  preparedAxis: d,
112
120
  height,
113
121
  width,
@@ -148,6 +156,40 @@ export const AxisY = (props) => {
148
156
  })
149
157
  .remove();
150
158
  }
159
+ if (plotRef && d.plotLines.length > 0) {
160
+ const plotLineClassName = b('plotLine');
161
+ const plotLineContainer = select(plotRef.current);
162
+ plotLineContainer.selectAll(`.${plotLineClassName}`).remove();
163
+ const plotLinesSelection = plotLineContainer
164
+ .selectAll(`.${plotLineClassName}`)
165
+ .data(plotLines)
166
+ .join('g')
167
+ .attr('class', plotLineClassName)
168
+ .style('transform', (plotLine) => plotLine.transform);
169
+ plotLinesSelection
170
+ .append('path')
171
+ .attr('d', (plotLine) => {
172
+ const plotLineValue = Number(axisScale(plotLine.value));
173
+ const points = [
174
+ [0, plotLineValue],
175
+ [width, plotLineValue],
176
+ ];
177
+ return line()(points);
178
+ })
179
+ .attr('stroke', (plotLine) => plotLine.color)
180
+ .attr('stroke-width', (plotLine) => plotLine.width)
181
+ .attr('stroke-dasharray', (plotLine) => getLineDashArray(plotLine.dashStyle, plotLine.width))
182
+ .attr('opacity', (plotLine) => plotLine.opacity);
183
+ plotLinesSelection.each((plotLineData, i, nodes) => {
184
+ const plotLineSelection = select(nodes[i]);
185
+ if (plotLineData.layerPlacement === 'before') {
186
+ plotLineSelection.lower();
187
+ }
188
+ else {
189
+ plotLineSelection.raise();
190
+ }
191
+ });
192
+ }
151
193
  return axisItem;
152
194
  });
153
195
  axisSelection
@@ -15,6 +15,7 @@ export const ChartInner = (props) => {
15
15
  const { width, height, data } = props;
16
16
  const svgRef = React.useRef(null);
17
17
  const htmlLayerRef = React.useRef(null);
18
+ const plotRef = React.useRef(null);
18
19
  const dispatcher = React.useMemo(() => getD3Dispatcher(), []);
19
20
  const { boundsHeight, boundsOffsetLeft, boundsOffsetTop, boundsWidth, handleLegendItemClick, legendConfig, legendItems, preparedSeries, preparedSplit, preparedLegend, prevHeight, prevWidth, shapes, shapesData, title, tooltip, xAxis, xScale, yAxis, yScale, } = useChartInnerProps(Object.assign(Object.assign({}, props), { dispatcher, htmlLayout: htmlLayerRef.current }));
20
21
  const { tooltipPinned, togglePinTooltip, unpinTooltip } = useChartInnerState({
@@ -63,9 +64,9 @@ export const ChartInner = (props) => {
63
64
  React.createElement("g", { transform: `translate(0, ${boundsOffsetTop})` }, preparedSplit.plots.map((plot, index) => {
64
65
  return React.createElement(PlotTitle, { key: `plot-${index}`, title: plot.title });
65
66
  })),
66
- React.createElement("g", { width: boundsWidth, height: boundsHeight, transform: `translate(${[boundsOffsetLeft, boundsOffsetTop].join(',')})` },
67
+ React.createElement("g", { width: boundsWidth, height: boundsHeight, transform: `translate(${[boundsOffsetLeft, boundsOffsetTop].join(',')})`, ref: plotRef },
67
68
  xScale && (yScale === null || yScale === void 0 ? void 0 : yScale.length) && (React.createElement(React.Fragment, null,
68
- React.createElement(AxisY, { axes: yAxis, width: boundsWidth, height: boundsHeight, scale: yScale, split: preparedSplit }),
69
+ React.createElement(AxisY, { axes: yAxis, width: boundsWidth, height: boundsHeight, scale: yScale, split: preparedSplit, plotRef: plotRef }),
69
70
  React.createElement("g", { transform: `translate(0, ${boundsHeight})` },
70
71
  React.createElement(AxisX, { axis: xAxis, width: boundsWidth, height: boundsHeight, scale: xScale, split: preparedSplit })))),
71
72
  shapes),
@@ -24,6 +24,8 @@ export function useChartInnerHandlers(props) {
24
24
  const closest = getClosestPoints({
25
25
  position: [x, y],
26
26
  shapesData,
27
+ boundsHeight,
28
+ boundsWidth,
27
29
  });
28
30
  dispatcher.call(EventType.HOVER_SHAPE, event.target, closest, [pointerX, pointerY]);
29
31
  dispatcher.call(EventType.POINTERMOVE_CHART, {}, {
@@ -65,6 +67,8 @@ export function useChartInnerHandlers(props) {
65
67
  const items = getClosestPoints({
66
68
  position: [x, y],
67
69
  shapesData,
70
+ boundsHeight,
71
+ boundsWidth,
68
72
  });
69
73
  const selected = items === null || items === void 0 ? void 0 : items.find((item) => item.closest);
70
74
  if (!selected) {
@@ -29,10 +29,10 @@ export declare function useChartInnerProps(props: Props): {
29
29
  prevWidth: number | undefined;
30
30
  shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
31
31
  shapesData: import("../../hooks").ShapeData[];
32
- title: (import("../../types").ChartTitle & {
32
+ title: (import("../..").ChartTitle & {
33
33
  height: number;
34
34
  }) | undefined;
35
- tooltip: import("../../types").ChartTooltip<any> & {
35
+ tooltip: import("../..").ChartTooltip<any> & {
36
36
  enabled: boolean;
37
37
  };
38
38
  xAxis: import("../../hooks").PreparedAxis;
@@ -1,9 +1,8 @@
1
1
  import React from 'react';
2
2
  import { line as lineGenerator, scaleLinear, select, symbol } from 'd3';
3
3
  import { CONTINUOUS_LEGEND_SIZE } from '../../constants';
4
- import { getLineDashArray } from '../../hooks/useShapes/utils';
5
4
  import { formatNumber } from '../../libs';
6
- import { block, createGradientRect, getContinuesColorFn, getLabelsSize, getSymbol, } from '../../utils';
5
+ import { block, createGradientRect, getContinuesColorFn, getLabelsSize, getLineDashArray, getSymbol, } from '../../utils';
7
6
  import { axisBottom } from '../../utils/chart/axis-generators';
8
7
  import './styles.css';
9
8
  const b = block('d3-legend');
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { block } from '../../utils';
3
3
  import './styles.css';
4
- const b = block('d3-plot-title');
4
+ const b = block('plot-title');
5
5
  export const PlotTitle = (props) => {
6
6
  const { title } = props;
7
7
  if (!title) {
@@ -1,4 +1,4 @@
1
- .chartkit-d3-plot-title {
1
+ .gcharts-plot-title {
2
2
  font-size: var(--g-text-subheader-3-font-size);
3
3
  font-weight: var(--g-text-subheader-font-weight);
4
4
  fill: var(--g-color-text-secondary);
@@ -1,9 +1,9 @@
1
1
  import React from 'react';
2
2
  import type { ChartTooltip, ChartXAxis, ChartYAxis, TooltipDataChunk } from '../../types';
3
- export type ChartTooltipContentProps = {
3
+ export interface ChartTooltipContentProps {
4
4
  hovered?: TooltipDataChunk[];
5
5
  xAxis?: ChartXAxis;
6
6
  yAxis?: ChartYAxis;
7
7
  renderer?: ChartTooltip['renderer'];
8
- };
8
+ }
9
9
  export declare const ChartTooltipContent: (props: ChartTooltipContentProps) => React.JSX.Element | null;
@@ -3,7 +3,7 @@ import { dateTime } from '@gravity-ui/date-utils';
3
3
  import get from 'lodash/get';
4
4
  import { formatNumber } from '../../libs';
5
5
  import { block, getDataCategoryValue, getWaterfallPointSubtotal } from '../../utils';
6
- const b = block('d3-tooltip');
6
+ const b = block('tooltip');
7
7
  const DEFAULT_DATE_FORMAT = 'DD.MM.YY';
8
8
  const getRowData = (fieldName, data, axis) => {
9
9
  switch (axis === null || axis === void 0 ? void 0 : axis.type) {
@@ -29,7 +29,7 @@ const getXRowData = (data, xAxis) => getRowData('x', data, xAxis);
29
29
  const getYRowData = (data, yAxis) => getRowData('y', data, yAxis);
30
30
  const getMeasureValue = (data, xAxis, yAxis) => {
31
31
  var _a, _b;
32
- if (data.every((item) => ['pie', 'treemap', 'waterfall'].includes(item.series.type))) {
32
+ if (data.every((item) => ['pie', 'treemap', 'waterfall', 'sankey'].includes(item.series.type))) {
33
33
  return null;
34
34
  }
35
35
  if (data.some((item) => item.series.type === 'bar-y')) {
@@ -41,7 +41,9 @@ export const DefaultContent = ({ hovered, xAxis, yAxis }) => {
41
41
  const measureValue = getMeasureValue(hovered, xAxis, yAxis);
42
42
  return (React.createElement(React.Fragment, null,
43
43
  measureValue && React.createElement("div", null, measureValue),
44
- hovered.map(({ data, series, closest }, i) => {
44
+ hovered.map((seriesItem, i) => {
45
+ var _a;
46
+ const { data, series, closest } = seriesItem;
45
47
  const id = `${get(series, 'id')}_${i}`;
46
48
  const color = get(series, 'color');
47
49
  switch (series.type) {
@@ -93,6 +95,20 @@ export const DefaultContent = ({ hovered, xAxis, yAxis }) => {
93
95
  "\u00A0"),
94
96
  React.createElement("span", null, seriesData.value)));
95
97
  }
98
+ case 'sankey': {
99
+ const { target, data: source } = seriesItem;
100
+ const value = (_a = source.links.find((d) => d.name === (target === null || target === void 0 ? void 0 : target.name))) === null || _a === void 0 ? void 0 : _a.value;
101
+ return (React.createElement("div", { key: id, className: b('content-row') },
102
+ React.createElement("div", { className: b('color'), style: { backgroundColor: source.color } }),
103
+ React.createElement("div", { style: { display: 'flex', gap: 8, verticalAlign: 'center' } },
104
+ source.name,
105
+ " ",
106
+ React.createElement("span", null, "\u2192"),
107
+ " ", target === null || target === void 0 ? void 0 :
108
+ target.name,
109
+ ": ",
110
+ value)));
111
+ }
96
112
  default: {
97
113
  return null;
98
114
  }
@@ -4,7 +4,7 @@ import { useTooltip } from '../../hooks';
4
4
  import { block } from '../../utils';
5
5
  import { ChartTooltipContent } from './ChartTooltipContent';
6
6
  import './styles.css';
7
- const b = block('d3-tooltip');
7
+ const b = block('tooltip');
8
8
  export const Tooltip = (props) => {
9
9
  const { tooltip, xAxis, yAxis, svgContainer, dispatcher, tooltipPinned, onOutsideClick } = props;
10
10
  const { hovered, pointerPosition } = useTooltip({ dispatcher, tooltip });
@@ -21,7 +21,7 @@ export const Tooltip = (props) => {
21
21
  React.useEffect(() => {
22
22
  window.dispatchEvent(new CustomEvent('scroll'));
23
23
  }, [left, top]);
24
- return (hovered === null || hovered === void 0 ? void 0 : hovered.length) ? (React.createElement(Popup, { className: b({ pinned: tooltipPinned }), open: true, anchorRef: anchorRef, offset: [0, 20], placement: ['right', 'left', 'top', 'bottom'], modifiers: [{ name: 'preventOverflow', options: { padding: 10, altAxis: true } }], onOutsideClick: tooltipPinned ? handleOutsideClick : undefined },
24
+ return (hovered === null || hovered === void 0 ? void 0 : hovered.length) ? (React.createElement(Popup, { className: b({ pinned: tooltipPinned }), contentClassName: b('popup-content'), open: true, anchorRef: anchorRef, offset: [0, 20], placement: ['right', 'left', 'top', 'bottom'], modifiers: [{ name: 'preventOverflow', options: { padding: 10, altAxis: true } }], onOutsideClick: tooltipPinned ? handleOutsideClick : undefined },
25
25
  React.createElement("div", { className: b('content') },
26
26
  React.createElement(ChartTooltipContent, { hovered: hovered, xAxis: xAxis, yAxis: yAxis, renderer: tooltip.renderer })))) : null;
27
27
  };
@@ -1,28 +1,30 @@
1
- .gcharts-d3-tooltip[class] {
1
+ .gcharts-tooltip[class] {
2
2
  --g-popup-border-width: 0;
3
3
  pointer-events: none;
4
4
  }
5
- .gcharts-d3-tooltip[class] > div {
5
+ .gcharts-tooltip[class] > div {
6
6
  animation-duration: unset;
7
7
  animation-timing-function: unset;
8
8
  animation-fill-mode: unset;
9
9
  }
10
- .gcharts-d3-tooltip[class].gcharts-d3-tooltip_pinned {
10
+ .gcharts-tooltip[class].gcharts-tooltip_pinned {
11
11
  pointer-events: inherit;
12
12
  }
13
- .gcharts-d3-tooltip__content {
14
- padding: 10px 14px;
13
+ .gcharts-tooltip__popup-content {
14
+ box-shadow: none;
15
+ }
16
+ .gcharts-tooltip__content {
17
+ padding: 8px 14px;
15
18
  text-wrap: nowrap;
16
- border: 1px solid var(--g-color-line-generic);
17
- border-radius: 3px;
19
+ border-radius: 4px;
18
20
  background-color: var(--g-color-infographics-tooltip-bg);
19
21
  box-shadow: 0 2px 12px var(--g-color-sfx-shadow);
20
22
  }
21
- .gcharts-d3-tooltip__content-row {
23
+ .gcharts-tooltip__content-row {
22
24
  display: flex;
23
25
  align-items: center;
24
26
  }
25
- .gcharts-d3-tooltip__color {
27
+ .gcharts-tooltip__color {
26
28
  display: inline-block;
27
29
  width: 16px;
28
30
  height: 8px;
@@ -1,18 +1,19 @@
1
1
  import React from 'react';
2
2
  import type { ChartData } from '../types';
3
3
  export * from './Tooltip/ChartTooltipContent';
4
- export type ChartRef = {
4
+ export interface ChartRef {
5
5
  reflow: () => void;
6
- };
7
- type ChartDimentions = {
6
+ }
7
+ export interface ChartDimentions {
8
8
  height: number;
9
9
  width: number;
10
- };
11
- export type ChartProps = {
10
+ }
11
+ export type ChartOnResize = (args: {
12
+ dimensions?: ChartDimentions;
13
+ }) => void;
14
+ export interface ChartProps {
12
15
  data: ChartData;
13
16
  lang?: string;
14
- onResize?: (args: {
15
- dimensions?: ChartDimentions;
16
- }) => void;
17
- };
17
+ onResize?: ChartOnResize;
18
+ }
18
19
  export declare const Chart: React.ForwardRefExoticComponent<ChartProps & React.RefAttributes<ChartRef>>;
@@ -9,6 +9,7 @@ export declare const SeriesType: {
9
9
  readonly Scatter: "scatter";
10
10
  readonly Treemap: "treemap";
11
11
  readonly Waterfall: "waterfall";
12
+ readonly Sankey: "sankey";
12
13
  };
13
14
  export declare enum DashStyle {
14
15
  Dash = "Dash",
@@ -9,6 +9,7 @@ export const SeriesType = {
9
9
  Scatter: 'scatter',
10
10
  Treemap: 'treemap',
11
11
  Waterfall: 'waterfall',
12
+ Sankey: 'sankey',
12
13
  };
13
14
  export var DashStyle;
14
15
  (function (DashStyle) {
@@ -1,4 +1,5 @@
1
- import type { BaseTextStyle, ChartAxis, ChartAxisLabels, ChartAxisTitleAlignment, ChartAxisType, ChartData, ChartMargin } from '../../types';
1
+ import type { DashStyle } from 'src/constants';
2
+ import type { AxisPlotLine, BaseTextStyle, ChartAxis, ChartAxisLabels, ChartAxisTitleAlignment, ChartAxisType, ChartData, ChartMargin } from '../../types';
2
3
  type PreparedAxisLabels = Omit<ChartAxisLabels, 'enabled' | 'padding' | 'style' | 'autoRotation'> & Required<Pick<ChartAxisLabels, 'enabled' | 'padding' | 'margin' | 'rotation'>> & {
3
4
  style: BaseTextStyle;
4
5
  rotation: number;
@@ -10,6 +11,14 @@ type PreparedAxisLabels = Omit<ChartAxisLabels, 'enabled' | 'padding' | 'style'
10
11
  export type PreparedChart = {
11
12
  margin: ChartMargin;
12
13
  };
14
+ export type PreparedAxisPlotLine = {
15
+ value: number;
16
+ color: string;
17
+ width: number;
18
+ dashStyle: DashStyle;
19
+ opacity: number;
20
+ layerPlacement: AxisPlotLine['layerPlacement'];
21
+ };
13
22
  export type PreparedAxis = Omit<ChartAxis, 'type' | 'labels'> & {
14
23
  type: ChartAxisType;
15
24
  labels: PreparedAxisLabels;
@@ -32,6 +41,7 @@ export type PreparedAxis = Omit<ChartAxis, 'type' | 'labels'> & {
32
41
  };
33
42
  position: 'left' | 'right' | 'top' | 'bottom';
34
43
  plotIndex: number;
44
+ plotLines: PreparedAxisPlotLine[];
35
45
  };
36
46
  export type PreparedTitle = ChartData['title'] & {
37
47
  height: number;
@@ -102,6 +102,7 @@ export const getPreparedXAxis = ({ xAxis, series, width, }) => {
102
102
  },
103
103
  position: 'bottom',
104
104
  plotIndex: 0,
105
+ plotLines: [],
105
106
  };
106
107
  const { height, rotation } = getLabelSettings({
107
108
  axis: preparedXAxis,
@@ -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 });
@@ -5,9 +5,9 @@ export declare const DEFAULT_LINE_WIDTH = 1;
5
5
  export declare const DEFAULT_MARKER: {
6
6
  enabled: boolean;
7
7
  symbol: `${import("../../constants").SymbolType}`;
8
+ radius: number;
8
9
  borderColor: string;
9
10
  borderWidth: number;
10
- radius: number;
11
11
  };
12
12
  type PrepareAreaSeriesArgs = {
13
13
  colorScale: ScaleOrdinal<string, string>;
@@ -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
  }
@@ -8,9 +8,9 @@ export declare const DEFAULT_DASH_STYLE = DashStyle.Solid;
8
8
  export declare const DEFAULT_MARKER: {
9
9
  enabled: boolean;
10
10
  symbol: `${import("../../constants").SymbolType}`;
11
+ radius: number;
11
12
  borderColor: string;
12
13
  borderWidth: number;
13
- radius: number;
14
14
  };
15
15
  type PrepareLineSeriesArgs = {
16
16
  colorScale: ScaleOrdinal<string, string>;
@@ -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
+ }