@octanejs/recharts 0.1.16 → 0.1.18

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 (88) hide show
  1. package/package.json +4 -4
  2. package/src/animation/CSSTransitionAnimate.tsrx +142 -0
  3. package/src/cartesian/Area.tsrx +1096 -0
  4. package/src/cartesian/Area.tsrx.d.ts +340 -0
  5. package/src/cartesian/AreaRevealShape.tsrx +202 -0
  6. package/src/cartesian/CartesianGrid.tsrx +643 -0
  7. package/src/cartesian/CartesianGrid.tsrx.d.ts +219 -0
  8. package/src/cartesian/ErrorBar.tsrx +322 -0
  9. package/src/cartesian/ErrorBar.tsrx.d.ts +131 -0
  10. package/src/cartesian/Funnel.tsrx +833 -0
  11. package/src/cartesian/Funnel.tsrx.d.ts +274 -0
  12. package/src/cartesian/ReferenceLine.tsrx +452 -0
  13. package/src/cartesian/ReferenceLine.tsrx.d.ts +178 -0
  14. package/src/cartesian/Scatter.tsrx +1076 -0
  15. package/src/cartesian/Scatter.tsrx.d.ts +351 -0
  16. package/src/cartesian/ZAxis.tsrx +148 -0
  17. package/src/cartesian/ZAxis.tsrx.d.ts +102 -0
  18. package/src/chart/AreaChart.tsrx +22 -0
  19. package/src/chart/AreaChart.tsrx.d.ts +12 -0
  20. package/src/chart/ComposedChart.tsrx +22 -0
  21. package/src/chart/ComposedChart.tsrx.d.ts +12 -0
  22. package/src/chart/FunnelChart.tsrx +22 -0
  23. package/src/chart/FunnelChart.tsrx.d.ts +12 -0
  24. package/src/chart/PieChart.tsrx +31 -0
  25. package/src/chart/PieChart.tsrx.d.ts +31 -0
  26. package/src/chart/PolarChart.tsrx +121 -0
  27. package/src/chart/RadarChart.tsrx +53 -0
  28. package/src/chart/RadarChart.tsrx.d.ts +31 -0
  29. package/src/chart/RadialBarChart.tsrx +31 -0
  30. package/src/chart/RadialBarChart.tsrx.d.ts +31 -0
  31. package/src/chart/Sankey.tsrx +1542 -0
  32. package/src/chart/Sankey.tsrx.d.ts +253 -0
  33. package/src/chart/ScatterChart.tsrx +22 -0
  34. package/src/chart/ScatterChart.tsrx.d.ts +12 -0
  35. package/src/chart/SunburstChart.tsrx +495 -0
  36. package/src/chart/SunburstChart.tsrx.d.ts +146 -0
  37. package/src/chart/types.ts +19 -0
  38. package/src/component/Cursor.tsrx +157 -0
  39. package/src/component/DefaultLegendContent.tsrx +288 -0
  40. package/src/component/DefaultLegendContent.tsrx.d.ts +125 -0
  41. package/src/component/DefaultTooltipContent.tsrx +215 -0
  42. package/src/component/DefaultTooltipContent.tsrx.d.ts +87 -0
  43. package/src/component/Legend.tsrx +302 -0
  44. package/src/component/Legend.tsrx.d.ts +88 -0
  45. package/src/component/ResponsiveContainer.ts +1 -22
  46. package/src/component/ResponsiveContainer.tsrx +171 -0
  47. package/src/component/ResponsiveContainer.tsrx.d.ts +81 -0
  48. package/src/component/Tooltip.tsrx +425 -0
  49. package/src/component/Tooltip.tsrx.d.ts +246 -0
  50. package/src/component/TooltipBoundingBox.tsrx +135 -0
  51. package/src/context/CellsContext.ts +12 -0
  52. package/src/context/legendPayloadContext.tsrx +11 -0
  53. package/src/context/useTooltipAxis.ts +20 -0
  54. package/src/index.d.ts +236 -0
  55. package/src/index.ts +67 -0
  56. package/src/polar/Pie.tsrx +1224 -0
  57. package/src/polar/Pie.tsrx.d.ts +436 -0
  58. package/src/polar/PolarAngleAxis.tsrx +554 -0
  59. package/src/polar/PolarAngleAxis.tsrx.d.ts +215 -0
  60. package/src/polar/PolarGrid.tsrx +317 -0
  61. package/src/polar/PolarGrid.tsrx.d.ts +117 -0
  62. package/src/polar/PolarRadiusAxis.tsrx +463 -0
  63. package/src/polar/PolarRadiusAxis.tsrx.d.ts +209 -0
  64. package/src/polar/Radar.tsrx +696 -0
  65. package/src/polar/Radar.tsrx.d.ts +215 -0
  66. package/src/polar/RadialBar.tsrx +887 -0
  67. package/src/polar/RadialBar.tsrx.d.ts +340 -0
  68. package/src/state/ReportPolarOptions.tsrx +11 -0
  69. package/src/state/selectors/areaSelectors.ts +257 -0
  70. package/src/state/selectors/funnelSelectors.ts +86 -0
  71. package/src/state/selectors/pieSelectors.ts +134 -0
  72. package/src/state/selectors/polarGridSelectors.ts +43 -0
  73. package/src/state/selectors/polarScaleSelectors.ts +159 -0
  74. package/src/state/selectors/polarSelectors.ts +198 -0
  75. package/src/state/selectors/radarSelectors.ts +228 -0
  76. package/src/state/selectors/radialBarSelectors.ts +511 -0
  77. package/src/state/selectors/scatterSelectors.ts +168 -0
  78. package/src/util/FunnelUtils.tsrx +19 -0
  79. package/src/util/RadialBarUtils.tsrx +29 -0
  80. package/src/util/ScatterUtils.tsrx +34 -0
  81. package/src/util/cursor/getCursorPoints.ts +45 -0
  82. package/src/util/cursor/getCursorRectangle.ts +28 -0
  83. package/src/util/cursor/getRadialCursorPoints.ts +31 -0
  84. package/src/util/payload/getUniqPayload.ts +28 -0
  85. package/src/util/scale/CartesianScaleHelper.ts +71 -0
  86. package/src/util/tooltip/translate.ts +168 -0
  87. package/src/util/types.ts +3 -0
  88. package/src/util/useElementOffset.ts +147 -0
