@gravity-ui/charts 1.51.7 → 1.52.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 (199) hide show
  1. package/dist/cjs/components/ChartInner/useChartInnerHandlers.d.ts +3 -2
  2. package/dist/cjs/components/ChartInner/useChartInnerHandlers.js +1 -3
  3. package/dist/cjs/components/ChartInner/useChartInnerProps.d.ts +3 -2
  4. package/dist/cjs/components/ChartInner/useDefaultState.d.ts +3 -2
  5. package/dist/cjs/components/index.d.ts +1 -0
  6. package/dist/cjs/components/index.js +1 -0
  7. package/dist/cjs/core/series/plugin.d.ts +47 -2
  8. package/dist/cjs/core/series/types.d.ts +4 -0
  9. package/dist/cjs/core/shapes/area/prepare-data.js +29 -19
  10. package/dist/cjs/core/shapes/area/renderer.d.ts +0 -5
  11. package/dist/cjs/core/shapes/area/renderer.js +0 -75
  12. package/dist/cjs/core/shapes/area/types.d.ts +2 -8
  13. package/dist/cjs/core/shapes/bar-x/prepare-data.js +18 -7
  14. package/dist/cjs/core/shapes/bar-x/renderer.d.ts +0 -1
  15. package/dist/cjs/core/shapes/bar-x/renderer.js +0 -18
  16. package/dist/cjs/core/shapes/bar-x/types.d.ts +2 -1
  17. package/dist/cjs/core/shapes/bar-y/get-tooltip-data.js +4 -2
  18. package/dist/cjs/core/shapes/bar-y/prepare-data.js +8 -2
  19. package/dist/cjs/core/shapes/funnel/prepare-data.js +121 -68
  20. package/dist/cjs/core/shapes/heatmap/prepare-data.js +11 -2
  21. package/dist/cjs/core/shapes/line/prepare-data.js +27 -17
  22. package/dist/cjs/core/shapes/line/renderer.d.ts +0 -5
  23. package/dist/cjs/core/shapes/line/renderer.js +0 -75
  24. package/dist/cjs/core/shapes/line/types.d.ts +2 -8
  25. package/dist/cjs/core/shapes/marker.d.ts +30 -0
  26. package/dist/cjs/core/shapes/marker.js +68 -0
  27. package/dist/cjs/core/shapes/pie/prepare-data.js +24 -9
  28. package/dist/cjs/core/shapes/radar/prepare-data.js +3 -0
  29. package/dist/cjs/core/shapes/sankey/prepare-data.js +10 -1
  30. package/dist/cjs/core/shapes/scatter/prepare-data.js +8 -1
  31. package/dist/cjs/core/shapes/scatter/renderer.js +3 -2
  32. package/dist/cjs/core/shapes/scatter/types.d.ts +1 -1
  33. package/dist/cjs/core/shapes/treemap/prepare-data.js +9 -1
  34. package/dist/cjs/core/shapes/types.d.ts +35 -0
  35. package/dist/cjs/core/shapes/waterfall/prepare-data.js +5 -2
  36. package/dist/cjs/core/shapes/x-range/prepare-data.js +7 -2
  37. package/dist/cjs/core/types/chart/base.d.ts +22 -2
  38. package/dist/cjs/core/types/chart/funnel.d.ts +25 -1
  39. package/dist/cjs/core/types/chart/tooltip.d.ts +6 -1
  40. package/dist/cjs/core/utils/data-labels.d.ts +34 -0
  41. package/dist/cjs/core/utils/data-labels.js +26 -0
  42. package/dist/cjs/core/utils/get-closest-data.d.ts +2 -2
  43. package/dist/cjs/core/utils/get-closest-data.js +14 -34
  44. package/dist/cjs/core/utils/tooltip-helpers.d.ts +16 -0
  45. package/dist/cjs/core/utils/tooltip-helpers.js +12 -0
  46. package/dist/cjs/hooks/useShapes/AnnotationLayer.d.ts +9 -0
  47. package/dist/cjs/hooks/useShapes/AnnotationLayer.js +17 -0
  48. package/dist/cjs/hooks/useShapes/HoverMarkerLayer.d.ts +10 -0
  49. package/dist/cjs/hooks/useShapes/HoverMarkerLayer.js +22 -0
  50. package/dist/cjs/hooks/useShapes/MarkerLayer.d.ts +7 -0
  51. package/dist/cjs/hooks/useShapes/MarkerLayer.js +12 -0
  52. package/dist/cjs/hooks/useShapes/SeriesShapes.d.ts +18 -0
  53. package/dist/cjs/hooks/useShapes/SeriesShapes.js +32 -0
  54. package/dist/cjs/hooks/useShapes/index.d.ts +5 -18
  55. package/dist/cjs/hooks/useShapes/index.js +39 -229
  56. package/dist/cjs/index.d.ts +0 -1
  57. package/dist/cjs/index.js +0 -1
  58. package/dist/cjs/plugins/area/index.js +42 -0
  59. package/dist/cjs/plugins/bar-x/index.js +42 -0
  60. package/dist/cjs/plugins/bar-y/index.js +26 -0
  61. package/dist/cjs/plugins/funnel/index.js +18 -0
  62. package/dist/cjs/plugins/funnel/prepare.js +17 -12
  63. package/dist/cjs/plugins/heatmap/index.js +23 -0
  64. package/dist/cjs/plugins/line/index.js +28 -0
  65. package/dist/cjs/plugins/pie/index.js +18 -0
  66. package/dist/cjs/plugins/radar/index.js +18 -0
  67. package/dist/cjs/plugins/sankey/index.js +18 -0
  68. package/dist/cjs/plugins/scatter/index.js +26 -0
  69. package/dist/cjs/plugins/treemap/index.js +18 -0
  70. package/dist/cjs/plugins/waterfall/index.js +39 -0
  71. package/dist/cjs/plugins/x-range/index.js +25 -0
  72. package/dist/cjs/setup-jsdom.d.ts +0 -1
  73. package/dist/cjs/setup-jsdom.js +1 -1
  74. package/dist/esm/components/ChartInner/useChartInnerHandlers.d.ts +3 -2
  75. package/dist/esm/components/ChartInner/useChartInnerHandlers.js +1 -3
  76. package/dist/esm/components/ChartInner/useChartInnerProps.d.ts +3 -2
  77. package/dist/esm/components/ChartInner/useDefaultState.d.ts +3 -2
  78. package/dist/esm/components/index.d.ts +1 -0
  79. package/dist/esm/components/index.js +1 -0
  80. package/dist/esm/core/series/plugin.d.ts +47 -2
  81. package/dist/esm/core/series/types.d.ts +4 -0
  82. package/dist/esm/core/shapes/area/prepare-data.js +29 -19
  83. package/dist/esm/core/shapes/area/renderer.d.ts +0 -5
  84. package/dist/esm/core/shapes/area/renderer.js +0 -75
  85. package/dist/esm/core/shapes/area/types.d.ts +2 -8
  86. package/dist/esm/core/shapes/bar-x/prepare-data.js +18 -7
  87. package/dist/esm/core/shapes/bar-x/renderer.d.ts +0 -1
  88. package/dist/esm/core/shapes/bar-x/renderer.js +0 -18
  89. package/dist/esm/core/shapes/bar-x/types.d.ts +2 -1
  90. package/dist/esm/core/shapes/bar-y/get-tooltip-data.js +4 -2
  91. package/dist/esm/core/shapes/bar-y/prepare-data.js +8 -2
  92. package/dist/esm/core/shapes/funnel/prepare-data.js +121 -68
  93. package/dist/esm/core/shapes/heatmap/prepare-data.js +11 -2
  94. package/dist/esm/core/shapes/line/prepare-data.js +27 -17
  95. package/dist/esm/core/shapes/line/renderer.d.ts +0 -5
  96. package/dist/esm/core/shapes/line/renderer.js +0 -75
  97. package/dist/esm/core/shapes/line/types.d.ts +2 -8
  98. package/dist/esm/core/shapes/marker.d.ts +30 -0
  99. package/dist/esm/core/shapes/marker.js +68 -0
  100. package/dist/esm/core/shapes/pie/prepare-data.js +24 -9
  101. package/dist/esm/core/shapes/radar/prepare-data.js +3 -0
  102. package/dist/esm/core/shapes/sankey/prepare-data.js +10 -1
  103. package/dist/esm/core/shapes/scatter/prepare-data.js +8 -1
  104. package/dist/esm/core/shapes/scatter/renderer.js +3 -2
  105. package/dist/esm/core/shapes/scatter/types.d.ts +1 -1
  106. package/dist/esm/core/shapes/treemap/prepare-data.js +9 -1
  107. package/dist/esm/core/shapes/types.d.ts +35 -0
  108. package/dist/esm/core/shapes/waterfall/prepare-data.js +5 -2
  109. package/dist/esm/core/shapes/x-range/prepare-data.js +7 -2
  110. package/dist/esm/core/types/chart/base.d.ts +22 -2
  111. package/dist/esm/core/types/chart/funnel.d.ts +25 -1
  112. package/dist/esm/core/types/chart/tooltip.d.ts +6 -1
  113. package/dist/esm/core/utils/data-labels.d.ts +34 -0
  114. package/dist/esm/core/utils/data-labels.js +26 -0
  115. package/dist/esm/core/utils/get-closest-data.d.ts +2 -2
  116. package/dist/esm/core/utils/get-closest-data.js +14 -34
  117. package/dist/esm/core/utils/tooltip-helpers.d.ts +16 -0
  118. package/dist/esm/core/utils/tooltip-helpers.js +12 -0
  119. package/dist/esm/hooks/useShapes/AnnotationLayer.d.ts +9 -0
  120. package/dist/esm/hooks/useShapes/AnnotationLayer.js +17 -0
  121. package/dist/esm/hooks/useShapes/HoverMarkerLayer.d.ts +10 -0
  122. package/dist/esm/hooks/useShapes/HoverMarkerLayer.js +22 -0
  123. package/dist/esm/hooks/useShapes/MarkerLayer.d.ts +7 -0
  124. package/dist/esm/hooks/useShapes/MarkerLayer.js +12 -0
  125. package/dist/esm/hooks/useShapes/SeriesShapes.d.ts +18 -0
  126. package/dist/esm/hooks/useShapes/SeriesShapes.js +32 -0
  127. package/dist/esm/hooks/useShapes/index.d.ts +5 -18
  128. package/dist/esm/hooks/useShapes/index.js +39 -229
  129. package/dist/esm/index.d.ts +0 -1
  130. package/dist/esm/index.js +0 -1
  131. package/dist/esm/plugins/area/index.js +42 -0
  132. package/dist/esm/plugins/bar-x/index.js +42 -0
  133. package/dist/esm/plugins/bar-y/index.js +26 -0
  134. package/dist/esm/plugins/funnel/index.js +18 -0
  135. package/dist/esm/plugins/funnel/prepare.js +17 -12
  136. package/dist/esm/plugins/heatmap/index.js +23 -0
  137. package/dist/esm/plugins/line/index.js +28 -0
  138. package/dist/esm/plugins/pie/index.js +18 -0
  139. package/dist/esm/plugins/radar/index.js +18 -0
  140. package/dist/esm/plugins/sankey/index.js +18 -0
  141. package/dist/esm/plugins/scatter/index.js +26 -0
  142. package/dist/esm/plugins/treemap/index.js +18 -0
  143. package/dist/esm/plugins/waterfall/index.js +39 -0
  144. package/dist/esm/plugins/x-range/index.js +25 -0
  145. package/dist/esm/setup-jsdom.d.ts +0 -1
  146. package/dist/esm/setup-jsdom.js +1 -1
  147. package/package.json +2 -3
  148. package/dist/cjs/hooks/useShapes/area/index.d.ts +0 -15
  149. package/dist/cjs/hooks/useShapes/area/index.js +0 -52
  150. package/dist/cjs/hooks/useShapes/bar-x/index.d.ts +0 -16
  151. package/dist/cjs/hooks/useShapes/bar-x/index.js +0 -45
  152. package/dist/cjs/hooks/useShapes/bar-y/index.d.ts +0 -13
  153. package/dist/cjs/hooks/useShapes/bar-y/index.js +0 -19
  154. package/dist/cjs/hooks/useShapes/funnel/index.d.ts +0 -13
  155. package/dist/cjs/hooks/useShapes/funnel/index.js +0 -21
  156. package/dist/cjs/hooks/useShapes/heatmap/index.d.ts +0 -13
  157. package/dist/cjs/hooks/useShapes/heatmap/index.js +0 -20
  158. package/dist/cjs/hooks/useShapes/line/index.d.ts +0 -15
  159. package/dist/cjs/hooks/useShapes/line/index.js +0 -38
  160. package/dist/cjs/hooks/useShapes/pie/index.d.ts +0 -12
  161. package/dist/cjs/hooks/useShapes/pie/index.js +0 -20
  162. package/dist/cjs/hooks/useShapes/radar/index.d.ts +0 -12
  163. package/dist/cjs/hooks/useShapes/radar/index.js +0 -19
  164. package/dist/cjs/hooks/useShapes/sankey/index.d.ts +0 -12
  165. package/dist/cjs/hooks/useShapes/sankey/index.js +0 -18
  166. package/dist/cjs/hooks/useShapes/scatter/index.d.ts +0 -13
  167. package/dist/cjs/hooks/useShapes/scatter/index.js +0 -22
  168. package/dist/cjs/hooks/useShapes/treemap/index.d.ts +0 -12
  169. package/dist/cjs/hooks/useShapes/treemap/index.js +0 -18
  170. package/dist/cjs/hooks/useShapes/waterfall/index.d.ts +0 -14
  171. package/dist/cjs/hooks/useShapes/waterfall/index.js +0 -31
  172. package/dist/cjs/hooks/useShapes/x-range/index.d.ts +0 -14
  173. package/dist/cjs/hooks/useShapes/x-range/index.js +0 -20
  174. package/dist/esm/hooks/useShapes/area/index.d.ts +0 -15
  175. package/dist/esm/hooks/useShapes/area/index.js +0 -52
  176. package/dist/esm/hooks/useShapes/bar-x/index.d.ts +0 -16
  177. package/dist/esm/hooks/useShapes/bar-x/index.js +0 -45
  178. package/dist/esm/hooks/useShapes/bar-y/index.d.ts +0 -13
  179. package/dist/esm/hooks/useShapes/bar-y/index.js +0 -19
  180. package/dist/esm/hooks/useShapes/funnel/index.d.ts +0 -13
  181. package/dist/esm/hooks/useShapes/funnel/index.js +0 -21
  182. package/dist/esm/hooks/useShapes/heatmap/index.d.ts +0 -13
  183. package/dist/esm/hooks/useShapes/heatmap/index.js +0 -20
  184. package/dist/esm/hooks/useShapes/line/index.d.ts +0 -15
  185. package/dist/esm/hooks/useShapes/line/index.js +0 -38
  186. package/dist/esm/hooks/useShapes/pie/index.d.ts +0 -12
  187. package/dist/esm/hooks/useShapes/pie/index.js +0 -20
  188. package/dist/esm/hooks/useShapes/radar/index.d.ts +0 -12
  189. package/dist/esm/hooks/useShapes/radar/index.js +0 -19
  190. package/dist/esm/hooks/useShapes/sankey/index.d.ts +0 -12
  191. package/dist/esm/hooks/useShapes/sankey/index.js +0 -18
  192. package/dist/esm/hooks/useShapes/scatter/index.d.ts +0 -13
  193. package/dist/esm/hooks/useShapes/scatter/index.js +0 -22
  194. package/dist/esm/hooks/useShapes/treemap/index.d.ts +0 -12
  195. package/dist/esm/hooks/useShapes/treemap/index.js +0 -18
  196. package/dist/esm/hooks/useShapes/waterfall/index.d.ts +0 -14
  197. package/dist/esm/hooks/useShapes/waterfall/index.js +0 -31
  198. package/dist/esm/hooks/useShapes/x-range/index.d.ts +0 -14
  199. package/dist/esm/hooks/useShapes/x-range/index.js +0 -20
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import type { Dispatch } from 'd3-dispatch';
3
3
  import type { ChartScale } from '../../core/scales/types';
