@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
@@ -93,14 +93,34 @@ export interface BaseSeries {
93
93
  };
94
94
  }
95
95
  export interface BaseSeriesData<T = MeaningfulAny> {
96
+ /** Individual color for the data chunk (point in scatter, segment in pie, bar etc) */
97
+ color?: string;
96
98
  /**
97
99
  * A reserved subspace to store options and values for customized functionality
98
100
  *
99
101
  * Here you can add additional data for your own event callbacks and formatter callbacks
100
102
  */
101
103
  custom?: T;
102
- /** Individual color for the data chunk (point in scatter, segment in pie, bar etc) */
103
- color?: string;
104
+ /** Per-point overrides for the series data label. */
105
+ dataLabels?: {
106
+ /**
107
+ * Per-point override of `series.dataLabels.enabled`. The point-level value takes precedence:
108
+ * `true` shows the label even when series-level labels are disabled,
109
+ * `false` hides the label even when series-level labels are enabled.
110
+ * @default series.dataLabels.enabled
111
+ */
112
+ enabled?: boolean;
113
+ };
114
+ /** Per-point overrides for the tooltip behavior. */
115
+ tooltip?: {
116
+ /**
117
+ * Per-point override of `series.tooltip.enabled`. The point-level value takes precedence:
118
+ * `true` shows the point in the tooltip even when the series is hidden from the tooltip,
119
+ * `false` hides the point even when the series is shown.
120
+ * @default series.tooltip.enabled
121
+ */
122
+ enabled?: boolean;
123
+ };
104
124
  }
105
125
  export interface BaseSeriesLegend extends ChartLegendItem {
106
126
  /**
@@ -62,8 +62,32 @@ export interface FunnelSeries<T = MeaningfulAny> extends Omit<BaseSeries, 'dataL
62
62
  areaOpacity?: number;
63
63
  };
64
64
  dataLabels?: Omit<BaseDataLabels, 'allowOverlap'> & {
65
- /** Horizontal alignment of the data labels. */
65
+ /**
66
+ * Horizontal alignment of the data labels.
67
+ * @default 'center'
68
+ */
66
69
  align?: 'left' | 'center' | 'right';
70
+ /**
71
+ * Whether to align the data label inside or outside the shape.
72
+ * @default false
73
+ */
74
+ inside?: boolean;
75
+ /**
76
+ * Whether to shrink the funnel shapes to reserve space for outside labels.
77
+ * When true, the plot area is inset on the labelled side so labels do not overlap segments.
78
+ * When false, no space is reserved and labels are clamped to the plot area boundary if they overflow.
79
+ * Only relevant when `inside` is false.
80
+ * @default true
81
+ */
82
+ reserveSpace?: boolean;
83
+ /**
84
+ * The reference area for label alignment. Only relevant when `inside` is false.
85
+ *
86
+ * - `'shape'` - aligns relative to the data shape (e.g., funnel section).
87
+ * - `'plot'` - aligns relative to the chart plot area boundaries.
88
+ * @default 'plot'
89
+ */
90
+ anchor?: 'plot' | 'shape';
67
91
  };
68
92
  /** Individual series legend options. Has higher priority than legend options in widget data */
69
93
  legend?: ChartLegendItem & {
@@ -6,7 +6,7 @@ import type { AreaSeries, AreaSeriesData } from './area';
6
6
  import type { AxisPlotBand, AxisPlotLine, AxisPlotShape, ChartXAxis, ChartYAxis } from './axis';
7
7
  import type { BarXSeries, BarXSeriesData } from './bar-x';
8
8
  import type { BarYSeries, BarYSeriesData } from './bar-y';
9
- import type { ValueFormat } from './base';
9
+ import type { BaseSeries, ValueFormat } from './base';
10
10
  import type { FunnelSeries, FunnelSeriesData } from './funnel';
11
11
  import type { HeatmapSeries, HeatmapSeriesData } from './heatmap';
12
12
  import type { LineSeries, LineSeriesData } from './line';
@@ -31,6 +31,7 @@ export interface TooltipDataChunkPie<T = MeaningfulAny> {
31
31
  type: PieSeries['type'];
32
32
  id: string;
33
33
  name: string;
34
+ tooltip?: BaseSeries['tooltip'];
34
35
  };
35
36
  }
