@solidports/recharts 0.1.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 (306) hide show
  1. package/LICENSE +22 -0
  2. package/NOTICE +19 -0
  3. package/README.md +102 -0
  4. package/dist/dev.js +28564 -0
  5. package/dist/index.d.ts +7859 -0
  6. package/dist/index.js +28546 -0
  7. package/package.json +98 -0
  8. package/src/animation/AnimatedItems.tsx +183 -0
  9. package/src/animation/AnimationController.ts +33 -0
  10. package/src/animation/AnimationControllerImpl.ts +36 -0
  11. package/src/animation/AnimationHandle.ts +307 -0
  12. package/src/animation/CSSTransitionAnimate.tsx +170 -0
  13. package/src/animation/JavascriptAnimate.tsx +119 -0
  14. package/src/animation/easing.ts +221 -0
  15. package/src/animation/matchBy.ts +164 -0
  16. package/src/animation/timeoutController.ts +70 -0
  17. package/src/animation/useAnimationController.tsx +34 -0
  18. package/src/animation/useAnimationStartSnapshot.ts +118 -0
  19. package/src/animation/util.ts +41 -0
  20. package/src/cartesian/Area.tsx +915 -0
  21. package/src/cartesian/AreaRevealShape.tsx +190 -0
  22. package/src/cartesian/Bar.tsx +1369 -0
  23. package/src/cartesian/BarStack.tsx +152 -0
  24. package/src/cartesian/Brush.tsx +951 -0
  25. package/src/cartesian/CartesianAxis.tsx +722 -0
  26. package/src/cartesian/CartesianGrid.tsx +711 -0
  27. package/src/cartesian/ErrorBar.tsx +361 -0
  28. package/src/cartesian/Funnel.tsx +803 -0
  29. package/src/cartesian/GraphicalItemClipPath.tsx +67 -0
  30. package/src/cartesian/Line.tsx +863 -0
  31. package/src/cartesian/LineDrawShape.tsx +89 -0
  32. package/src/cartesian/ReferenceArea.tsx +331 -0
  33. package/src/cartesian/ReferenceDot.tsx +304 -0
  34. package/src/cartesian/ReferenceLine.tsx +474 -0
  35. package/src/cartesian/Scatter.tsx +888 -0
  36. package/src/cartesian/XAxis.tsx +433 -0
  37. package/src/cartesian/YAxis.tsx +443 -0
  38. package/src/cartesian/ZAxis.tsx +155 -0
  39. package/src/cartesian/cartesianPositionToCSSTranslate.tsx +29 -0
  40. package/src/cartesian/cartesianViewBoxToTrapezoid.tsx +21 -0
  41. package/src/cartesian/getCartesianPosition.tsx +267 -0
  42. package/src/cartesian/getEquidistantTicks.ts +144 -0
  43. package/src/cartesian/getTicks.ts +225 -0
  44. package/src/cartesian/isOutsidePosition.ts +15 -0
  45. package/src/cartesian/useAnimatedLineLength.ts +54 -0
  46. package/src/chart/AreaChart.tsx +29 -0
  47. package/src/chart/BarChart.tsx +29 -0
  48. package/src/chart/CartesianChart.tsx +131 -0
  49. package/src/chart/CategoricalChart.tsx +94 -0
  50. package/src/chart/ComposedChart.tsx +29 -0
  51. package/src/chart/FunnelChart.tsx +29 -0
  52. package/src/chart/LineChart.tsx +29 -0
  53. package/src/chart/PieChart.tsx +50 -0
  54. package/src/chart/PolarChart.tsx +164 -0
  55. package/src/chart/RadarChart.tsx +70 -0
  56. package/src/chart/RadialBarChart.tsx +46 -0
  57. package/src/chart/RechartsWrapper.tsx +551 -0
  58. package/src/chart/Sankey.tsx +1534 -0
  59. package/src/chart/ScatterChart.tsx +29 -0
  60. package/src/chart/SunburstChart.tsx +504 -0
  61. package/src/chart/Treemap.tsx +1223 -0
  62. package/src/chart/createInitialRootProps.ts +24 -0
  63. package/src/chart/types.ts +53 -0
  64. package/src/component/ActivePoints.tsx +144 -0
  65. package/src/component/Cell.tsx +37 -0
  66. package/src/component/Cursor.tsx +185 -0
  67. package/src/component/Customized.tsx +50 -0
  68. package/src/component/DefaultLegendContent.tsx +348 -0
  69. package/src/component/DefaultTooltipContent.tsx +224 -0
  70. package/src/component/Dots.tsx +157 -0
  71. package/src/component/Label.tsx +636 -0
  72. package/src/component/LabelList.tsx +375 -0
  73. package/src/component/Legend.tsx +512 -0
  74. package/src/component/ResponsiveContainer.tsx +348 -0
  75. package/src/component/Text.tsx +541 -0
  76. package/src/component/Tooltip.tsx +470 -0
  77. package/src/component/TooltipBoundingBox.tsx +146 -0
  78. package/src/component/responsiveContainerUtils.ts +134 -0
  79. package/src/container/ClipPathProvider.tsx +51 -0
  80. package/src/container/Layer.tsx +38 -0
  81. package/src/container/RootSurface.tsx +120 -0
  82. package/src/container/Surface.tsx +61 -0
  83. package/src/context/CellsContext.tsx +54 -0
  84. package/src/context/ErrorBarContext.tsx +146 -0
  85. package/src/context/GraphicalItemChildrenScope.tsx +18 -0
  86. package/src/context/PanoramaContext.tsx +9 -0
  87. package/src/context/RegisterGraphicalItemId.tsx +30 -0
  88. package/src/context/accessibilityContext.tsx +6 -0
  89. package/src/context/brushUpdateContext.tsx +9 -0
  90. package/src/context/chartDataContext.tsx +97 -0
  91. package/src/context/chartLayoutContext.tsx +201 -0
  92. package/src/context/legendPayloadContext.tsx +20 -0
  93. package/src/context/legendPortalContext.tsx +12 -0
  94. package/src/context/tooltipContext.tsx +89 -0
  95. package/src/context/tooltipPortalContext.tsx +12 -0
  96. package/src/context/useTooltipAxis.ts +22 -0
  97. package/src/hooks.ts +476 -0
  98. package/src/index.ts +280 -0
  99. package/src/polar/Pie.tsx +1360 -0
  100. package/src/polar/PolarAngleAxis.tsx +616 -0
  101. package/src/polar/PolarGrid.tsx +312 -0
  102. package/src/polar/PolarRadiusAxis.tsx +547 -0
  103. package/src/polar/Radar.tsx +734 -0
  104. package/src/polar/RadialBar.tsx +917 -0
  105. package/src/polar/defaultPolarAngleAxisProps.tsx +27 -0
  106. package/src/polar/defaultPolarRadiusAxisProps.tsx +25 -0
  107. package/src/shape/Cross.tsx +89 -0
  108. package/src/shape/Curve.tsx +343 -0
  109. package/src/shape/Dot.tsx +70 -0
  110. package/src/shape/Polygon.tsx +195 -0
  111. package/src/shape/Rectangle.tsx +470 -0
  112. package/src/shape/Sector.tsx +347 -0
  113. package/src/shape/Symbols.tsx +139 -0
  114. package/src/shape/Trapezoid.tsx +280 -0
  115. package/src/state/RechartsStateContext.tsx +12 -0
  116. package/src/state/RechartsStateProvider.tsx +87 -0
  117. package/src/state/RechartsStoreContext.tsx +25 -0
  118. package/src/state/RechartsStoreProvider.tsx +35 -0
  119. package/src/state/ReportChartProps.tsx +40 -0
  120. package/src/state/ReportEventSettings.tsx +30 -0
  121. package/src/state/ReportMainChartProps.tsx +61 -0
  122. package/src/state/ReportPolarOptions.tsx +35 -0
  123. package/src/state/SetGraphicalItem.ts +79 -0
  124. package/src/state/SetLegendPayload.ts +134 -0
  125. package/src/state/SetTooltipEntrySettings.tsx +72 -0
  126. package/src/state/actions.ts +464 -0
  127. package/src/state/brushSlice.ts +13 -0
  128. package/src/state/cartesianAxisSlice.ts +141 -0
  129. package/src/state/chartDataSlice.ts +50 -0
  130. package/src/state/chartState.ts +297 -0
  131. package/src/state/errorBarSlice.ts +29 -0
  132. package/src/state/eventSettingsSlice.ts +8 -0
  133. package/src/state/events.ts +76 -0
  134. package/src/state/externalEventsMiddleware.ts +255 -0
  135. package/src/state/graphicalItemsSlice.ts +74 -0
  136. package/src/state/hooks/useChartSelectors.tsx +45 -0
  137. package/src/state/keyboardEventsMiddleware.ts +228 -0
  138. package/src/state/layoutSlice.ts +21 -0
  139. package/src/state/legendSlice.ts +57 -0
  140. package/src/state/mouseEventsMiddleware.ts +185 -0
  141. package/src/state/optionsSlice.ts +47 -0
  142. package/src/state/polarAxisSlice.ts +10 -0
  143. package/src/state/polarOptionsSlice.ts +12 -0
  144. package/src/state/rawData.ts +26 -0
  145. package/src/state/referenceElementsSlice.ts +40 -0
  146. package/src/state/renderedTicksSlice.ts +15 -0
  147. package/src/state/rootPropsSlice.ts +47 -0
  148. package/src/state/selectors/areaSelectors.ts +240 -0
  149. package/src/state/selectors/arrayEqualityCheck.ts +29 -0
  150. package/src/state/selectors/axisSelectors.ts +2157 -0
  151. package/src/state/selectors/barSelectors.ts +310 -0
  152. package/src/state/selectors/barStackSelectors.ts +77 -0
  153. package/src/state/selectors/brushSelectors.ts +33 -0
  154. package/src/state/selectors/chartSelector.ts +185 -0
  155. package/src/state/selectors/combiners/combineActiveLabel.ts +16 -0
  156. package/src/state/selectors/combiners/combineActiveTooltipIndex.ts +95 -0
  157. package/src/state/selectors/combiners/combineAllBarPositions.ts +122 -0
  158. package/src/state/selectors/combiners/combineAxisRangeWithReverse.ts +16 -0
  159. package/src/state/selectors/combiners/combineBarPosition.ts +23 -0
  160. package/src/state/selectors/combiners/combineBarSizeList.ts +80 -0
  161. package/src/state/selectors/combiners/combineCheckedDomain.ts +48 -0
  162. package/src/state/selectors/combiners/combineConfiguredScale.ts +111 -0
  163. package/src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts +45 -0
  164. package/src/state/selectors/combiners/combineDisplayedStackedData.ts +50 -0
  165. package/src/state/selectors/combiners/combineInverseScaleFunction.ts +16 -0
  166. package/src/state/selectors/combiners/combineRealScaleType.ts +44 -0
  167. package/src/state/selectors/combiners/combineStackedData.ts +27 -0
  168. package/src/state/selectors/combiners/combineTooltipInteractionState.ts +86 -0
  169. package/src/state/selectors/combiners/combineTooltipPayload.ts +205 -0
  170. package/src/state/selectors/combiners/combineTooltipPayloadConfigurations.ts +58 -0
  171. package/src/state/selectors/containerSelectors.ts +12 -0
  172. package/src/state/selectors/dataSelectors.ts +88 -0
  173. package/src/state/selectors/funnelSelectors.ts +75 -0
  174. package/src/state/selectors/graphicalItemSelectors.ts +30 -0
  175. package/src/state/selectors/legendSelectors.ts +29 -0
  176. package/src/state/selectors/lineSelectors.ts +134 -0
  177. package/src/state/selectors/numberDomainEqualityCheck.ts +14 -0
  178. package/src/state/selectors/pickAxisId.ts +5 -0
  179. package/src/state/selectors/pickAxisType.ts +3 -0
  180. package/src/state/selectors/pieSelectors.ts +97 -0
  181. package/src/state/selectors/polarAxisSelectors.ts +201 -0
  182. package/src/state/selectors/polarGridSelectors.ts +28 -0
  183. package/src/state/selectors/polarScaleSelectors.ts +133 -0
  184. package/src/state/selectors/polarSelectors.ts +219 -0
  185. package/src/state/selectors/radarSelectors.ts +191 -0
  186. package/src/state/selectors/radialBarSelectors.ts +435 -0
  187. package/src/state/selectors/rootPropsSelectors.ts +25 -0
  188. package/src/state/selectors/scatterSelectors.ts +96 -0
  189. package/src/state/selectors/selectActivePropsFromChartPointer.ts +26 -0
  190. package/src/state/selectors/selectAllAxes.ts +17 -0
  191. package/src/state/selectors/selectChartOffset.ts +16 -0
  192. package/src/state/selectors/selectChartOffsetInternal.ts +136 -0
  193. package/src/state/selectors/selectLegendArea.ts +20 -0
  194. package/src/state/selectors/selectPlotArea.ts +22 -0
  195. package/src/state/selectors/selectTooltipAxisId.ts +7 -0
  196. package/src/state/selectors/selectTooltipAxisType.ts +32 -0
  197. package/src/state/selectors/selectTooltipEventType.ts +48 -0
  198. package/src/state/selectors/selectTooltipPayloadSearcher.ts +6 -0
  199. package/src/state/selectors/selectTooltipSettings.ts +39 -0
  200. package/src/state/selectors/selectTooltipState.ts +8 -0
  201. package/src/state/selectors/selectors.ts +271 -0
  202. package/src/state/selectors/tooltipSelectors.ts +578 -0
  203. package/src/state/selectors/touchSelectors.ts +31 -0
  204. package/src/state/store.ts +29 -0
  205. package/src/state/storeIdentity.ts +9 -0
  206. package/src/state/teardownWrite.ts +10 -0
  207. package/src/state/tooltipInteraction.ts +23 -0
  208. package/src/state/tooltipSlice.ts +334 -0
  209. package/src/state/touchEventsMiddleware.ts +214 -0
  210. package/src/state/types/AnimationSettings.ts +20 -0
  211. package/src/state/types/AreaSettings.ts +14 -0
  212. package/src/state/types/BarSettings.ts +15 -0
  213. package/src/state/types/LineSettings.ts +9 -0
  214. package/src/state/types/PieSettings.ts +34 -0
  215. package/src/state/types/RadarSettings.ts +5 -0
  216. package/src/state/types/RadialBarSettings.ts +10 -0
  217. package/src/state/types/ScatterSettings.ts +12 -0
  218. package/src/state/types/StackedGraphicalItem.ts +34 -0
  219. package/src/state/useChartState.ts +17 -0
  220. package/src/state/zIndexSlice.ts +39 -0
  221. package/src/synchronisation/syncSelectors.ts +7 -0
  222. package/src/synchronisation/types.ts +44 -0
  223. package/src/synchronisation/useChartSynchronisation.tsx +404 -0
  224. package/src/theme/RechartsTheme.ts +16 -0
  225. package/src/theme/RechartsThemeContext.ts +19 -0
  226. package/src/theme/darkTheme.ts +13 -0
  227. package/src/theme/graphicalItemIdentity.ts +70 -0
  228. package/src/theme/legacyTheme.ts +17 -0
  229. package/src/theme/lightTheme.ts +13 -0
  230. package/src/types.ts +54 -0
  231. package/src/util/ActiveShapeUtils.tsx +162 -0
  232. package/src/util/BarUtils.tsx +62 -0
  233. package/src/util/BarePortal.tsx +50 -0
  234. package/src/util/CamelCaseSVGAttrs.ts +34 -0
  235. package/src/util/CartesianUtils.ts +48 -0
  236. package/src/util/ChartUtils.ts +802 -0
  237. package/src/util/Constants.ts +42 -0
  238. package/src/util/CssPrefixUtils.ts +20 -0
  239. package/src/util/DOMUtils.ts +129 -0
  240. package/src/util/DataUtils.ts +216 -0
  241. package/src/util/Events.ts +16 -0
  242. package/src/util/FunnelUtils.tsx +15 -0
  243. package/src/util/Global.ts +12 -0
  244. package/src/util/IfOverflow.ts +15 -0
  245. package/src/util/LRUCache.ts +41 -0
  246. package/src/util/LogUtils.ts +22 -0
  247. package/src/util/PolarUtils.ts +132 -0
  248. package/src/util/RadialBarUtils.tsx +24 -0
  249. package/src/util/ReactUtils.ts +95 -0
  250. package/src/util/ReduceCSSCalc.ts +187 -0
  251. package/src/util/ScatterUtils.tsx +52 -0
  252. package/src/util/ShapeElementProps.tsx +87 -0
  253. package/src/util/TickUtils.ts +60 -0
  254. package/src/util/XAxisUtils.ts +48 -0
  255. package/src/util/YAxisUtils.ts +48 -0
  256. package/src/util/axisPropsAreEqual.ts +48 -0
  257. package/src/util/createCartesianCharts.tsx +150 -0
  258. package/src/util/createEventProxy.ts +20 -0
  259. package/src/util/createPolarCharts.tsx +112 -0
  260. package/src/util/cursor/getCursorPoints.ts +46 -0
  261. package/src/util/cursor/getCursorRectangle.ts +28 -0
  262. package/src/util/cursor/getRadialCursorPoints.ts +32 -0
  263. package/src/util/excludeEventProps.ts +171 -0
  264. package/src/util/getActiveCoordinate.ts +213 -0
  265. package/src/util/getAxisTypeBasedOnLayout.ts +21 -0
  266. package/src/util/getClassNameFromUnknown.ts +6 -0
  267. package/src/util/getEveryNth.ts +27 -0
  268. package/src/util/getRadiusAndStrokeWidthFromDot.ts +35 -0
  269. package/src/util/getRelativeCoordinate.ts +80 -0
  270. package/src/util/getSliced.ts +13 -0
  271. package/src/util/hoverDedupe.ts +41 -0
  272. package/src/util/isDomainSpecifiedByUser.ts +219 -0
  273. package/src/util/isWellBehavedNumber.ts +7 -0
  274. package/src/util/pathTotalLength.ts +25 -0
  275. package/src/util/payload/getUniqPayload.ts +28 -0
  276. package/src/util/propsAreEqual.ts +121 -0
  277. package/src/util/resolveDefaultProps.ts +161 -0
  278. package/src/util/round.ts +32 -0
  279. package/src/util/scale/CartesianScaleHelper.ts +72 -0
  280. package/src/util/scale/CustomScaleDefinition.ts +81 -0
  281. package/src/util/scale/RechartsScale.ts +130 -0
  282. package/src/util/scale/createCategoricalInverse.ts +72 -0
  283. package/src/util/scale/getNiceTickValues.ts +311 -0
  284. package/src/util/scale/index.ts +2 -0
  285. package/src/util/scale/util/arithmetic.ts +54 -0
  286. package/src/util/solid-1-compat.ts +310 -0
  287. package/src/util/solidJsxCamelAugment.d.ts +84 -0
  288. package/src/util/stacks/getStackSeriesIdentifier.ts +21 -0
  289. package/src/util/stacks/stackTypes.ts +60 -0
  290. package/src/util/structurallyEqual.ts +31 -0
  291. package/src/util/svgPropertiesAndEvents.ts +53 -0
  292. package/src/util/svgPropertiesNoEvents.ts +571 -0
  293. package/src/util/tooltip/translate.ts +171 -0
  294. package/src/util/typedDataKey.ts +48 -0
  295. package/src/util/types.ts +1560 -0
  296. package/src/util/useAnimationId.ts +31 -0
  297. package/src/util/useElementOffset.ts +110 -0
  298. package/src/util/useId.ts +8 -0
  299. package/src/util/usePrefersReducedMotion.ts +48 -0
  300. package/src/util/useReportScale.ts +24 -0
  301. package/src/util/useUniqueId.ts +30 -0
  302. package/src/zIndex/DefaultZIndexes.ts +84 -0
  303. package/src/zIndex/ZIndexLayer.tsx +121 -0
  304. package/src/zIndex/ZIndexPortal.tsx +79 -0
  305. package/src/zIndex/getZIndexFromUnknown.ts +14 -0
  306. package/src/zIndex/zIndexSelectors.ts +48 -0
