@gravity-ui/charts 1.8.0 → 1.10.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 (255) hide show
  1. package/dist/cjs/components/Axis/AxisX.d.ts +2 -1
  2. package/dist/cjs/components/Axis/AxisX.js +147 -141
  3. package/dist/cjs/components/Axis/AxisY.d.ts +2 -1
  4. package/dist/cjs/components/Axis/AxisY.js +118 -116
  5. package/dist/cjs/components/ChartInner/index.js +36 -9
  6. package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +1 -1
  7. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +8 -5
  8. package/dist/cjs/components/ChartInner/useChartInnerProps.js +59 -10
  9. package/dist/cjs/components/ChartInner/utils.d.ts +3 -0
  10. package/dist/cjs/components/ChartInner/utils.js +28 -0
  11. package/dist/cjs/components/Legend/index.js +202 -191
  12. package/dist/cjs/components/Legend/styles.css +2 -0
  13. package/dist/cjs/components/Tooltip/ChartTooltipContent.d.ts +1 -1
  14. package/dist/cjs/components/Tooltip/DefaultContent.d.ts +1 -1
  15. package/dist/cjs/components/Tooltip/DefaultContent.js +1 -1
  16. package/dist/cjs/components/Tooltip/index.d.ts +1 -1
  17. package/dist/cjs/constants/chart-types.d.ts +12 -0
  18. package/dist/cjs/constants/chart-types.js +12 -0
  19. package/dist/cjs/constants/defaults/axis.d.ts +3 -1
  20. package/dist/cjs/constants/defaults/axis.js +10 -0
  21. package/dist/cjs/constants/index.d.ts +6 -47
  22. package/dist/cjs/constants/index.js +6 -72
  23. package/dist/cjs/constants/layout-algorithms.d.ts +7 -0
  24. package/dist/cjs/constants/layout-algorithms.js +8 -0
  25. package/dist/cjs/constants/line-styles.d.ts +20 -0
  26. package/dist/cjs/constants/line-styles.js +20 -0
  27. package/dist/cjs/constants/palette.d.ts +1 -0
  28. package/dist/cjs/constants/palette.js +22 -0
  29. package/dist/cjs/constants/symbol-types.d.ts +7 -0
  30. package/dist/cjs/constants/symbol-types.js +8 -0
  31. package/dist/cjs/constants/typography.d.ts +1 -0
  32. package/dist/cjs/constants/typography.js +1 -0
  33. package/dist/cjs/hooks/hooks-utils/index.d.ts +1 -0
  34. package/dist/cjs/hooks/hooks-utils/index.js +1 -0
  35. package/dist/cjs/hooks/hooks-utils/zoom.d.ts +8 -0
  36. package/dist/cjs/hooks/hooks-utils/zoom.js +81 -0
  37. package/dist/cjs/hooks/index.d.ts +1 -0
  38. package/dist/cjs/hooks/index.js +1 -0
  39. package/dist/cjs/hooks/useAxisScales/index.d.ts +4 -2
  40. package/dist/cjs/hooks/useAxisScales/index.js +22 -8
  41. package/dist/cjs/hooks/useBrush/index.d.ts +3 -0
  42. package/dist/cjs/hooks/useBrush/index.js +70 -0
  43. package/dist/cjs/hooks/useBrush/styles.css +10 -0
  44. package/dist/cjs/hooks/useBrush/types.d.ts +24 -0
  45. package/dist/cjs/hooks/useBrush/types.js +1 -0
  46. package/dist/cjs/hooks/useChartDimensions/index.d.ts +3 -3
  47. package/dist/cjs/hooks/useChartDimensions/index.js +2 -2
  48. package/dist/cjs/hooks/useChartDimensions/utils.d.ts +2 -2
  49. package/dist/cjs/hooks/useChartOptions/chart.d.ts +2 -1
  50. package/dist/cjs/hooks/useChartOptions/chart.js +80 -1
  51. package/dist/cjs/hooks/useChartOptions/index.js +3 -2
  52. package/dist/cjs/hooks/useChartOptions/types.d.ts +6 -2
  53. package/dist/cjs/hooks/useChartOptions/x-axis.d.ts +3 -3
  54. package/dist/cjs/hooks/useChartOptions/x-axis.js +22 -13
  55. package/dist/cjs/hooks/useChartOptions/y-axis.d.ts +3 -3
  56. package/dist/cjs/hooks/useChartOptions/y-axis.js +36 -21
  57. package/dist/cjs/hooks/useCrosshair/index.d.ts +17 -0
  58. package/dist/cjs/hooks/useCrosshair/index.js +139 -0
  59. package/dist/cjs/hooks/useCrosshair/useCrosshairHover.d.ts +11 -0
  60. package/dist/cjs/hooks/useCrosshair/useCrosshairHover.js +18 -0
  61. package/dist/cjs/hooks/useSeries/index.d.ts +8 -6
  62. package/dist/cjs/hooks/useSeries/index.js +41 -22
  63. package/dist/cjs/hooks/useSeries/prepare-bar-y.d.ts +27 -2
  64. package/dist/cjs/hooks/useSeries/prepare-bar-y.js +5 -5
  65. package/dist/cjs/hooks/useSeries/prepare-legend.d.ts +1 -1
  66. package/dist/cjs/hooks/useSeries/prepare-legend.js +27 -9
  67. package/dist/cjs/hooks/useSeries/prepare-line.d.ts +1 -2
  68. package/dist/cjs/hooks/useSeries/prepare-line.js +3 -3
  69. package/dist/cjs/hooks/useSeries/prepareSeries.d.ts +1 -1
  70. package/dist/cjs/hooks/useSeries/prepareSeries.js +2 -2
  71. package/dist/cjs/hooks/useSeries/types.d.ts +2 -1
  72. package/dist/cjs/hooks/useShapes/area/index.js +1 -1
  73. package/dist/cjs/hooks/useShapes/area/prepare-data.d.ts +1 -1
  74. package/dist/cjs/hooks/useShapes/area/prepare-data.js +32 -16
  75. package/dist/cjs/hooks/useShapes/area/types.d.ts +1 -0
  76. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.d.ts +1 -1
  77. package/dist/cjs/hooks/useShapes/bar-x/prepare-data.js +17 -13
  78. package/dist/cjs/hooks/useShapes/bar-y/prepare-data.d.ts +1 -1
  79. package/dist/cjs/hooks/useShapes/bar-y/prepare-data.js +6 -6
  80. package/dist/cjs/hooks/useShapes/index.d.ts +1 -1
  81. package/dist/cjs/hooks/useShapes/index.js +40 -31
  82. package/dist/cjs/hooks/useShapes/line/prepare-data.d.ts +1 -1
  83. package/dist/cjs/hooks/useShapes/line/prepare-data.js +14 -11
  84. package/dist/cjs/hooks/useShapes/line/types.d.ts +1 -0
  85. package/dist/cjs/hooks/useShapes/marker.js +2 -2
  86. package/dist/cjs/hooks/useShapes/pie/index.js +3 -3
  87. package/dist/cjs/hooks/useShapes/pie/prepare-data.d.ts +1 -1
  88. package/dist/cjs/hooks/useShapes/pie/prepare-data.js +15 -11
  89. package/dist/cjs/hooks/useShapes/radar/prepare-data.d.ts +1 -1
  90. package/dist/cjs/hooks/useShapes/radar/prepare-data.js +6 -7
  91. package/dist/cjs/hooks/useShapes/radar/types.d.ts +1 -0
  92. package/dist/cjs/hooks/useShapes/scatter/index.js +0 -1
  93. package/dist/cjs/hooks/useShapes/scatter/prepare-data.js +2 -0
  94. package/dist/cjs/hooks/useShapes/scatter/types.d.ts +1 -0
  95. package/dist/cjs/hooks/useShapes/treemap/prepare-data.d.ts +1 -1
  96. package/dist/cjs/hooks/useShapes/treemap/prepare-data.js +19 -16
  97. package/dist/cjs/hooks/useShapes/waterfall/index.js +2 -2
  98. package/dist/cjs/hooks/useShapes/waterfall/prepare-data.d.ts +1 -1
  99. package/dist/cjs/hooks/useShapes/waterfall/prepare-data.js +8 -7
  100. package/dist/cjs/hooks/useZoom/index.d.ts +18 -0
  101. package/dist/cjs/hooks/useZoom/index.js +54 -0
  102. package/dist/cjs/hooks/useZoom/types.d.ts +19 -0
  103. package/dist/cjs/hooks/useZoom/types.js +1 -0
  104. package/dist/cjs/hooks/useZoom/utils.d.ts +12 -0
  105. package/dist/cjs/hooks/useZoom/utils.js +128 -0
  106. package/dist/cjs/types/chart/axis.d.ts +26 -21
  107. package/dist/cjs/types/chart/chart.d.ts +5 -0
  108. package/dist/cjs/types/chart/line.d.ts +1 -1
  109. package/dist/cjs/types/chart/pie.d.ts +1 -1
  110. package/dist/cjs/types/chart/series.d.ts +1 -1
  111. package/dist/cjs/types/chart/tooltip.d.ts +1 -1
  112. package/dist/cjs/types/chart/zoom.d.ts +36 -0
  113. package/dist/cjs/types/chart/zoom.js +1 -0
  114. package/dist/cjs/types/index.d.ts +1 -0
  115. package/dist/cjs/types/index.js +1 -0
  116. package/dist/cjs/types/misc.d.ts +7 -0
  117. package/dist/cjs/utils/chart/axis-generators/bottom.d.ts +1 -1
  118. package/dist/cjs/utils/chart/axis-generators/bottom.js +25 -25
  119. package/dist/cjs/utils/chart/axis.d.ts +2 -1
  120. package/dist/cjs/utils/chart/axis.js +10 -2
  121. package/dist/cjs/utils/chart/get-closest-data.js +1 -1
  122. package/dist/cjs/utils/chart/text.d.ts +7 -7
  123. package/dist/cjs/utils/chart/text.js +37 -29
  124. package/dist/cjs/utils/chart-ui/pie-center-text.d.ts +1 -1
  125. package/dist/cjs/utils/chart-ui/pie-center-text.js +2 -2
  126. package/dist/cjs/validation/index.d.ts +1 -1
  127. package/dist/cjs/validation/index.js +16 -16
  128. package/dist/esm/components/Axis/AxisX.d.ts +2 -1
  129. package/dist/esm/components/Axis/AxisX.js +147 -141
  130. package/dist/esm/components/Axis/AxisY.d.ts +2 -1
  131. package/dist/esm/components/Axis/AxisY.js +118 -116
  132. package/dist/esm/components/ChartInner/index.js +36 -9
  133. package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +1 -1
  134. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +8 -5
  135. package/dist/esm/components/ChartInner/useChartInnerProps.js +59 -10
  136. package/dist/esm/components/ChartInner/utils.d.ts +3 -0
  137. package/dist/esm/components/ChartInner/utils.js +28 -0
  138. package/dist/esm/components/Legend/index.js +202 -191
  139. package/dist/esm/components/Legend/styles.css +2 -0
  140. package/dist/esm/components/Tooltip/ChartTooltipContent.d.ts +1 -1
  141. package/dist/esm/components/Tooltip/DefaultContent.d.ts +1 -1
  142. package/dist/esm/components/Tooltip/DefaultContent.js +1 -1
  143. package/dist/esm/components/Tooltip/index.d.ts +1 -1
  144. package/dist/esm/constants/chart-types.d.ts +12 -0
  145. package/dist/esm/constants/chart-types.js +12 -0
  146. package/dist/esm/constants/defaults/axis.d.ts +3 -1
  147. package/dist/esm/constants/defaults/axis.js +10 -0
  148. package/dist/esm/constants/index.d.ts +6 -47
  149. package/dist/esm/constants/index.js +6 -72
  150. package/dist/esm/constants/layout-algorithms.d.ts +7 -0
  151. package/dist/esm/constants/layout-algorithms.js +8 -0
  152. package/dist/esm/constants/line-styles.d.ts +20 -0
  153. package/dist/esm/constants/line-styles.js +20 -0
  154. package/dist/esm/constants/palette.d.ts +1 -0
  155. package/dist/esm/constants/palette.js +22 -0
  156. package/dist/esm/constants/symbol-types.d.ts +7 -0
  157. package/dist/esm/constants/symbol-types.js +8 -0
  158. package/dist/esm/constants/typography.d.ts +1 -0
  159. package/dist/esm/constants/typography.js +1 -0
  160. package/dist/esm/hooks/hooks-utils/index.d.ts +1 -0
  161. package/dist/esm/hooks/hooks-utils/index.js +1 -0
  162. package/dist/esm/hooks/hooks-utils/zoom.d.ts +8 -0
  163. package/dist/esm/hooks/hooks-utils/zoom.js +81 -0
  164. package/dist/esm/hooks/index.d.ts +1 -0
  165. package/dist/esm/hooks/index.js +1 -0
  166. package/dist/esm/hooks/useAxisScales/index.d.ts +4 -2
  167. package/dist/esm/hooks/useAxisScales/index.js +22 -8
  168. package/dist/esm/hooks/useBrush/index.d.ts +3 -0
  169. package/dist/esm/hooks/useBrush/index.js +70 -0
  170. package/dist/esm/hooks/useBrush/styles.css +10 -0
  171. package/dist/esm/hooks/useBrush/types.d.ts +24 -0
  172. package/dist/esm/hooks/useBrush/types.js +1 -0
  173. package/dist/esm/hooks/useChartDimensions/index.d.ts +3 -3
  174. package/dist/esm/hooks/useChartDimensions/index.js +2 -2
  175. package/dist/esm/hooks/useChartDimensions/utils.d.ts +2 -2
  176. package/dist/esm/hooks/useChartOptions/chart.d.ts +2 -1
  177. package/dist/esm/hooks/useChartOptions/chart.js +80 -1
  178. package/dist/esm/hooks/useChartOptions/index.js +3 -2
  179. package/dist/esm/hooks/useChartOptions/types.d.ts +6 -2
  180. package/dist/esm/hooks/useChartOptions/x-axis.d.ts +3 -3
  181. package/dist/esm/hooks/useChartOptions/x-axis.js +22 -13
  182. package/dist/esm/hooks/useChartOptions/y-axis.d.ts +3 -3
  183. package/dist/esm/hooks/useChartOptions/y-axis.js +36 -21
  184. package/dist/esm/hooks/useCrosshair/index.d.ts +17 -0
  185. package/dist/esm/hooks/useCrosshair/index.js +139 -0
  186. package/dist/esm/hooks/useCrosshair/useCrosshairHover.d.ts +11 -0
  187. package/dist/esm/hooks/useCrosshair/useCrosshairHover.js +18 -0
  188. package/dist/esm/hooks/useSeries/index.d.ts +8 -6
  189. package/dist/esm/hooks/useSeries/index.js +41 -22
  190. package/dist/esm/hooks/useSeries/prepare-bar-y.d.ts +27 -2
  191. package/dist/esm/hooks/useSeries/prepare-bar-y.js +5 -5
  192. package/dist/esm/hooks/useSeries/prepare-legend.d.ts +1 -1
  193. package/dist/esm/hooks/useSeries/prepare-legend.js +27 -9
  194. package/dist/esm/hooks/useSeries/prepare-line.d.ts +1 -2
  195. package/dist/esm/hooks/useSeries/prepare-line.js +3 -3
  196. package/dist/esm/hooks/useSeries/prepareSeries.d.ts +1 -1
  197. package/dist/esm/hooks/useSeries/prepareSeries.js +2 -2
  198. package/dist/esm/hooks/useSeries/types.d.ts +2 -1
  199. package/dist/esm/hooks/useShapes/area/index.js +1 -1
  200. package/dist/esm/hooks/useShapes/area/prepare-data.d.ts +1 -1
  201. package/dist/esm/hooks/useShapes/area/prepare-data.js +32 -16
  202. package/dist/esm/hooks/useShapes/area/types.d.ts +1 -0
  203. package/dist/esm/hooks/useShapes/bar-x/prepare-data.d.ts +1 -1
  204. package/dist/esm/hooks/useShapes/bar-x/prepare-data.js +17 -13
  205. package/dist/esm/hooks/useShapes/bar-y/prepare-data.d.ts +1 -1
  206. package/dist/esm/hooks/useShapes/bar-y/prepare-data.js +6 -6
  207. package/dist/esm/hooks/useShapes/index.d.ts +1 -1
  208. package/dist/esm/hooks/useShapes/index.js +40 -31
  209. package/dist/esm/hooks/useShapes/line/prepare-data.d.ts +1 -1
  210. package/dist/esm/hooks/useShapes/line/prepare-data.js +14 -11
  211. package/dist/esm/hooks/useShapes/line/types.d.ts +1 -0
  212. package/dist/esm/hooks/useShapes/marker.js +2 -2
  213. package/dist/esm/hooks/useShapes/pie/index.js +3 -3
  214. package/dist/esm/hooks/useShapes/pie/prepare-data.d.ts +1 -1
  215. package/dist/esm/hooks/useShapes/pie/prepare-data.js +15 -11
  216. package/dist/esm/hooks/useShapes/radar/prepare-data.d.ts +1 -1
  217. package/dist/esm/hooks/useShapes/radar/prepare-data.js +6 -7
  218. package/dist/esm/hooks/useShapes/radar/types.d.ts +1 -0
  219. package/dist/esm/hooks/useShapes/scatter/index.js +0 -1
  220. package/dist/esm/hooks/useShapes/scatter/prepare-data.js +2 -0
  221. package/dist/esm/hooks/useShapes/scatter/types.d.ts +1 -0
  222. package/dist/esm/hooks/useShapes/treemap/prepare-data.d.ts +1 -1
  223. package/dist/esm/hooks/useShapes/treemap/prepare-data.js +19 -16
  224. package/dist/esm/hooks/useShapes/waterfall/index.js +2 -2
  225. package/dist/esm/hooks/useShapes/waterfall/prepare-data.d.ts +1 -1
  226. package/dist/esm/hooks/useShapes/waterfall/prepare-data.js +8 -7
  227. package/dist/esm/hooks/useZoom/index.d.ts +18 -0
  228. package/dist/esm/hooks/useZoom/index.js +54 -0
  229. package/dist/esm/hooks/useZoom/types.d.ts +19 -0
  230. package/dist/esm/hooks/useZoom/types.js +1 -0
  231. package/dist/esm/hooks/useZoom/utils.d.ts +12 -0
  232. package/dist/esm/hooks/useZoom/utils.js +128 -0
  233. package/dist/esm/types/chart/axis.d.ts +26 -21
  234. package/dist/esm/types/chart/chart.d.ts +5 -0
  235. package/dist/esm/types/chart/line.d.ts +1 -1
  236. package/dist/esm/types/chart/pie.d.ts +1 -1
  237. package/dist/esm/types/chart/series.d.ts +1 -1
  238. package/dist/esm/types/chart/tooltip.d.ts +1 -1
  239. package/dist/esm/types/chart/zoom.d.ts +36 -0
  240. package/dist/esm/types/chart/zoom.js +1 -0
  241. package/dist/esm/types/index.d.ts +1 -0
  242. package/dist/esm/types/index.js +1 -0
  243. package/dist/esm/types/misc.d.ts +7 -0
  244. package/dist/esm/utils/chart/axis-generators/bottom.d.ts +1 -1
  245. package/dist/esm/utils/chart/axis-generators/bottom.js +25 -25
  246. package/dist/esm/utils/chart/axis.d.ts +2 -1
  247. package/dist/esm/utils/chart/axis.js +10 -2
  248. package/dist/esm/utils/chart/get-closest-data.js +1 -1
  249. package/dist/esm/utils/chart/text.d.ts +7 -7
  250. package/dist/esm/utils/chart/text.js +37 -29
  251. package/dist/esm/utils/chart-ui/pie-center-text.d.ts +1 -1
  252. package/dist/esm/utils/chart-ui/pie-center-text.js +2 -2
  253. package/dist/esm/validation/index.d.ts +1 -1
  254. package/dist/esm/validation/index.js +16 -16
  255. package/package.json +2 -1