36
37
  export interface TooltipDataChunkScatter<T = MeaningfulAny> {
@@ -39,6 +40,7 @@ export interface TooltipDataChunkScatter<T = MeaningfulAny> {
39
40
  type: ScatterSeries['type'];
40
41
  id: string;
41
42
  name: string;
43
+ tooltip?: BaseSeries['tooltip'];
42
44
  };
43
45
  }
44
46
  export interface TooltipDataChunkLine<T = MeaningfulAny> {
@@ -47,6 +49,7 @@ export interface TooltipDataChunkLine<T = MeaningfulAny> {
47
49
  type: LineSeries['type'];
48
50
  id: string;
49
51
  name: string;
52
+ tooltip?: BaseSeries['tooltip'];
50
53
  };
51
54
  closest?: boolean;
52
55
  }
@@ -56,6 +59,7 @@ export interface TooltipDataChunkArea<T = MeaningfulAny> {
56
59
  type: AreaSeries['type'];
57
60
  id: string;
58
61
  name: string;
62
+ tooltip?: BaseSeries['tooltip'];
59
63
  };
60
64
  }
61
65
  export interface TooltipDataChunkTreemap<T = MeaningfulAny> {
@@ -88,6 +92,7 @@ export interface TooltipDataChunkFunnel<T = MeaningfulAny> {
88
92
  type: FunnelSeries['type'];
89
93
  id: string;
90
94
  name: string;
95
+ tooltip?: BaseSeries['tooltip'];
91
96
  };
92
97
  }
93
98
  export interface TooltipDataChunkXRange<T = MeaningfulAny> {
@@ -7,12 +7,46 @@ type PointLabelSeries = {
7
7
  html: boolean;
8
8
  padding: number;
9
9
  format?: ValueFormat;
10
+ enabled?: boolean;
10
11
  };
11
12
  };