@@ -0,0 +1,636 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import { createContext, createMemo, untrack, useContext, type Accessor } from 'solid-js';
3
+ import type { WithoutRemoveFalse } from "../util/types"
4
+ import type { CamelCaseSVGAttrs } from "../util/CamelCaseSVGAttrs"
5
+ import type { JSX } from '@solidjs/web';
6
+ import { clsx } from "clsx"
7
+ import {
8
+ isValidTextAnchor,
9
+ type RenderableText,
10
+ Text,
11
+ type TextAnchor,
12
+ type TextVerticalAnchor,
13
+ } from "./Text"
14
+ import { isNullish, isNumber, isNumOrStr, mathSign, uniqueId } from "../util/DataUtils"
15
+ import { polarToCartesian } from "../util/PolarUtils"
16
+ import type {
17
+ CartesianViewBoxRequired,
18
+ DataKey,
19
+ PolarViewBoxRequired,
20
+ TrapezoidViewBox,
21
+ ViewBox,
22
+ } from "../util/types"
23
+ import { cartesianViewBoxToTrapezoid } from "../cartesian/cartesianViewBoxToTrapezoid"
24
+ import { useChartStore } from "../state/RechartsStoreContext"
25
+ import { selectPolarViewBox } from "../state/selectors/polarAxisSelectors"
26
+ import { selectChartViewBox } from "../state/selectors/selectChartOffsetInternal"
27
+ import { resolveDefaultProps } from "../util/resolveDefaultProps"
28
+ import { svgPropertiesAndEvents } from "../util/svgPropertiesAndEvents"
29
+ import { cloneJsxNodeWithProps, isJsxNode } from "../util/ReactUtils"
30
+ import type { ZIndexable } from "../zIndex/ZIndexLayer"
31
+ import { ZIndexLayer } from "../zIndex/ZIndexLayer"
32
+ import { DefaultZIndexes } from "../zIndex/DefaultZIndexes"
33
+
34
+ import {
35
+ type CartesianLabelPosition,
36
+ getCartesianPosition,
37
+ } from "../cartesian/getCartesianPosition"
38
+
39
+ /**
40
+ * @inline
41
+ */
42
+ export type LabelContentType = JSX.Element | ((props: Props) => RenderableText | JSX.Element)
43
+
44
+ type PolarLabelPosition = "insideStart" | "insideEnd" | "end"
45
+
46
+ /**
47
+ * @inline
48
+ */
49
+ export type LabelPosition = CartesianLabelPosition | PolarLabelPosition
50
+
51
+ /**
52
+ * @inline
53
+ */
54
+ export type LabelFormatter = (label: RenderableText) => RenderableText
55
+
56
+ interface LabelProps extends ZIndexable {
57
+ /**
58
+ * The box of viewing area. Used for positioning.
59
+ * If undefined, viewBox will be calculated based on surrounding context.
60
+ */
61
+ viewBox?: ViewBox
62
+ parentViewBox?: ViewBox
63
+ /**
64
+ * Function to customize how content is serialized before rendering.
65
+ *
66
+ * This should return a renderable text - something that the {@link Text} component can render.
67
+ * Typically, a string or number.
68
+ * Custom components are not supported here - use the `content` prop instead.
69
+ */
70
+ formatter?: LabelFormatter
71
+ /**
72
+ * The value of label can be set as children or as the `value` prop
73
+ *
74
+ * @example <Label value="foo" />
75
+ */
76
+ value?: RenderableText
77
+ /**
78
+ * The offset to the specified "position". Direction of the offset depends on the position.
79
+ *
80
+ * @defaultValue 5
81
+ */
82
+ offset?: number
83
+ /**
84
+ * The position of label relative to the view box.
85
+ *
86
+ * @defaultValue middle
87
+ */
88
+ position?: LabelPosition
89
+ /**
90
+ * The value of label can be set as children or as the `value` prop
91
+ *
92
+ * @example <Label>foo</Label>
93
+ */
94
+ children?: RenderableText
95
+ className?: string
96
+ /**
97
+ * If set a JSX element, the option is the custom element of rendering label.
98
+ * If set a function, the function will be called to render label content.
99
+ *
100
+ * @example <Label content={CustomizedLabel} />
101
+ * @example
102
+ * const renderCustomLabel = (props) => <text {...props}>Custom Label</text>
103
+ * <Label content={renderCustomLabel} />
104
+ */
105
+ content?: LabelContentType
106
+ /**
107
+ * @defaultValue false
108
+ */
109
+ textBreakAll?: boolean
110
+ /**
111
+ * Text rotation angle in degrees.
112
+ * Positive values rotate clockwise, negative values rotate counterclockwise.
113
+ *
114
+ * @defaultValue 0
115
+ */
116
+ angle?: number
117
+ index?: number
118
+ labelRef?: SVGTextElement | ((el: SVGTextElement) => void)
119
+ /**
120
+ * Z-Index of this component and its children. The higher the value,
121
+ * the more on top it will be rendered.
122
+ * Components with higher zIndex will appear in front of components with lower zIndex.
123
+ * If undefined or 0, the content is rendered in the default layer without portals.
124
+ *
125
+ * @since 3.4
126
+ * @defaultValue 2000
127
+ * @see {@link https://recharts.github.io/en-US/guide/zIndex/ Z-Index and layers guide}
128
+ */
129
+ zIndex?: number
130
+ /**
131
+ * Unique identifier of this component.
132
+ * Used as an HTML attribute `id`.
133
+ */
134
+ id?: string
135
+ }
136
+
137
+ export type Props = WithoutRemoveFalse<
138
+ Omit<JSX.TextSVGAttributes<SVGTextElement>, "viewBox" | "children" | "ref" | "style">
139
+ > &
140
+ CamelCaseSVGAttrs &
141
+ LabelProps & {
142
+ style?: JSX.CSSProperties
143
+ }
144
+
145
+ type PropsWithDefaults = Props & {
146
+ offset: number
147
+ }
148
+
149
+ export type ImplicitLabelType =
150
+ | boolean
151
+ | string
152
+ | number
153
+ | JSX.Element
154
+ | ((props: Record<string, unknown>) => RenderableText | JSX.Element)
155
+ /* dataKey is only applicable when label is used implicitly from graphical element props */
156
+ | (Props & { dataKey?: DataKey<unknown> })
157
+
158
+ type LabelContextValue<T> = Accessor<T> | T
159
+
160
+ /**
161
+ * Solid 2 `createContext` stores `props.value` as a one-shot snapshot. Passing a
162
+ * memo accessor keeps the value live; the compiler may also unwrap that accessor
163
+ * before the snapshot, so consumers must accept either an accessor or the box.
164
+ */
165
+ function readMaybeAccessor<T>(value: LabelContextValue<T> | null | undefined): T | undefined {
166
+ if (value == null) {
167
+ return undefined
168
+ }
169
+ let current: unknown = value
170
+ for (let i = 0; i < 2 && typeof current === "function"; i++) {
171
+ current = (current as Accessor<unknown>)()
172
+ }
173
+ return current as T
174
+ }
175
+
176
+ const CartesianLabelContext = createContext<LabelContextValue<TrapezoidViewBox> | null>(null)
177
+
178
+ export function CartesianLabelContextProvider(props: TrapezoidViewBox & { children: JSX.Element }) {
179
+ const viewBox = createMemo(
180
+ (): TrapezoidViewBox => ({
181
+ height: props.height,
182
+ lowerWidth: props.lowerWidth,
183
+ upperWidth: props.upperWidth,
184
+ width: props.width,
185
+ x: props.x,
186
+ y: props.y,
187
+ }),
188
+ )
189
+ return <CartesianLabelContext value={viewBox}>{props.children}</CartesianLabelContext>
190
+ }
191
+
192
+ const useCartesianLabelContext = (): TrapezoidViewBox | undefined => {
193
+ const labelChildContext = useContext(CartesianLabelContext)
194
+ const ctx = useChartStore()
195
+ if (labelChildContext != null) {
196
+ return untrack(() => readMaybeAccessor(labelChildContext))
197
+ }
198
+ const rootViewBox = ctx ? selectChartViewBox(ctx.store) : undefined
199
+ return rootViewBox ? cartesianViewBoxToTrapezoid(rootViewBox) : undefined
200
+ }
201
+
202
+ const PolarLabelContext = createContext<LabelContextValue<PolarViewBoxRequired | undefined> | null>(null)
203
+
204
+ /**
205
+ * `pending` keeps the context present but empty: polar labels inside wait (render nothing)
206
+ * instead of falling back to the chart viewBox, e.g. a Pie whose sectors are not known yet.
207
+ */
208
+ export function PolarLabelContextProvider(
209
+ props: PolarViewBoxRequired & { children: JSX.Element; pending?: boolean },
210
+ ) {
211
+ const viewBox = createMemo(
212
+ (): PolarViewBoxRequired | undefined => props.pending ? undefined : ({
213
+ clockWise: props.clockWise,
214
+ cx: props.cx,
215
+ cy: props.cy,
216
+ endAngle: props.endAngle,
217
+ innerRadius: props.innerRadius,
218
+ outerRadius: props.outerRadius,
219
+ startAngle: props.startAngle,
220
+ }),
221
+ )
222
+ return <PolarLabelContext value={viewBox}>{props.children}</PolarLabelContext>
223
+ }
224
+
225
+ export const usePolarLabelContext = (): PolarViewBoxRequired | undefined => {
226
+ const labelChildContext = useContext(PolarLabelContext)
227
+ const ctx = useChartStore()
228
+ if (labelChildContext != null) {
229
+ return untrack(() => readMaybeAccessor(labelChildContext))
230
+ }
231
+ return ctx ? selectPolarViewBox(ctx.store) : undefined
232
+ }
233
+
234
+ /* eslint-disable solid/reactivity -- plain utility fn; Props parameter is not a Solid reactive proxy at this call site */
235
+ const getLabel = (props: Props): RenderableText => {
236
+ const label: RenderableText = isNullish(props.children) ? props.value : props.children
237
+
238
+ if (typeof props.formatter === "function") {
239
+ return props.formatter(label)
240
+ }
241
+
242
+ return label
243
+ }
244
+ /* eslint-enable solid/reactivity */
245
+
246
+ export const isLabelContentAFunction = (
247
+ content: unknown,
248
+ ): content is (props: Props) => JSX.Element => {
249
+ return content != null && typeof content === "function"
250
+ }
251
+
252
+ const getDeltaAngle = (startAngle: number, endAngle: number) => {
253
+ const sign = mathSign(endAngle - startAngle)
254
+ const deltaAngle = Math.min(Math.abs(endAngle - startAngle), 360)
255
+
256
+ return sign * deltaAngle
257
+ }
258
+
259
+ const renderRadialLabel = (
260
+ labelProps: PropsWithDefaults,
261
+ position: PolarLabelPosition,
262
+ label: RenderableText | JSX.Element,
263
+ attrs: Record<PropertyKey, unknown>,
264
+ viewBox: PolarViewBoxRequired,
265
+ ): JSX.Element => {
266
+ const { cx, cy, innerRadius, outerRadius, startAngle, endAngle, clockWise } = viewBox
267
+ const radius = (innerRadius + outerRadius) / 2
268
+ const deltaAngle = getDeltaAngle(startAngle, endAngle)
269
+ const sign = deltaAngle >= 0 ? 1 : -1
270
+ let labelAngle: number
271
+ let direction: boolean | undefined
272
+
273
+ switch (position) {
274
+ case "insideStart":
275
+ labelAngle = startAngle + sign * labelProps.offset
276
+ direction = clockWise
277
+ break
278
+ case "insideEnd":
279
+ labelAngle = endAngle - sign * labelProps.offset
280
+ direction = !clockWise
281
+ break
282
+ case "end":
283
+ labelAngle = endAngle + sign * labelProps.offset
284
+ direction = clockWise
285
+ break
286
+ default:
287
+ throw new Error(`Unsupported position ${position}`)
288
+ }
289
+
290
+ direction = deltaAngle <= 0 ? direction : !direction
291
+
292
+ const startPoint = polarToCartesian(cx, cy, radius, labelAngle)
293
+ const endPoint = polarToCartesian(cx, cy, radius, labelAngle + (direction ? 1 : -1) * 359)
294
+ const path = `M${startPoint.x},${startPoint.y}
295
+ A${radius},${radius},0,1,${direction ? 0 : 1},
296
+ ${endPoint.x},${endPoint.y}`
297
+ const id = isNullish(labelProps.id) ? uniqueId("recharts-radial-line-") : labelProps.id
298
+
299
+ return (
300
+ <text
301
+ {...attrs}
302
+ dominant-baseline="central"
303
+ class={clsx("recharts-radial-bar-label", labelProps.className)}
304
+ >
305
+ <defs>
306
+ <path id={id} d={path} />
307
+ </defs>
308
+ <textPath href={`#${id}`}>{label}</textPath>
309
+ </text>
310
+ )
311
+ }
312
+
313
+ const getAttrsOfPolarLabel = (
314
+ viewBox: PolarViewBoxRequired,
315
+ offset: number,
316
+ position: LabelPosition | undefined,
317
+ ): LabelPositionAttributes => {
318
+ const { cx, cy, innerRadius, outerRadius, startAngle, endAngle } = viewBox
319
+ const midAngle = (startAngle + endAngle) / 2
320
+
321
+ if (position === "outside") {
322
+ const { x, y } = polarToCartesian(cx, cy, outerRadius + offset, midAngle)
323
+
324
+ return {
325
+ textAnchor: x >= cx ? "start" : "end",
326
+ verticalAnchor: "middle",
327
+ x,
328
+ y,
329
+ }
330
+ }
331
+
332
+ if (position === "center") {
333
+ return {
334
+ textAnchor: "middle",
335
+ verticalAnchor: "middle",
336
+ x: cx,
337
+ y: cy,
338
+ }
339
+ }
340
+
341
+ if (position === "centerTop") {
342
+ return {
343
+ textAnchor: "middle",
344
+ verticalAnchor: "start",
345
+ x: cx,
346
+ y: cy,
347
+ }
348
+ }
349
+
350
+ if (position === "centerBottom") {
351
+ return {
352
+ textAnchor: "middle",
353
+ verticalAnchor: "end",
354
+ x: cx,
355
+ y: cy,
356
+ }
357
+ }
358
+
359
+ const r = (innerRadius + outerRadius) / 2
360
+ const { x, y } = polarToCartesian(cx, cy, r, midAngle)
361
+
362
+ return {
363
+ textAnchor: "middle",
364
+ verticalAnchor: "middle",
365
+ x,
366
+ y,
367
+ }
368
+ }
369
+
370
+ const isPolar = (
371
+ viewBox: CartesianViewBoxRequired | TrapezoidViewBox | PolarViewBoxRequired | undefined,
372
+ ): viewBox is PolarViewBoxRequired => viewBox != null && "cx" in viewBox && isNumber(viewBox.cx)
373
+
374
+ export type LabelPositionAttributes = {
375
+ height?: number
376
+ textAnchor: TextAnchor
377
+ verticalAnchor: TextVerticalAnchor
378
+ width?: number
379
+ x: number
380
+ y: number
381
+ }
382
+
383
+ export const defaultLabelProps = {
384
+ angle: 0,
385
+ offset: 5,
386
+ position: "middle",
387
+ textBreakAll: false,
388
+ zIndex: DefaultZIndexes.label,
389
+ } as const satisfies Partial<Props>
390
+
391
+ function polarViewBoxToTrapezoid(
392
+ viewBox: PolarViewBoxRequired | TrapezoidViewBox | undefined,
393
+ ): TrapezoidViewBox | undefined {
394
+ if (!isPolar(viewBox)) {
395
+ return viewBox
396
+ }
397
+ const { cx, cy, outerRadius } = viewBox
398
+ const diameter = outerRadius * 2
399
+ return {
400
+ height: diameter,
401
+ lowerWidth: diameter,
402
+ upperWidth: diameter,
403
+ width: diameter,
404
+ x: cx - outerRadius,
405
+ y: cy - outerRadius,
406
+ }
407
+ }
408
+
409
+ /**
410
+ * @consumes CartesianViewBoxContext
411
+ * @consumes PolarViewBoxContext
412
+ * @consumes CartesianLabelContext
413
+ * @consumes PolarLabelContext
414
+ */
415
+ export function Label(outerProps: Props): JSX.Element | null {
416
+ const props: PropsWithDefaults = resolveDefaultProps(
417
+ outerProps,
418
+ defaultLabelProps,
419
+ ) as PropsWithDefaults
420
+ const polarContext = useContext(PolarLabelContext)
421
+ const cartesianContext = useContext(CartesianLabelContext)
422
+ const ctx = useChartStore()
423
+ const polarViewBox = createMemo(() => {
424
+ if (polarContext != null) {
425
+ return readMaybeAccessor(polarContext)
426
+ }
427
+ return ctx ? selectPolarViewBox(ctx.store) : undefined
428
+ })
429
+ const cartesianViewBox = createMemo(() => {
430
+ if (cartesianContext != null) {
431
+ return readMaybeAccessor(cartesianContext)
432
+ }
433
+ const rootViewBox = ctx ? selectChartViewBox(ctx.store) : undefined
434
+ return rootViewBox ? cartesianViewBoxToTrapezoid(rootViewBox) : undefined
435
+ })
436
+
437
+ const output = createMemo(() => {
438
+ /*
439
+ * I am not proud about this solution, but it's a quick fix for https://github.com/recharts/recharts/issues/6030#issuecomment-3155352460.
440
+ * What we should really do is split Label into two components: CartesianLabel and PolarLabel and then handle their respective viewBoxes separately.
441
+ * Also other components should set its own viewBox in a context so that we can fix https://github.com/recharts/recharts/issues/6156
442
+ */
443
+ const polar = polarViewBox()
444
+ const cartesian = cartesianViewBox()
445
+ /*
446
+ * When PolarLabelContext is present, wait for the polar box. Falling back to
447
+ * the chart cartesian trapezoid makes custom `content` see `innerRadius: undefined`.
448
+ */
449
+ const resolveViewBox = () => {
450
+ if (props.position === "center") {
451
+ return cartesian
452
+ }
453
+ if (polarContext != null) {
454
+ return polar
455
+ }
456
+ return polar ?? cartesian
457
+ }
458
+ const resolvedViewBox = resolveViewBox()
459
+
460
+ let viewBox: PolarViewBoxRequired | TrapezoidViewBox | undefined
461
+ if (props.viewBox == null) {
462
+ viewBox = resolvedViewBox
463
+ } else if (isPolar(props.viewBox)) {
464
+ viewBox = props.viewBox
465
+ } else {
466
+ viewBox = cartesianViewBoxToTrapezoid(props.viewBox)
467
+ }
468
+
469
+ const cartesianBox = polarViewBoxToTrapezoid(viewBox)
470
+
471
+ /* Solid has no isValidElement: an element is a Node (or a component's render accessor). */
472
+ const content = props.content
473
+ const isElementContent = isJsxNode(content)
474
+ if (
475
+ !viewBox ||
476
+ (isNullish(props.value) &&
477
+ isNullish(props.children) &&
478
+ !isElementContent &&
479
+ typeof content !== "function")
480
+ ) {
481
+ return null
482
+ }
483
+
484
+ // TODO: Generic Polar Hook
485
+ const isRadialPolarLabel =
486
+ isPolar(viewBox) &&
487
+ (props.position === "insideStart" || props.position === "insideEnd" || props.position === "end")
488
+
489
+ let positionAttrs: LabelPositionAttributes | undefined
490
+ if (isPolar(viewBox)) {
491
+ if (!isRadialPolarLabel) {
492
+ positionAttrs = getAttrsOfPolarLabel(viewBox, props.offset, props.position)
493
+ }
494
+ } else if (cartesianBox) {
495
+ const cartesianResult = getCartesianPosition({
496
+ clamp: true,
497
+ offset: props.offset,
498
+ parentViewBox: isPolar(props.parentViewBox) ? undefined : props.parentViewBox,
499
+ position: props.position,
500
+ viewBox: cartesianBox,
501
+ })
502
+
503
+ positionAttrs = {
504
+ textAnchor: cartesianResult.horizontalAnchor,
505
+ verticalAnchor: cartesianResult.verticalAnchor,
506
+ x: cartesianResult.x,
507
+ y: cartesianResult.y,
508
+ ...(cartesianResult.width !== undefined ? { width: cartesianResult.width } : {}),
509
+ ...(cartesianResult.height !== undefined ? { height: cartesianResult.height } : {}),
510
+ }
511
+ }
512
+
513
+ /*
514
+ * Custom content receives the computed x and y too, so that custom labels
515
+ * can be positioned the same way the built-in Text label is. Explicitly
516
+ * passed props win over the computed values. Only x and y are forwarded (not
517
+ * the anchors): a custom label that spreads its props into a nested Label
518
+ * would otherwise have that Label's own computed anchors overridden.
519
+ * https://github.com/recharts/recharts/issues/5067
520
+ */
521
+ const propsWithViewBox: Record<string, unknown> = {
522
+ ...(positionAttrs?.x !== undefined ? { x: positionAttrs.x } : {}),
523
+ ...(positionAttrs?.y !== undefined ? { y: positionAttrs.y } : {}),
524
+ ...props,
525
+ viewBox,
526
+ }
527
+
528
+ if (isElementContent) {
529
+ /* upstream: cloneElement(content, props) */
530
+ const { labelRef: _ref, children: _children, content: _content, ...propsWithoutLabelRef } = propsWithViewBox
531
+ return cloneJsxNodeWithProps(content as Node, propsWithoutLabelRef) as unknown as JSX.Element
532
+ }
533
+
534
+ let label: RenderableText
535
+ if (typeof content === "function") {
536
+ const { content: _, ...propsForContent } = propsWithViewBox
537
+ /* React's createElement(content, props) calls function components with
538
+ (props, legacyContext={}). Tests are 1:1 ports so they assert the
539
+ two-arg shape. Solid has no legacy context so pass an empty object. */
540
+ const rendered = (content as (p: Record<string, unknown>, legacyCtx: Record<string, never>) => RenderableText | JSX.Element)(propsForContent, {})
541
+ if (rendered != null && typeof rendered === "object") {
542
+ return rendered as JSX.Element
543
+ }
544
+ label = rendered as RenderableText
545
+ } else {
546
+ label = getLabel(props)
547
+ }
548
+
549
+ const attrs = svgPropertiesAndEvents({ ...props })
550
+
551
+ if (isRadialPolarLabel && isPolar(viewBox)) {
552
+ return renderRadialLabel(props, props.position as PolarLabelPosition, label, attrs, viewBox)
553
+ }
554
+
555
+ if (positionAttrs == null) {
556
+ return null
557
+ }
558
+
559
+ return (
560
+ <ZIndexLayer zIndex={props.zIndex}>
561
+ <Text
562
+ ref={props.labelRef}
563
+ className={clsx("recharts-label", props.className ?? "")}
564
+ {...attrs}
565
+ {...positionAttrs}
566
+ /*
567
+ * textAnchor is decided by default based on the `position`
568
+ * but we allow overriding via props for precise control.
569
+ */
570
+ textAnchor={
571
+ isValidTextAnchor(props.textAnchor) ? props.textAnchor : positionAttrs.textAnchor
572
+ }
573
+ breakAll={props.textBreakAll}
574
+ >
575
+ {label}
576
+ </Text>
577
+ </ZIndexLayer>
578
+ )
579
+ })
580
+
581
+ return output as unknown as JSX.Element
582
+ }
583
+
584
+ Label.displayName = "Label"
585
+
586
+ const parseLabel = (
587
+ label: ImplicitLabelType | undefined,
588
+ viewBox: ViewBox | undefined,
589
+ labelRef?: SVGTextElement | ((el: SVGTextElement) => void),
590
+ ): JSX.Element | null => {
591
+ if (!label) {
592
+ return null
593
+ }
594
+
595
+ const commonProps = { labelRef, viewBox }
596
+
597
+ if (label === true) {
598
+ return <Label {...commonProps} />
599
+ }
600
+
601
+ if (isNumOrStr(label)) {
602
+ return <Label value={label} {...commonProps} />
603
+ }
604
+
605
+ if (isLabelContentAFunction(label)) {
606
+ return <Label content={label} {...commonProps} />
607
+ }
608
+
609
+ /* `label={<CustomLabel />}` — user JSX evaluated to a live Node before reaching us.
610
+ * Render it directly; clone if reused so position attrs from Label compute via the
611
+ * cloned subtree. Single-instance render at this site (no per-tick repeat). */
612
+ if (isJsxNode(label)) {
613
+ return <>{(label as Node).cloneNode(true) as unknown as JSX.Element}</>
614
+ }
615
+
616
+ if (label && typeof label === "object") {
617
+ return <Label {...(label as Props)} {...commonProps} />
618
+ }
619
+
620
+ return null
621
+ }
622
+
623
+ export function CartesianLabelFromLabelProp(props: {
624
+ label: ImplicitLabelType | undefined
625
+ labelRef?: SVGTextElement | ((el: SVGTextElement) => void)
626
+ }): JSX.Element | null {
627
+ return (
628
+ untrack(() => parseLabel(props.label, useCartesianLabelContext(), props.labelRef)) || null
629
+ )
630
+ }
631
+
632
+ export function PolarLabelFromLabelProp(props: {
633
+ label: ImplicitLabelType | undefined
634
+ }): JSX.Element | null {
635
+ return untrack(() => parseLabel(props.label, usePolarLabelContext())) || null
636
+ }