4
- import type { PreparedXAxis, PreparedYAxis, ShapeData } from '../../hooks';
4
+ import type { TooltipItemData } from '../../core/shapes/types';
5
+ import type { PreparedXAxis, PreparedYAxis } from '../../hooks';
5
6
  import type { useChartInnerState } from './useChartInnerState';
6
7
  type ChartInnerState = ReturnType<typeof useChartInnerState>;
7
8
  type Props = {
@@ -10,7 +11,7 @@ type Props = {
10
11
  boundsOffsetTop: number;
11
12
  boundsWidth: number;
12
13
  dispatcher: Dispatch<object>;
13
- shapesData: ShapeData[];
14
+ shapesData: TooltipItemData[];
14
15
  svgContainer: SVGSVGElement | null;
15
16
  togglePinTooltip: ChartInnerState['togglePinTooltip'];
16
17
  tooltipPinned: boolean;
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
2
  import { pointer } from 'd3-selection';
3
- import get from 'lodash/get';
4
3
  import throttle from 'lodash/throttle';
5
4
  import { EventType } from '../../core/utils';
6
5
  import { getClosestPoints } from '../../core/utils/get-closest-data';
@@ -21,10 +20,9 @@ export function useChartInnerHandlers(props) {
21
20
  dispatcher.call(EventType.POINTERMOVE_CHART, {}, undefined, event);
22
21
  return;
23
22
  }
24
- const shapesDataWithTooltipEnabled = shapesData.filter((d) => get(d, 'series.tooltip.enabled', true));
25
23
  const closest = getClosestPoints({
26
24
  position: [x, y],
27
- shapesData: shapesDataWithTooltipEnabled,
25
+ shapesData,
28
26
  boundsHeight,
29
27
  boundsWidth,
30
28
  });
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { Dispatch } from 'd3-dispatch';
3
- import type { ChartScale, LegendItem, OnLegendItemClick, PreparedLegend, PreparedSeries, PreparedSplit, PreparedXAxis, PreparedYAxis, RangeSliderState, ShapeData, ZoomState } from '../../hooks';
3
+ import type { TooltipItemData } from '../../core/shapes/types';
4
+ import type { ChartScale, LegendItem, OnLegendItemClick, PreparedLegend, PreparedSeries, PreparedSplit, PreparedXAxis, PreparedYAxis, RangeSliderState, ZoomState } from '../../hooks';
4
5
  import type { PreparedChart, PreparedTitle } from '../../hooks/types';
5
6
  import type { LegendConfig } from '../../types';
6
7
  import type { ChartInnerProps } from './types';
@@ -22,7 +23,7 @@ export declare function useChartInnerProps(props: Props): {
22
23
  boundsWidth: number;
23
24
  xAxis: PreparedXAxis | null;
24
25
  yAxis: PreparedYAxis[];
25
- shapesData: ShapeData[];
26
+ shapesData: TooltipItemData[];
26
27
  shapesReady: boolean;
27
28
  handleLegendItemClick: OnLegendItemClick;
28
29
  preparedTitle: PreparedTitle | undefined;
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import type { Dispatch } from 'd3-dispatch';
3
3
  import type { ChartScale } from '../../core/scales/types';
4
- import type { PreparedXAxis, PreparedYAxis, ShapeData } from '../../hooks';
4
+ import type { TooltipItemData } from '../../core/shapes/types';
5
+ import type { PreparedXAxis, PreparedYAxis } from '../../hooks';
5
6
  type Props = {
6
7
  boundsHeight: number;
7
8
  boundsOffsetLeft: number;
@@ -14,7 +15,7 @@ type Props = {
14
15
  };
15
16
  };
16
17
  dispatcher: Dispatch<object>;
17
- shapesData: ShapeData[];
18
+ shapesData: TooltipItemData[];
18
19
  shapesReady: boolean;
19
20
  svgRef: React.RefObject<SVGSVGElement | null>;
20
21
  xAxis: PreparedXAxis | null;
@@ -1,4 +1,5 @@
1
1
  import React from 'react';
2
+ import '../plugins';
2
3
  import type { ChartData } from '../types';
3
4
  export * from './Tooltip/ChartTooltipContent';
4
5
  export interface ChartReflowOptions {
@@ -2,6 +2,7 @@ import React from 'react';
2
2
  import debounce from 'lodash/debounce';
3
3
  import { i18nFactory } from '../core/i18n';
4
4
  import { validateData } from '../core/validation';
5
+ import '../plugins';
5
6
  import { ChartInner } from './ChartInner';
6
7
  export * from './Tooltip/ChartTooltipContent';
7
8
  export const Chart = React.forwardRef(function Chart(props, forwardedRef) {
@@ -1,6 +1,12 @@
1
+ import type { Dispatch } from 'd3-dispatch';
1
2
  import type { ScaleOrdinal } from 'd3-scale';
2
- import type { ChartSeries, ChartSeriesOptions } from '../../types';
3
- import type { PreparedLegend, PreparedSeries } from './types';
3
+ import type { ChartSeries, ChartSeriesOptions, ShapeDataWithLabels } from '../../types';
4
+ import type { PreparedXAxis, PreparedYAxis } from '../axes/types';
5
+ import type { PreparedSplit } from '../layout/split-types';
6
+ import type { ChartScale } from '../scales/types';
7
+ import type { SeriesShapeData, TooltipItemData } from '../shapes/types';
8
+ import type { GetTooltipDataFn } from '../utils/tooltip-helpers';
9
+ import type { PreparedLegend, PreparedSeries, PreparedSeriesOptions } from './types';
4
10
  export interface PrepareSeriesArgs {
5
11
  series: ChartSeries[];
6
12
  seriesOptions?: ChartSeriesOptions;
@@ -8,7 +14,46 @@ export interface PrepareSeriesArgs {
8
14
  colorScale: ScaleOrdinal<string, string>;
9
15
  colors: string[];
10
16
  }
17
+ export interface PrepareShapeDataArgs {
18
+ series: PreparedSeries[];
19
+ boundsWidth: number;
20
+ boundsHeight: number;
21
+ seriesOptions: PreparedSeriesOptions;
22
+ xAxis?: PreparedXAxis | null;
23
+ yAxis?: PreparedYAxis[];
24
+ xScale?: ChartScale;
25
+ yScale?: (ChartScale | undefined)[];
26
+ split?: PreparedSplit;
27
+ isOutsideBounds?: (x: number, y: number) => boolean;
28
+ isRangeSlider?: boolean;
29
+ otherLayers?: ShapeDataWithLabels[];
30
+ }
31
+ export interface PrepareShapeDataResult {
32
+ renderData: SeriesShapeData[];
33
+ tooltipItems: TooltipItemData[];
34
+ }
35
+ export interface RenderShapesArgs {
36
+ plot: SVGGElement;
37
+ preparedData: SeriesShapeData[];
38
+ seriesOptions: PreparedSeriesOptions;
39
+ boundsWidth: number;
40
+ boundsHeight: number;
41
+ dispatcher?: Dispatch<object>;
42
+ }
11
43
  export interface SeriesPlugin<T extends ChartSeries = ChartSeries> {
44
+ /** Unique series type identifier (e.g. `'line'`, `'bar-x'`). Used for plugin lookup and CSS class generation. */
12
45
  type: T['type'];
46
+ /**
47
+ * Whether the shape `<g>` element should be clipped to the chart bounds.
48
+ * Defaults to `true`. Set to `false` for series that render outside the plot area (e.g. pie, radar, treemap).
49
+ */
50
+ useClipPath?: boolean;
51
+ /** Transforms raw chart series config into prepared series objects used throughout the render pipeline. */
13
52
  prepareSeries(args: PrepareSeriesArgs): PreparedSeries[] | Promise<PreparedSeries[]>;
53
+ /** Computes shape data (geometry, labels, markers) from prepared series. Called once per render cycle. */
54
+ prepareShapeData(args: PrepareShapeDataArgs): PrepareShapeDataResult | Promise<PrepareShapeDataResult>;
55
+ /** Renders shapes into the provided SVG `<g>` element using D3. May return a cleanup function. */
56
+ renderShapes(args: RenderShapesArgs): (() => void) | void;
57
+ /** Returns tooltip data for a given pointer position and prepared series. */
58
+ getTooltipData: GetTooltipDataFn;
14
59
  }
@@ -369,6 +369,10 @@ export type PreparedFunnelSeries = {
369
369
  html: boolean;
370
370
  format?: ValueFormat;
371
371
  align: Required<Required<FunnelSeries>['dataLabels']>['align'];
372
+ inside: boolean;
373
+ reserveSpace: boolean;
374
+ padding: number;
375
+ anchor: Required<Required<FunnelSeries>['dataLabels']>['anchor'];
372
376
  };
373
377
  connectors: Required<FunnelSeries['connectors']>;
374
378
  } & BasePreparedSeries;
@@ -2,8 +2,9 @@ import { group, min, sort } from 'd3-array';
2
2
  import isNil from 'lodash/isNil';
3
3
  import round from 'lodash/round';
4
4
  import { prepareAnnotation } from '../../series/prepare-annotation';
5
+ import { buildHoverMarkerGetter } from '../../shapes/marker';
5
6
  import { getXValue, getYValue, markHiddenPointsOutOfYRange } from '../../shapes/utils';
6
- import { getDataCategoryValue, preparePointDataLabels } from '../../utils';
7
+ import { getDataCategoryValue, preparePointDataLabels, shouldPrepareSeriesDataLabels, } from '../../utils';
7
8
  function getXValues(series, xAxis, xScale) {
8
9
  const categories = xAxis.categories || [];
9
10
  const xValues = series.reduce((acc, s) => {
@@ -242,41 +243,50 @@ export const prepareAreaData = async (args) => {
242
243
  });
243
244
  }
244
245
  }
245
- let markers = [];
246
+ markHiddenPointsOutOfYRange({
247
+ points,
248
+ yScale: seriesYScale,
249
+ yAxisTop,
250
+ });
251
+ const normalState = s.marker.states.normal;
246
252
  const hasPerPointNormalMarkers = s.data.some((d) => { var _a, _b, _c; return (_c = (_b = (_a = d.marker) === null || _a === void 0 ? void 0 : _a.states) === null || _b === void 0 ? void 0 : _b.normal) === null || _c === void 0 ? void 0 : _c.enabled; });
247
- if (s.marker.states.normal.enabled || hasPerPointNormalMarkers) {
248
- markers = points.reduce((markersAcc, p) => {
249
- var _a, _b, _c, _d;
250
- if (p.y === null) {
251
- return markersAcc;
253
+ const markers = s.marker.states.normal.enabled || hasPerPointNormalMarkers
254
+ ? points.reduce((acc, p) => {
255
+ var _a, _b, _c, _d, _e;
256
+ if (p.y === null || p.hiddenInLine) {
257
+ return acc;
252
258
  }
253
259
  const pointNormalEnabled = (_d = (_c = (_b = (_a = p.data.marker) === null || _a === void 0 ? void 0 : _a.states) === null || _b === void 0 ? void 0 : _b.normal) === null || _c === void 0 ? void 0 : _c.enabled) !== null && _d !== void 0 ? _d : false;
254
260
  if (s.marker.states.normal.enabled || pointNormalEnabled) {
255
- markersAcc.push({
256
- point: p,
261
+ acc.push({
262
+ cx: p.x,
263
+ cy: p.y,
264
+ radius: normalState.radius,
265
+ symbolType: normalState.symbol,
266
+ fill: (_e = p.color) !== null && _e !== void 0 ? _e : s.color,
267
+ stroke: normalState.borderColor,
268
+ strokeWidth: normalState.borderWidth,
269
+ opacity: 1,
257
270
  active: true,
258
- hovered: false,
259
271
  clipped: isOutsideBounds(p.x, p.y),
272
+ series: { id: s.id },
273
+ data: p.data,
260
274
  });
261
275
  }
262
- return markersAcc;
263
- }, []);
264
- }
276
+ return acc;
277
+ }, [])
278
+ : [];
265
279
  const annotations = points.reduce((result, p) => {
266
280
  if (p.annotation && p.y !== null) {
267
281
  result.push({ annotation: p.annotation, x: p.x, y: p.y });
268
282
  }
269
283
  return result;
270
284
  }, []);
271
- markHiddenPointsOutOfYRange({
272
- points,
273
- yScale: seriesYScale,
274
- yAxisTop,
275
- });
276
285
  seriesStackData.push({
277
286
  annotations,
278
287
  points,
279
288
  markers,
289
+ getHoverMarkers: buildHoverMarkerGetter(points, s),
280
290
  svgLabels: [],
281
291
  color: s.color,
282
292
  opacity: s.opacity,
@@ -292,7 +302,7 @@ export const prepareAreaData = async (args) => {
292
302
  const item = seriesStackData[itemIndex];
293
303
  const currentYAxis = yAxis[item.series.yAxis];
294
304
  const itemYAxisTop = ((_p = split.plots[currentYAxis.plotIndex]) === null || _p === void 0 ? void 0 : _p.top) || 0;
295
- if (item.series.dataLabels.enabled && !isRangeSlider) {
305
+ if (!isRangeSlider && shouldPrepareSeriesDataLabels(item.series)) {
296
306
  const labelsData = await preparePointDataLabels({
297
307
  series: item.series,
298
308
  points: item.points,
@@ -3,9 +3,4 @@ import type { PreparedSeriesOptions } from '../../series/types';
3
3
  import type { PreparedAreaData } from './types';
4
4
  export declare function renderArea(elements: {
5
5
  plot: SVGGElement;
6
- markers: SVGGElement;
7
- hoverMarkers: SVGGElement;
8
- annotations: SVGGElement;
9
- boundsWidth: number;
10
- boundsHeight: number;
11
6
  }, preparedData: PreparedAreaData[], seriesOptions: PreparedSeriesOptions, allowOverlapDataLabels: boolean, dispatcher?: Dispatch<object>): () => void;
@@ -4,16 +4,11 @@ import { area as areaGenerator, line as lineGenerator } from 'd3-shape';
4
4
  import get from 'lodash/get';
5
5
  import { block } from '../../../utils';
6
6
  import { filterOverlappingLabels } from '../../utils';
7
- import { renderAnnotations } from '../annotation';
8
7
  import { renderDataLabels } from '../data-labels';
9
- import { getMarkerHaloVisibility, getMarkerVisibility, renderMarker, selectMarkerHalo, selectMarkerSymbol, setMarker, } from '../marker';
10
8
  import { setActiveState } from '../utils';
11
9
  const b = block('area');
12
10
  export function renderArea(elements, preparedData, seriesOptions, allowOverlapDataLabels, dispatcher) {
13
11
  const plotSvgElement = select(elements.plot);
14
- const markersSvgElement = select(elements.markers);
15
- const hoverMarkersSvgElement = select(elements.hoverMarkers);
16
- const annotationsSvgElement = select(elements.annotations);
17
12
  const hoverOptions = get(seriesOptions, 'area.states.hover');
18
13
  const inactiveOptions = get(seriesOptions, 'area.states.inactive');
19
14
  const line = lineGenerator()
@@ -21,7 +16,6 @@ export function renderArea(elements, preparedData, seriesOptions, allowOverlapDa
21
16
  .defined((d) => d.y !== null && !d.hiddenInLine)
22
17
  .y((d) => d.y);
23
18
  plotSvgElement.selectAll('*').remove();
24
- markersSvgElement.selectAll('*').remove();
25
19
  const shapeSelection = plotSvgElement
26
20
  .selectAll('shape')
27
21
  .data(preparedData)
@@ -59,23 +53,10 @@ export function renderArea(elements, preparedData, seriesOptions, allowOverlapDa
59
53
  data: dataLabels,
60
54
  className: b('label'),
61
55
  });
62
- const markers = preparedData.reduce((acc, d) => acc.concat(d.markers), []);
63
- const markerSelection = markersSvgElement
64
- .selectAll('marker')
65
- .data(markers)
66
- .join('g')
67
- .call(renderMarker);
68
- renderAnnotations({
69
- anchors: preparedData.flatMap((d) => d.annotations),
70
- container: annotationsSvgElement,
71
- plotHeight: elements.boundsHeight,
72
- plotWidth: elements.boundsWidth,
73
- });
74
56
  const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
75
57
  const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
76
58
  function handleShapeHover(data) {
77
59
  const selected = (data === null || data === void 0 ? void 0 : data.filter((d) => d.series.type === 'area')) || [];
78
- const selectedDataItems = selected.map((d) => d.data);
79
60
  const selectedSeriesIds = selected.map((d) => { var _a; return (_a = d.series) === null || _a === void 0 ? void 0 : _a.id; });
80
61
  shapeSelection.datum((d, index, list) => {
81
62
  var _a;
@@ -111,62 +92,6 @@ export function renderArea(elements, preparedData, seriesOptions, allowOverlapDa
111
92
  datum: d,
112
93
  });
113
94
  });
114
- markerSelection.datum((d, index, list) => {
115
- const elementSelection = select(list[index]);
116
- const hovered = Boolean(hoverEnabled && selectedDataItems.includes(d.point.data));
117
- if (d.hovered !== hovered) {
118
- d.hovered = hovered;
119
- elementSelection.attr('visibility', getMarkerVisibility(d));
120
- selectMarkerHalo(elementSelection).attr('visibility', getMarkerHaloVisibility);
121
- selectMarkerSymbol(elementSelection).call(setMarker, hovered ? 'hover' : 'normal');
122
- }
123
- if (d.point.series.marker.states.normal.enabled) {
124
- const isActive = Boolean(!inactiveEnabled ||
125
- !selectedSeriesIds.length ||
126
- selectedSeriesIds.includes(d.point.series.id));
127
- setActiveState({
128
- element: list[index],
129
- state: inactiveOptions,
130
- active: isActive,
131
- datum: d,
132
- });
133
- }
134
- return d;
135
- });
136
- hoverMarkersSvgElement.selectAll('*').remove();
137
- if (hoverEnabled && selected.length > 0) {
138
- const hoverOnlyMarkers = [];
139
- for (const chunk of selected) {
140
- const seriesData = preparedData.find((pd) => pd.id === chunk.series.id);
141
- if (!seriesData) {
142
- continue;
143
- }
144
- const { series } = seriesData;
145
- if (series.marker.states.normal.enabled || !series.marker.states.hover.enabled) {
146
- continue;
147
- }
148
- const point = seriesData.points.find((p) => p.data === chunk.data);
149
- if (!point || point.y === null) {
150
- continue;
151
- }
152
- hoverOnlyMarkers.push({
153
- point: point,
154
- active: true,
155
- hovered: true,
156
- clipped: false,
157
- });
158
- }
159
- if (hoverOnlyMarkers.length > 0) {
160
- hoverMarkersSvgElement
161
- .selectAll('g')
162
- .data(hoverOnlyMarkers)
163
- .join('g')
164
- .call(renderMarker)
165
- .each((_d, i, nodes) => {
166
- selectMarkerSymbol(select(nodes[i])).call(setMarker, 'hover');
167
- });
168
- }
169
- }
170
95
  }
171
96
  dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on('hover-shape.area', handleShapeHover);
172
97
  return () => {
@@ -1,6 +1,6 @@
1
1
  import type { AreaSeriesData, LabelData } from '../../../types';
2
2
  import type { AnnotationAnchor, PreparedAnnotation, PreparedAreaSeries } from '../../series/types';
3
- import type { SeriesShapeData } from '../types';
3
+ import type { MarkerItem, SeriesShapeData } from '../types';
4
4
  export type PointData = {
5
5
  annotation?: PreparedAnnotation;
6
6
  color?: string;
@@ -14,17 +14,11 @@ export type PointData = {
14
14
  export type MarkerPointData = PointData & {
15
15
  y: number;
16
16
  };
17
- export type MarkerData = {
18
- point: MarkerPointData;
19
- active: boolean;
20
- hovered: boolean;
21
- clipped: boolean;
22
- };
23
17
  export type PreparedAreaData = {
24
18
  annotations: AnnotationAnchor[];
25
19
  id: string;
26
20
  points: PointData[];
27
- markers: MarkerData[];
21
+ markers: MarkerItem[];
28
22
  color: string;
29
23
  opacity: number;
30
24
  width: number;
@@ -3,15 +3,12 @@ import get from 'lodash/get';
3
3
  import { prepareAnnotation } from '../../series/prepare-annotation';
4
4
  import { getSeriesStackId } from '../../series/utils';
5
5
  import { MIN_BAR_GAP, MIN_BAR_GROUP_GAP, MIN_BAR_WIDTH } from '../../shapes/bar-constants';
6
- import { getDataCategoryValue, getLabelsSize, getTextSizeFn } from '../../utils';
6
+ import { getDataCategoryValue, getLabelsSize, getTextSizeFn, isPointDataLabelEnabled, } from '../../utils';
7
7
  import { getBandSize } from '../../utils/band-size';
8
8
  import { getFormattedValue } from '../../utils/format';
9
9
  const isSeriesDataValid = (d) => d.y !== null;
10
10
  async function getLabelData(d, xMax) {
11
11
  var _a;
12
- if (!d.series.dataLabels.enabled) {
13
- return {};
14
- }
15
12
  const text = getFormattedValue(Object.assign({ value: (_a = d.data.label) !== null && _a !== void 0 ? _a : d.data.y }, d.series.dataLabels));
16
13
  const style = d.series.dataLabels.style;
17
14
  if (d.series.dataLabels.html) {
@@ -209,6 +206,7 @@ export const prepareBarXData = async (args) => {
209
206
  optionsPopup: (_j = (_h = seriesOptions['bar-x']) === null || _h === void 0 ? void 0 : _h.annotation) === null || _j === void 0 ? void 0 : _j.popup,
210
207
  })
211
208
  : undefined,
209
+ annotations: [],
212
210
  x,
213
211
  y: barPositionY,
214
212
  width: rectWidth,
@@ -220,6 +218,8 @@ export const prepareBarXData = async (args) => {
220
218
  htmlLabels: [],
221
219
  svgLabels: [],
222
220
  isLastStackItem,
221
+ markers: [],
222
+ getHoverMarkers: () => [],
223
223
  };
224
224
  stackItems.push(barData);
225
225
  if (yDataValue > 0) {
@@ -243,6 +243,17 @@ export const prepareBarXData = async (args) => {
243
243
  }
244
244
  }
245
245
  }
246
+ for (const barData of result) {
247
+ if (barData.annotation) {
248
+ barData.annotations = [
249
+ {
250
+ annotation: barData.annotation,
251
+ x: barData.x + barData.width / 2,
252
+ y: barData.y,
253
+ },
254
+ ];
255
+ }
256
+ }
246
257
  const [_xMin, xRangeMax] = xScale.range();
247
258
  const xMax = xRangeMax;
248
259
  for (let i = 0; i < result.length; i++) {
@@ -252,9 +263,9 @@ export const prepareBarXData = async (args) => {
252
263
  barData.y + barData.height <= 0 ||
253
264
  barData.y >= plotHeight;
254
265
  const isZeroValue = ((_k = barData.data.y) !== null && _k !== void 0 ? _k : 0) === 0;
255
- if (barData.series.dataLabels.enabled &&
256
- !isRangeSlider &&
257
- (!isBarOutsideBounds || isZeroValue)) {
266
+ if (!isRangeSlider &&
267
+ (!isBarOutsideBounds || isZeroValue) &&
268
+ isPointDataLabelEnabled({ data: barData.data, series: barData.series })) {
258
269
  const { svgLabel, htmlLabel } = await getLabelData(barData, xMax);
259
270
  if (svgLabel) {
260
271
  barData.svgLabels.push(svgLabel);
@@ -3,7 +3,6 @@ import type { PreparedSeriesOptions } from '../../series/types';
3
3
  import type { PreparedBarXData } from './types';
4
4
  export declare function renderBarX(elements: {
5
5
  plot: SVGGElement;
6
- annotations: SVGGElement;
7
6
  boundsWidth: number;
8
7
  boundsHeight: number;
9
8
  }, preparedData: PreparedBarXData[], seriesOptions: PreparedSeriesOptions, allowOverlapDataLabels: boolean, dispatcher?: Dispatch<object>): () => void;
@@ -3,13 +3,11 @@ import { select } from 'd3-selection';
3
3
  import get from 'lodash/get';
4
4
  import { block } from '../../../utils';
5
5
  import { filterOverlappingLabels } from '../../utils';
6
- import { renderAnnotations } from '../annotation';
7
6
  import { renderDataLabels } from '../data-labels';
8
7
  import { getRectPath } from '../utils';
9
8
  const b = block('bar-x');
10
9
  export function renderBarX(elements, preparedData, seriesOptions, allowOverlapDataLabels, dispatcher) {
11
10
  const svgElement = select(elements.plot);
12
- const annotationsSvgElement = select(elements.annotations);
13
11
  const hoverOptions = get(seriesOptions, 'bar-x.states.hover');
14
12
  const inactiveOptions = get(seriesOptions, 'bar-x.states.inactive');
15
13
  svgElement.selectAll('*').remove();
@@ -43,22 +41,6 @@ export function renderBarX(elements, preparedData, seriesOptions, allowOverlapDa
43
41
  data: dataLabels,
44
42
  className: b('label'),
45
43
  });
46
- const annotationAnchors = [];
47
- for (const d of preparedData) {
48
- if (d.annotation) {
49
- annotationAnchors.push({
50
- annotation: d.annotation,
51
- x: d.x + d.width / 2,
52
- y: d.y,
53
- });
54
- }
55
- }
56
- renderAnnotations({
57
- anchors: annotationAnchors,
58
- container: annotationsSvgElement,
59
- plotHeight: elements.boundsHeight,
60
- plotWidth: elements.boundsWidth,
61
- });
62
44
  function handleShapeHover(data) {
63
45
  const hoverEnabled = hoverOptions === null || hoverOptions === void 0 ? void 0 : hoverOptions.enabled;
64
46
  const inactiveEnabled = inactiveOptions === null || inactiveOptions === void 0 ? void 0 : inactiveOptions.enabled;
@@ -1,8 +1,9 @@
1
1
  import type { LabelData, TooltipDataChunkBarX } from '../../../types';
2
- import type { PreparedAnnotation, PreparedBarXSeries } from '../../series/types';
2
+ import type { AnnotationAnchor, PreparedAnnotation, PreparedBarXSeries } from '../../series/types';
3
3
  import type { SeriesShapeData } from '../types';
4
4
  export type PreparedBarXData = Omit<TooltipDataChunkBarX, 'series'> & {
5
5
  annotation?: PreparedAnnotation;
6
+ annotations: AnnotationAnchor[];
6
7
  x: number;
7
8
  y: number;
8
9
  width: number;
@@ -1,15 +1,17 @@
1
1
  import { bisector, sort } from 'd3-array';
2
+ import { isPointTooltipEnabled } from '../../utils/tooltip-helpers';
2
3
  export function getTooltipData(args) {
3
4
  var _a, _b;
4
5
  const { data, position } = args;
5
6
  const [pointerX, pointerY] = position;
6
- const sorted = sort(data, (p) => p.y);
7
+ const visibleData = data.filter((p) => isPointTooltipEnabled({ data: p.data, series: p.series }));
8
+ const sorted = sort(visibleData, (p) => p.y);
7
9
  const closestYIndex = bisector((p) => p.y + p.height / 2).center(sorted, pointerY);
8
10
  const closestYPoint = sorted[closestYIndex];
9
11
  if (!closestYPoint) {
10
12
  return { chunks: [] };
11
13
  }
12
- const selectedPoints = data.filter((p) => p.data.y === closestYPoint.data.y);
14
+ const selectedPoints = visibleData.filter((p) => p.data.y === closestYPoint.data.y);
13
15
  const closestPoints = sort(selectedPoints.filter((p) => p.y === closestYPoint.y), (p) => p.x);
14
16
  let closestPointXValue;
15
17
  const lastPoint = closestPoints[closestPoints.length - 1];
@@ -1,6 +1,6 @@
1
1
  import { ascending, descending, sort } from 'd3-array';
2
2
  import get from 'lodash/get';
3
- import { filterOverlappingLabels, getHtmlLabelConstraintedPosition, getLabelsSize, getSvgLabelConstraintedPosition, getTextSizeFn, } from '../../utils';
3
+ import { filterOverlappingLabels, getHtmlLabelConstraintedPosition, getLabelsSize, getSvgLabelConstraintedPosition, getTextSizeFn, isPointDataLabelEnabled, } from '../../utils';
4
4
  import { getBarYLayout, groupBarYDataByYValue } from '../../utils/bar-y';
5
5
  import { getFormattedValue } from '../../utils/format';
6
6
  export async function prepareBarYData(args) {
@@ -14,6 +14,9 @@ export async function prepareBarYData(args) {
14
14
  shapes: [],
15
15
  labels: [],
16
16
  htmlLabels: [],
17
+ markers: [],
18
+ getHoverMarkers: () => [],
19
+ annotations: [],
17
20
  };
18
21
  }
19
22
  const sortingOptions = get(seriesOptions, 'bar-y.dataSorting');
@@ -139,7 +142,7 @@ export async function prepareBarYData(args) {
139
142
  for (let i = 0; i < result.length; i++) {
140
143
  const prepared = result[i];
141
144
  const dataLabels = prepared.series.dataLabels;
142
- if (dataLabels.enabled) {
145
+ if (isPointDataLabelEnabled({ data: prepared.data, series: prepared.series })) {
143
146
  const data = prepared.data;
144
147
  const content = getFormattedValue(Object.assign({ value: (_a = data.label) !== null && _a !== void 0 ? _a : data.x }, dataLabels));
145
148
  const y = prepared.y + prepared.height / 2;
@@ -209,5 +212,8 @@ export async function prepareBarYData(args) {
209
212
  shapes: result,
210
213
  labels,
211
214
  htmlLabels,
215
+ markers: [],
216
+ getHoverMarkers: () => [],
217
+ annotations: [],
212
218
  };
213
219
  }