13
+ /**
14
+ * Resolves the effective dataLabels visibility for a point: point-level setting wins
15
+ * over series-level. Both default to `true` when unset.
16
+ */
17
+ export declare function isPointDataLabelEnabled(args: {
18
+ data?: {
19
+ dataLabels?: {
20
+ enabled?: boolean;
21
+ };
22
+ } | null;
23
+ series?: {
24
+ dataLabels?: {
25
+ enabled?: boolean;
26
+ };
27
+ } | null;
28
+ }): boolean;
29
+ /**
30
+ * Returns `true` if the series should run its dataLabels prep pipeline:
31
+ * either series-level is enabled, or at least one point opts in via override.
32
+ */
33
+ export declare function shouldPrepareSeriesDataLabels(series: {
34
+ dataLabels?: {
35
+ enabled?: boolean;
36
+ };
37
+ data?: ReadonlyArray<{
38
+ dataLabels?: {
39
+ enabled?: boolean;
40
+ };
41
+ }>;
42
+ }): boolean;
12
43
  type LabelPoint = {
13
44
  x: number | null;
14
45
  y: number | null;
15
46
  data: {
47
+ dataLabels?: {
48
+ enabled?: boolean;
49
+ };
16
50
  label?: string | number | null;
17
51
  y?: string | number | null;
18
52
  };
@@ -1,5 +1,28 @@
1
1
  import { getFormattedValue } from './format';
2
2
  import { getLabelsSize, getTextSizeFn } from './text';
3
+ /**
4
+ * Resolves the effective dataLabels visibility for a point: point-level setting wins
5
+ * over series-level. Both default to `true` when unset.
6
+ */
7
+ export function isPointDataLabelEnabled(args) {
8
+ var _a, _b, _c, _d, _e;
9
+ const pointEnabled = (_b = (_a = args.data) === null || _a === void 0 ? void 0 : _a.dataLabels) === null || _b === void 0 ? void 0 : _b.enabled;
10
+ if (pointEnabled !== undefined) {
11
+ return pointEnabled;
12
+ }
13
+ return (_e = (_d = (_c = args.series) === null || _c === void 0 ? void 0 : _c.dataLabels) === null || _d === void 0 ? void 0 : _d.enabled) !== null && _e !== void 0 ? _e : true;
14
+ }
15
+ /**
16
+ * Returns `true` if the series should run its dataLabels prep pipeline:
17
+ * either series-level is enabled, or at least one point opts in via override.
18
+ */
19
+ export function shouldPrepareSeriesDataLabels(series) {
20
+ var _a, _b;
21
+ if ((_a = series.dataLabels) === null || _a === void 0 ? void 0 : _a.enabled) {
22
+ return true;
23
+ }
24
+ return Boolean((_b = series.data) === null || _b === void 0 ? void 0 : _b.some((d) => { var _a; return ((_a = d.dataLabels) === null || _a === void 0 ? void 0 : _a.enabled) === true; }));
25
+ }
3
26
  /**
4
27
  * Shared "above-point" dataLabels algorithm used by line, area, and scatter series.
5
28
  *
@@ -25,6 +48,9 @@ export async function preparePointDataLabels({ series, points, xMax, yAxisTop, i
25
48
  if (point.y === null || point.x === null || isOutsideBounds(point.x, point.y)) {
26
49
  continue;
27
50
  }
51
+ if (!isPointDataLabelEnabled({ data: point.data, series })) {
52
+ continue;
53
+ }
28
54
  const text = getFormattedValue(Object.assign({ value: (_a = point.data.label) !== null && _a !== void 0 ? _a : point.data.y }, series.dataLabels));
29
55
  const anchorY = point.y - anchorYOffset;
30
56
  if (series.dataLabels.html) {
@@ -1,8 +1,8 @@
1
- import type { ShapeData } from '../../hooks/useShapes';
2
1
  import type { TooltipDataChunk } from '../../types';
2
+ import type { TooltipItemData } from '../shapes/types';
3
3
  type GetClosestPointsArgs = {
4
4
  position: [number, number];
5
- shapesData: ShapeData[];
5
+ shapesData: TooltipItemData[];
6
6
  boundsHeight: number;
7
7
  boundsWidth: number;
8
8
  };
@@ -1,34 +1,7 @@
1
1
  import get from 'lodash/get';
2
2
  import groupBy from 'lodash/groupBy';
3
- import { getTooltipData as areaGetTooltipData } from '../shapes/area/get-tooltip-data';
4
- import { getTooltipData as barXGetTooltipData } from '../shapes/bar-x/get-tooltip-data';
5
- import { getTooltipData as barYGetTooltipData } from '../shapes/bar-y/get-tooltip-data';
6
- import { getTooltipData as funnelGetTooltipData } from '../shapes/funnel/get-tooltip-data';
7
- import { getTooltipData as heatmapGetTooltipData } from '../shapes/heatmap/get-tooltip-data';
8
- import { getTooltipData as lineGetTooltipData } from '../shapes/line/get-tooltip-data';
9
- import { getTooltipData as pieGetTooltipData } from '../shapes/pie/get-tooltip-data';
10
- import { getTooltipData as radarGetTooltipData } from '../shapes/radar/get-tooltip-data';
11
- import { getTooltipData as sankeyGetTooltipData } from '../shapes/sankey/get-tooltip-data';
12
- import { getTooltipData as scatterGetTooltipData } from '../shapes/scatter/get-tooltip-data';
13
- import { getTooltipData as treemapGetTooltipData } from '../shapes/treemap/get-tooltip-data';
14
- import { getTooltipData as waterfallGetTooltipData } from '../shapes/waterfall/get-tooltip-data';
15
- import { getTooltipData as xRangeGetTooltipData } from '../shapes/x-range/get-tooltip-data';
16
- import { getClosestPointsByXValue } from './tooltip-helpers';
17
- const tooltipFnByType = {
18
- line: lineGetTooltipData,
19
- area: areaGetTooltipData,
20
- 'bar-x': barXGetTooltipData,
21
- 'bar-y': barYGetTooltipData,
22
- waterfall: waterfallGetTooltipData,
23
- scatter: scatterGetTooltipData,
24
- pie: pieGetTooltipData,
25
- treemap: treemapGetTooltipData,
26
- heatmap: heatmapGetTooltipData,
27
- sankey: sankeyGetTooltipData,
28
- radar: radarGetTooltipData,
29
- funnel: funnelGetTooltipData,
30
- 'x-range': xRangeGetTooltipData,
31
- };
3
+ import { getSeriesPlugin } from '../series/seriesRegistry';
4
+ import { getClosestPointsByXValue, isPointTooltipEnabled } from './tooltip-helpers';
32
5
  function getSeriesType(shapeData) {
33
6
  return (get(shapeData, 'series.type') ||
34
7
  get(shapeData, 'point.series.type') ||
@@ -41,19 +14,26 @@ export function getClosestPoints(args) {
41
14
  const xLookupPoints = [];
42
15
  const groups = groupBy(shapesData, getSeriesType);
43
16
  for (const [seriesType, list] of Object.entries(groups)) {
44
- const fn = tooltipFnByType[seriesType];
45
- if (!fn) {
17
+ let plugin;
18
+ try {
19
+ plugin = getSeriesPlugin(seriesType);
20
+ }
21
+ catch (_a) {
46
22
  continue;
47
23
  }
48
- const { chunks, xLookupPoints: seriesXLookupPoints } = fn({
24
+ const { chunks, xLookupPoints: seriesXLookupPoints } = plugin.getTooltipData({
49
25
  data: list,
50
26
  position,
51
27
  boundsWidth,
52
28
  boundsHeight,
53
29
  });
54
- result.push(...chunks);
30
+ result.push(...chunks.filter((c) => isPointTooltipEnabled(c)));
55
31
  if (seriesXLookupPoints) {
56
- xLookupPoints.push(...seriesXLookupPoints);
32
+ for (const p of seriesXLookupPoints) {
33
+ if (isPointTooltipEnabled(p)) {
34
+ xLookupPoints.push(p);
35
+ }
36
+ }
57
37
  }
58
38
  }
59
39
  if (xLookupPoints.length) {
@@ -30,6 +30,22 @@ export declare function getClosestPointsByXValue(x: number, y: number, points: S
30
30
  subTotal?: number;
31
31
  sourceX?: number;
32
32
  }[];
33
+ /**
34
+ * Resolves the effective tooltip visibility for a point: point-level setting wins
35
+ * over series-level. Both default to `true` when unset.
36
+ */
37
+ export declare function isPointTooltipEnabled(args: {
38
+ data?: {
39
+ tooltip?: {
40
+ enabled?: boolean;
41
+ };
42
+ } | null;
43
+ series?: {
44
+ tooltip?: {
45
+ enabled?: boolean;
46
+ };
47
+ } | null;
48
+ }): boolean;
33
49
  export declare function isInsidePath(args: {
34
50
  path: string;
35
51
  point: [number, number];
@@ -50,6 +50,18 @@ export function getClosestPointsByXValue(x, y, points) {
50
50
  const closestYIndex = getClosestYIndex(closestPoints, y);
51
51
  return closestPoints.map((p, i) => (Object.assign(Object.assign({}, p), { closest: i === closestYIndex })));
52
52
  }
53
+ /**
54
+ * Resolves the effective tooltip visibility for a point: point-level setting wins
55
+ * over series-level. Both default to `true` when unset.
56
+ */
57
+ export function isPointTooltipEnabled(args) {
58
+ var _a, _b, _c, _d, _e;
59
+ const pointEnabled = (_b = (_a = args.data) === null || _a === void 0 ? void 0 : _a.tooltip) === null || _b === void 0 ? void 0 : _b.enabled;
60
+ if (pointEnabled !== undefined) {
61
+ return pointEnabled;
62
+ }
63
+ return (_e = (_d = (_c = args.series) === null || _c === void 0 ? void 0 : _c.tooltip) === null || _d === void 0 ? void 0 : _d.enabled) !== null && _e !== void 0 ? _e : true;
64
+ }
53
65
  export function isInsidePath(args) {
54
66
  const { path, point, width, height, strokeWidth } = args;
55
67
  const canvas = document.createElement('canvas');
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import type { AnnotationAnchor } from '../../core/series/types';
3
+ interface Props {
4
+ annotations: AnnotationAnchor[];
5
+ boundsWidth: number;
6
+ boundsHeight: number;
7
+ }
8
+ export declare const AnnotationLayer: ({ annotations, boundsWidth, boundsHeight }: Props) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { select } from 'd3-selection';
3
+ import { renderAnnotations } from '../../core/shapes/annotation';
4
+ export const AnnotationLayer = ({ annotations, boundsWidth, boundsHeight }) => {
5
+ const ref = React.useRef(null);
6
+ React.useEffect(() => {
7
+ if (!ref.current)
8
+ return;
9
+ renderAnnotations({
10
+ anchors: annotations,
11
+ container: select(ref.current),
12
+ plotWidth: boundsWidth,
13
+ plotHeight: boundsHeight,
14
+ });
15
+ }, [annotations, boundsWidth, boundsHeight]);
16
+ return React.createElement("g", { ref: ref });
17
+ };
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import type { Dispatch } from 'd3-dispatch';
3
+ import type { SeriesShapeData } from '../../core/shapes/types';
4
+ interface Props {
5
+ preparedData: SeriesShapeData[];
6
+ dispatcher?: Dispatch<object>;
7
+ namespace: string;
8
+ }
9
+ export declare const HoverMarkerLayer: ({ preparedData, dispatcher, namespace }: Props) => React.JSX.Element;
10
+ export {};
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import { select } from 'd3-selection';
3
+ import { renderHoverMarkers } from '../../core/shapes/marker';
4
+ export const HoverMarkerLayer = ({ preparedData, dispatcher, namespace }) => {
5
+ const ref = React.useRef(null);
6
+ React.useEffect(() => {
7
+ if (!ref.current)
8
+ return () => { };
9
+ const container = select(ref.current);
10
+ function handleHover(data) {
11
+ var _a;
12
+ const hoveredData = (_a = data === null || data === void 0 ? void 0 : data.map((d) => d.data)) !== null && _a !== void 0 ? _a : [];
13
+ const items = preparedData.flatMap((d) => d.getHoverMarkers(hoveredData));
14
+ renderHoverMarkers(container, items);
15
+ }
16
+ dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on(`hover-shape.${namespace}`, handleHover);
17
+ return () => {
18
+ dispatcher === null || dispatcher === void 0 ? void 0 : dispatcher.on(`hover-shape.${namespace}`, null);
19
+ };
20
+ }, [preparedData, dispatcher, namespace]);
21
+ return React.createElement("g", { ref: ref });
22
+ };
@@ -0,0 +1,7 @@
1
+ import React from 'react';
2
+ import type { MarkerItem } from '../../core/shapes/types';
3
+ interface Props {
4
+ markers: MarkerItem[];
5
+ }
6
+ export declare const MarkerLayer: ({ markers }: Props) => React.JSX.Element;
7
+ export {};
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { select } from 'd3-selection';
3
+ import { renderMarkers } from '../../core/shapes/marker';
4
+ export const MarkerLayer = ({ markers }) => {
5
+ const ref = React.useRef(null);
6
+ React.useEffect(() => {
7
+ if (ref.current) {
8
+ renderMarkers(select(ref.current), markers);
9
+ }
10
+ }, [markers]);
11
+ return React.createElement("g", { ref: ref });
12
+ };
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+ import type { Dispatch } from 'd3-dispatch';
3
+ import type { SeriesPlugin } from '../../core/series/plugin';
4
+ import type { PreparedSeriesOptions } from '../../core/series/types';
5
+ import type { SeriesShapeData } from '../../core/shapes/types';
6
+ interface Props {
7
+ boundsHeight: number;
8
+ boundsWidth: number;
9
+ clipPathId?: string;
10
+ dispatcher?: Dispatch<object>;
11
+ htmlLayout: HTMLElement | null;
12
+ namespace: string;
13
+ plugin: SeriesPlugin;
14
+ preparedData: SeriesShapeData[];
15
+ seriesOptions: PreparedSeriesOptions;
16
+ }
17
+ export declare const SeriesShapes: ({ boundsHeight, boundsWidth, clipPathId, dispatcher, htmlLayout, namespace, plugin, preparedData, seriesOptions, }: Props) => React.JSX.Element;
18
+ export {};
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import { block } from '../../utils';
3
+ import { AnnotationLayer } from './AnnotationLayer';
4
+ import { HoverMarkerLayer } from './HoverMarkerLayer';
5
+ import { HtmlLayer } from './HtmlLayer';
6
+ import { MarkerLayer } from './MarkerLayer';
7
+ export const SeriesShapes = ({ boundsHeight, boundsWidth, clipPathId, dispatcher, htmlLayout, namespace, plugin, preparedData, seriesOptions, }) => {
8
+ const b = block(plugin.type);
9
+ const ref = React.useRef(null);
10
+ React.useEffect(() => {
11
+ var _a;
12
+ if (!ref.current)
13
+ return () => { };
14
+ return ((_a = plugin.renderShapes({
15
+ plot: ref.current,
16
+ preparedData,
17
+ seriesOptions,
18
+ boundsWidth,
19
+ boundsHeight,
20
+ dispatcher,
21
+ })) !== null && _a !== void 0 ? _a : undefined);
22
+ }, [boundsHeight, boundsWidth, dispatcher, plugin, preparedData, seriesOptions]);
23
+ const markers = React.useMemo(() => preparedData.flatMap((d) => d.markers), [preparedData]);
24
+ const annotations = React.useMemo(() => preparedData.flatMap((d) => d.annotations), [preparedData]);
25
+ const htmlLayerData = React.useMemo(() => ({ htmlElements: preparedData.flatMap((d) => d.htmlLabels) }), [preparedData]);
26
+ return (React.createElement(React.Fragment, null,
27
+ React.createElement("g", { ref: ref, className: b(), clipPath: clipPathId ? `url(#${clipPathId})` : undefined }),
28
+ React.createElement(MarkerLayer, { markers: markers }),
29
+ React.createElement(HoverMarkerLayer, { preparedData: preparedData, dispatcher: dispatcher, namespace: namespace }),
30
+ React.createElement(AnnotationLayer, { annotations: annotations, boundsWidth: boundsWidth, boundsHeight: boundsHeight }),
31
+ React.createElement(HtmlLayer, { preparedData: htmlLayerData, htmlLayout: htmlLayout })));
32
+ };
@@ -1,26 +1,14 @@
1
1
  import React from 'react';
2
2
  import type { Dispatch } from 'd3-dispatch';
3
- import type { SeriesType } from '../../core/constants';
4
3
  import type { PreparedSplit } from '../../core/layout/split-types';
5
4
  import type { ChartScale } from '../../core/scales/types';
6
5
  import type { PreparedSeries, PreparedSeriesOptions } from '../../core/series/types';
7
- import type { PreparedAreaData } from '../../core/shapes/area/types';
8
- import type { PreparedBarXData } from '../../core/shapes/bar-x/types';
9
- import type { PreparedBarYData } from '../../core/shapes/bar-y/types';
10
- import type { PreparedFunnelData } from '../../core/shapes/funnel/types';
11
- import type { PreparedHeatmapData } from '../../core/shapes/heatmap/types';
12
- import type { PreparedLineData } from '../../core/shapes/line/types';
13
- import type { PreparedPieData } from '../../core/shapes/pie/types';
14
- import type { PreparedRadarData } from '../../core/shapes/radar/types';
15
- import type { PreparedSankeyData } from '../../core/shapes/sankey/types';
16
- import type { PreparedScatterData } from '../../core/shapes/scatter/types';
17
- import type { PreparedWaterfallData } from '../../core/shapes/waterfall/types';
18
- import type { PreparedXRangeData } from '../../core/shapes/x-range/types';
6
+ import type { TooltipItemData } from '../../core/shapes/types';
19
7
  import type { ZoomState } from '../../core/zoom/types';
20
8
  import type { PreparedXAxis, PreparedYAxis } from '../useAxis/types';
21
9
  import './styles.css';
22
- export type ShapeData = PreparedBarXData | PreparedBarYData | PreparedScatterData | PreparedLineData | PreparedPieData | PreparedAreaData | PreparedWaterfallData | PreparedSankeyData | PreparedRadarData | PreparedHeatmapData | PreparedFunnelData | PreparedXRangeData;
23
- export type ClipPathBySeriesType = Partial<Record<SeriesType, boolean>>;
10
+ export type { TooltipItemData };
11
+ export type ClipPathBySeriesType = Partial<Record<string, boolean>>;
24
12
  type Args = {
25
13
  boundsWidth: number;
26
14
  boundsHeight: number;
@@ -41,11 +29,10 @@ type Args = {
41
29
  };
42
30
  export declare function getShapes(args: Args): Promise<{
43
31
  shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
44
- shapesData: ShapeData[];
32
+ shapesData: TooltipItemData[];
45
33
  }>;
46
34
  export declare const useShapes: (args: Args) => {
47
35
  shapes: React.ReactElement<any, string | React.JSXElementConstructor<any>>[];
48
- shapesData: ShapeData[];
36
+ shapesData: TooltipItemData[];
49
37
  shapesReady: boolean;
50
38
  };
51
- export {};