@@ -0,0 +1,1076 @@
1
+ import * as React from 'octane';
2
+ import { MutableRefObject, ReactElement, ReactNode, useMemo, useRef } from 'octane';
3
+
4
+ import { clsx } from 'clsx';
5
+ import { Layer } from '../container/Layer';
6
+ import {
7
+ CartesianLabelListContextProvider,
8
+ CartesianLabelListEntry,
9
+ ImplicitLabelListType,
10
+ LabelListFromLabelProp,
11
+ } from '../component/LabelList';
12
+ import { Curve, CurveType, Props as CurveProps } from '../shape/Curve';
13
+ import { ErrorBarDataItem, ErrorBarDataPointFormatter, ErrorBarDirection } from './ErrorBar';
14
+ import { getLinearRegression, interpolate, isNullish } from '../util/DataUtils';
15
+ import { getCateCoordinateOfLine, getTooltipNameProp, getValueByDataKey } from '../util/ChartUtils';
16
+ import {
17
+ ActiveShape,
18
+ adaptEventsOfChild,
19
+ AnimationDuration,
20
+ EasingInput,
21
+ Coordinate,
22
+ DataConsumer,
23
+ DataKey,
24
+ DataProvider,
25
+ isNonEmptyArray,
26
+ LegendType,
27
+ NonEmptyArray,
28
+ NullableCoordinate,
29
+ PresentationAttributesAdaptChildEvent,
30
+ ShapeAnimationProps,
31
+ SymbolType,
32
+ TickItem,
33
+ TrapezoidViewBox,
34
+ CartesianLayout,
35
+ } from '../util/types';
36
+ import { Formatter, TooltipType } from '../component/DefaultTooltipContent';
37
+ import { ScatterShapeProps, ScatterSymbol } from '../util/ScatterUtils';
38
+ import { InnerSymbolsProp } from '../shape/Symbols';
39
+ import type { LegendPayload } from '../component/DefaultLegendContent';
40
+ import {
41
+ useMouseClickItemDispatch,
42
+ useMouseEnterItemDispatch,
43
+ useMouseLeaveItemDispatch,
44
+ } from '../context/tooltipContext';
45
+ import {
46
+ TooltipPayload,
47
+ TooltipPayloadConfiguration,
48
+ TooltipPayloadEntry,
49
+ } from '../state/tooltipSlice';
50
+ import { SetTooltipEntrySettings } from '../state/SetTooltipEntrySettings';
51
+ import { SetErrorBarContext } from '../context/ErrorBarContext';
52
+ import { AxisId } from '../state/cartesianAxisSlice';
53
+ import { GraphicalItemClipPath, useNeedsClip } from './GraphicalItemClipPath';
54
+ import { selectScatterPoints } from '../state/selectors/scatterSelectors';
55
+ import { useAppSelector } from '../state/hooks';
56
+ import { RechartsRootState } from '../state/store';
57
+ import { BaseAxisWithScale, implicitZAxis, ZAxisWithScale } from '../state/selectors/axisSelectors';
58
+ import { useIsPanorama } from '../context/PanoramaContext';
59
+ import { selectActiveTooltipIndex } from '../state/selectors/tooltipSelectors';
60
+ import { SetLegendPayload } from '../state/SetLegendPayload';
61
+ import { DATA_ITEM_GRAPHICAL_ITEM_ID_ATTRIBUTE_NAME } from '../util/Constants';
62
+ import { resolveDefaultProps } from '../util/resolveDefaultProps';
63
+ import { RegisterGraphicalItemId } from '../context/RegisterGraphicalItemId';
64
+ import type { ScatterSettings } from '../state/types/ScatterSettings';
65
+ import { SetCartesianGraphicalItem } from '../state/SetGraphicalItem';
66
+ import {
67
+ svgPropertiesNoEvents,
68
+ svgPropertiesNoEventsFromUnknown,
69
+ } from '../util/svgPropertiesNoEvents';
70
+ import { useCartesianChartLayout, useViewBox } from '../context/chartLayoutContext';
71
+ import {
72
+ AnimatedItems,
73
+ AnimationInterpolateFn,
74
+ useAnimationCallbacks,
75
+ } from '../animation/AnimatedItems';
76
+ import { AnimationMatchByProp, matchAppend } from '../animation/matchBy';
77
+ import { WithIdRequired, WithoutId } from '../util/useUniqueId';
78
+ import { GraphicalItemId } from '../state/graphicalItemsSlice';
79
+ import { ZIndexable, ZIndexLayer } from '../zIndex/ZIndexLayer';
80
+ import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
81
+ import { propsAreEqual } from '../util/propsAreEqual';
82
+ import { ChartData } from '../state/chartDataSlice';
83
+ import { CellsContext, useCellRegistry } from '../context/CellsContext';
84
+
85
+ export interface ScatterPointNode {
86
+ x?: number | string;
87
+ y?: number | string;
88
+ z?: number | string;
89
+ }
90
+
91
+ /**
92
+ * Scatter coordinates are nullable because sometimes the point value is out of the domain,
93
+ * and we can't compute a valid coordinate for it.
94
+ *
95
+ * Scatter -> Symbol ignores points with null cx or cy so those won't render if using the default shapes.
96
+ * However: the points are exposed via various props and can be used in custom shapes so we keep them around.
97
+ */
98
+ export interface ScatterPointItem {
99
+ /**
100
+ * The x coordinate of the point center in pixels.
101
+ */
102
+ cx: number | undefined;
103
+ /**
104
+ * The y coordinate of the point center in pixels.
105
+ */
106
+ cy: number | undefined;
107
+ /**
108
+ * The x coordinate (in pixels) of the top-left corner of the rectangle that wraps the point.
109
+ */
110
+ x: number | undefined;
111
+ /**
112
+ * The y coordinate (in pixels) of the top-left corner of the rectangle that wraps the point.
113
+ */
114
+ y: number | undefined;
115
+ /**
116
+ * ScatterPointItem size is an abstract number that is used to calculate the radius of the point.
117
+ * It's not the radius itself, but rather a value that is used to calculate the radius.
118
+ * Interacts with the zAxis range.
119
+ */
120
+ size: number;
121
+ /**
122
+ * Width of the point in pixels.
123
+ */
124
+ width: number;
125
+ /**
126
+ * Height of the point in pixels.
127
+ */
128
+ height: number;
129
+ node: ScatterPointNode;
130
+ payload?: any;
131
+ tooltipPayload?: TooltipPayload;
132
+ tooltipPosition: Coordinate;
133
+ }
134
+
135
+ export type ScatterCustomizedShape =
136
+ ActiveShape<ScatterShapeProps & InnerSymbolsProp, SVGPathElement> | SymbolType;
137
+
138
+ /**
139
+ * Internal props, combination of external props + defaultProps + private Recharts state
140
+ */
141
+ interface ScatterInternalProps extends ZIndexable {
142
+ data?: ChartData;
143
+ xAxisId: string | number;
144
+ yAxisId: string | number;
145
+ zAxisId: string | number;
146
+ dataKey?: DataKey<any>;
147
+ line?: | ReactElement<SVGElement>
148
+ | ((props: any) => ReactElement<SVGElement>)
149
+ | CurveProps
150
+ | boolean;
151
+ lineType: 'fitting' | 'joint';
152
+ lineJointType: CurveType;
153
+ legendType: LegendType;
154
+ tooltipType?: TooltipType;
155
+ formatter?: Formatter;
156
+ className?: string;
157
+ name?: string;
158
+ activeShape?: ScatterCustomizedShape;
159
+ shape: ScatterCustomizedShape;
160
+ points: ReadonlyArray<ScatterPointItem>;
161
+ hide: boolean;
162
+ label?: ImplicitLabelListType;
163
+ isAnimationActive: boolean | 'auto';
164
+ animationBegin: number;
165
+ animationDuration: AnimationDuration;
166
+ animationEasing: EasingInput;
167
+ animationInterpolateFn: AnimationInterpolateFn<ScatterPointItem, CartesianLayout>;
168
+ animationMatchBy: AnimationMatchByProp<ScatterPointItem>;
169
+ onAnimationStart?: () => void;
170
+ onAnimationEnd?: () => void;
171
+ needClip: boolean;
172
+ id: GraphicalItemId;
173
+ children?: ReactNode;
174
+ }
175
+
176
+ /**
177
+ * External props, intended for end users to fill in
178
+ */
179
+ interface ScatterProps<DataPointType = any, DataValueType = any> extends DataProvider<
180
+ DataPointType
181
+ >, DataConsumer<DataPointType, DataValueType>, ZIndexable {
182
+ /**
183
+ * Unique identifier of this component.
184
+ * Used as an HTML attribute `id`, and also to identify this element internally.
185
+ *
186
+ * If undefined, Recharts will generate a unique ID automatically.
187
+ */
188
+ id?: string;
189
+ /**
190
+ * The id of XAxis which is corresponding to the data. Required when there are multiple XAxes.
191
+ * @defaultValue 0
192
+ */
193
+ xAxisId?: AxisId;
194
+ /**
195
+ * The id of YAxis which is corresponding to the data. Required when there are multiple YAxes.
196
+ * @defaultValue 0
197
+ */
198
+ yAxisId?: AxisId;
199
+ /**
200
+ * The id of ZAxis which is corresponding to the data. Required when there are multiple ZAxes.
201
+ *
202
+ * ZAxis does not render directly, has no ticks and no tick line.
203
+ * It is used to control the size of each scatter point.
204
+ *
205
+ * @defaultValue 0
206
+ * @see {@link https://recharts.github.io/en-US/examples/ThreeDimScatterChart/ Scatter chart with Z axis}
207
+ */
208
+ zAxisId?: AxisId;
209
+ /**
210
+ * Renders line connecting individual points.
211
+ * Options:
212
+ * - `false`: no line is drawn.
213
+ * - `true`: a default line is drawn.
214
+ * - `ReactElement`: the option is the custom line element.
215
+ * - `function`: the function will be called to render customized line.
216
+ * - `object`: the option is the props of Curve element.
217
+ *
218
+ * Also see the `lineType` prop which controls how is this line calculated.
219
+ *
220
+ * @defaultValue false
221
+ * @example <Scatter line />
222
+ * @example <Scatter line={CustomizedLineComponent} />
223
+ * @example <Scatter line={{ strokeDasharray: '5 5' }} />
224
+ *
225
+ * @see {@link https://recharts.github.io/en-US/examples/JointLineScatterChart/ Scatter chart with joint line}
226
+ */
227
+ line?: | ReactElement<SVGElement>
228
+ | ((props: any) => ReactElement<SVGElement>)
229
+ | CurveProps
230
+ | boolean;
231
+ /**
232
+ * Determines calculation method of the line if the `line` prop is set.
233
+ * Options:
234
+ * - `'joint'`: line will be generated by connecting all the points.
235
+ * - `'fitting'`: line will be generated by fitting algorithm (linear regression).
236
+ *
237
+ * Has no effect if `line` prop is not set or is false.
238
+ *
239
+ * @defaultValue joint
240
+ * @example <Scatter line lineType="fitting" />
241
+ * @see {@link https://recharts.github.io/en-US/examples/JointLineScatterChart/ Scatter chart with joint line}
242
+ */
243
+ lineType?: 'fitting' | 'joint';
244
+ /**
245
+ * Determines the shape of joint line.
246
+ * Same as `type` prop on Curve, Line and Area components.
247
+ *
248
+ * Has no effect if `line` prop is not set or is false or if `lineType` is 'fitting'.
249
+ *
250
+ * @defaultValue linear
251
+ * @see {@link https://recharts.github.io/en-US/examples/JointLineScatterChart/ Scatter chart with joint line}
252
+ */
253
+ lineJointType?: CurveType;
254
+ /**
255
+ * The type of icon in legend.
256
+ * If set to 'none', no legend item will be rendered.
257
+ *
258
+ * @defaultValue 'circle'
259
+ * @example <Scatter legendType="diamond" />
260
+ */
261
+ legendType?: LegendType;
262
+ tooltipType?: TooltipType;
263
+ /**
264
+ * Formats the value displayed in the tooltip for this Scatter.
265
+ * When set, takes precedence over the `formatter` prop on the Tooltip component.
266
+ */
267
+ formatter?: Formatter;
268
+ className?: string;
269
+ /**
270
+ * The name of data.
271
+ * This option will be used in tooltip and legend to represent this graphical item.
272
+ * If no value was set to this option, the value of dataKey will be used alternatively.
273
+ */
274
+ name?: string;
275
+ /**
276
+ * This component is rendered when this graphical item is activated
277
+ * (could be by mouse hover, touch, keyboard, programmatically).
278
+ *
279
+ * @see {@link https://recharts.github.io/en-US/examples/SimpleScatterChart/ Scatter chart with custom active shape}
280
+ * @example <Scatter activeShape={{ fill: 'red' }} />
281
+ */
282
+ activeShape?: ScatterCustomizedShape;
283
+ /**
284
+ * Determines the shape of individual data points.
285
+ * - Can be one of the predefined shapes as a string, which will be passed to {@link Symbols} component.
286
+ * - If set a ReactElement, the shape of point can be customized.
287
+ * - If set a function, the function will be called to render customized shape.
288
+ * - During animations, the function shape also receives `animationElapsedTime`, `isAnimating`, and `isEntrance`.
289
+ * @defaultValue circle
290
+ *
291
+ * @example <Scatter shape={CustomizedShapeComponent} />
292
+ * @example <Scatter shape="diamond" />
293
+ *
294
+ * @see {@link https://recharts.github.io/en-US/examples/JointLineScatterChart/ Scatter chart with custom shapes}
295
+ */
296
+ shape?: ScatterCustomizedShape;
297
+ /**
298
+ * Hides the whole graphical element when true.
299
+ *
300
+ * Hiding an element is different from removing it from the chart:
301
+ * Hidden graphical elements are still visible in Legend,
302
+ * and can be included in axis domain calculations,
303
+ * depending on `includeHidden` props of your XAxis/YAxis.
304
+ *
305
+ * @defaultValue false
306
+ */
307
+ hide?: boolean;
308
+ /**
309
+ * Renders one label for each data point. Options:
310
+ * - `true`: renders default labels;
311
+ * - `false`: no labels are rendered;
312
+ * - `object`: the props of LabelList component;
313
+ * - `ReactElement`: a custom SVG label element, such as `<text>` or `<g>`.
314
+ * HTML elements such as `<div>` are not valid inside the chart SVG and may trigger React DOM warnings.
315
+ * - `function`: a render function of custom label.
316
+ *
317
+ * @defaultValue false
318
+ */
319
+ label?: ImplicitLabelListType;
320
+ /**
321
+ * If set false, animation of Scatter points will be disabled.
322
+ * If set "auto", the animation will be disabled in SSR and will respect the user's prefers-reduced-motion system preference for accessibility.
323
+ * @defaultValue 'auto'
324
+ */
325
+ isAnimationActive?: boolean | 'auto';
326
+ /**
327
+ * Specifies when the animation should begin, the unit of this option is ms.
328
+ * @defaultValue 0
329
+ */
330
+ animationBegin?: number;
331
+ /**
332
+ * Specifies the duration of animation, the unit of this option is ms.
333
+ * @defaultValue 400
334
+ */
335
+ animationDuration?: AnimationDuration;
336
+ /**
337
+ * The type of easing function.
338
+ * @defaultValue 'linear'
339
+ */
340
+ animationEasing?: EasingInput;
341
+ /**
342
+ * Custom animation function for interpolating data items.
343
+ * When provided, this replaces the default animation interpolation.
344
+ *
345
+ * @param prevItems The items from the previous animation frame, or null on first render
346
+ * @param nextItems The target items to animate towards
347
+ * @param animationElapsedTime A normalized time value (0 = start, 1 = end)
348
+ * @returns The interpolated items at time animationElapsedTime
349
+ *
350
+ * @since 3.9
351
+ * @see {@link https://recharts.github.io/en-US/guide/animations/ Animations guide}
352
+ */
353
+ animationInterpolateFn?: AnimationInterpolateFn<ScatterPointItem, CartesianLayout>;
354
+ /**
355
+ * Strategy for matching previous items to next items during animation.
356
+ * Determines how Recharts pairs old data points with new data points
357
+ * to create smooth transitions.
358
+ *
359
+ * - `matchAppend` (default): match sequentially by index and treat newly appended items as new
360
+ * - `matchByIndex`: match by array position with proportional stretching
361
+ * - `matchByDataKey('someKey')`: match by a data key from the payload
362
+ * - Custom function `(item, index) => key`: match by the returned key
363
+ *
364
+ * @defaultValue append
365
+ * @see matchByIndex
366
+ * @see matchByDataKey
367
+ * @see matchAppend
368
+ *
369
+ * @since 3.9
370
+ * @see {@link https://recharts.github.io/en-US/guide/animations/ Animations guide}
371
+ */
372
+ animationMatchBy?: AnimationMatchByProp<ScatterPointItem>;
373
+ /**
374
+ * Called when the Scatter animation starts.
375
+ */
376
+ onAnimationStart?: () => void;
377
+ /**
378
+ * Called when the Scatter animation finishes.
379
+ */
380
+ onAnimationEnd?: () => void;
381
+ /**
382
+ * Z-Index of this component and its children. The higher the value,
383
+ * the more on top it will be rendered.
384
+ * Components with higher zIndex will appear in front of components with lower zIndex.
385
+ * If undefined or 0, the content is rendered in the default layer without portals.
386
+ *
387
+ * @since 3.4
388
+ * @defaultValue 600
389
+ * @see {@link https://recharts.github.io/en-US/guide/zIndex/ Z-Index and layers guide}
390
+ */
391
+ zIndex?: number;
392
+ children?: ReactNode;
393
+ }
394
+
395
+ /**
396
+ * Because of naming conflict, we are forced to ignore certain (valid) SVG attributes.
397
+ */
398
+ type BaseScatterSvgProps =
399
+ Omit<
400
+ PresentationAttributesAdaptChildEvent<ScatterPointItem, SVGGraphicsElement>,
401
+ 'points' | 'ref' | 'children' | 'dangerouslySetInnerHTML'
402
+ >;
403
+
404
+ type InternalProps = BaseScatterSvgProps & ScatterInternalProps;
405
+
406
+ export type Props<DataPointType = any, ValueAxisType = any> =
407
+ BaseScatterSvgProps & ScatterProps<DataPointType, ValueAxisType>;
408
+
409
+ const computeLegendPayloadFromScatterProps = (props: Props): ReadonlyArray<LegendPayload> => {
410
+ const { dataKey, name, fill, legendType, hide } = props;
411
+ return [
412
+ {
413
+ inactive: hide,
414
+ dataKey,
415
+ type: legendType,
416
+ color: fill,
417
+ value: getTooltipNameProp(name, dataKey),
418
+ payload: props,
419
+ },
420
+ ];
421
+ };
422
+
423
+ type InputRequiredToComputeTooltipEntrySettings = {
424
+ dataKey?: DataKey<any> | undefined;
425
+ points?: ReadonlyArray<ScatterPointItem>;
426
+ stroke?: string;
427
+ strokeWidth?: number | string;
428
+ fill?: string;
429
+ name?: string;
430
+ hide?: boolean;
431
+ formatter?: Formatter;
432
+ tooltipType?: TooltipType;
433
+ id: GraphicalItemId;
434
+ };
435
+
436
+ const SetScatterTooltipEntrySettings = React.memo(({
437
+ dataKey,
438
+ points,
439
+ stroke,
440
+ strokeWidth,
441
+ fill,
442
+ name,
443
+ hide,
444
+ formatter,
445
+ tooltipType,
446
+ id,
447
+ }: InputRequiredToComputeTooltipEntrySettings) => {
448
+ const tooltipEntrySettings: TooltipPayloadConfiguration = {
449
+ dataDefinedOnItem: points?.map((p: ScatterPointItem) => p.tooltipPayload),
450
+ getPosition: (index) => points?.[Number(index)]?.tooltipPosition,
451
+ settings: {
452
+ stroke,
453
+ strokeWidth,
454
+ fill,
455
+ nameKey: undefined,
456
+ dataKey,
457
+ name: getTooltipNameProp(name, dataKey),
458
+ hide,
459
+ type: tooltipType,
460
+ color: fill,
461
+ unit: '', // why doesn't Scatter support unit?
462
+ formatter,
463
+ graphicalItemId: id,
464
+ },
465
+ };
466
+ return <SetTooltipEntrySettings tooltipEntrySettings={tooltipEntrySettings} />;
467
+ });
468
+
469
+ type ScatterSymbolsProps =
470
+ ShapeAnimationProps & {
471
+ points: ReadonlyArray<ScatterPointItem>;
472
+ showLabels: boolean;
473
+ allOtherScatterProps: InternalProps;
474
+ };
475
+
476
+ function ScatterLine({
477
+ points,
478
+ props,
479
+ }: {
480
+ points: NonEmptyArray<ScatterPointItem>;
481
+ props: WithoutId<InternalProps>;
482
+ }) {
483
+ const { line, lineType, lineJointType } = props;
484
+
485
+ if (!line) {
486
+ return null;
487
+ }
488
+
489
+ const scatterProps = svgPropertiesNoEvents(props);
490
+ const customLineProps = svgPropertiesNoEventsFromUnknown(line);
491
+ let linePoints: ReadonlyArray<NullableCoordinate>, lineItem: ReactNode;
492
+
493
+ if (lineType === 'joint') {
494
+ linePoints = points.map((entry) => ({ x: entry.cx ?? null, y: entry.cy ?? null }));
495
+ } else if (lineType === 'fitting') {
496
+ const { xmin, xmax, a, b } = getLinearRegression(points);
497
+ const linearExp = (x: number) => a * x + b;
498
+ linePoints = [
499
+ { x: xmin, y: linearExp(xmin) },
500
+ { x: xmax, y: linearExp(xmax) },
501
+ ];
502
+ }
503
+
504
+ const lineProps: CurveProps = {
505
+ ...scatterProps,
506
+ // @ts-expect-error customLineProps is contributing unknown props
507
+ fill: 'none',
508
+ // @ts-expect-error customLineProps is contributing unknown props
509
+ stroke: scatterProps && scatterProps.fill,
510
+ ...customLineProps,
511
+ // @ts-expect-error linePoints is used before it is assigned (???)
512
+ points: linePoints,
513
+ };
514
+
515
+ if (React.isValidElement(line)) {
516
+ lineItem = React.cloneElement(line as any, lineProps);
517
+ } else if (typeof line === 'function') {
518
+ lineItem = line(lineProps);
519
+ } else {
520
+ lineItem = <Curve {...lineProps} type={lineJointType} />;
521
+ }
522
+
523
+ return <Layer className="recharts-scatter-line" key="recharts-scatter-line">{lineItem}</Layer>;
524
+ }
525
+
526
+ function ScatterLabelListProvider({
527
+ showLabels,
528
+ points,
529
+ children,
530
+ }: {
531
+ showLabels: boolean;
532
+ points: ReadonlyArray<ScatterPointItem>;
533
+ children: ReactNode;
534
+ }) {
535
+ const chartViewBox = useViewBox();
536
+ const labelListEntries: ReadonlyArray<CartesianLabelListEntry> = useMemo(() => {
537
+ return points?.map((point): CartesianLabelListEntry => {
538
+ const viewBox: TrapezoidViewBox = {
539
+ /*
540
+ * Scatter label uses x and y as the reference point for the label,
541
+ * not cx and cy.
542
+ */
543
+ x: point.x ?? 0,
544
+ /*
545
+ * Scatter label uses x and y as the reference point for the label,
546
+ * not cx and cy.
547
+ */
548
+ y: point.y ?? 0,
549
+ width: point.width,
550
+ height: point.height,
551
+ lowerWidth: point.width,
552
+ upperWidth: point.width,
553
+ };
554
+ return {
555
+ ...viewBox,
556
+ /*
557
+ * Here we put undefined because Scatter shows two values usually, one for X and one for Y.
558
+ * LabelList will see this undefined and will use its own `dataKey` prop to determine which value to show,
559
+ * using the payload below.
560
+ */
561
+ value: undefined,
562
+ payload: point.payload,
563
+ viewBox,
564
+ parentViewBox: chartViewBox,
565
+ fill: undefined,
566
+ };
567
+ });
568
+ }, [chartViewBox, points]);
569
+
570
+ return <CartesianLabelListContextProvider
571
+ value={showLabels ? labelListEntries : undefined}
572
+ >{children}</CartesianLabelListContextProvider>;
573
+ }
574
+
575
+ /**
576
+ * Individual scatter point component that subscribes to its own isActive state.
577
+ * This avoids re-rendering all points when the active index changes —
578
+ * only the point becoming active and the point becoming inactive re-render.
579
+ *
580
+ * @param entry The scatter point data including coordinates, size, and tooltip payload
581
+ * @param index The index of this point in the points array
582
+ * @param shape The default shape to render for inactive points
583
+ * @param activeShape The shape to render when this point is active, or undefined if no active shape
584
+ * @param baseProps SVG presentation attributes (fill, stroke, etc.) shared across all points
585
+ * @param id The graphical item ID of the parent Scatter component
586
+ * @param restOfAllOtherProps Remaining Scatter props for user-provided event handlers via adaptEventsOfChild
587
+ * @param onMouseEnterFromContext Curried mouse enter handler that dispatches tooltip activation
588
+ * @param onMouseLeaveFromContext Curried mouse leave handler that dispatches tooltip deactivation
589
+ * @param onClickFromContext Curried click handler that dispatches tooltip click activation
590
+ */
591
+ function ScatterPoint({
592
+ entry,
593
+ index,
594
+ shape,
595
+ activeShape,
596
+ baseProps,
597
+ id,
598
+ restOfAllOtherProps,
599
+ animationElapsedTime,
600
+ isAnimating,
601
+ isEntrance,
602
+ onMouseEnterFromContext,
603
+ onMouseLeaveFromContext,
604
+ onClickFromContext,
605
+ }: ShapeAnimationProps & {
606
+ entry: ScatterPointItem;
607
+ index: number;
608
+ shape: ScatterCustomizedShape;
609
+ activeShape: ScatterCustomizedShape | undefined;
610
+ baseProps: ReturnType<typeof svgPropertiesNoEvents>;
611
+ id: GraphicalItemId;
612
+ restOfAllOtherProps: InternalProps;
613
+ onMouseEnterFromContext: (data: ScatterPointItem, index: number) => (event: React.MouseEvent<
614
+ SVGGraphicsElement
615
+ >) => void;
616
+ onMouseLeaveFromContext: (data: ScatterPointItem, index: number) => (event: React.MouseEvent<
617
+ SVGGraphicsElement
618
+ >) => void;
619
+ onClickFromContext: (data: ScatterPointItem, index: number) => (event: React.MouseEvent<
620
+ SVGGraphicsElement
621
+ >) => void;
622
+ }): React.ReactElement {
623
+ const hasActiveShape = activeShape != null && activeShape !== false;
624
+ const selectIsActive = useMemo(() => {
625
+ const strIndex = String(index);
626
+ return (state: RechartsRootState): boolean =>
627
+ hasActiveShape && selectActiveTooltipIndex(state) === strIndex;
628
+ }, [hasActiveShape, index]);
629
+ const isActive: boolean = useAppSelector(selectIsActive) ?? false;
630
+
631
+ // isActive is only true when hasActiveShape is true, so activeShape is defined here
632
+ const option =
633
+ isActive && activeShape != null && activeShape !== false ? activeShape : shape;
634
+ const symbolProps: ScatterShapeProps = {
635
+ ...baseProps,
636
+ ...entry,
637
+ isActive,
638
+ index,
639
+ animationElapsedTime,
640
+ isAnimating,
641
+ isEntrance,
642
+ [DATA_ITEM_GRAPHICAL_ITEM_ID_ATTRIBUTE_NAME]: String(id),
643
+ };
644
+
645
+ return <ZIndexLayer
646
+ /*
647
+ * inactive Scatters use the parent zIndex, which is represented by undefined here.
648
+ * ZIndexLayer will render undefined zIndex as-is, as regular children, without portals.
649
+ * Active Scatters use the activeDot zIndex so they render above other elements.
650
+ */
651
+ zIndex={isActive ? DefaultZIndexes.activeDot : undefined}
652
+ >
653
+ <Layer
654
+ className="recharts-scatter-symbol"
655
+ {...adaptEventsOfChild(restOfAllOtherProps, entry, index)}
656
+ onMouseEnter={onMouseEnterFromContext(entry, index)}
657
+ onMouseLeave={onMouseLeaveFromContext(entry, index)}
658
+ onClick={onClickFromContext(entry, index)}
659
+ >
660
+ <ScatterSymbol option={option} {...symbolProps} />
661
+ </Layer>
662
+ </ZIndexLayer>;
663
+ }
664
+
665
+ function ScatterSymbols(props: ScatterSymbolsProps) {
666
+ const { points, allOtherScatterProps, animationElapsedTime, isAnimating, isEntrance } = props;
667
+ const { shape, activeShape, dataKey } = allOtherScatterProps;
668
+ const { id, ...allOtherPropsWithoutId } = allOtherScatterProps;
669
+
670
+ const {
671
+ onMouseEnter: onMouseEnterFromProps,
672
+ onClick: onItemClickFromProps,
673
+ onMouseLeave: onMouseLeaveFromProps,
674
+ ...restOfAllOtherProps
675
+ } = allOtherScatterProps;
676
+
677
+ const onMouseEnterFromContext = useMouseEnterItemDispatch(onMouseEnterFromProps, dataKey, id);
678
+ const onMouseLeaveFromContext = useMouseLeaveItemDispatch(onMouseLeaveFromProps);
679
+ const onClickFromContext = useMouseClickItemDispatch(onItemClickFromProps, dataKey, id);
680
+ if (!isNonEmptyArray(points)) {
681
+ return null;
682
+ }
683
+
684
+ const baseProps = svgPropertiesNoEvents(allOtherPropsWithoutId);
685
+
686
+ return <>
687
+ <ScatterLine points={points} props={allOtherPropsWithoutId} />
688
+ {points.map(
689
+ (entry: ScatterPointItem, i: number) =>
690
+ <ScatterPoint
691
+ key={`symbol-${entry?.cx}-${entry?.cy}-${entry?.size}-${i}`}
692
+ entry={entry}
693
+ index={i}
694
+ shape={shape}
695
+ activeShape={activeShape}
696
+ baseProps={baseProps}
697
+ id={id}
698
+ restOfAllOtherProps={restOfAllOtherProps}
699
+ animationElapsedTime={animationElapsedTime}
700
+ isAnimating={isAnimating}
701
+ isEntrance={isEntrance}
702
+ onMouseEnterFromContext={onMouseEnterFromContext}
703
+ onMouseLeaveFromContext={onMouseLeaveFromContext}
704
+ onClickFromContext={onClickFromContext}
705
+ />,
706
+ )}
707
+ </>;
708
+ }
709
+
710
+ const defaultScatterAnimateItems: AnimationInterpolateFn<ScatterPointItem, CartesianLayout> = (
711
+ items,
712
+ animationElapsedTime,
713
+ ) => {
714
+ if (items == null) return [];
715
+ if (animationElapsedTime === 1) {
716
+ return items.flatMap((item) => (item.status === 'removed' ? [] : [item.next]));
717
+ }
718
+ return items.flatMap((item) => {
719
+ if (item.status === 'removed') return [];
720
+ if (item.status === 'matched') {
721
+ return [
722
+ {
723
+ ...item.next,
724
+ cx: item.next.cx == null
725
+ ? undefined
726
+ : interpolate(item.prev.cx, item.next.cx, animationElapsedTime),
727
+ cy: item.next.cy == null
728
+ ? undefined
729
+ : interpolate(item.prev.cy, item.next.cy, animationElapsedTime),
730
+ size: interpolate(item.prev.size, item.next.size, animationElapsedTime),
731
+ },
732
+ ];
733
+ }
734
+ // added
735
+ return [
736
+ { ...item.next, size: interpolate(0, item.next.size, animationElapsedTime) },
737
+ ];
738
+ });
739
+ };
740
+
741
+ function SymbolsWithAnimation({
742
+ previousPointsRef,
743
+ props,
744
+ }: {
745
+ previousPointsRef: MutableRefObject<ReadonlyArray<ScatterPointItem> | null>;
746
+ props: InternalProps;
747
+ }) {
748
+ const {
749
+ points,
750
+ isAnimationActive,
751
+ animationBegin,
752
+ animationDuration,
753
+ animationEasing,
754
+ animationInterpolateFn,
755
+ onAnimationStart,
756
+ onAnimationEnd,
757
+ } = props;
758
+
759
+ const { isAnimating, handleAnimationStart, handleAnimationEnd } = useAnimationCallbacks(
760
+ onAnimationStart,
761
+ onAnimationEnd,
762
+ );
763
+ const layout = useCartesianChartLayout();
764
+
765
+ if (layout == null) return null;
766
+
767
+ return <ScatterLabelListProvider showLabels={!isAnimating} points={points}>
768
+ <AnimatedItems
769
+ animationInput={points}
770
+ animationIdPrefix="recharts-scatter-"
771
+ items={points}
772
+ previousItemsRef={previousPointsRef}
773
+ isAnimationActive={isAnimationActive}
774
+ animationBegin={animationBegin}
775
+ animationDuration={animationDuration}
776
+ animationEasing={animationEasing}
777
+ onAnimationStart={handleAnimationStart}
778
+ onAnimationEnd={handleAnimationEnd}
779
+ animationInterpolateFn={animationInterpolateFn}
780
+ animationMatchBy={props.animationMatchBy}
781
+ layout={layout}
782
+ >
783
+ {(stepData, animationElapsedTime, isEntrance) => <Layer>
784
+ <ScatterSymbols
785
+ points={stepData}
786
+ allOtherScatterProps={props}
787
+ showLabels={!isAnimating}
788
+ animationElapsedTime={animationElapsedTime}
789
+ isAnimating={isAnimating || animationElapsedTime < 1}
790
+ isEntrance={isEntrance}
791
+ />
792
+ </Layer>}
793
+ </AnimatedItems>
794
+ {props.children}
795
+ <LabelListFromLabelProp label={props.label} />
796
+ </ScatterLabelListProvider>;
797
+ }
798
+
799
+ export function computeScatterPoints({
800
+ displayedData,
801
+ xAxis,
802
+ yAxis,
803
+ zAxis,
804
+ scatterSettings,
805
+ xAxisTicks,
806
+ yAxisTicks,
807
+ cells,
808
+ }: {
809
+ displayedData: ReadonlyArray<unknown>;
810
+ xAxis: BaseAxisWithScale;
811
+ yAxis: BaseAxisWithScale;
812
+ zAxis: ZAxisWithScale | undefined;
813
+ scatterSettings: ScatterSettings;
814
+ xAxisTicks: ReadonlyArray<TickItem> | undefined;
815
+ yAxisTicks: ReadonlyArray<TickItem> | undefined;
816
+ cells: ReadonlyArray<ReactElement> | undefined;
817
+ }): ReadonlyArray<ScatterPointItem> {
818
+ const xAxisDataKey = isNullish(xAxis.dataKey) ? scatterSettings.dataKey : xAxis.dataKey;
819
+ const yAxisDataKey = isNullish(yAxis.dataKey) ? scatterSettings.dataKey : yAxis.dataKey;
820
+ const zAxisDataKey = zAxis && zAxis.dataKey;
821
+ const defaultRangeZ = zAxis ? zAxis.range : implicitZAxis.range;
822
+ const defaultZ = defaultRangeZ && defaultRangeZ[0];
823
+ const xBandSize =
824
+ xAxis.scale.bandwidth ? xAxis.scale.bandwidth() : 0;
825
+ const yBandSize =
826
+ yAxis.scale.bandwidth ? yAxis.scale.bandwidth() : 0;
827
+ return displayedData.map((entry: unknown, index): ScatterPointItem => {
828
+ const x: unknown = getValueByDataKey(entry, xAxisDataKey);
829
+ const y: unknown = getValueByDataKey(entry, yAxisDataKey);
830
+ const z: unknown = isNullish(zAxisDataKey)
831
+ ? '-'
832
+ : getValueByDataKey(entry, zAxisDataKey) ?? '-';
833
+
834
+ const tooltipPayload: Array<TooltipPayloadEntry> = [
835
+ {
836
+ name: isNullish(xAxis.dataKey) ? scatterSettings.name : xAxis.name || String(xAxis.dataKey),
837
+ unit: xAxis.unit || '',
838
+ // @ts-expect-error getValueByDataKey does not validate the output type
839
+ value: x,
840
+ payload: entry,
841
+ dataKey: xAxisDataKey,
842
+ type: scatterSettings.tooltipType,
843
+ graphicalItemId: scatterSettings.id,
844
+ },
845
+ {
846
+ name: isNullish(yAxis.dataKey) ? scatterSettings.name : yAxis.name || String(yAxis.dataKey),
847
+ unit: yAxis.unit || '',
848
+ // @ts-expect-error getValueByDataKey does not validate the output type
849
+ value: y,
850
+ payload: entry,
851
+ dataKey: yAxisDataKey,
852
+ type: scatterSettings.tooltipType,
853
+ graphicalItemId: scatterSettings.id,
854
+ },
855
+ ];
856
+
857
+ if (z !== '-' && zAxis != null) {
858
+ tooltipPayload.push({
859
+ // @ts-expect-error name prop should not have dataKey in it
860
+ name: zAxis.name || zAxis.dataKey,
861
+ unit: zAxis.unit || '',
862
+ // @ts-expect-error getValueByDataKey does not validate the output type
863
+ value: z,
864
+ payload: entry,
865
+ dataKey: zAxisDataKey,
866
+ type: scatterSettings.tooltipType,
867
+ graphicalItemId: scatterSettings.id,
868
+ });
869
+ }
870
+
871
+ const cx: number | null = getCateCoordinateOfLine({
872
+ axis: xAxis,
873
+ ticks: xAxisTicks,
874
+ bandSize: xBandSize,
875
+ entry,
876
+ index,
877
+ dataKey: xAxisDataKey,
878
+ });
879
+ const cy = getCateCoordinateOfLine({
880
+ axis: yAxis,
881
+ ticks: yAxisTicks,
882
+ bandSize: yBandSize,
883
+ entry,
884
+ index,
885
+ dataKey: yAxisDataKey,
886
+ });
887
+ const size =
888
+ z !== '-' && zAxis != null ? zAxis.scale.map(z) : defaultZ;
889
+ const radius =
890
+ size == null ? 0 : Math.sqrt(Math.max(size, 0) / Math.PI);
891
+
892
+ return {
893
+ // @ts-expect-error can't spread unknown
894
+ ...entry,
895
+ cx,
896
+ cy,
897
+ x: cx == null ? undefined : cx - radius,
898
+ y: cy == null ? undefined : cy - radius,
899
+ width: 2 * radius,
900
+ height: 2 * radius,
901
+ size,
902
+ node: { x, y, z },
903
+ tooltipPayload,
904
+ tooltipPosition: { x: cx, y: cy },
905
+ payload: entry,
906
+ ...cells && cells[index] && cells[index].props,
907
+ };
908
+ });
909
+ }
910
+
911
+ const errorBarDataPointFormatter: ErrorBarDataPointFormatter<ScatterPointItem> = (
912
+ dataPoint: ScatterPointItem,
913
+ dataKey: Props['dataKey'],
914
+ direction: ErrorBarDirection,
915
+ ): ErrorBarDataItem => {
916
+ return {
917
+ x: dataPoint.cx,
918
+ y: dataPoint.cy,
919
+ value: direction === 'x' ? Number(dataPoint.node.x) : Number(dataPoint.node.y),
920
+ // @ts-expect-error getValueByDataKey does not validate the output type
921
+ errorVal: getValueByDataKey(dataPoint, dataKey),
922
+ };
923
+ };
924
+
925
+ function ScatterWithId(props: InternalProps) {
926
+ const { hide, points, className, needClip, xAxisId, yAxisId, id } = props;
927
+ const previousPointsRef = useRef<ReadonlyArray<ScatterPointItem> | null>(null);
928
+ if (hide) {
929
+ return props.children;
930
+ }
931
+ const layerClass = clsx('recharts-scatter', className);
932
+ const clipPathId = id;
933
+
934
+ return <ZIndexLayer zIndex={props.zIndex}>
935
+ <Layer
936
+ className={layerClass}
937
+ clipPath={needClip ? `url(#clipPath-${clipPathId})` : undefined}
938
+ id={id}
939
+ >
940
+ {needClip &&
941
+ <defs>
942
+ <GraphicalItemClipPath clipPathId={clipPathId} xAxisId={xAxisId} yAxisId={yAxisId} />
943
+ </defs>}
944
+ <SetErrorBarContext
945
+ xAxisId={xAxisId}
946
+ yAxisId={yAxisId}
947
+ data={points}
948
+ dataPointFormatter={errorBarDataPointFormatter}
949
+ errorBarOffset={0}
950
+ >
951
+ <Layer key="recharts-scatter-symbols">
952
+ <SymbolsWithAnimation props={props} previousPointsRef={previousPointsRef} />
953
+ </Layer>
954
+ </SetErrorBarContext>
955
+ </Layer>
956
+ </ZIndexLayer>;
957
+ }
958
+
959
+ export const defaultScatterProps = {
960
+ xAxisId: 0,
961
+ yAxisId: 0,
962
+ zAxisId: 0,
963
+ label: false,
964
+ line: false,
965
+ legendType: 'circle',
966
+ lineType: 'joint',
967
+ lineJointType: 'linear',
968
+ shape: 'circle',
969
+ hide: false,
970
+
971
+ isAnimationActive: 'auto',
972
+ animationBegin: 0,
973
+ animationDuration: 400,
974
+ animationEasing: 'linear',
975
+ animationMatchBy: matchAppend,
976
+ animationInterpolateFn: defaultScatterAnimateItems,
977
+ zIndex: DefaultZIndexes.scatter,
978
+ } as const satisfies Partial<Props>;
979
+
980
+ function ScatterImpl(props: WithIdRequired<Props>) {
981
+ const {
982
+ animationBegin,
983
+ animationDuration,
984
+ animationEasing,
985
+ hide,
986
+ isAnimationActive,
987
+ legendType,
988
+ lineJointType,
989
+ lineType,
990
+ shape,
991
+ xAxisId,
992
+ yAxisId,
993
+ zAxisId,
994
+ ...everythingElse
995
+ } = resolveDefaultProps(props, defaultScatterProps);
996
+
997
+ const { needClip } = useNeedsClip(xAxisId, yAxisId);
998
+ const [cells, cellRegistry] = useCellRegistry();
999
+ const isPanorama = useIsPanorama();
1000
+
1001
+ const points = useAppSelector((state) => {
1002
+ return selectScatterPoints(state, xAxisId, yAxisId, zAxisId, props.id, cells, isPanorama);
1003
+ });
1004
+ if (needClip == null || points == null) {
1005
+ return <CellsContext.Provider value={cellRegistry}>{props.children}</CellsContext.Provider>;
1006
+ }
1007
+ return <CellsContext.Provider value={cellRegistry}>
1008
+ <SetScatterTooltipEntrySettings
1009
+ dataKey={props.dataKey}
1010
+ points={points}
1011
+ stroke={props.stroke}
1012
+ strokeWidth={props.strokeWidth}
1013
+ fill={props.fill}
1014
+ name={props.name}
1015
+ hide={props.hide}
1016
+ formatter={props.formatter}
1017
+ tooltipType={props.tooltipType}
1018
+ id={props.id}
1019
+ />
1020
+ <ScatterWithId
1021
+ {...everythingElse}
1022
+ xAxisId={xAxisId}
1023
+ yAxisId={yAxisId}
1024
+ zAxisId={zAxisId}
1025
+ lineType={lineType}
1026
+ lineJointType={lineJointType}
1027
+ legendType={legendType}
1028
+ shape={shape}
1029
+ hide={hide}
1030
+ isAnimationActive={isAnimationActive}
1031
+ animationBegin={animationBegin}
1032
+ animationDuration={animationDuration}
1033
+ animationEasing={animationEasing}
1034
+ points={points}
1035
+ needClip={needClip}
1036
+ />
1037
+ </CellsContext.Provider>;
1038
+ }
1039
+
1040
+ function ScatterFn(outsideProps: Props) {
1041
+ const props = resolveDefaultProps(outsideProps, defaultScatterProps);
1042
+ const isPanorama = useIsPanorama();
1043
+ return <RegisterGraphicalItemId id={props.id} type="scatter">
1044
+ {(id) => <>
1045
+ <SetLegendPayload legendPayload={computeLegendPayloadFromScatterProps(props)} />
1046
+ <SetCartesianGraphicalItem
1047
+ type="scatter"
1048
+ id={id}
1049
+ data={props.data}
1050
+ xAxisId={props.xAxisId}
1051
+ yAxisId={props.yAxisId}
1052
+ zAxisId={props.zAxisId}
1053
+ dataKey={props.dataKey}
1054
+ hide={props.hide}
1055
+ name={props.name}
1056
+ tooltipType={props.tooltipType}
1057
+ isPanorama={isPanorama}
1058
+ />
1059
+ <ScatterImpl {...props} id={id} />
1060
+ </>}
1061
+ </RegisterGraphicalItemId>;
1062
+ }
1063
+
1064
+ /**
1065
+ * @provides LabelListContext
1066
+ * @provides ErrorBarContext
1067
+ * @provides CellReader
1068
+ * @consumes CartesianChartContext
1069
+ */
1070
+ export const Scatter = React.memo(ScatterFn, propsAreEqual) as (props: Props<
1071
+ DataPointType,
1072
+ ValueAxisType
1073
+ >) => ReactElement;
1074
+ // @ts-expect-error we need to set the displayName for debugging purposes
1075
+
1076
+ Scatter.displayName = 'Scatter';