@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,802 @@
1
+ /* eslint-disable import/no-cycle */
2
+ import sortBy from "es-toolkit/compat/sortBy"
3
+ import get from "es-toolkit/compat/get"
4
+
5
+ import {
6
+ Series,
7
+ type SeriesPoint,
8
+ stack as shapeStack,
9
+ stackOffsetExpand,
10
+ stackOffsetNone,
11
+ stackOffsetSilhouette,
12
+ stackOffsetWiggle,
13
+ stackOrderNone,
14
+ } from "victory-vendor/d3-shape"
15
+
16
+ import {
17
+ findEntryInArray,
18
+ isNan,
19
+ isNotNil,
20
+ isNullish,
21
+ isNumber,
22
+ isNumOrStr,
23
+ mathSign,
24
+ } from "./DataUtils"
25
+
26
+ import { TooltipEntrySettings, TooltipPayloadEntry } from "../state/tooltipSlice"
27
+ import {
28
+ AxisTick,
29
+ AxisType,
30
+ CartesianLayout,
31
+ CategoricalDomainItem,
32
+ RelativePointer,
33
+ DataKey,
34
+ LayoutType,
35
+ NumberDomain,
36
+ OffsetHorizontal,
37
+ OffsetVertical,
38
+ PolarLayout,
39
+ RangeObj,
40
+ Size,
41
+ StackOffsetType,
42
+ TickItem,
43
+ AxisDomainTypeInput,
44
+ } from "./types"
45
+ import { ValueType } from "../component/DefaultTooltipContent"
46
+ import { LegendSettings } from "../state/legendSlice"
47
+
48
+ function isOutsideLegendPosition(position: unknown): boolean {
49
+ if (position == null) {
50
+ return false
51
+ }
52
+ if (typeof position === "object") {
53
+ return true
54
+ }
55
+ return position === "top" || position === "left" || position === "right" || position === "bottom"
56
+ }
57
+ import { AxisRange, BaseAxisWithScale } from "../state/selectors/axisSelectors"
58
+ import { StackGroup } from "./stacks/stackTypes"
59
+ import { getSliced } from "./getSliced"
60
+ import { isWellBehavedNumber } from "./isWellBehavedNumber"
61
+ import { RechartsScale } from "./scale/RechartsScale"
62
+
63
+ export function getValueByDataKey<DataPointType, DataValueType>(
64
+ obj: DataPointType | null | undefined,
65
+ dataKey: DataKey<DataPointType, DataValueType> | undefined,
66
+ defaultValue: DataValueType,
67
+ ): DataValueType
68
+ export function getValueByDataKey<DataPointType, DataValueType>(
69
+ obj: DataPointType | null | undefined,
70
+ dataKey: DataKey<DataPointType, DataValueType> | undefined,
71
+ defaultValue?: DataValueType,
72
+ ): DataValueType | undefined
73
+ export function getValueByDataKey<DataPointType, DataValueType>(
74
+ obj: DataPointType | null | undefined,
75
+ dataKey: DataKey<DataPointType, DataValueType> | undefined,
76
+ defaultValue?: DataValueType,
77
+ ): DataValueType | undefined {
78
+ if (isNullish(obj) || isNullish(dataKey)) {
79
+ return defaultValue
80
+ }
81
+
82
+ if (isNumOrStr(dataKey)) {
83
+ return get(obj, dataKey, defaultValue)
84
+ }
85
+
86
+ if (typeof dataKey === "function") {
87
+ return dataKey(obj)
88
+ }
89
+
90
+ return defaultValue
91
+ }
92
+
93
+ export type BarPositionPosition = {
94
+ /**
95
+ * Offset is returned always from zero position.
96
+ * So in a way it's "absolute".
97
+ *
98
+ * NOT inbetween bars, but always from zero.
99
+ */
100
+ offset: number
101
+ /**
102
+ * Size of the bar.
103
+ * If the input data is undefined, this will be 0.
104
+ * If the input data is NaN then this size too will be NaN.
105
+ */
106
+ size: number
107
+ }
108
+
109
+ export const appendOffsetOfLegend = (
110
+ offset: OffsetVertical & OffsetHorizontal,
111
+ legendSettings: LegendSettings,
112
+ legendSize: Size,
113
+ ): OffsetVertical & OffsetHorizontal => {
114
+ if (legendSettings && legendSize) {
115
+ const { width: boxWidth, height: boxHeight } = legendSize
116
+ const { align, verticalAlign, layout, position, offset: legendOffset = 0 } = legendSettings
117
+
118
+ if (position != null) {
119
+ /* Position-based legends are absolutely placed. They only move the plot
120
+ area if they sit outside the chart. */
121
+ if (isOutsideLegendPosition(position)) {
122
+ if (position === "top" && isNumber(offset.top)) {
123
+ return { ...offset, top: offset.top + (boxHeight || 0) + legendOffset }
124
+ }
125
+ if (position === "bottom" && isNumber(offset.bottom)) {
126
+ return { ...offset, bottom: offset.bottom + (boxHeight || 0) + legendOffset }
127
+ }
128
+ if (position === "left" && isNumber(offset.left)) {
129
+ return { ...offset, left: offset.left + (boxWidth || 0) + legendOffset }
130
+ }
131
+ if (position === "right" && isNumber(offset.right)) {
132
+ return { ...offset, right: offset.right + (boxWidth || 0) + legendOffset }
133
+ }
134
+ }
135
+ return offset
136
+ }
137
+
138
+ if (
139
+ (layout === "vertical" || (layout === "horizontal" && verticalAlign === "middle")) &&
140
+ align !== "center" &&
141
+ isNumber(offset[align])
142
+ ) {
143
+ return { ...offset, [align]: offset[align] + (boxWidth || 0) }
144
+ }
145
+
146
+ if (
147
+ (layout === "horizontal" || (layout === "vertical" && align === "center")) &&
148
+ verticalAlign !== "middle" &&
149
+ isNumber(offset[verticalAlign])
150
+ ) {
151
+ return { ...offset, [verticalAlign]: offset[verticalAlign] + (boxHeight || 0) }
152
+ }
153
+ }
154
+
155
+ return offset
156
+ }
157
+
158
+ export const isCategoricalAxis = (layout: LayoutType, axisType: AxisType) =>
159
+ (layout === "horizontal" && axisType === "xAxis") ||
160
+ (layout === "vertical" && axisType === "yAxis") ||
161
+ (layout === "centric" && axisType === "angleAxis") ||
162
+ (layout === "radial" && axisType === "radiusAxis")
163
+
164
+ /**
165
+ * Calculate the Coordinates of grid
166
+ * @param {Array} ticks The ticks in axis
167
+ * @param {Number} minValue The minimum value of axis
168
+ * @param {Number} maxValue The maximum value of axis
169
+ * @param {boolean} syncWithTicks Synchronize grid lines with ticks or not
170
+ * @return {Array} Coordinates
171
+ */
172
+ export const getCoordinatesOfGrid = (
173
+ ticks: ReadonlyArray<TickItem>,
174
+ minValue: number,
175
+ maxValue: number,
176
+ syncWithTicks: boolean,
177
+ ) => {
178
+ if (syncWithTicks) {
179
+ return ticks.map((entry) => entry.coordinate)
180
+ }
181
+
182
+ let hasMin, hasMax
183
+
184
+ const values = ticks.map((entry) => {
185
+ if (entry.coordinate === minValue) {
186
+ hasMin = true
187
+ }
188
+ if (entry.coordinate === maxValue) {
189
+ hasMax = true
190
+ }
191
+
192
+ return entry.coordinate
193
+ })
194
+
195
+ if (!hasMin) {
196
+ values.push(minValue)
197
+ }
198
+ if (!hasMax) {
199
+ values.push(maxValue)
200
+ }
201
+
202
+ return values
203
+ }
204
+
205
+ export type AxisPropsNeededForTicksGenerator = {
206
+ axisType?: AxisType
207
+ categoricalDomain?: ReadonlyArray<unknown>
208
+ duplicateDomain?: ReadonlyArray<unknown>
209
+ isCategorical?: boolean
210
+ niceTicks?: ReadonlyArray<AxisTick>
211
+ /**
212
+ * The range appears to be only used in Angle Axis - needs further investigation
213
+ */
214
+ range?: AxisRange
215
+ realScaleType?: "scaleBand" | string
216
+ scale: RechartsScale | undefined
217
+ tickCount?: number
218
+ ticks?: ReadonlyArray<AxisTick>
219
+ type?: "number" | "category"
220
+ }
221
+
222
+ /**
223
+ * Of on four almost identical implementations of tick generation.
224
+ * The four horsemen of tick generation are:
225
+ * - selectTooltipAxisTicks
226
+ * - combineAxisTicks
227
+ * - getTicksOfAxis.
228
+ * - combineGraphicalItemTicks
229
+ */
230
+ export const getTicksOfAxis = (
231
+ axis: undefined | AxisPropsNeededForTicksGenerator,
232
+ isGrid?: boolean,
233
+ isAll?: boolean,
234
+ ): ReadonlyArray<TickItem> | null => {
235
+ if (!axis) {
236
+ return null
237
+ }
238
+ const {
239
+ duplicateDomain,
240
+ type,
241
+ range,
242
+ scale,
243
+ realScaleType,
244
+ isCategorical,
245
+ categoricalDomain,
246
+ tickCount,
247
+ ticks,
248
+ niceTicks,
249
+ axisType,
250
+ } = axis
251
+
252
+ if (!scale) {
253
+ return null
254
+ }
255
+
256
+ const offsetForBand = realScaleType === "scaleBand" && scale.bandwidth ? scale.bandwidth() / 2 : 2
257
+ let offset =
258
+ (isGrid || isAll) && type === "category" && scale.bandwidth
259
+ ? scale.bandwidth() / offsetForBand
260
+ : 0
261
+
262
+ offset =
263
+ axisType === "angleAxis" && range && range.length >= 2
264
+ ? mathSign(range[0] - range[1]) * 2 * offset
265
+ : offset
266
+
267
+ if (isGrid && (ticks || niceTicks)) {
268
+ const result = (ticks || niceTicks || [])
269
+ .map((entry: AxisTick, index: number): TickItem | null => {
270
+ const scaleContent = duplicateDomain ? duplicateDomain.indexOf(entry) : entry
271
+
272
+ const scaled = scale.map(scaleContent)
273
+ if (!isWellBehavedNumber(scaled)) {
274
+ return null
275
+ }
276
+ return {
277
+ coordinate: scaled + offset,
278
+ index,
279
+ offset,
280
+ value: entry,
281
+ }
282
+ })
283
+ .filter(isNotNil)
284
+
285
+ return result
286
+ }
287
+
288
+ if (isCategorical && categoricalDomain) {
289
+ return categoricalDomain
290
+ .map((entry: unknown, index: number): TickItem | null => {
291
+ const scaled = scale.map(entry)
292
+ if (!isWellBehavedNumber(scaled)) {
293
+ return null
294
+ }
295
+ return {
296
+ coordinate: scaled + offset,
297
+ index,
298
+ offset,
299
+ value: entry,
300
+ }
301
+ })
302
+ .filter(isNotNil)
303
+ }
304
+
305
+ if (scale.ticks && !isAll && tickCount != null) {
306
+ return scale
307
+ .ticks(tickCount)
308
+ .map((entry: number, index: number): TickItem | null => {
309
+ const scaled = scale.map(entry)
310
+ if (!isWellBehavedNumber(scaled)) {
311
+ return null
312
+ }
313
+ return { coordinate: scaled + offset, index, offset, value: entry }
314
+ })
315
+ .filter(isNotNil)
316
+ }
317
+
318
+ return scale
319
+ .domain()
320
+ .map((entry: CategoricalDomainItem, index: number): TickItem | null => {
321
+ const scaled = scale.map(entry)
322
+ if (!isWellBehavedNumber(scaled)) {
323
+ return null
324
+ }
325
+ return {
326
+ coordinate: scaled + offset,
327
+ index,
328
+ offset,
329
+ value: duplicateDomain ? duplicateDomain[entry as number] : entry,
330
+ }
331
+ })
332
+ .filter(isNotNil)
333
+ }
334
+
335
+ /**
336
+ * Both value and domain are tuples of two numbers
337
+ * - but the type stays as array of numbers until we have better support in rest of the app
338
+ * @param value input that will be truncated
339
+ * @param domain boundaries
340
+ * @returns tuple of two numbers
341
+ */
342
+ export const truncateByDomain = (
343
+ value: SeriesPoint<Record<string, unknown>>,
344
+ domain: ReadonlyArray<number>,
345
+ ): [number, number] | SeriesPoint<Record<string, unknown>> => {
346
+ if (!domain || domain.length !== 2 || !isNumber(domain[0]) || !isNumber(domain[1])) {
347
+ return value
348
+ }
349
+
350
+ const minValue = Math.min(domain[0], domain[1])
351
+ const maxValue = Math.max(domain[0], domain[1])
352
+
353
+ const result: [number, number] = [value[0], value[1]]
354
+ if (!isNumber(value[0]) || value[0] < minValue) {
355
+ result[0] = minValue
356
+ }
357
+
358
+ if (!isNumber(value[1]) || value[1] > maxValue) {
359
+ result[1] = maxValue
360
+ }
361
+
362
+ if (result[0] > maxValue) {
363
+ result[0] = maxValue
364
+ }
365
+
366
+ if (result[1] < minValue) {
367
+ result[1] = minValue
368
+ }
369
+
370
+ return result
371
+ }
372
+
373
+ /**
374
+ * Stacks all positive numbers above zero and all negative numbers below zero.
375
+ *
376
+ * If all values in the series are positive then this behaves the same as 'none' stacker.
377
+ *
378
+ * @param {Array} series from d3-shape Stack
379
+ * @return {Array} series with applied offset
380
+ */
381
+ export const offsetSign: OffsetAccessor = (series) => {
382
+ const n = series.length
383
+ if (n <= 0) {
384
+ return
385
+ }
386
+ const m = series[0]?.length
387
+ if (m == null || m <= 0) {
388
+ return
389
+ }
390
+
391
+ for (let j = 0; j < m; ++j) {
392
+ let positive = 0
393
+ let negative = 0
394
+
395
+ for (let i = 0; i < n; ++i) {
396
+ const row = series[i]
397
+ const col = row?.[j]
398
+ if (col == null) {
399
+ continue
400
+ }
401
+ const series1 = col[1]
402
+ const series0 = col[0]
403
+ const value = isNan(series1) ? series0 : series1
404
+
405
+ if (value >= 0) {
406
+ col[0] = positive
407
+ positive += value
408
+ col[1] = positive
409
+ } else {
410
+ col[0] = negative
411
+ negative += value
412
+ col[1] = negative
413
+ }
414
+ }
415
+ }
416
+ }
417
+
418
+ /**
419
+ * Replaces all negative values with zero when stacking data.
420
+ *
421
+ * If all values in the series are positive then this behaves the same as 'none' stacker.
422
+ *
423
+ * @param {Array} series from d3-shape Stack
424
+ * @return {Array} series with applied offset
425
+ */
426
+ export const offsetPositive: OffsetAccessor = (series) => {
427
+ const n = series.length
428
+ if (n <= 0) {
429
+ return
430
+ }
431
+ const m = series[0]?.length
432
+ if (m == null || m <= 0) {
433
+ return
434
+ }
435
+
436
+ for (let j = 0; j < m; ++j) {
437
+ let positive = 0
438
+
439
+ for (let i = 0; i < n; ++i) {
440
+ const row = series[i]
441
+ const col = row?.[j]
442
+ if (col == null) {
443
+ continue
444
+ }
445
+ const value = isNan(col[1]) ? col[0] : col[1]
446
+
447
+ if (value >= 0) {
448
+ col[0] = positive
449
+ positive += value
450
+ col[1] = positive
451
+ } else {
452
+ col[0] = 0
453
+ col[1] = 0
454
+ }
455
+ }
456
+ }
457
+ }
458
+
459
+ /**
460
+ * Function type to compute offset for stacked data.
461
+ *
462
+ * d3-shape has something fishy going on with its types.
463
+ * In definitelytyped/d3-shape, this function (the offset accessor) is typed as Series<> => void.
464
+ * However when I actually open the storybook I can see that the offset accessor actually receives Array<Series<>>.
465
+ * The same I can see in the source code itself:
466
+ * https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/66042
467
+ * That one unfortunately has no types but we can tell it passes three-dimensional array.
468
+ *
469
+ * Which leads me to believe that definitelytyped is wrong on this one.
470
+ */
471
+ type OffsetAccessor = (
472
+ series: Array<Series<Record<string, unknown>, string>>,
473
+ order: number[],
474
+ ) => void
475
+
476
+ /**
477
+ * d3-shape offset functions have slightly different type signatures than our OffsetAccessor,
478
+ * but they are compatible at runtime. We store them untyped and cast at call site.
479
+ */
480
+ const STACK_OFFSET_MAP: Record<StackOffsetType, Function> = {
481
+ expand: stackOffsetExpand,
482
+ none: stackOffsetNone,
483
+ positive: offsetPositive,
484
+ sign: offsetSign,
485
+ silhouette: stackOffsetSilhouette,
486
+ wiggle: stackOffsetWiggle,
487
+ }
488
+
489
+ export const getStackedData = (
490
+ data: ReadonlyArray<Record<string, unknown>>,
491
+ dataKeys: ReadonlyArray<string>,
492
+ offsetType: StackOffsetType,
493
+ ): ReadonlyArray<Series<Record<string, unknown>, string>> => {
494
+ const offsetAccessor = STACK_OFFSET_MAP[offsetType] ?? stackOffsetNone
495
+ const stack = shapeStack<Record<string, unknown>, string>()
496
+ .keys(dataKeys)
497
+ .value((d, key) => Number(getValueByDataKey(d, key, 0)))
498
+ .order(stackOrderNone)
499
+ .offset(offsetAccessor as Parameters<ReturnType<typeof shapeStack>["offset"]>[0])
500
+
501
+ const result = stack(data)
502
+
503
+ result.forEach((series, seriesIndex) => {
504
+ series.forEach((point, pointIndex) => {
505
+ const value = getValueByDataKey(data[pointIndex], dataKeys[seriesIndex], 0)
506
+ if (Array.isArray(value) && value.length === 2 && isNumber(value[0]) && isNumber(value[1])) {
507
+ point[0] = value[0]
508
+ point[1] = value[1]
509
+ }
510
+ })
511
+ })
512
+
513
+ return result
514
+ }
515
+
516
+ /**
517
+ * Externally, we accept both strings and numbers as stack IDs
518
+ * @inline
519
+ */
520
+ export type StackId = string | number
521
+ /**
522
+ * Stack IDs in the external props allow numbers; but internally we use it as an object key
523
+ * and object keys are always strings. Also, it would be kinda confusing if stackId=8 and stackId='8' were different stacks
524
+ * so let's just force a string.
525
+ */
526
+ export type NormalizedStackId = string
527
+
528
+ export function getNormalizedStackId(
529
+ publicStackId: StackId | undefined,
530
+ ): NormalizedStackId | undefined {
531
+ return publicStackId == null ? undefined : String(publicStackId)
532
+ }
533
+
534
+ export function getCateCoordinateOfLine<T extends Record<string, unknown>>({
535
+ axis,
536
+ ticks,
537
+ bandSize,
538
+ entry,
539
+ index,
540
+ dataKey,
541
+ }: {
542
+ axis: {
543
+ dataKey?: DataKey<T>
544
+ allowDuplicatedCategory?: boolean
545
+ type?: AxisDomainTypeInput
546
+ scale: RechartsScale
547
+ }
548
+ ticks: ReadonlyArray<TickItem> | undefined
549
+ bandSize: number
550
+ entry: T
551
+ index: number
552
+ dataKey?: DataKey<T>
553
+ }): number | null {
554
+ if (axis.type === "category") {
555
+ if (
556
+ !axis.allowDuplicatedCategory &&
557
+ axis.dataKey &&
558
+ !isNullish((entry as Record<string, unknown>)[axis.dataKey as string])
559
+ ) {
560
+ const matchedTick = ticks
561
+ ? findEntryInArray(
562
+ ticks,
563
+ "value",
564
+ (entry as Record<string, unknown>)[axis.dataKey as string],
565
+ )
566
+ : undefined
567
+
568
+ if (matchedTick) {
569
+ return matchedTick.coordinate + bandSize / 2
570
+ }
571
+ }
572
+
573
+ return ticks?.[index] ? ticks[index].coordinate + bandSize / 2 : null
574
+ }
575
+
576
+ const value = getValueByDataKey(entry, !isNullish(dataKey) ? dataKey : axis.dataKey)
577
+
578
+ const scaled = axis.scale.map(value)
579
+ if (!isNumber(scaled)) {
580
+ return null
581
+ }
582
+ return scaled
583
+ }
584
+
585
+ export const getCateCoordinateOfBar = ({
586
+ axis,
587
+ ticks,
588
+ offset,
589
+ bandSize,
590
+ entry,
591
+ index,
592
+ }: {
593
+ axis: BaseAxisWithScale
594
+ ticks: ReadonlyArray<TickItem>
595
+ offset: number
596
+ bandSize: number
597
+ entry: unknown
598
+ index: number
599
+ }): number | null => {
600
+ if (axis.type === "category") {
601
+ return ticks[index] ? ticks[index].coordinate + offset : null
602
+ }
603
+ const value: number | undefined = getValueByDataKey(
604
+ entry,
605
+ axis.dataKey,
606
+ axis.scale.domain()[index],
607
+ )
608
+
609
+ if (isNullish(value)) {
610
+ return null
611
+ }
612
+
613
+ const scaled = axis.scale.map(value)
614
+ if (!isNumber(scaled)) {
615
+ return null
616
+ }
617
+ return scaled - bandSize / 2 + offset
618
+ }
619
+
620
+ export const getBaseValueOfBar = ({
621
+ numericAxis,
622
+ }: {
623
+ numericAxis: BaseAxisWithScale
624
+ }): number | unknown => {
625
+ const domain = numericAxis.scale.domain()
626
+
627
+ if (numericAxis.type === "number") {
628
+ const minValue = Math.min(domain[0] as number, domain[1] as number)
629
+ const maxValue = Math.max(domain[0] as number, domain[1] as number)
630
+
631
+ if (minValue <= 0 && maxValue >= 0) {
632
+ return 0
633
+ }
634
+ if (maxValue < 0) {
635
+ return maxValue
636
+ }
637
+
638
+ return minValue
639
+ }
640
+
641
+ return domain[0]
642
+ }
643
+
644
+ const getDomainOfSingle = (data: ReadonlyArray<ReadonlyArray<unknown>>): number[] => {
645
+ const flat = data.flat(2).filter(isNumber)
646
+ return [Math.min(...flat), Math.max(...flat)]
647
+ }
648
+
649
+ const makeDomainFinite = (domain: NumberDomain): NumberDomain => {
650
+ return [domain[0] === Infinity ? 0 : domain[0], domain[1] === -Infinity ? 0 : domain[1]]
651
+ }
652
+
653
+ export const getDomainOfStackGroups = (
654
+ stackGroups: Record<StackId, StackGroup> | undefined,
655
+ startIndex: number,
656
+ endIndex: number,
657
+ ): NumberDomain | undefined => {
658
+ if (stackGroups == null || Object.keys(stackGroups).length === 0) {
659
+ return undefined
660
+ }
661
+ return makeDomainFinite(
662
+ Object.keys(stackGroups).reduce(
663
+ (result, stackId): NumberDomain => {
664
+ const group = stackGroups[stackId]
665
+ if (!group) {
666
+ return result
667
+ }
668
+ const { stackedData } = group
669
+ const domain: NumberDomain = stackedData.reduce(
670
+ (res: NumberDomain, entry): NumberDomain => {
671
+ const sliced = getSliced(entry, startIndex, endIndex)
672
+ const s = getDomainOfSingle(sliced)
673
+ if (!isWellBehavedNumber(s[0]) || !isWellBehavedNumber(s[1])) {
674
+ return res
675
+ }
676
+ return [Math.min(res[0], s[0]), Math.max(res[1], s[1])]
677
+ },
678
+ [Infinity, -Infinity],
679
+ )
680
+
681
+ return [Math.min(domain[0], result[0]), Math.max(domain[1], result[1])]
682
+ },
683
+ [Infinity, -Infinity],
684
+ ),
685
+ )
686
+ }
687
+
688
+ export const MIN_VALUE_REG = /^dataMin[\s]*-[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/
689
+ export const MAX_VALUE_REG = /^dataMax[\s]*\+[\s]*([0-9]+([.]{1}[0-9]+){0,1})$/
690
+
691
+ /**
692
+ * Calculate the size between two category
693
+ * @param {Object} axis The options of axis
694
+ * @param {Array} ticks The ticks of axis
695
+ * @param {Boolean} isBar if items in axis are bars
696
+ * @return {Number} Size
697
+ */
698
+ export const getBandSizeOfAxis = (
699
+ axis?: BaseAxisWithScale,
700
+ ticks?: ReadonlyArray<TickItem>,
701
+ isBar?: boolean,
702
+ ): number | undefined => {
703
+ if (axis && axis.scale && axis.scale.bandwidth) {
704
+ const bandWidth = axis.scale.bandwidth()
705
+
706
+ if (!isBar || bandWidth > 0) {
707
+ return bandWidth
708
+ }
709
+ }
710
+
711
+ if (axis && ticks && ticks.length >= 2) {
712
+ const orderedTicks: ReadonlyArray<TickItem> = sortBy(ticks, (o: TickItem) => o.coordinate)
713
+
714
+ // Collect the pixel gaps between adjacent category positions and track the widest one.
715
+ const gaps: number[] = []
716
+ let maxGap = 0
717
+ for (let i = 1, len = orderedTicks.length; i < len; i++) {
718
+ const gap = (orderedTicks[i]?.coordinate || 0) - (orderedTicks[i - 1]?.coordinate || 0)
719
+ gaps.push(gap)
720
+ maxGap = Math.max(gap, maxGap)
721
+ }
722
+
723
+ /*
724
+ * High-precision float values can place two ticks at (almost) the same pixel,
725
+ * producing a spurious sub-pixel gap. Such near-coincident positions are the
726
+ * same category slot for rendering purposes and must not define the band
727
+ * size, otherwise every bar collapses to ~0px wide (issue #4043). Ignore gaps
728
+ * that are a negligible fraction of the widest gap.
729
+ */
730
+ const minMeaningfulGap = maxGap * 1e-4
731
+ let bandSize = Infinity
732
+ for (const gap of gaps) {
733
+ if (gap > minMeaningfulGap) {
734
+ bandSize = Math.min(gap, bandSize)
735
+ }
736
+ }
737
+
738
+ return bandSize === Infinity ? 0 : bandSize
739
+ }
740
+
741
+ return isBar ? undefined : 0
742
+ }
743
+
744
+ export function getTooltipEntry({
745
+ tooltipEntrySettings,
746
+ dataKey,
747
+ payload,
748
+ value,
749
+ name,
750
+ }: {
751
+ tooltipEntrySettings: TooltipEntrySettings
752
+ dataKey: DataKey<unknown> | undefined
753
+ payload: unknown
754
+ value: ValueType
755
+ name: string | undefined
756
+ }): TooltipPayloadEntry {
757
+ return {
758
+ ...tooltipEntrySettings,
759
+ dataKey,
760
+ name,
761
+ payload,
762
+ value,
763
+ }
764
+ }
765
+
766
+ export function getTooltipNameProp(
767
+ nameFromItem: string | number | undefined | unknown,
768
+ dataKey: DataKey<unknown> | undefined,
769
+ ): string | undefined {
770
+ if (nameFromItem != null) {
771
+ return String(nameFromItem)
772
+ }
773
+ if (typeof dataKey === "string") {
774
+ return dataKey
775
+ }
776
+ return undefined
777
+ }
778
+
779
+ export const calculateCartesianTooltipPos = (
780
+ coordinate: RelativePointer,
781
+ layout: CartesianLayout,
782
+ ): number | undefined => {
783
+ if (layout === "horizontal") {
784
+ return coordinate.relativeX
785
+ }
786
+ if (layout === "vertical") {
787
+ return coordinate.relativeY
788
+ }
789
+
790
+ return undefined
791
+ }
792
+
793
+ export const calculatePolarTooltipPos = (
794
+ rangeObj: RangeObj,
795
+ layout: PolarLayout,
796
+ ): number | undefined => {
797
+ if (layout === "centric") {
798
+ return rangeObj.angle
799
+ }
800
+
801
+ return rangeObj.radius
802
+ }