@@ -7,7 +7,8 @@ type Props = {
7
7
  height: number;
8
8
  scale: ChartScale;
9
9
  split: PreparedSplit;
10
- plotRef?: React.MutableRefObject<SVGGElement | null>;
10
+ plotBeforeRef?: React.MutableRefObject<SVGGElement | null>;
11
+ plotAfterRef?: React.MutableRefObject<SVGGElement | null>;
11
12
  leftmostLimit?: number;
12
13
  };
13
14
  export declare function getTitlePosition(args: {
@@ -42,149 +42,155 @@ export function getTitlePosition(args) {
42
42
  return { x, y };
43
43
  }
44
44
  export const AxisX = React.memo(function AxisX(props) {
45
- const { axis, width, height: totalHeight, scale, split, plotRef, leftmostLimit } = props;
45
+ const { axis, width, height: totalHeight, scale, split, plotBeforeRef, plotAfterRef, leftmostLimit, } = props;
46
46
  const ref = React.useRef(null);
47
47
  React.useEffect(() => {
48
- if (!ref.current) {
49
- return;
50
- }
51
- const svgElement = select(ref.current);
52
- svgElement.selectAll('*').remove();
53
- const plotClassName = b('plot-x');
54
- let plotContainer = null;
55
- if (plotRef === null || plotRef === void 0 ? void 0 : plotRef.current) {
56
- plotContainer = select(plotRef.current);
57
- plotContainer.selectAll(`.${plotClassName}`).remove();
58
- }
59
- if (!axis.visible) {
60
- return;
61
- }
62
- let tickItems = [];
63
- if (axis.grid.enabled) {
64
- tickItems = new Array(split.plots.length || 1).fill(null).map((_, index) => {
65
- var _a, _b;
66
- const top = ((_a = split.plots[index]) === null || _a === void 0 ? void 0 : _a.top) || 0;
67
- const height = ((_b = split.plots[index]) === null || _b === void 0 ? void 0 : _b.height) || totalHeight;
68
- return [-top, -(top + height)];
69
- });
70
- }
71
- const axisScale = scale;
72
- const xAxisGenerator = axisBottom({
73
- leftmostLimit,
74
- scale: axisScale,
75
- ticks: {
76
- items: tickItems,
77
- labelFormat: getLabelFormatter({ axis, scale }),
78
- labelsPaddings: axis.labels.padding,
79
- labelsMargin: axis.labels.margin,
80
- labelsStyle: axis.labels.style,
81
- labelsMaxWidth: axis.labels.maxWidth,
82
- labelsLineHeight: axis.labels.lineHeight,
83
- count: getTicksCount({ axis, range: width }),
84
- maxTickCount: getMaxTickCount({ axis, width }),
85
- rotation: axis.labels.rotation,
86
- },
87
- domain: {
88
- size: width,
89
- color: axis.lineColor,
90
- },
91
- });
92
- svgElement.call(xAxisGenerator).attr('class', b());
93
- // add an axis header if necessary
94
- if (axis.title.text) {
95
- const titleRows = getAxisTitleRows({ axis, textMaxWidth: width });
96
- svgElement
97
- .append('text')
98
- .attr('class', b('title'))
99
- .attr('transform', () => {
100
- const { x, y } = getTitlePosition({ axis, width, rowCount: titleRows.length });
101
- return `translate(${x}, ${y})`;
102
- })
103
- .attr('font-size', axis.title.style.fontSize)
104
- .attr('text-anchor', 'middle')
105
- .selectAll('tspan')
106
- .data(titleRows)
107
- .join('tspan')
108
- .attr('x', 0)
109
- .attr('y', (d) => d.y)
110
- .text((d) => d.text)
111
- .each((_d, index, nodes) => {
112
- if (index === axis.title.maxRowCount - 1) {
113
- handleOverflowingText(nodes[index], width);
114
- }
48
+ (async () => {
49
+ if (!ref.current) {
50
+ return;
51
+ }
52
+ const svgElement = select(ref.current);
53
+ svgElement.selectAll('*').remove();
54
+ const plotDataAttr = 'data-plot-x';
55
+ let plotBeforeContainer = null;
56
+ let plotAfterContainer = null;
57
+ if (plotBeforeRef === null || plotBeforeRef === void 0 ? void 0 : plotBeforeRef.current) {
58
+ plotBeforeContainer = select(plotBeforeRef.current);
59
+ plotBeforeContainer.selectAll(`[${plotDataAttr}]`).remove();
60
+ }
61
+ if (plotAfterRef === null || plotAfterRef === void 0 ? void 0 : plotAfterRef.current) {
62
+ plotAfterContainer = select(plotAfterRef.current);
63
+ plotAfterContainer.selectAll(`[${plotDataAttr}]`).remove();
64
+ }
65
+ if (!axis.visible) {
66
+ return;
67
+ }
68
+ let tickItems = [];
69
+ if (axis.grid.enabled) {
70
+ tickItems = new Array(split.plots.length || 1).fill(null).map((_, index) => {
71
+ var _a, _b;
72
+ const top = ((_a = split.plots[index]) === null || _a === void 0 ? void 0 : _a.top) || 0;
73
+ const height = ((_b = split.plots[index]) === null || _b === void 0 ? void 0 : _b.height) || totalHeight;
74
+ return [-top, -(top + height)];
75
+ });
76
+ }
77
+ const axisScale = scale;
78
+ const xAxisGenerator = await axisBottom({
79
+ leftmostLimit,
80
+ scale: axisScale,
81
+ ticks: {
82
+ items: tickItems,
83
+ labelFormat: getLabelFormatter({ axis, scale }),
84
+ labelsPaddings: axis.labels.padding,
85
+ labelsMargin: axis.labels.margin,
86
+ labelsStyle: axis.labels.style,
87
+ labelsMaxWidth: axis.labels.maxWidth,
88
+ labelsLineHeight: axis.labels.lineHeight,
89
+ count: getTicksCount({ axis, range: width }),
90
+ maxTickCount: getMaxTickCount({ axis, width }),
91
+ rotation: axis.labels.rotation,
92
+ },
93
+ domain: {
94
+ size: width,
95
+ color: axis.lineColor,
96
+ },
115
97
  });
116
- }
117
- // add plot bands
118
- if (plotContainer && axis.plotBands.length > 0) {
119
- const plotBandClassName = b('plot-x-band');
120
- const plotBandsSelection = plotContainer
121
- .selectAll(`.${plotBandClassName}-x`)
122
- .data(axis.plotBands)
123
- .join('g')
124
- .attr('class', `${plotClassName} ${plotBandClassName}-x`);
125
- plotBandsSelection
126
- .append('rect')
127
- .attr('x', (band) => {
128
- var _a, _b;
129
- const { from, to } = getBandsPosition({ band, axisScale, axis: 'x' });
130
- const halfBandwidth = ((_b = (_a = axisScale.bandwidth) === null || _a === void 0 ? void 0 : _a.call(axisScale)) !== null && _b !== void 0 ? _b : 0) / 2;
131
- const startPos = halfBandwidth + Math.min(from, to);
132
- return Math.max(0, startPos);
133
- })
134
- .attr('width', (band) => {
135
- const { from, to } = getBandsPosition({ band, axisScale, axis: 'x' });
136
- const startPos = width - Math.min(from, to);
137
- const endPos = Math.min(Math.abs(to - from), startPos);
138
- return Math.min(endPos, width);
139
- })
140
- .attr('y', 0)
141
- .attr('height', totalHeight)
142
- .attr('fill', (band) => band.color)
143
- .attr('opacity', (band) => band.opacity);
144
- plotBandsSelection.each((plotBandData, i, nodes) => {
145
- const plotLineSelection = select(nodes[i]);
146
- if (plotBandData.layerPlacement === 'before') {
147
- plotLineSelection.lower();
148
- }
149
- else {
150
- plotLineSelection.raise();
151
- }
152
- });
153
- }
154
- // add plot lines
155
- if (plotContainer && axis.plotLines.length > 0) {
156
- const plotLineClassName = b('plot-x-line');
157
- const plotLinesSelection = plotContainer
158
- .selectAll(`.${plotLineClassName}`)
159
- .data(axis.plotLines)
160
- .join('g')
161
- .attr('class', `${plotClassName} ${plotLineClassName}`);
162
- const lineGenerator = line();
163
- plotLinesSelection
164
- .append('path')
165
- .attr('d', (plotLine) => {
166
- const plotLineValue = Number(axisScale(plotLine.value));
167
- const points = [
168
- [plotLineValue, 0],
169
- [plotLineValue, totalHeight],
170
- ];
171
- return lineGenerator(points);
172
- })
173
- .attr('stroke', (plotLine) => plotLine.color)
174
- .attr('stroke-width', (plotLine) => plotLine.width)
175
- .attr('stroke-dasharray', (plotLine) => getLineDashArray(plotLine.dashStyle, plotLine.width))
176
- .attr('opacity', (plotLine) => plotLine.opacity);
177
- // set layer placement
178
- plotLinesSelection.each((plotLineData, i, nodes) => {
179
- const plotLineSelection = select(nodes[i]);
180
- if (plotLineData.layerPlacement === 'before') {
181
- plotLineSelection.lower();
182
- }
183
- else {
184
- plotLineSelection.raise();
185
- }
186
- });
187
- }
188
- }, [axis, width, totalHeight, scale, split, plotRef, leftmostLimit]);
98
+ svgElement.call(xAxisGenerator).attr('class', b());
99
+ // add an axis header if necessary
100
+ if (axis.title.text) {
101
+ const titleRows = await getAxisTitleRows({ axis, textMaxWidth: width });
102
+ svgElement
103
+ .append('text')
104
+ .attr('class', b('title'))
105
+ .attr('transform', () => {
106
+ const { x, y } = getTitlePosition({ axis, width, rowCount: titleRows.length });
107
+ return `translate(${x}, ${y})`;
108
+ })
109
+ .attr('font-size', axis.title.style.fontSize)
110
+ .attr('text-anchor', 'middle')
111
+ .selectAll('tspan')
112
+ .data(titleRows)
113
+ .join('tspan')
114
+ .attr('x', 0)
115
+ .attr('y', (d) => d.y)
116
+ .text((d) => d.text)
117
+ .each((_d, index, nodes) => {
118
+ if (index === axis.title.maxRowCount - 1) {
119
+ handleOverflowingText(nodes[index], width);
120
+ }
121
+ });
122
+ }
123
+ // add plot bands
124
+ if (axis.plotBands.length > 0) {
125
+ const plotBandDataAttr = 'plot-x-band';
126
+ const setPlotBands = (plotContainer, plotBands) => {
127
+ if (!plotContainer || !plotBands.length) {
128
+ return;
129
+ }
130
+ const plotBandsSelection = plotContainer
131
+ .selectAll(`[${plotBandDataAttr}]`)
132
+ .remove()
133
+ .data(plotBands)
134
+ .join('g')
135
+ .attr(plotDataAttr, 1)
136
+ .attr(plotBandDataAttr, 1);
137
+ plotBandsSelection
138
+ .append('rect')
139
+ .attr('x', (band) => {
140
+ var _a, _b;
141
+ const { from, to } = getBandsPosition({ band, axisScale, axis: 'x' });
142
+ const halfBandwidth = ((_b = (_a = axisScale.bandwidth) === null || _a === void 0 ? void 0 : _a.call(axisScale)) !== null && _b !== void 0 ? _b : 0) / 2;
143
+ const startPos = halfBandwidth + Math.min(from, to);
144
+ return Math.max(0, startPos);
145
+ })
146
+ .attr('width', (band) => {
147
+ const { from, to } = getBandsPosition({ band, axisScale, axis: 'x' });
148
+ const startPos = width - Math.min(from, to);
149
+ const endPos = Math.min(Math.abs(to - from), startPos);
150
+ return Math.min(endPos, width);
151
+ })
152
+ .attr('y', 0)
153
+ .attr('height', totalHeight)
154
+ .attr('fill', (band) => band.color)
155
+ .attr('opacity', (band) => band.opacity);
156
+ };
157
+ setPlotBands(plotBeforeContainer, axis.plotBands.filter((d) => d.layerPlacement === 'before'));
158
+ setPlotBands(plotAfterContainer, axis.plotBands.filter((d) => d.layerPlacement === 'after'));
159
+ }
160
+ // add plot lines
161
+ if (axis.plotLines.length > 0) {
162
+ const plotLineDataAttr = 'plot-x-line';
163
+ const setPlotLines = (plotContainer, plotLines) => {
164
+ if (!plotContainer || !plotLines.length) {
165
+ return;
166
+ }
167
+ const plotLinesSelection = plotContainer
168
+ .selectAll(`[${plotLineDataAttr}]`)
169
+ .remove()
170
+ .data(plotLines)
171
+ .join('g')
172
+ .attr(plotDataAttr, 1)
173
+ .attr(plotLineDataAttr, 1);
174
+ const lineGenerator = line();
175
+ plotLinesSelection
176
+ .append('path')
177
+ .attr('d', (plotLine) => {
178
+ const plotLineValue = Number(axisScale(plotLine.value));
179
+ const points = [
180
+ [plotLineValue, 0],
181
+ [plotLineValue, totalHeight],
182
+ ];
183
+ return lineGenerator(points);
184
+ })
185
+ .attr('stroke', (plotLine) => plotLine.color)
186
+ .attr('stroke-width', (plotLine) => plotLine.width)
187
+ .attr('stroke-dasharray', (plotLine) => getLineDashArray(plotLine.dashStyle, plotLine.width))
188
+ .attr('opacity', (plotLine) => plotLine.opacity);
189
+ };
190
+ setPlotLines(plotBeforeContainer, axis.plotLines.filter((d) => d.layerPlacement === 'before'));
191
+ setPlotLines(plotAfterContainer, axis.plotLines.filter((d) => d.layerPlacement === 'after'));
192
+ }
193
+ })();
194
+ }, [axis, width, totalHeight, scale, split, leftmostLimit, plotBeforeRef, plotAfterRef]);
189
195
  return React.createElement("g", { ref: ref });
190
196
  });
@@ -7,7 +7,8 @@ type Props = {
7
7
  width: number;
8
8
  height: number;
9
9
  split: PreparedSplit;
10
- plotRef?: React.MutableRefObject<SVGGElement | null>;
10
+ plotBeforeRef?: React.MutableRefObject<SVGGElement | null>;
11
+ plotAfterRef?: React.MutableRefObject<SVGGElement | null>;
11
12
  bottomLimit?: number;
12
13
  };
13
14
  export declare const AxisY: (props: Props) => React.JSX.Element;
@@ -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, getBandsPosition, getClosestPointsRange, getLineDashArray, getScaleTicks, getTicksCount, handleOverflowingText, parseTransformStyle, setEllipsisForOverflowTexts, wrapText, } from '../../utils';
3
+ import { block, calculateCos, calculateSin, formatAxisTickLabel, getAxisHeight, getAxisPlotsPosition, getAxisTitleRows, getBandsPosition, getClosestPointsRange, getLineDashArray, getScaleTicks, getTicksCount, handleOverflowingText, parseTransformStyle, setEllipsisForOverflowTexts, wrapText, } from '../../utils';
4
4
  import './styles.css';
5
5
  const b = block('axis');
6
6
  function transformLabel(args) {
@@ -85,7 +85,7 @@ function getTitlePosition(args) {
85
85
  return { x, y };
86
86
  }
87
87
  export const AxisY = (props) => {
88
- const { axes: allAxes, width, height: totalHeight, scale, split, plotRef, bottomLimit = 0, } = props;
88
+ const { axes: allAxes, width, height: totalHeight, scale, split, plotBeforeRef, plotAfterRef, bottomLimit = 0, } = props;
89
89
  const height = getAxisHeight({ split, boundsHeight: totalHeight });
90
90
  const ref = React.useRef(null);
91
91
  const lineGenerator = line();
@@ -96,40 +96,23 @@ export const AxisY = (props) => {
96
96
  const axes = allAxes.filter((a) => a.visible);
97
97
  const svgElement = select(ref.current);
98
98
  svgElement.selectAll('*').remove();
99
- let plotContainer = null;
100
- const plotClassName = b('plot-y');
101
- if (plotRef === null || plotRef === void 0 ? void 0 : plotRef.current) {
102
- plotContainer = select(plotRef.current);
103
- plotContainer.selectAll(`.${plotClassName}`).remove();
99
+ let plotBeforeContainer = null;
100
+ let plotAfterContainer = null;
101
+ const plotDataAttr = 'data-plot-y';
102
+ if (plotBeforeRef === null || plotBeforeRef === void 0 ? void 0 : plotBeforeRef.current) {
103
+ plotBeforeContainer = select(plotBeforeRef.current);
104
+ plotBeforeContainer.selectAll(`[${plotDataAttr}]`).remove();
105
+ }
106
+ if (plotAfterRef === null || plotAfterRef === void 0 ? void 0 : plotAfterRef.current) {
107
+ plotAfterContainer = select(plotAfterRef.current);
108
+ plotAfterContainer.selectAll(`[${plotDataAttr}]`).remove();
104
109
  }
105
- const getAxisPosition = (axis) => {
106
- var _a;
107
- const top = ((_a = split.plots[axis.plotIndex]) === null || _a === void 0 ? void 0 : _a.top) || 0;
108
- if (axis.position === 'left') {
109
- return `translate(0, ${top}px)`;
110
- }
111
- return `translate(${width}px, 0)`;
112
- };
113
- const plotLines = axes.reduce((acc, axis) => {
114
- if (axis.plotLines.length) {
115
- acc.push(...axis.plotLines.map((plotLine) => {
116
- return Object.assign(Object.assign({}, plotLine), { transform: getAxisPosition(axis) });
117
- }));
118
- }
119
- return acc;
120
- }, []);
121
- const plotBands = axes.reduce((acc, axis) => {
122
- if (axis.plotBands.length) {
123
- acc.push(...axis.plotBands.map((plotBand) => (Object.assign(Object.assign({}, plotBand), { transform: getAxisPosition(axis) }))));
124
- }
125
- return acc;
126
- }, []);
127
110
  const axisSelection = svgElement
128
111
  .selectAll('axis')
129
112
  .data(axes)
130
113
  .join('g')
131
114
  .attr('class', b())
132
- .style('transform', (d) => getAxisPosition(d));
115
+ .style('transform', (d) => getAxisPlotsPosition(d, split, width));
133
116
  axisSelection.each((d, index, node) => {
134
117
  const seriesScale = scale[index];
135
118
  const axisItem = select(node[index]);
@@ -196,74 +179,74 @@ export const AxisY = (props) => {
196
179
  })
197
180
  .remove();
198
181
  }
199
- if (plotContainer && d.plotBands.length > 0) {
200
- const plotBandClassName = b('plot-y-band');
201
- const plotBandsSelection = plotContainer
202
- .selectAll(`.${plotBandClassName}`)
203
- .data(plotBands)
204
- .join('g')
205
- .attr('class', `${plotClassName} ${plotBandClassName}`)
206
- .style('transform', (plotBand) => plotBand.transform);
207
- plotBandsSelection
208
- .append('rect')
209
- .attr('x', 0)
210
- .attr('width', width)
211
- .attr('y', (band) => {
212
- var _a, _b;
213
- const { from, to } = getBandsPosition({ band, axisScale, axis: 'y' });
214
- const halfBandwidth = ((_b = (_a = axisScale.bandwidth) === null || _a === void 0 ? void 0 : _a.call(axisScale)) !== null && _b !== void 0 ? _b : 0) / 2;
215
- const startPos = halfBandwidth + Math.min(from, to);
216
- return Math.max(0, startPos);
217
- })
218
- .attr('height', (band) => {
219
- const { from, to } = getBandsPosition({ band, axisScale, axis: 'y' });
220
- const startPos = height - Math.min(from, to);
221
- const endPos = Math.min(Math.abs(to - from), startPos);
222
- return Math.min(endPos, height);
223
- })
224
- .attr('fill', (band) => band.color)
225
- .attr('opacity', (band) => band.opacity);
226
- plotBandsSelection.each((plotBandData, i, nodes) => {
227
- const plotLineSelection = select(nodes[i]);
228
- if (plotBandData.layerPlacement === 'before') {
229
- plotLineSelection.lower();
182
+ if (d.plotBands.length > 0) {
183
+ const plotBandDataAttr = `data-plot-y-band-${index}`;
184
+ const setPlotBands = (plotContainer, plotBands) => {
185
+ if (!plotContainer || !plotBands.length) {
186
+ return;
230
187
  }
231
- else {
232
- plotLineSelection.raise();
233
- }
234
- });
188
+ const plotBandsSelection = plotContainer
189
+ .selectAll(`[${plotBandDataAttr}]`)
190
+ .remove()
191
+ .data(plotBands)
192
+ .join('g')
193
+ .attr(plotDataAttr, 1)
194
+ .attr(plotBandDataAttr, 1)
195
+ .style('transform', getAxisPlotsPosition(d, split));
196
+ plotBandsSelection
197
+ .append('rect')
198
+ .attr('x', 0)
199
+ .attr('width', width)
200
+ .attr('y', (band) => {
201
+ var _a, _b;
202
+ const { from, to } = getBandsPosition({ band, axisScale, axis: 'y' });
203
+ const halfBandwidth = ((_b = (_a = axisScale.bandwidth) === null || _a === void 0 ? void 0 : _a.call(axisScale)) !== null && _b !== void 0 ? _b : 0) / 2;
204
+ const startPos = halfBandwidth + Math.min(from, to);
205
+ return Math.max(0, startPos);
206
+ })
207
+ .attr('height', (band) => {
208
+ const { from, to } = getBandsPosition({ band, axisScale, axis: 'y' });
209
+ const startPos = height - Math.min(from, to);
210
+ const endPos = Math.min(Math.abs(to - from), startPos);
211
+ return Math.min(endPos, height);
212
+ })
213
+ .attr('fill', (band) => band.color)
214
+ .attr('opacity', (band) => band.opacity);
215
+ };
216
+ setPlotBands(plotBeforeContainer, d.plotBands.filter((item) => item.layerPlacement === 'before'));
217
+ setPlotBands(plotAfterContainer, d.plotBands.filter((item) => item.layerPlacement === 'after'));
235
218
  }
236
- if (plotContainer && d.plotLines.length > 0) {
237
- const plotLineClassName = b('plot-y-line');
238
- const plotLinesSelection = plotContainer
239
- .selectAll(`.${plotLineClassName}`)
240
- .data(plotLines)
241
- .join('g')
242
- .attr('class', `${plotClassName} ${plotLineClassName}`)
243
- .style('transform', (plotLine) => plotLine.transform);
244
- plotLinesSelection
245
- .append('path')
246
- .attr('d', (plotLine) => {
247
- const plotLineValue = Number(axisScale(plotLine.value));
248
- const points = [
249
- [0, plotLineValue],
250
- [width, plotLineValue],
251
- ];
252
- return lineGenerator(points);
253
- })
254
- .attr('stroke', (plotLine) => plotLine.color)
255
- .attr('stroke-width', (plotLine) => plotLine.width)
256
- .attr('stroke-dasharray', (plotLine) => getLineDashArray(plotLine.dashStyle, plotLine.width))
257
- .attr('opacity', (plotLine) => plotLine.opacity);
258
- plotLinesSelection.each((plotLineData, i, nodes) => {
259
- const plotLineSelection = select(nodes[i]);
260
- if (plotLineData.layerPlacement === 'before') {
261
- plotLineSelection.lower();
262
- }
263
- else {
264
- plotLineSelection.raise();
219
+ if (d.plotLines.length > 0) {
220
+ const plotLineDataAttr = `data-plot-y-line-${index}`;
221
+ const setPlotLines = (plotContainer, plotLines) => {
222
+ if (!plotContainer || !plotLines.length) {
223
+ return;
265
224
  }
266
- });
225
+ const plotLinesSelection = plotContainer
226
+ .selectAll(`[${plotLineDataAttr}]`)
227
+ .remove()
228
+ .data(plotLines)
229
+ .join('g')
230
+ .attr(plotDataAttr, 1)
231
+ .attr(plotLineDataAttr, 1)
232
+ .style('transform', getAxisPlotsPosition(d, split));
233
+ plotLinesSelection
234
+ .append('path')
235
+ .attr('d', (plotLine) => {
236
+ const plotLineValue = Number(axisScale(plotLine.value));
237
+ const points = [
238
+ [0, plotLineValue],
239
+ [width, plotLineValue],
240
+ ];
241
+ return lineGenerator(points);
242
+ })
243
+ .attr('stroke', (plotLine) => plotLine.color)
244
+ .attr('stroke-width', (plotLine) => plotLine.width)
245
+ .attr('stroke-dasharray', (plotLine) => getLineDashArray(plotLine.dashStyle, plotLine.width))
246
+ .attr('opacity', (plotLine) => plotLine.opacity);
247
+ };
248
+ setPlotLines(plotBeforeContainer, d.plotLines.filter((item) => item.layerPlacement === 'before'));
249
+ setPlotLines(plotAfterContainer, d.plotLines.filter((item) => item.layerPlacement === 'after'));
267
250
  }
268
251
  return axisItem;
269
252
  });
@@ -289,28 +272,47 @@ export const AxisY = (props) => {
289
272
  .attr('class', b('title'))
290
273
  .attr('text-anchor', 'middle')
291
274
  .attr('font-size', (d) => d.title.style.fontSize)
292
- .attr('transform', (d) => {
293
- const titleRows = wrapText({
294
- text: d.title.text,
295
- style: d.title.style,
296
- width: height,
275
+ .call(async (s) => {
276
+ s.each(async function prepareAxisTitle(d) {
277
+ if (!this) {
278
+ return;
279
+ }
280
+ const selection = select(this);
281
+ const titleRows = await wrapText({
282
+ text: d.title.text,
283
+ style: d.title.style,
284
+ width: height,
285
+ });
286
+ const rowCount = Math.min(titleRows.length, d.title.maxRowCount);
287
+ const { x, y } = getTitlePosition({ axis: d, axisHeight: height, rowCount });
288
+ const angle = d.position === 'left' ? -90 : 90;
289
+ selection.attr('transform', `translate(${x}, ${y}) rotate(${angle})`);
290
+ const axisTitleRows = await getAxisTitleRows({ axis: d, textMaxWidth: height });
291
+ selection
292
+ .selectAll('tspan')
293
+ .data(axisTitleRows)
294
+ .join('tspan')
295
+ .attr('x', 0)
296
+ .attr('y', (titleRow) => titleRow.y)
297
+ .text((titleRow) => titleRow.text)
298
+ .each((_d, index, nodes) => {
299
+ if (index === nodes.length - 1) {
300
+ handleOverflowingText(nodes[index], height);
301
+ }
302
+ });
297
303
  });
298
- const rowCount = Math.min(titleRows.length, d.title.maxRowCount);
299
- const { x, y } = getTitlePosition({ axis: d, axisHeight: height, rowCount });
300
- const angle = d.position === 'left' ? -90 : 90;
301
- return `translate(${x}, ${y}) rotate(${angle})`;
302
- })
303
- .selectAll('tspan')
304
- .data((d) => getAxisTitleRows({ axis: d, textMaxWidth: height }))
305
- .join('tspan')
306
- .attr('x', 0)
307
- .attr('y', (d) => d.y)
308
- .text((d) => d.text)
309
- .each((_d, index, nodes) => {
310
- if (index === nodes.length - 1) {
311
- handleOverflowingText(nodes[index], height);
312
- }
304
+ return s;
313
305
  });
314
- }, [allAxes, width, height, scale, split, bottomLimit]);
306
+ }, [
307
+ allAxes,
308
+ width,
309
+ height,
310
+ scale,
311
+ split,
312
+ bottomLimit,
313
+ lineGenerator,
314
+ plotBeforeRef,
315
+ plotAfterRef,
316
+ ]);
315
317
  return React.createElement("g", { ref: ref, className: b('container') });
316
318
  };