@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,887 @@
1
+ import * as React from 'octane';
2
+ import { MutableRefObject, ReactElement, ReactNode, useRef } from 'octane';
3
+ import { clsx } from 'clsx';
4
+
5
+ import { Series } from 'victory-vendor/d3-shape';
6
+ import {
7
+ defaultRadialBarShape,
8
+ parseCornerRadius,
9
+ RadialBarSector,
10
+ RadialBarSectorProps,
11
+ } from '../util/RadialBarUtils';
12
+ import { Props as SectorProps } from '../shape/Sector';
13
+ import { Layer } from '../container/Layer';
14
+ import {
15
+ ImplicitLabelListType,
16
+ LabelListFromLabelProp,
17
+ PolarLabelListContextProvider,
18
+ PolarLabelListEntry,
19
+ } from '../component/LabelList';
20
+ import { interpolate, mathSign, noop } from '../util/DataUtils';
21
+ import {
22
+ BarPositionPosition,
23
+ getCateCoordinateOfBar,
24
+ getNormalizedStackId,
25
+ getTooltipNameProp,
26
+ getValueByDataKey,
27
+ truncateByDomain,
28
+ } from '../util/ChartUtils';
29
+ import {
30
+ ActiveShape,
31
+ adaptEventsOfChild,
32
+ AnimationDuration,
33
+ EasingInput,
34
+ DataConsumer,
35
+ DataKey,
36
+ LayoutType,
37
+ LegendType,
38
+ PolarViewBoxRequired,
39
+ PresentationAttributesAdaptChildEvent,
40
+ ShapeAnimationProps,
41
+ TickItem,
42
+ TooltipType,
43
+ PolarLayout,
44
+ } from '../util/types';
45
+ import {
46
+ TooltipTriggerInfo,
47
+ useMouseClickItemDispatch,
48
+ useMouseEnterItemDispatch,
49
+ useMouseLeaveItemDispatch,
50
+ } from '../context/tooltipContext';
51
+ import { TooltipPayloadConfiguration } from '../state/tooltipSlice';
52
+ import { SetTooltipEntrySettings } from '../state/SetTooltipEntrySettings';
53
+ import { Formatter } from '../component/DefaultTooltipContent';
54
+ import { BaseAxisWithScale } from '../state/selectors/axisSelectors';
55
+ import { ChartData } from '../state/chartDataSlice';
56
+ import {
57
+ selectRadialBarLegendPayload,
58
+ selectRadialBarSectors,
59
+ } from '../state/selectors/radialBarSelectors';
60
+ import { useAppSelector } from '../state/hooks';
61
+ import { selectActiveTooltipIndex } from '../state/selectors/tooltipSelectors';
62
+ import { SetPolarLegendPayload } from '../state/SetLegendPayload';
63
+ import {
64
+ AnimatedItems,
65
+ AnimationInterpolateFn,
66
+ useAnimationCallbacks,
67
+ } from '../animation/AnimatedItems';
68
+ import { AnimationMatchByProp, matchAppend } from '../animation/matchBy';
69
+ import { AxisId } from '../state/cartesianAxisSlice';
70
+ import { RegisterGraphicalItemId } from '../context/RegisterGraphicalItemId';
71
+ import type { RadialBarSettings } from '../state/types/RadialBarSettings';
72
+ import { SetPolarGraphicalItem } from '../state/SetGraphicalItem';
73
+ import {
74
+ svgPropertiesNoEvents,
75
+ svgPropertiesNoEventsFromUnknown,
76
+ } from '../util/svgPropertiesNoEvents';
77
+ import { RequiresDefaultProps, resolveDefaultProps } from '../util/resolveDefaultProps';
78
+ import { WithIdRequired } from '../util/useUniqueId';
79
+ import { ZIndexable, ZIndexLayer } from '../zIndex/ZIndexLayer';
80
+ import { DefaultZIndexes } from '../zIndex/DefaultZIndexes';
81
+ import { getZIndexFromUnknown } from '../zIndex/getZIndexFromUnknown';
82
+ import { usePolarChartLayout } from '../context/chartLayoutContext';
83
+ import { CellsContext, useCellRegistry } from '../context/CellsContext';
84
+
85
+ const STABLE_EMPTY_ARRAY: readonly RadialBarDataItem[] = [];
86
+
87
+ export type RadialBarDataItem =
88
+ SectorProps & PolarViewBoxRequired & TooltipTriggerInfo & {
89
+ value?: any;
90
+ payload?: any;
91
+ background?: SectorProps;
92
+ };
93
+
94
+ type RadialBarBackground = boolean | (ActiveShape<SectorProps> & ZIndexable);
95
+
96
+ type RadialBarSectorsProps =
97
+ ShapeAnimationProps & {
98
+ sectors: ReadonlyArray<RadialBarDataItem>;
99
+ allOtherRadialBarProps: InternalProps;
100
+ showLabels: boolean;
101
+ };
102
+
103
+ function RadialBarLabelListProvider({
104
+ showLabels,
105
+ sectors,
106
+ children,
107
+ }: {
108
+ showLabels: boolean;
109
+ sectors: ReadonlyArray<RadialBarDataItem>;
110
+ children: ReactNode;
111
+ }) {
112
+ const labelListEntries: ReadonlyArray<PolarLabelListEntry> = sectors.map(
113
+ (sector: RadialBarDataItem): PolarLabelListEntry => ({
114
+ value: sector.value,
115
+ payload: sector.payload,
116
+ parentViewBox: undefined,
117
+ clockWise: false,
118
+ viewBox: {
119
+ cx: sector.cx,
120
+ cy: sector.cy,
121
+ innerRadius: sector.innerRadius,
122
+ outerRadius: sector.outerRadius,
123
+ startAngle: sector.startAngle,
124
+ endAngle: sector.endAngle,
125
+ clockWise: false,
126
+ },
127
+ fill: sector.fill,
128
+ }),
129
+ );
130
+
131
+ return <PolarLabelListContextProvider
132
+ value={showLabels ? labelListEntries : undefined}
133
+ >{children}</PolarLabelListContextProvider>;
134
+ }
135
+
136
+ function RadialBarSectors({
137
+ sectors,
138
+ allOtherRadialBarProps,
139
+ showLabels,
140
+ animationElapsedTime,
141
+ isAnimating,
142
+ isEntrance,
143
+ }: RadialBarSectorsProps) {
144
+ const { shape, activeShape, cornerRadius, id, ...others } = allOtherRadialBarProps;
145
+ const baseProps = svgPropertiesNoEvents(others);
146
+
147
+ const activeIndex = useAppSelector(selectActiveTooltipIndex);
148
+ const {
149
+ onMouseEnter: onMouseEnterFromProps,
150
+ onClick: onItemClickFromProps,
151
+ onMouseLeave: onMouseLeaveFromProps,
152
+ ...restOfAllOtherProps
153
+ } = allOtherRadialBarProps;
154
+
155
+ const onMouseEnterFromContext = useMouseEnterItemDispatch(
156
+ onMouseEnterFromProps,
157
+ allOtherRadialBarProps.dataKey,
158
+ id,
159
+ );
160
+ const onMouseLeaveFromContext = useMouseLeaveItemDispatch(onMouseLeaveFromProps);
161
+ const onClickFromContext = useMouseClickItemDispatch(
162
+ onItemClickFromProps,
163
+ allOtherRadialBarProps.dataKey,
164
+ id,
165
+ );
166
+
167
+ if (sectors == null) {
168
+ return null;
169
+ }
170
+
171
+ return <RadialBarLabelListProvider showLabels={showLabels} sectors={sectors}>
172
+ {sectors.map((entry: RadialBarDataItem, i: number) => {
173
+ const isActive: boolean = Boolean(activeShape && activeIndex === String(i));
174
+ const onMouseEnter = onMouseEnterFromContext(entry, i);
175
+ const onMouseLeave = onMouseLeaveFromContext(entry, i);
176
+ const onClick = onClickFromContext(entry, i);
177
+
178
+ const radialBarSectorProps: React.ComponentProps<typeof RadialBarSector> = {
179
+ ...baseProps,
180
+ cornerRadius: parseCornerRadius(cornerRadius),
181
+ ...entry,
182
+ ...adaptEventsOfChild(restOfAllOtherProps, entry, i),
183
+ onMouseEnter,
184
+ onMouseLeave,
185
+ onClick,
186
+ className: `recharts-radial-bar-sector ${entry.className}`,
187
+ forceCornerRadius: others.forceCornerRadius,
188
+ cornerIsExternal: others.cornerIsExternal,
189
+ animationElapsedTime,
190
+ isAnimating,
191
+ isEntrance,
192
+ isActive,
193
+ option: isActive && activeShape != null ? activeShape : shape,
194
+ index: i,
195
+ };
196
+
197
+ if (isActive) {
198
+ return <ZIndexLayer
199
+ zIndex={DefaultZIndexes.activeBar}
200
+ key={`sector-${entry.cx}-${entry.cy}-${entry.innerRadius}-${entry.outerRadius}-${entry.startAngle}-${entry.endAngle}-${i}`}
201
+ >
202
+ <RadialBarSector {...radialBarSectorProps} />
203
+ </ZIndexLayer>;
204
+ }
205
+
206
+ return <RadialBarSector
207
+ key={`sector-${entry.cx}-${entry.cy}-${entry.innerRadius}-${entry.outerRadius}-${entry.startAngle}-${entry.endAngle}-${i}`}
208
+ {...radialBarSectorProps}
209
+ />;
210
+ })}
211
+ <LabelListFromLabelProp label={allOtherRadialBarProps.label} />
212
+ {allOtherRadialBarProps.children}
213
+ </RadialBarLabelListProvider>;
214
+ }
215
+
216
+ const defaultRadialBarAnimateItems: AnimationInterpolateFn<RadialBarDataItem, PolarLayout> = (
217
+ items,
218
+ animationElapsedTime,
219
+ ) => {
220
+ if (items == null) return [];
221
+ if (animationElapsedTime === 1) {
222
+ return items.flatMap((item) => (item.status === 'removed' ? [] : [item.next]));
223
+ }
224
+ return items.flatMap((item) => {
225
+ if (item.status === 'removed') return [];
226
+ if (item.status === 'matched') {
227
+ return [
228
+ {
229
+ ...item.next,
230
+ startAngle: interpolate(item.prev.startAngle, item.next.startAngle, animationElapsedTime),
231
+ endAngle: interpolate(item.prev.endAngle, item.next.endAngle, animationElapsedTime),
232
+ },
233
+ ];
234
+ }
235
+ // added
236
+ return [
237
+ {
238
+ ...item.next,
239
+ endAngle: interpolate(item.next.startAngle, item.next.endAngle, animationElapsedTime),
240
+ },
241
+ ];
242
+ });
243
+ };
244
+
245
+ function SectorsWithAnimation({
246
+ props,
247
+ previousSectorsRef,
248
+ }: {
249
+ props: InternalProps;
250
+ previousSectorsRef: MutableRefObject<ReadonlyArray<RadialBarDataItem> | null>;
251
+ }) {
252
+ const {
253
+ sectors,
254
+ isAnimationActive,
255
+ animationBegin,
256
+ animationDuration,
257
+ animationEasing,
258
+ onAnimationStart,
259
+ onAnimationEnd,
260
+ } = props;
261
+ const animationInput = JSON.stringify(
262
+ sectors.map(
263
+ ({ cx, cy, innerRadius, outerRadius, startAngle, endAngle }) => [
264
+ cx,
265
+ cy,
266
+ innerRadius,
267
+ outerRadius,
268
+ startAngle,
269
+ endAngle,
270
+ ],
271
+ ),
272
+ );
273
+
274
+ const { isAnimating, handleAnimationStart, handleAnimationEnd } = useAnimationCallbacks(
275
+ onAnimationStart,
276
+ onAnimationEnd,
277
+ );
278
+
279
+ const layout = usePolarChartLayout();
280
+
281
+ if (layout == null) return null;
282
+
283
+ return <AnimatedItems
284
+ animationInput={animationInput}
285
+ animationIdPrefix="recharts-radialbar-"
286
+ items={sectors}
287
+ previousItemsRef={previousSectorsRef}
288
+ isAnimationActive={isAnimationActive}
289
+ animationBegin={animationBegin}
290
+ animationDuration={animationDuration}
291
+ animationEasing={animationEasing}
292
+ onAnimationStart={handleAnimationStart}
293
+ onAnimationEnd={handleAnimationEnd}
294
+ animationInterpolateFn={props.animationInterpolateFn}
295
+ animationMatchBy={props.animationMatchBy}
296
+ layout={layout}
297
+ >
298
+ {(stepData, animationElapsedTime, isEntrance) =>
299
+ <RadialBarSectors
300
+ sectors={stepData}
301
+ allOtherRadialBarProps={props}
302
+ showLabels={!isAnimating}
303
+ animationElapsedTime={animationElapsedTime}
304
+ isAnimating={isAnimating || animationElapsedTime < 1}
305
+ isEntrance={isEntrance}
306
+ />}
307
+ </AnimatedItems>;
308
+ }
309
+
310
+ function RenderSectors(props: InternalProps) {
311
+ const previousSectorsRef = useRef<ReadonlyArray<RadialBarDataItem> | null>(null);
312
+
313
+ return <SectorsWithAnimation props={props} previousSectorsRef={previousSectorsRef} />;
314
+ }
315
+
316
+ interface InternalRadialBarProps<DataPointType = any, DataValueType = any> extends DataConsumer<
317
+ DataPointType,
318
+ DataValueType
319
+ >, ZIndexable {
320
+ activeShape?: ActiveShape<RadialBarSectorProps, SVGPathElement>;
321
+ /**
322
+ * @defaultValue 0
323
+ */
324
+ angleAxisId?: AxisId;
325
+ /**
326
+ * Specifies when the animation should begin, the unit of this option is ms.
327
+ * @defaultValue 0
328
+ */
329
+ animationBegin?: number;
330
+ /**
331
+ * Specifies the duration of animation, the unit of this option is ms.
332
+ * @defaultValue 1500
333
+ */
334
+ animationDuration?: AnimationDuration;
335
+ /**
336
+ * The type of easing function.
337
+ * @defaultValue ease
338
+ */
339
+ animationEasing?: EasingInput;
340
+ /**
341
+ * Custom animation function for interpolating data items.
342
+ * When provided, this replaces the default animation interpolation.
343
+ *
344
+ * @param prevItems The items from the previous animation frame, or null on first render
345
+ * @param nextItems The target items to animate towards
346
+ * @param animationElapsedTime A normalized time value (0 = start, 1 = end)
347
+ * @returns The interpolated items at time animationElapsedTime
348
+ *
349
+ * @since 3.9
350
+ * @see {@link https://recharts.github.io/en-US/guide/animations/ Animations guide}
351
+ */
352
+ animationInterpolateFn?: AnimationInterpolateFn<RadialBarDataItem, PolarLayout>;
353
+ /**
354
+ * Strategy for matching previous items to next items during animation.
355
+ * Determines how Recharts pairs old data points with new data points
356
+ * to create smooth transitions.
357
+ *
358
+ * - `matchAppend` (default): match sequentially by index and treat newly appended items as new
359
+ * - `matchByIndex`: match by array position with proportional stretching
360
+ * - `matchByDataKey('someKey')`: match by a data key from the payload
361
+ * - Custom function `(item, index) => key`: match by the returned key
362
+ *
363
+ * @defaultValue append
364
+ * @see matchByIndex
365
+ * @see matchByDataKey
366
+ * @see matchAppend
367
+ */
368
+ animationMatchBy?: AnimationMatchByProp<RadialBarDataItem>;
369
+ /**
370
+ * Renders a background for each bar. Options:
371
+ * - `false`: no background;
372
+ * - `true`: renders default background;
373
+ * - `object`: the props of background rectangle;
374
+ * - `ReactElement`: a custom background element;
375
+ * - `function`: a render function of custom background.
376
+ *
377
+ * @defaultValue false
378
+ */
379
+ background?: RadialBarBackground;
380
+ /**
381
+ * The width or height of each bar. If the barSize is not specified, the size of the bar will be calculated by the barCategoryGap, barGap and the quantity of bar groups.
382
+ */
383
+ barSize?: number;
384
+ className?: string;
385
+ /**
386
+ * @defaultValue false
387
+ */
388
+ cornerIsExternal?: boolean;
389
+ /**
390
+ * @defaultValue 0
391
+ */
392
+ cornerRadius?: string | number;
393
+ /**
394
+ * Calculated radial bar sectors
395
+ */
396
+ sectors: ReadonlyArray<RadialBarDataItem>;
397
+ /**
398
+ * @defaultValue false
399
+ */
400
+ forceCornerRadius?: boolean;
401
+ /**
402
+ * @defaultValue false
403
+ */
404
+ hide?: boolean;
405
+ /**
406
+ * If set false, animation of radial bars will be disabled.
407
+ * If set "auto", the animation will be disabled in SSR and will respect the user's prefers-reduced-motion system preference for accessibility.
408
+ * @defaultValue auto
409
+ */
410
+ isAnimationActive?: boolean | 'auto';
411
+ /**
412
+ * Renders one label for each data point. Options:
413
+ * - `true`: renders default labels;
414
+ * - `false`: no labels are rendered;
415
+ * - `object`: the props of LabelList component;
416
+ * - `ReactElement`: a custom SVG label element, such as `<text>` or `<g>`.
417
+ * HTML elements such as `<div>` are not valid inside the chart SVG and may trigger React DOM warnings.
418
+ * - `function`: a render function of custom label.
419
+ *
420
+ * @defaultValue false
421
+ */
422
+ label?: ImplicitLabelListType;
423
+ /**
424
+ * The type of icon in legend. If set to 'none', no legend item will be rendered.
425
+ * @defaultValue rect
426
+ */
427
+ legendType?: LegendType;
428
+ maxBarSize?: number;
429
+ /**
430
+ * @defaultValue 0
431
+ */
432
+ minPointSize?: number;
433
+ /**
434
+ * The customized event handler of animation end
435
+ */
436
+ onAnimationEnd?: () => void;
437
+ /**
438
+ * The customized event handler of animation start
439
+ */
440
+ onAnimationStart?: () => void;
441
+ /**
442
+ * The customized event handler of click in this chart.
443
+ */
444
+ onClick?: (data: RadialBarDataItem, index: number, e: React.MouseEvent<
445
+ SVGGraphicsElement
446
+ >) => void;
447
+ /**
448
+ * The customized event handler of mousedown in this chart.
449
+ */
450
+ onMouseDown?: (data: RadialBarDataItem, index: number, e: React.MouseEvent<
451
+ SVGGraphicsElement
452
+ >) => void;
453
+ /**
454
+ * The customized event handler of mouseup in this chart.
455
+ */
456
+ onMouseUp?: (data: RadialBarDataItem, index: number, e: React.MouseEvent<
457
+ SVGGraphicsElement
458
+ >) => void;
459
+ /**
460
+ * The customized event handler of mousemove in this chart.
461
+ */
462
+ onMouseMove?: (data: RadialBarDataItem, index: number, e: React.MouseEvent<
463
+ SVGGraphicsElement
464
+ >) => void;
465
+ /**
466
+ * The customized event handler of mouseover in this chart.
467
+ */
468
+ onMouseOver?: (data: RadialBarDataItem, index: number, e: React.MouseEvent<
469
+ SVGGraphicsElement
470
+ >) => void;
471
+ /**
472
+ * The customized event handler of mouseout in this chart.
473
+ */
474
+ onMouseOut?: (data: RadialBarDataItem, index: number, e: React.MouseEvent<
475
+ SVGGraphicsElement
476
+ >) => void;
477
+ /**
478
+ * The customized event handler of mouseenter in this chart.
479
+ */
480
+ onMouseEnter?: (data: RadialBarDataItem, index: number, e: React.MouseEvent<
481
+ SVGGraphicsElement
482
+ >) => void;
483
+ /**
484
+ * The customized event handler of mouseleave in this chart.
485
+ */
486
+ onMouseLeave?: (data: RadialBarDataItem, index: number, e: React.MouseEvent<
487
+ SVGGraphicsElement
488
+ >) => void;
489
+ onTouchStart?: (data: RadialBarDataItem, index: number, e: React.TouchEvent<
490
+ SVGGraphicsElement
491
+ >) => void;
492
+ onTouchMove?: (data: RadialBarDataItem, index: number, e: React.TouchEvent<
493
+ SVGGraphicsElement
494
+ >) => void;
495
+ onTouchEnd?: (data: RadialBarDataItem, index: number, e: React.TouchEvent<
496
+ SVGGraphicsElement
497
+ >) => void;
498
+ /**
499
+ * @defaultValue 0
500
+ */
501
+ radiusAxisId?: AxisId;
502
+ /**
503
+ * If set a ReactElement, the shape of radial bar sectors can be customized.
504
+ * If set a function, the function will be called to render customized shape.
505
+ * During animations, the function shape also receives `animationElapsedTime`, `isAnimating`, and `isEntrance`.
506
+ * By default, renders a sector.
507
+ */
508
+ shape?: ActiveShape<RadialBarSectorProps, SVGPathElement>;
509
+ stackId?: string | number;
510
+ tooltipType?: TooltipType;
511
+ /**
512
+ * Formats the value displayed in the tooltip for this RadialBar.
513
+ * When set, takes precedence over the `formatter` prop on the Tooltip component.
514
+ */
515
+ formatter?: Formatter;
516
+ /**
517
+ * @defaultValue 300
518
+ */
519
+ zIndex?: number;
520
+ }
521
+
522
+ export type RadialBarProps<DataPointType = any, DataValueType = any> =
523
+ Omit<
524
+ PresentationAttributesAdaptChildEvent<RadialBarDataItem, SVGElement>,
525
+ 'ref' | keyof InternalRadialBarProps<DataPointType, DataValueType>
526
+ > & Omit<InternalRadialBarProps<DataPointType, DataValueType>, 'sectors'>;
527
+
528
+ type InternalProps = WithIdRequired<PropsWithDefaults> & Pick<InternalRadialBarProps, 'sectors'>;
529
+
530
+ function SetRadialBarPayloadLegend(props: RadialBarProps) {
531
+ const legendPayload = useAppSelector(
532
+ (state) => selectRadialBarLegendPayload(state, props.legendType),
533
+ );
534
+ return <SetPolarLegendPayload legendPayload={legendPayload ?? []} />;
535
+ }
536
+
537
+ const SetRadialBarTooltipEntrySettings = React.memo(({
538
+ dataKey,
539
+ sectors,
540
+ stroke,
541
+ strokeWidth,
542
+ name,
543
+ hide,
544
+ fill,
545
+ tooltipType,
546
+ formatter,
547
+ id,
548
+ }: Pick<
549
+ InternalProps,
550
+ | 'dataKey'
551
+ | 'sectors'
552
+ | 'stroke'
553
+ | 'strokeWidth'
554
+ | 'name'
555
+ | 'hide'
556
+ | 'fill'
557
+ | 'tooltipType'
558
+ | 'formatter'
559
+ | 'id'
560
+ >) => {
561
+ const tooltipEntrySettings: TooltipPayloadConfiguration = {
562
+ dataDefinedOnItem: sectors,
563
+ getPosition: noop,
564
+ settings: {
565
+ graphicalItemId: id,
566
+ stroke,
567
+ strokeWidth,
568
+ fill,
569
+ nameKey: undefined, // RadialBar does not have nameKey, why?
570
+ dataKey,
571
+ name: getTooltipNameProp(name, dataKey),
572
+ hide,
573
+ type: tooltipType,
574
+ color: fill,
575
+ unit: '', // Why does RadialBar not support unit?
576
+ formatter,
577
+ },
578
+ };
579
+ return <SetTooltipEntrySettings tooltipEntrySettings={tooltipEntrySettings} />;
580
+ });
581
+
582
+ function renderBackground(props: InternalProps, sectors?: ReadonlyArray<RadialBarDataItem>) {
583
+ if (sectors == null) {
584
+ return null;
585
+ }
586
+ const { cornerRadius } = props;
587
+ const backgroundProps = svgPropertiesNoEventsFromUnknown(props.background);
588
+ return <ZIndexLayer
589
+ zIndex={getZIndexFromUnknown(props.background, DefaultZIndexes.barBackground)}
590
+ >{sectors.map((entry, i) => {
591
+ const { value, background, ...rest } = entry;
592
+
593
+ if (!background) {
594
+ return null;
595
+ }
596
+
597
+ const sectorProps: React.ComponentProps<typeof RadialBarSector> = {
598
+ cornerRadius: parseCornerRadius(cornerRadius),
599
+ ...rest,
600
+ // @ts-expect-error backgroundProps is contributing unknown props
601
+ fill: '#eee',
602
+ ...background,
603
+ ...backgroundProps,
604
+ ...adaptEventsOfChild(props, entry, i),
605
+ index: i,
606
+ className: clsx('recharts-radial-bar-background-sector', String(backgroundProps?.className)),
607
+ option: background,
608
+ isActive: false,
609
+ };
610
+
611
+ return <RadialBarSector
612
+ key={`background-${rest.cx}-${rest.cy}-${rest.innerRadius}-${rest.outerRadius}-${rest.startAngle}-${rest.endAngle}-${i}`}
613
+ {...sectorProps}
614
+ />;
615
+ })}</ZIndexLayer>;
616
+ }
617
+
618
+ function RadialBarWithState(props: InternalProps) {
619
+ const { hide, sectors, className, background } = props;
620
+
621
+ if (hide) {
622
+ return props.children;
623
+ }
624
+
625
+ const layerClass = clsx('recharts-area', className);
626
+
627
+ return <ZIndexLayer zIndex={props.zIndex}>
628
+ <Layer className={layerClass}>
629
+ {background &&
630
+ <Layer className="recharts-radial-bar-background">{renderBackground(
631
+ props,
632
+ sectors,
633
+ )}</Layer>}
634
+ <Layer className="recharts-radial-bar-sectors">
635
+ <RenderSectors {...props} />
636
+ </Layer>
637
+ </Layer>
638
+ </ZIndexLayer>;
639
+ }
640
+
641
+ function RadialBarImpl(props: WithIdRequired<PropsWithDefaults>) {
642
+ const [cells, cellRegistry] = useCellRegistry();
643
+
644
+ const radialBarSettings: RadialBarSettings = React.useMemo(
645
+ () => ({
646
+ data: undefined,
647
+ hide: false,
648
+ id: props.id,
649
+ dataKey: props.dataKey,
650
+ minPointSize: props.minPointSize,
651
+ stackId: getNormalizedStackId(props.stackId),
652
+ maxBarSize: props.maxBarSize,
653
+ barSize: props.barSize,
654
+ type: 'radialBar',
655
+ angleAxisId: props.angleAxisId,
656
+ radiusAxisId: props.radiusAxisId,
657
+ }),
658
+ [
659
+ props.id,
660
+ props.dataKey,
661
+ props.minPointSize,
662
+ props.stackId,
663
+ props.maxBarSize,
664
+ props.barSize,
665
+ props.angleAxisId,
666
+ props.radiusAxisId,
667
+ ],
668
+ );
669
+ const sectors: ReadonlyArray<RadialBarDataItem> =
670
+ useAppSelector(
671
+ (state) => selectRadialBarSectors(
672
+ state,
673
+ props.radiusAxisId,
674
+ props.angleAxisId,
675
+ radialBarSettings,
676
+ cells,
677
+ ),
678
+ ) ??
679
+ STABLE_EMPTY_ARRAY;
680
+ return <CellsContext.Provider value={cellRegistry}>
681
+ <SetRadialBarTooltipEntrySettings
682
+ dataKey={props.dataKey}
683
+ sectors={sectors}
684
+ stroke={props.stroke}
685
+ strokeWidth={props.strokeWidth}
686
+ name={props.name}
687
+ hide={props.hide}
688
+ fill={props.fill}
689
+ tooltipType={props.tooltipType}
690
+ formatter={props.formatter}
691
+ id={props.id}
692
+ />
693
+ <RadialBarWithState {...props} sectors={sectors} />
694
+ </CellsContext.Provider>;
695
+ }
696
+
697
+ export const defaultRadialBarProps = {
698
+ angleAxisId: 0,
699
+ animationBegin: 0,
700
+ animationDuration: 1500,
701
+ animationEasing: 'ease',
702
+ animationMatchBy: matchAppend,
703
+ animationInterpolateFn: defaultRadialBarAnimateItems,
704
+ background: false,
705
+ cornerIsExternal: false,
706
+ cornerRadius: 0,
707
+ forceCornerRadius: false,
708
+ hide: false,
709
+ isAnimationActive: 'auto',
710
+ label: false,
711
+ legendType: 'rect',
712
+ minPointSize: 0,
713
+ radiusAxisId: 0,
714
+ shape: defaultRadialBarShape,
715
+ zIndex: DefaultZIndexes.bar,
716
+ } as const satisfies Partial<RadialBarProps>;
717
+
718
+ type PropsWithDefaults<DataPointType = any, DataValueType = any> =
719
+ RequiresDefaultProps<RadialBarProps<DataPointType, DataValueType>, typeof defaultRadialBarProps>;
720
+
721
+ export function computeRadialBarDataItems({
722
+ displayedData,
723
+ stackedData,
724
+ dataStartIndex,
725
+ stackedDomain,
726
+ dataKey,
727
+ baseValue,
728
+ layout,
729
+ radiusAxis,
730
+ radiusAxisTicks,
731
+ bandSize,
732
+ pos,
733
+ angleAxis,
734
+ minPointSize,
735
+ cx,
736
+ cy,
737
+ angleAxisTicks,
738
+ cells,
739
+ startAngle: rootStartAngle,
740
+ endAngle: rootEndAngle,
741
+ }: {
742
+ displayedData: ChartData;
743
+ stackedData: Series<Record<number, number>, DataKey<any>> | undefined;
744
+ dataStartIndex: number;
745
+ stackedDomain: ReadonlyArray<unknown> | null;
746
+ dataKey: DataKey<any> | undefined;
747
+ baseValue: number | unknown;
748
+ layout: LayoutType;
749
+ radiusAxis: BaseAxisWithScale;
750
+ radiusAxisTicks: ReadonlyArray<TickItem> | undefined;
751
+ bandSize: number;
752
+ pos: BarPositionPosition;
753
+ angleAxis: BaseAxisWithScale;
754
+ minPointSize: number;
755
+ cx: number;
756
+ cy: number;
757
+ angleAxisTicks: ReadonlyArray<TickItem> | undefined;
758
+ cells: ReadonlyArray<ReactElement> | undefined;
759
+ startAngle: number;
760
+ endAngle: number;
761
+ }): ReadonlyArray<RadialBarDataItem> {
762
+ if (angleAxisTicks == null || radiusAxisTicks == null) {
763
+ return STABLE_EMPTY_ARRAY;
764
+ }
765
+
766
+ return (displayedData ?? []).map((entry: unknown, index: number) => {
767
+ let value, innerRadius: number | null | undefined, outerRadius: | number
768
+ | undefined, startAngle: number | null, endAngle: number, backgroundSector;
769
+
770
+ if (stackedData) {
771
+ // @ts-expect-error truncateByDomain expects only numerical domain, but it can received categorical domain too
772
+ value = truncateByDomain(stackedData[dataStartIndex + index], stackedDomain);
773
+ } else {
774
+ value = getValueByDataKey(entry, dataKey);
775
+ if (!Array.isArray(value)) {
776
+ value = [baseValue, value];
777
+ }
778
+ }
779
+
780
+ if (layout === 'radial') {
781
+ startAngle = angleAxis.scale.map(value[0]) ?? rootStartAngle;
782
+ endAngle = angleAxis.scale.map(value[1]) ?? rootEndAngle;
783
+ innerRadius = getCateCoordinateOfBar({
784
+ axis: radiusAxis,
785
+ ticks: radiusAxisTicks,
786
+ bandSize,
787
+ offset: pos.offset,
788
+ entry,
789
+ index,
790
+ });
791
+ if (innerRadius != null && endAngle != null && startAngle != null) {
792
+ outerRadius = innerRadius + pos.size;
793
+ const deltaAngle = endAngle - startAngle;
794
+
795
+ if (Math.abs(minPointSize) > 0 && Math.abs(deltaAngle) < Math.abs(minPointSize)) {
796
+ const delta =
797
+ mathSign(deltaAngle || minPointSize) * (Math.abs(minPointSize) - Math.abs(deltaAngle));
798
+
799
+ endAngle += delta;
800
+ }
801
+ backgroundSector = {
802
+ background: {
803
+ cx,
804
+ cy,
805
+ innerRadius,
806
+ outerRadius,
807
+ startAngle: rootStartAngle,
808
+ endAngle: rootEndAngle,
809
+ },
810
+ };
811
+ }
812
+ } else {
813
+ innerRadius = radiusAxis.scale.map(value[0]);
814
+ outerRadius = radiusAxis.scale.map(value[1]);
815
+ startAngle = getCateCoordinateOfBar({
816
+ axis: angleAxis,
817
+ ticks: angleAxisTicks,
818
+ bandSize,
819
+ offset: pos.offset,
820
+ entry,
821
+ index,
822
+ });
823
+ if (innerRadius != null && outerRadius != null && startAngle != null) {
824
+ endAngle = startAngle + pos.size;
825
+ const deltaRadius = outerRadius - innerRadius;
826
+
827
+ if (Math.abs(minPointSize) > 0 && Math.abs(deltaRadius) < Math.abs(minPointSize)) {
828
+ const delta =
829
+ mathSign(deltaRadius || minPointSize) *
830
+ (Math.abs(minPointSize) - Math.abs(deltaRadius));
831
+ outerRadius += delta;
832
+ }
833
+ }
834
+ }
835
+
836
+ return {
837
+ // @ts-expect-error can't spread unknown
838
+ ...entry,
839
+ ...backgroundSector,
840
+ payload: entry,
841
+ value: stackedData ? value : value[1],
842
+ cx,
843
+ cy,
844
+ innerRadius,
845
+ outerRadius,
846
+ startAngle,
847
+ // @ts-expect-error endAngle is used before assigned (?)
848
+ endAngle,
849
+ ...cells && cells[index] && cells[index].props,
850
+ } satisfies RadialBarDataItem;
851
+ });
852
+ }
853
+
854
+ /**
855
+ * @consumes PolarChartContext
856
+ * @provides LabelListContext
857
+ * @provides CellReader
858
+ */
859
+ export function RadialBar<DataPointType = any, DataValueType = any>(
860
+ outsideProps: RadialBarProps<DataPointType, DataValueType>,
861
+ ) {
862
+ const props: PropsWithDefaults<DataPointType, DataValueType> = resolveDefaultProps(
863
+ outsideProps,
864
+ defaultRadialBarProps,
865
+ );
866
+ return <RegisterGraphicalItemId id={props.id} type="radialBar">
867
+ {(id) => <>
868
+ <SetPolarGraphicalItem
869
+ type="radialBar"
870
+ id={id}
871
+ data={undefined}
872
+ dataKey={props.dataKey}
873
+ hide={props.hide ?? defaultRadialBarProps.hide}
874
+ angleAxisId={props.angleAxisId ?? defaultRadialBarProps.angleAxisId}
875
+ radiusAxisId={props.radiusAxisId ?? defaultRadialBarProps.radiusAxisId}
876
+ stackId={getNormalizedStackId(props.stackId)}
877
+ barSize={props.barSize}
878
+ minPointSize={props.minPointSize}
879
+ maxBarSize={props.maxBarSize}
880
+ />
881
+ <SetRadialBarPayloadLegend {...props} />
882
+ <RadialBarImpl {...props} id={id} />
883
+ </>}
884
+ </RegisterGraphicalItemId>;
885
+ }
886
+
887
+ RadialBar.displayName = 'RadialBar';