solid-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 (639) hide show
  1. package/NEXT_SESSION_PROMPT.md +114 -0
  2. package/package.json +28 -0
  3. package/src/animation/AnimatedItems.tsx +169 -0
  4. package/src/animation/AnimationController.ts +24 -0
  5. package/src/animation/AnimationControllerImpl.ts +37 -0
  6. package/src/animation/AnimationHandle.ts +273 -0
  7. package/src/animation/CSSTransitionAnimate.tsx +142 -0
  8. package/src/animation/JavascriptAnimate.tsx +107 -0
  9. package/src/animation/easing.ts +261 -0
  10. package/src/animation/matchBy.ts +211 -0
  11. package/src/animation/timeoutController.ts +51 -0
  12. package/src/animation/useAnimationController.tsx +31 -0
  13. package/src/animation/useAnimationStartSnapshot.ts +73 -0
  14. package/src/animation/util.ts +16 -0
  15. package/src/cartesian/Area.tsx +810 -0
  16. package/src/cartesian/AreaRevealShape.tsx +250 -0
  17. package/src/cartesian/Bar.tsx +1216 -0
  18. package/src/cartesian/BarStack.tsx +148 -0
  19. package/src/cartesian/Brush.tsx +653 -0
  20. package/src/cartesian/CartesianAxis.tsx +541 -0
  21. package/src/cartesian/CartesianGrid.tsx +605 -0
  22. package/src/cartesian/ErrorBar.tsx +319 -0
  23. package/src/cartesian/Funnel.tsx +594 -0
  24. package/src/cartesian/GraphicalItemClipPath.tsx +75 -0
  25. package/src/cartesian/Line.tsx +742 -0
  26. package/src/cartesian/LineDrawShape.tsx +190 -0
  27. package/src/cartesian/ReferenceArea.tsx +275 -0
  28. package/src/cartesian/ReferenceDot.tsx +286 -0
  29. package/src/cartesian/ReferenceLine.tsx +414 -0
  30. package/src/cartesian/RenderedTicksReporter.tsx +49 -0
  31. package/src/cartesian/Scatter.tsx +741 -0
  32. package/src/cartesian/XAxis.tsx +293 -0
  33. package/src/cartesian/YAxis.tsx +333 -0
  34. package/src/cartesian/ZAxis.tsx +80 -0
  35. package/src/cartesian/getCartesianPosition.ts +255 -0
  36. package/src/cartesian/getEquidistantTicks.ts +126 -0
  37. package/src/cartesian/getTicks.ts +225 -0
  38. package/src/cartesian/useAnimatedLineLength.ts +84 -0
  39. package/src/chart/AreaChart.tsx +30 -0
  40. package/src/chart/BarChart.tsx +27 -0
  41. package/src/chart/CartesianChart.tsx +91 -0
  42. package/src/chart/CategoricalChart.tsx +60 -0
  43. package/src/chart/ComposedChart.tsx +29 -0
  44. package/src/chart/FunnelChart.tsx +29 -0
  45. package/src/chart/LineChart.tsx +29 -0
  46. package/src/chart/PieChart.tsx +41 -0
  47. package/src/chart/PolarChart.tsx +97 -0
  48. package/src/chart/RadarChart.tsx +37 -0
  49. package/src/chart/RadialBarChart.tsx +39 -0
  50. package/src/chart/RechartsWrapper.tsx +486 -0
  51. package/src/chart/Sankey.tsx +992 -0
  52. package/src/chart/ScatterChart.tsx +29 -0
  53. package/src/chart/SunburstChart.tsx +394 -0
  54. package/src/chart/Treemap.tsx +874 -0
  55. package/src/chart/types.ts +37 -0
  56. package/src/component/ActivePoints.tsx +136 -0
  57. package/src/component/Cell.tsx +72 -0
  58. package/src/component/Cursor.tsx +249 -0
  59. package/src/component/Customized.tsx +8 -0
  60. package/src/component/DefaultLegendContent.tsx +205 -0
  61. package/src/component/DefaultTooltipContent.tsx +247 -0
  62. package/src/component/Dots.tsx +128 -0
  63. package/src/component/Label.tsx +507 -0
  64. package/src/component/LabelList.tsx +270 -0
  65. package/src/component/Legend.tsx +273 -0
  66. package/src/component/ResponsiveContainer.tsx +397 -0
  67. package/src/component/Text.tsx +436 -0
  68. package/src/component/Tooltip.tsx +309 -0
  69. package/src/component/TooltipBoundingBox.tsx +152 -0
  70. package/src/component/responsiveContainerUtils.ts +128 -0
  71. package/src/container/ClipPathProvider.tsx +40 -0
  72. package/src/container/Layer.tsx +38 -0
  73. package/src/container/RootSurface.tsx +124 -0
  74. package/src/container/Surface.tsx +70 -0
  75. package/src/context/ErrorBarContext.tsx +85 -0
  76. package/src/context/PanoramaContext.tsx +13 -0
  77. package/src/context/RegisterGraphicalItemId.tsx +41 -0
  78. package/src/context/accessibilityContext.tsx +10 -0
  79. package/src/context/brushUpdateContext.ts +14 -0
  80. package/src/context/chartDataContext.tsx +79 -0
  81. package/src/context/chartLayoutContext.tsx +158 -0
  82. package/src/context/legendPayloadContext.ts +11 -0
  83. package/src/context/legendPortalContext.ts +11 -0
  84. package/src/context/tooltipContext.ts +72 -0
  85. package/src/context/tooltipPortalContext.ts +14 -0
  86. package/src/context/useTooltipAxis.ts +24 -0
  87. package/src/hooks.ts +312 -0
  88. package/src/index.ts +288 -0
  89. package/src/polar/Pie.tsx +912 -0
  90. package/src/polar/PolarAngleAxis.tsx +494 -0
  91. package/src/polar/PolarGrid.tsx +269 -0
  92. package/src/polar/PolarRadiusAxis.tsx +422 -0
  93. package/src/polar/Radar.tsx +652 -0
  94. package/src/polar/RadialBar.tsx +767 -0
  95. package/src/polar/defaultPolarAngleAxisProps.tsx +33 -0
  96. package/src/polar/defaultPolarRadiusAxisProps.tsx +28 -0
  97. package/src/shape/Cross.tsx +83 -0
  98. package/src/shape/Curve.tsx +335 -0
  99. package/src/shape/Dot.tsx +49 -0
  100. package/src/shape/Polygon.tsx +168 -0
  101. package/src/shape/Rectangle.tsx +301 -0
  102. package/src/shape/Sector.tsx +304 -0
  103. package/src/shape/Symbols.tsx +144 -0
  104. package/src/shape/Trapezoid.tsx +228 -0
  105. package/src/state/RechartsReduxContext.tsx +8 -0
  106. package/src/state/RechartsStoreContext.ts +15 -0
  107. package/src/state/RechartsStoreProvider.tsx +27 -0
  108. package/src/state/ReportChartProps.tsx +19 -0
  109. package/src/state/ReportEventSettings.tsx +19 -0
  110. package/src/state/ReportMainChartProps.tsx +35 -0
  111. package/src/state/ReportPolarOptions.tsx +28 -0
  112. package/src/state/SetLegendPayload.ts +50 -0
  113. package/src/state/SetTooltipEntrySettings.tsx +46 -0
  114. package/src/state/brushSlice.ts +60 -0
  115. package/src/state/cartesianAxisSlice.ts +288 -0
  116. package/src/state/chartDataSlice.ts +115 -0
  117. package/src/state/errorBarSlice.ts +84 -0
  118. package/src/state/eventSettingsSlice.ts +41 -0
  119. package/src/state/externalEventsMiddleware.ts +136 -0
  120. package/src/state/graphicalItemsSlice.ts +162 -0
  121. package/src/state/hooks.ts +42 -0
  122. package/src/state/keyboardEventsMiddleware.ts +213 -0
  123. package/src/state/layoutSlice.ts +71 -0
  124. package/src/state/legendSlice.ts +107 -0
  125. package/src/state/mouseEventsMiddleware.ts +103 -0
  126. package/src/state/optionsSlice.ts +64 -0
  127. package/src/state/polarAxisSlice.ts +65 -0
  128. package/src/state/polarOptionsSlice.ts +54 -0
  129. package/src/state/reduxDevtoolsJsonStringifyReplacer.ts +15 -0
  130. package/src/state/referenceElementsSlice.ts +121 -0
  131. package/src/state/renderedTicksSlice.ts +61 -0
  132. package/src/state/rootPropsSlice.ts +70 -0
  133. package/src/state/selectors/areaSelectors.ts +169 -0
  134. package/src/state/selectors/arrayEqualityCheck.ts +8 -0
  135. package/src/state/selectors/axisSelectors.ts +2196 -0
  136. package/src/state/selectors/barSelectors.ts +319 -0
  137. package/src/state/selectors/barStackSelectors.ts +79 -0
  138. package/src/state/selectors/brushSelectors.ts +40 -0
  139. package/src/state/selectors/combiners/combineActiveLabel.ts +21 -0
  140. package/src/state/selectors/combiners/combineActiveTooltipIndex.ts +93 -0
  141. package/src/state/selectors/combiners/combineAllBarPositions.ts +131 -0
  142. package/src/state/selectors/combiners/combineAxisRangeWithReverse.ts +17 -0
  143. package/src/state/selectors/combiners/combineBarPosition.ts +24 -0
  144. package/src/state/selectors/combiners/combineBarSizeList.ts +75 -0
  145. package/src/state/selectors/combiners/combineCheckedDomain.ts +49 -0
  146. package/src/state/selectors/combiners/combineConfiguredScale.ts +121 -0
  147. package/src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts +43 -0
  148. package/src/state/selectors/combiners/combineDisplayedStackedData.ts +50 -0
  149. package/src/state/selectors/combiners/combineInverseScaleFunction.ts +17 -0
  150. package/src/state/selectors/combiners/combineRealScaleType.ts +48 -0
  151. package/src/state/selectors/combiners/combineStackedData.ts +28 -0
  152. package/src/state/selectors/combiners/combineTooltipInteractionState.ts +86 -0
  153. package/src/state/selectors/combiners/combineTooltipPayload.ts +203 -0
  154. package/src/state/selectors/combiners/combineTooltipPayloadConfigurations.ts +45 -0
  155. package/src/state/selectors/containerSelectors.ts +12 -0
  156. package/src/state/selectors/dataSelectors.ts +90 -0
  157. package/src/state/selectors/funnelSelectors.ts +83 -0
  158. package/src/state/selectors/graphicalItemSelectors.ts +23 -0
  159. package/src/state/selectors/legendSelectors.ts +29 -0
  160. package/src/state/selectors/lineSelectors.ts +111 -0
  161. package/src/state/selectors/numberDomainEqualityCheck.ts +8 -0
  162. package/src/state/selectors/pickAxisId.ts +6 -0
  163. package/src/state/selectors/pickAxisType.ts +4 -0
  164. package/src/state/selectors/pieSelectors.ts +103 -0
  165. package/src/state/selectors/polarAxisSelectors.ts +202 -0
  166. package/src/state/selectors/polarGridSelectors.ts +24 -0
  167. package/src/state/selectors/polarScaleSelectors.ts +149 -0
  168. package/src/state/selectors/polarSelectors.ts +211 -0
  169. package/src/state/selectors/radarSelectors.ts +152 -0
  170. package/src/state/selectors/radialBarSelectors.ts +328 -0
  171. package/src/state/selectors/rootPropsSelectors.ts +36 -0
  172. package/src/state/selectors/scatterSelectors.ts +77 -0
  173. package/src/state/selectors/selectAllAxes.ts +10 -0
  174. package/src/state/selectors/selectChartOffset.ts +15 -0
  175. package/src/state/selectors/selectChartOffsetInternal.ts +111 -0
  176. package/src/state/selectors/selectPlotArea.ts +27 -0
  177. package/src/state/selectors/selectTooltipAxisId.ts +6 -0
  178. package/src/state/selectors/selectTooltipAxisType.ts +33 -0
  179. package/src/state/selectors/selectTooltipEventType.ts +45 -0
  180. package/src/state/selectors/selectTooltipPayloadSearcher.ts +7 -0
  181. package/src/state/selectors/selectTooltipSettings.ts +6 -0
  182. package/src/state/selectors/selectTooltipState.ts +5 -0
  183. package/src/state/selectors/tooltipSelectors.ts +690 -0
  184. package/src/state/selectors/touchSelectors.ts +29 -0
  185. package/src/state/store.ts +167 -0
  186. package/src/state/tooltipSlice.ts +289 -0
  187. package/src/state/types/AreaSettings.ts +17 -0
  188. package/src/state/types/BarSettings.ts +16 -0
  189. package/src/state/types/LineSettings.ts +12 -0
  190. package/src/state/types/PieSettings.ts +32 -0
  191. package/src/state/types/RadarSettings.ts +6 -0
  192. package/src/state/types/RadialBarSettings.ts +10 -0
  193. package/src/state/types/ScatterSettings.ts +13 -0
  194. package/src/state/types/StackedGraphicalItem.ts +33 -0
  195. package/src/state/unregisterOnCleanup.ts +26 -0
  196. package/src/state/zIndexSlice.ts +128 -0
  197. package/src/synchronisation/syncRegistry.ts +131 -0
  198. package/src/synchronisation/syncSelectors.ts +7 -0
  199. package/src/synchronisation/types.ts +42 -0
  200. package/src/synchronisation/useChartSynchronisation.tsx +372 -0
  201. package/src/types.ts +39 -0
  202. package/src/util/ActiveShapeUtils.tsx +80 -0
  203. package/src/util/BarUtils.tsx +74 -0
  204. package/src/util/CartesianUtils.ts +53 -0
  205. package/src/util/ChartUtils.ts +696 -0
  206. package/src/util/Constants.ts +42 -0
  207. package/src/util/CssPrefixUtils.ts +24 -0
  208. package/src/util/DOMUtils.ts +141 -0
  209. package/src/util/DataUtils.ts +205 -0
  210. package/src/util/FunnelUtils.tsx +37 -0
  211. package/src/util/Global.ts +15 -0
  212. package/src/util/IfOverflow.ts +17 -0
  213. package/src/util/LRUCache.ts +46 -0
  214. package/src/util/LogUtils.ts +26 -0
  215. package/src/util/PolarUtils.ts +134 -0
  216. package/src/util/RadialBarUtils.tsx +35 -0
  217. package/src/util/ReduceCSSCalc.ts +186 -0
  218. package/src/util/ShallowEqual.ts +43 -0
  219. package/src/util/TickUtils.ts +61 -0
  220. package/src/util/YAxisUtils.ts +49 -0
  221. package/src/util/adaptEventHandlers.ts +69 -0
  222. package/src/util/axisPropsAreEqual.ts +42 -0
  223. package/src/util/collectionUtils.ts +83 -0
  224. package/src/util/createCartesianCharts.tsx +101 -0
  225. package/src/util/createEventProxy.ts +24 -0
  226. package/src/util/createPolarCharts.tsx +86 -0
  227. package/src/util/cursor/getCursorPoints.ts +48 -0
  228. package/src/util/cursor/getCursorRectangle.ts +31 -0
  229. package/src/util/cursor/getRadialCursorPoints.ts +34 -0
  230. package/src/util/excludeEventProps.ts +172 -0
  231. package/src/util/getActiveCoordinate.ts +205 -0
  232. package/src/util/getAxisTypeBasedOnLayout.ts +21 -0
  233. package/src/util/getEveryNth.ts +30 -0
  234. package/src/util/getRadiusAndStrokeWidthFromDot.ts +35 -0
  235. package/src/util/getRelativeCoordinate.ts +84 -0
  236. package/src/util/getSliced.ts +21 -0
  237. package/src/util/isDomainSpecifiedByUser.ts +217 -0
  238. package/src/util/isWellBehavedNumber.ts +10 -0
  239. package/src/util/objectPath.ts +129 -0
  240. package/src/util/payload/getUniqPayload.ts +31 -0
  241. package/src/util/propsAreEqual.ts +137 -0
  242. package/src/util/resolveDefaultProps.tsx +8 -0
  243. package/src/util/round.ts +35 -0
  244. package/src/util/scale/CartesianScaleHelper.ts +72 -0
  245. package/src/util/scale/CustomScaleDefinition.ts +82 -0
  246. package/src/util/scale/RechartsScale.ts +131 -0
  247. package/src/util/scale/createCategoricalInverse.ts +83 -0
  248. package/src/util/scale/getNiceTickValues.ts +334 -0
  249. package/src/util/scale/index.ts +3 -0
  250. package/src/util/scale/util/DecimalLite.ts +194 -0
  251. package/src/util/scale/util/arithmetic.ts +56 -0
  252. package/src/util/stacks/getStackSeriesIdentifier.ts +20 -0
  253. package/src/util/stacks/stackTypes.ts +53 -0
  254. package/src/util/svgPropertiesAndEvents.ts +84 -0
  255. package/src/util/svgPropertiesNoEvents.ts +520 -0
  256. package/src/util/tooltip/translate.ts +179 -0
  257. package/src/util/typedDataKey.ts +8 -0
  258. package/src/util/types.ts +724 -0
  259. package/src/util/useAnimationId.tsx +31 -0
  260. package/src/util/useElementOffset.ts +164 -0
  261. package/src/util/useId.ts +20 -0
  262. package/src/util/usePrefersReducedMotion.ts +44 -0
  263. package/src/util/useUniqueId.ts +34 -0
  264. package/src/zIndex/DefaultZIndexes.tsx +87 -0
  265. package/src/zIndex/ZIndexLayer.tsx +126 -0
  266. package/src/zIndex/ZIndexPortal.tsx +69 -0
  267. package/src/zIndex/getZIndexFromUnknown.tsx +17 -0
  268. package/src/zIndex/zIndexSelectors.ts +46 -0
  269. package/test/_data.ts +408 -0
  270. package/test/animation/AnimationController.typed.spec.ts +53 -0
  271. package/test/animation/AnimationControllerImpl.spec.ts +271 -0
  272. package/test/animation/CSSTransitionAnimate.timing.spec.tsx +473 -0
  273. package/test/animation/JavascriptAnimate.spec.tsx +62 -0
  274. package/test/animation/RechartsAnimation.spec.ts +636 -0
  275. package/test/animation/easing.spec.ts +218 -0
  276. package/test/animation/legacyAnimationLengthChange.spec.tsx +803 -0
  277. package/test/animation/matchBy.spec.ts +467 -0
  278. package/test/animation/mockAnimationController.ts +40 -0
  279. package/test/animation/mockControllerAnimationManager.ts +143 -0
  280. package/test/animation/mockTimeoutController.ts +114 -0
  281. package/test/animation/timeoutController.spec.ts +138 -0
  282. package/test/animation/useAnimationStartSnapshot.spec.ts +147 -0
  283. package/test/animation/util.spec.ts +28 -0
  284. package/test/cartesian/Area.animation.spec.tsx +363 -0
  285. package/test/cartesian/Area.range.spec.tsx +54 -0
  286. package/test/cartesian/Area.spec.tsx +1202 -0
  287. package/test/cartesian/Area.stacked.render.spec.tsx +69 -0
  288. package/test/cartesian/Area.typed.spec.tsx +209 -0
  289. package/test/cartesian/Axis.integration.spec.tsx +158 -0
  290. package/test/cartesian/Bar/Bar.csstransition.spec.tsx +299 -0
  291. package/test/cartesian/Bar/Bar.spec.tsx +2314 -0
  292. package/test/cartesian/Bar/Bar.typed.spec.tsx +192 -0
  293. package/test/cartesian/Bar.animation.spec.tsx +426 -0
  294. package/test/cartesian/Bar.stackDomain.spec.tsx +66 -0
  295. package/test/cartesian/Bar.stacked.render.spec.tsx +53 -0
  296. package/test/cartesian/Bar.truncateByDomain.spec.tsx +237 -0
  297. package/test/cartesian/Bar.zeroDimensionFiltering.spec.tsx +336 -0
  298. package/test/cartesian/BarStack.spec.tsx +91 -0
  299. package/test/cartesian/Brush.keyboard.spec.tsx +88 -0
  300. package/test/cartesian/Brush.panorama.spec.tsx +41 -0
  301. package/test/cartesian/Brush.props.spec.tsx +63 -0
  302. package/test/cartesian/Brush.render.spec.tsx +117 -0
  303. package/test/cartesian/Brush.spec.tsx +522 -0
  304. package/test/cartesian/Brush.stacked.spec.tsx +221 -0
  305. package/test/cartesian/CartesianAxis.render.spec.tsx +50 -0
  306. package/test/cartesian/CartesianAxis.spec.tsx +396 -0
  307. package/test/cartesian/CartesianGrid.render.spec.tsx +39 -0
  308. package/test/cartesian/CartesianGrid.spec.tsx +2103 -0
  309. package/test/cartesian/ErrorBar.render.spec.tsx +69 -0
  310. package/test/cartesian/ErrorBar.spec.tsx +2414 -0
  311. package/test/cartesian/Funnel.animation.spec.tsx +241 -0
  312. package/test/cartesian/Funnel.spec.tsx +226 -0
  313. package/test/cartesian/Funnel.typed.spec.tsx +221 -0
  314. package/test/cartesian/GraphicalItemClipPath.scale-behavior.spec.tsx +627 -0
  315. package/test/cartesian/GraphicalItemClipPath.spec.tsx +427 -0
  316. package/test/cartesian/Line.animation.spec.tsx +643 -0
  317. package/test/cartesian/Line.sparseAnimationPath.spec.tsx +98 -0
  318. package/test/cartesian/Line.spec.tsx +471 -0
  319. package/test/cartesian/Line.typed.spec.tsx +152 -0
  320. package/test/cartesian/ReferenceArea.render.spec.tsx +63 -0
  321. package/test/cartesian/ReferenceArea.spec.tsx +663 -0
  322. package/test/cartesian/ReferenceArea.typed.spec.tsx +74 -0
  323. package/test/cartesian/ReferenceDot.render.spec.tsx +55 -0
  324. package/test/cartesian/ReferenceDot.spec.tsx +462 -0
  325. package/test/cartesian/ReferenceDot.typed.spec.tsx +76 -0
  326. package/test/cartesian/ReferenceLine/ReferenceLine.panorama.spec.tsx +184 -0
  327. package/test/cartesian/ReferenceLine/ReferenceLine.spec.tsx +744 -0
  328. package/test/cartesian/ReferenceLine/ReferenceLine.typed.spec.tsx +74 -0
  329. package/test/cartesian/ReferenceLine/getEndPoints.spec.ts +399 -0
  330. package/test/cartesian/ReferenceLine.render.spec.tsx +134 -0
  331. package/test/cartesian/Scatter.animation.spec.tsx +381 -0
  332. package/test/cartesian/Scatter.render.spec.tsx +61 -0
  333. package/test/cartesian/Scatter.spec.tsx +406 -0
  334. package/test/cartesian/Scatter.typed.spec.tsx +153 -0
  335. package/test/cartesian/XAxis/XAxis.barSize.spec.tsx +336 -0
  336. package/test/cartesian/XAxis/XAxis.brush.spec.tsx +266 -0
  337. package/test/cartesian/XAxis/XAxis.categorydomain.spec.tsx +872 -0
  338. package/test/cartesian/XAxis/XAxis.dataKey.spec.tsx +86 -0
  339. package/test/cartesian/XAxis/XAxis.datatypes.spec.tsx +127 -0
  340. package/test/cartesian/XAxis/XAxis.hide.spec.tsx +106 -0
  341. package/test/cartesian/XAxis/XAxis.multiaxis.spec.tsx +336 -0
  342. package/test/cartesian/XAxis/XAxis.numberdomain.spec.tsx +1466 -0
  343. package/test/cartesian/XAxis/XAxis.padding.spec.tsx +758 -0
  344. package/test/cartesian/XAxis/XAxis.padding_clip.spec.tsx +65 -0
  345. package/test/cartesian/XAxis/XAxis.state.spec.tsx +355 -0
  346. package/test/cartesian/XAxis/XAxis.tick.spec.tsx +493 -0
  347. package/test/cartesian/XAxis/XAxis.timescale.spec.tsx +233 -0
  348. package/test/cartesian/XAxis/XAxis.type.spec.tsx +107 -0
  349. package/test/cartesian/XAxis/XAxis.typed.spec.tsx +102 -0
  350. package/test/cartesian/XAxis/XAxis.vertical.spec.tsx +265 -0
  351. package/test/cartesian/XAxis.tickFormatter.spec.tsx +54 -0
  352. package/test/cartesian/YAxis/YAxis.7362.derivedDomain.spec.tsx +230 -0
  353. package/test/cartesian/YAxis/YAxis.7362.spec.tsx +104 -0
  354. package/test/cartesian/YAxis/YAxis.interval-zero.spec.tsx +88 -0
  355. package/test/cartesian/YAxis/YAxis.label.spec.tsx +219 -0
  356. package/test/cartesian/YAxis/YAxis.spec.tsx +1595 -0
  357. package/test/cartesian/YAxis/YAxis.tick.spec.tsx +428 -0
  358. package/test/cartesian/YAxis/YAxis.tickFormatter.spec.tsx +54 -0
  359. package/test/cartesian/YAxis/YAxis.ticks.spec.tsx +263 -0
  360. package/test/cartesian/YAxis/YAxis.type.spec.tsx +107 -0
  361. package/test/cartesian/YAxis/YAxis.typed.spec.tsx +102 -0
  362. package/test/cartesian/ZAxis.spec.tsx +300 -0
  363. package/test/cartesian/ZAxis.typed.spec.tsx +33 -0
  364. package/test/cartesian/__snapshots__/Brush.spec.tsx.snap +5 -0
  365. package/test/cartesian/axisLineAndStroke.spec.tsx +72 -0
  366. package/test/cartesian/getCartesianPosition.spec.ts +907 -0
  367. package/test/cartesian/getEquidistantTicks.spec.ts +88 -0
  368. package/test/cartesian/getTicks.spec.ts +378 -0
  369. package/test/cartesian/miscFeatureGaps.spec.tsx +89 -0
  370. package/test/cartesian/useAnimatedLineLength.spec.ts +168 -0
  371. package/test/chart/AccessibilityLayer.spec.tsx +569 -0
  372. package/test/chart/AccessibilityScans.spec.tsx +286 -0
  373. package/test/chart/AreaChart.spec.tsx +409 -0
  374. package/test/chart/AreaChart.stacked.spec.tsx +1407 -0
  375. package/test/chart/AreaChart.typed.spec.tsx +39 -0
  376. package/test/chart/BarChart.spec.tsx +3719 -0
  377. package/test/chart/BarChart.typed.spec.tsx +60 -0
  378. package/test/chart/CategoricalChart.spec.tsx +255 -0
  379. package/test/chart/ComposedChart.spec.tsx +199 -0
  380. package/test/chart/ComposedChart.typed.spec.tsx +39 -0
  381. package/test/chart/FunnelChart.spec.tsx +215 -0
  382. package/test/chart/FunnelChart.typed.spec.tsx +39 -0
  383. package/test/chart/LineChart.multiseries.spec.tsx +50 -0
  384. package/test/chart/LineChart.smoke.spec.tsx +50 -0
  385. package/test/chart/LineChart.spec.tsx +930 -0
  386. package/test/chart/LineChart.typed.spec.tsx +39 -0
  387. package/test/chart/NicheChartTooltip.spec.tsx +81 -0
  388. package/test/chart/PieChart.spec.tsx +793 -0
  389. package/test/chart/PieChart.typed.spec.tsx +39 -0
  390. package/test/chart/RadarChart.spec.tsx +530 -0
  391. package/test/chart/RadarChart.typed.spec.tsx +39 -0
  392. package/test/chart/RadialBarChart.5966.spec.tsx +48 -0
  393. package/test/chart/RadialBarChart.spec.tsx +679 -0
  394. package/test/chart/RadialBarChart.typed.spec.tsx +39 -0
  395. package/test/chart/RechartsWrapper.spec.tsx +83 -0
  396. package/test/chart/Sankey.content.spec.tsx +46 -0
  397. package/test/chart/Sankey.spec.tsx +952 -0
  398. package/test/chart/Sankey.typed.spec.tsx +29 -0
  399. package/test/chart/ScatterChart.spec.tsx +2613 -0
  400. package/test/chart/ScatterChart.typed.spec.tsx +39 -0
  401. package/test/chart/SunburstChart.spec.tsx +146 -0
  402. package/test/chart/Treemap.animation.spec.tsx +52 -0
  403. package/test/chart/Treemap.spec.tsx +1003 -0
  404. package/test/chart/Treemap.typed.spec.tsx +26 -0
  405. package/test/chart/chartEvents.spec.tsx +127 -0
  406. package/test/chart/responsive.spec.tsx +620 -0
  407. package/test/component/Cell.render.spec.tsx +155 -0
  408. package/test/component/Cell.spec.tsx +12 -0
  409. package/test/component/Cursor.spec.tsx +186 -0
  410. package/test/component/DefaultTooltipContent.spec.tsx +102 -0
  411. package/test/component/Label.render.spec.tsx +63 -0
  412. package/test/component/Label.spec.tsx +686 -0
  413. package/test/component/Label.typed.spec.tsx +46 -0
  414. package/test/component/LabelList.spec.tsx +188 -0
  415. package/test/component/Legend.itemSorter.spec.tsx +704 -0
  416. package/test/component/Legend.render.spec.tsx +92 -0
  417. package/test/component/Legend.spec.tsx +2213 -0
  418. package/test/component/Legend.typed.spec.tsx +22 -0
  419. package/test/component/ResponsiveContainer.spec.tsx +523 -0
  420. package/test/component/ResponsiveContainerDataTest.spec.tsx +51 -0
  421. package/test/component/Text.spec.tsx +415 -0
  422. package/test/component/Text.typed.spec.tsx +46 -0
  423. package/test/component/Tooltip/ActiveDot.spec.tsx +370 -0
  424. package/test/component/Tooltip/Tooltip.animation.spec.tsx +209 -0
  425. package/test/component/Tooltip/Tooltip.content.spec.tsx +128 -0
  426. package/test/component/Tooltip/Tooltip.formatter.spec.tsx +152 -0
  427. package/test/component/Tooltip/Tooltip.includeHidden.spec.tsx +79 -0
  428. package/test/component/Tooltip/Tooltip.multipleDataArrays.spec.tsx +165 -0
  429. package/test/component/Tooltip/Tooltip.offset.spec.tsx +113 -0
  430. package/test/component/Tooltip/Tooltip.state.spec.tsx +74 -0
  431. package/test/component/Tooltip/Tooltip.sync.spec.tsx +639 -0
  432. package/test/component/Tooltip/defaultIndex.spec.tsx +227 -0
  433. package/test/component/Tooltip/graphicalItem.formatter.spec.tsx +138 -0
  434. package/test/component/Tooltip/itemSorter.spec.tsx +2815 -0
  435. package/test/component/Tooltip/tooltipEventType.spec.tsx +344 -0
  436. package/test/component/Tooltip/tooltipMouseHoverSelectors.ts +41 -0
  437. package/test/component/Tooltip/tooltipTestHelpers.tsx +162 -0
  438. package/test/component/Tooltip.defaultIndex.spec.tsx +48 -0
  439. package/test/component/Tooltip.hover.spec.tsx +61 -0
  440. package/test/component/Tooltip.item.spec.tsx +54 -0
  441. package/test/component/Tooltip.keyboard.spec.tsx +51 -0
  442. package/test/component/Tooltip.payload.spec.tsx +1716 -0
  443. package/test/component/Tooltip.touch.spec.tsx +39 -0
  444. package/test/component/Tooltip.visibility.spec.tsx +1889 -0
  445. package/test/component/TooltipBoundingBox.spec.tsx +89 -0
  446. package/test/component/responsiveContainerUtils.spec.ts +205 -0
  447. package/test/container/ClipPath.spec.tsx +602 -0
  448. package/test/container/chartDimensions.spec.tsx +368 -0
  449. package/test/context/chartLayoutContext.spec.tsx +378 -0
  450. package/test/helper/ExpectAxisDomain.tsx +27 -0
  451. package/test/helper/assertNotNull.ts +6 -0
  452. package/test/helper/assertZIndexLayerOrder.ts +19 -0
  453. package/test/helper/createSelectorTestCase.tsx +176 -0
  454. package/test/helper/expectAnimatedPieAngles.ts +100 -0
  455. package/test/helper/expectAnimatedPiePaths.ts +78 -0
  456. package/test/helper/expectAreaCurve.ts +15 -0
  457. package/test/helper/expectAxisTicks.ts +48 -0
  458. package/test/helper/expectBars.ts +54 -0
  459. package/test/helper/expectFunctionReturning.ts +58 -0
  460. package/test/helper/expectLabel.ts +32 -0
  461. package/test/helper/expectLastCalledWith.ts +48 -0
  462. package/test/helper/expectLine.ts +20 -0
  463. package/test/helper/expectPieSectors.ts +80 -0
  464. package/test/helper/expectScale.ts +37 -0
  465. package/test/helper/expectScatterPoints.ts +52 -0
  466. package/test/helper/expectStackGroups.ts +144 -0
  467. package/test/helper/mockAxes.ts +22 -0
  468. package/test/helper/mockGetBoundingClientRect.ts +66 -0
  469. package/test/helper/mockHTMLElementProperty.ts +19 -0
  470. package/test/helper/mockTouchingElement.ts +27 -0
  471. package/test/helper/offsetHelpers.ts +19 -0
  472. package/test/helper/parameterizedTestCases.tsx +99 -0
  473. package/test/helper/produceState.ts +32 -0
  474. package/test/helper/render.ts +7 -0
  475. package/test/helper/selectorTestHelpers.tsx +63 -0
  476. package/test/helper/trim.spec.ts +35 -0
  477. package/test/helper/trim.ts +11 -0
  478. package/test/hooks/useActiveTooltipDataPoints.spec.tsx +358 -0
  479. package/test/hooks/useAxisDomain.spec.tsx +361 -0
  480. package/test/hooks/useAxisScale.spec.tsx +283 -0
  481. package/test/hooks/useAxisTicks.spec.tsx +130 -0
  482. package/test/hooks/useOffset.spec.tsx +248 -0
  483. package/test/hooks/useTooltipStateHooks.spec.tsx +109 -0
  484. package/test/polar/Pie/Pie-TwoLevelPieChart.spec.tsx +135 -0
  485. package/test/polar/Pie/Pie.spec.tsx +784 -0
  486. package/test/polar/Pie/Pie.typed.spec.tsx +78 -0
  487. package/test/polar/Pie.animation.spec.tsx +529 -0
  488. package/test/polar/PieWithLegend.animation.spec.tsx +142 -0
  489. package/test/polar/PolarAngleAxis/PolarAngleAxis.events.spec.tsx +76 -0
  490. package/test/polar/PolarAngleAxis/PolarAngleAxis.spec.tsx +2079 -0
  491. package/test/polar/PolarAngleAxis/PolarAngleAxis.typed.spec.tsx +102 -0
  492. package/test/polar/PolarAngleAxis.render.spec.tsx +79 -0
  493. package/test/polar/PolarGrid.render.spec.tsx +75 -0
  494. package/test/polar/PolarGrid.spec.tsx +918 -0
  495. package/test/polar/PolarLegendPerRow.render.spec.tsx +85 -0
  496. package/test/polar/PolarRadiusAxis.events.spec.tsx +65 -0
  497. package/test/polar/PolarRadiusAxis.render.spec.tsx +52 -0
  498. package/test/polar/PolarRadiusAxis.spec.tsx +991 -0
  499. package/test/polar/PolarRadiusAxis.typed.spec.tsx +84 -0
  500. package/test/polar/PolarTooltipLegend.render.spec.tsx +80 -0
  501. package/test/polar/Radar.animation.spec.tsx +570 -0
  502. package/test/polar/Radar.render.spec.tsx +71 -0
  503. package/test/polar/Radar.spec.tsx +265 -0
  504. package/test/polar/Radar.typed.spec.tsx +119 -0
  505. package/test/polar/RadialBar/RadialBar.spec.tsx +1521 -0
  506. package/test/polar/RadialBar/RadialBar.typed.spec.tsx +132 -0
  507. package/test/polar/RadialBar.animation.spec.tsx +375 -0
  508. package/test/polar/RadialBar.render.spec.tsx +66 -0
  509. package/test/polar/RadialBar.stacked.spec.tsx +57 -0
  510. package/test/setup.ts +84 -0
  511. package/test/shape/ActiveShape.spec.tsx +181 -0
  512. package/test/shape/Cross.spec.tsx +60 -0
  513. package/test/shape/Cross.typed.spec.tsx +26 -0
  514. package/test/shape/Curve.spec.tsx +368 -0
  515. package/test/shape/Curve.typed.spec.tsx +69 -0
  516. package/test/shape/Dot.spec.tsx +73 -0
  517. package/test/shape/Dot.typed.spec.tsx +30 -0
  518. package/test/shape/Polygon.spec.tsx +357 -0
  519. package/test/shape/Polygon.typed.spec.tsx +28 -0
  520. package/test/shape/Rectangle.animation.spec.tsx +451 -0
  521. package/test/shape/Rectangle.spec.tsx +68 -0
  522. package/test/shape/Rectangle.typed.spec.tsx +24 -0
  523. package/test/shape/Sector.spec.tsx +76 -0
  524. package/test/shape/Sector.typed.spec.tsx +24 -0
  525. package/test/shape/Symbols.spec.tsx +43 -0
  526. package/test/shape/Symbols.typed.spec.tsx +24 -0
  527. package/test/shape/Trapezoid.spec.tsx +50 -0
  528. package/test/shape/Trapezoid.typed.spec.tsx +24 -0
  529. package/test/shape/__snapshots__/Cross.spec.tsx.snap +62 -0
  530. package/test/shape/__snapshots__/Curve.spec.tsx.snap +460 -0
  531. package/test/shape/__snapshots__/Polygon.spec.tsx.snap +58 -0
  532. package/test/shape/__snapshots__/Rectangle.spec.tsx.snap +117 -0
  533. package/test/shape/__snapshots__/Sector.spec.tsx.snap +71 -0
  534. package/test/shape/__snapshots__/Trapezoid.spec.tsx.snap +64 -0
  535. package/test/state/chartDataSlice.spec.ts +53 -0
  536. package/test/state/externalEventsMiddleware.spec.ts +178 -0
  537. package/test/state/graphicalItemsSlice.spec.ts +92 -0
  538. package/test/state/hooks.spec.tsx +68 -0
  539. package/test/state/legendSlice.spec.ts +44 -0
  540. package/test/state/mouseEventsMiddleware.spec.ts +75 -0
  541. package/test/state/optionsSlice.spec.ts +19 -0
  542. package/test/state/reduxDevtoolsJsonStringifyReplacer.spec.ts +25 -0
  543. package/test/state/referenceElementsSlice.spec.ts +84 -0
  544. package/test/state/selectors/areaSelectors.spec.tsx +77 -0
  545. package/test/state/selectors/axisSelectors.spec.tsx +1418 -0
  546. package/test/state/selectors/barStackSelectors.spec.tsx +752 -0
  547. package/test/state/selectors/brushSelectors.spec.tsx +30 -0
  548. package/test/state/selectors/cartesianAxisSlice.spec.ts +96 -0
  549. package/test/state/selectors/combineNiceTicks.spec.ts +207 -0
  550. package/test/state/selectors/combiners/combineActiveTooltipIndex.spec.ts +61 -0
  551. package/test/state/selectors/combiners/combineAllBarPositions.spec.ts +39 -0
  552. package/test/state/selectors/combiners/combineConfiguredScale.spec.ts +56 -0
  553. package/test/state/selectors/combiners/combineDisplayedStackedData.spec.ts +123 -0
  554. package/test/state/selectors/combiners/combineRealScaleType.spec.ts +80 -0
  555. package/test/state/selectors/containerSelectors.spec.tsx +168 -0
  556. package/test/state/selectors/dataSelectors.spec.tsx +136 -0
  557. package/test/state/selectors/legendSelectors.spec.tsx +113 -0
  558. package/test/state/selectors/lineSelectors.spec.tsx +60 -0
  559. package/test/state/selectors/pieSelectors.spec.tsx +72 -0
  560. package/test/state/selectors/radarSelectors.spec.tsx +496 -0
  561. package/test/state/selectors/rootPropsSelectors.spec.tsx +169 -0
  562. package/test/state/selectors/scatterSelectors.spec.tsx +47 -0
  563. package/test/state/selectors/selectActiveTooltipIndex.spec.tsx +234 -0
  564. package/test/state/selectors/selectAllAxes.spec.tsx +18 -0
  565. package/test/state/selectors/selectAxisDomain.spec.tsx +21 -0
  566. package/test/state/selectors/selectAxisDomainIncludingNiceTicks.spec.tsx +19 -0
  567. package/test/state/selectors/selectAxisRangeWithReverse.spec.tsx +22 -0
  568. package/test/state/selectors/selectAxisScale.spec.tsx +91 -0
  569. package/test/state/selectors/selectBarRectangles.stackOffset.spec.tsx +503 -0
  570. package/test/state/selectors/selectBaseAxis.spec.tsx +56 -0
  571. package/test/state/selectors/selectCartesianItemsSettings.spec.tsx +57 -0
  572. package/test/state/selectors/selectChartOffset.spec.tsx +26 -0
  573. package/test/state/selectors/selectDisplayedData.spec.tsx +282 -0
  574. package/test/state/selectors/selectIsTooltipActive.spec.tsx +231 -0
  575. package/test/state/selectors/selectNumericalDomain.spec.tsx +21 -0
  576. package/test/state/selectors/selectRealScaleType.spec.tsx +19 -0
  577. package/test/state/selectors/selectStackGroups.spec.tsx +322 -0
  578. package/test/state/selectors/selectXAxisPosition.spec.tsx +22 -0
  579. package/test/state/selectors/selectYAxisPosition.spec.tsx +22 -0
  580. package/test/state/selectors/selectors.spec.tsx +1613 -0
  581. package/test/state/throttling.spec.ts +200 -0
  582. package/test/state/zIndexSlice.spec.ts +85 -0
  583. package/test/synchronisation/useChartSynchronisation.spec.tsx +225 -0
  584. package/test/util/BarUtils.spec.ts +39 -0
  585. package/test/util/CartesianUtils/CartesianUtils.spec.ts +261 -0
  586. package/test/util/CartesianUtils/rectWithPoints.spec.ts +48 -0
  587. package/test/util/ChartUtils/ChartUtils.spec.ts +491 -0
  588. package/test/util/ChartUtils/appendOffsetOfLegend.spec.ts +136 -0
  589. package/test/util/ChartUtils/appendOffsetOfLegend.spec.tsx +133 -0
  590. package/test/util/ChartUtils/getCateCoordinateOfLine.spec.ts +83 -0
  591. package/test/util/ChartUtils/getStackedData.spec.ts +416 -0
  592. package/test/util/ChartUtils/truncateByDomain.spec.ts +70 -0
  593. package/test/util/DataUtils.spec.ts +385 -0
  594. package/test/util/DomUtils.spec.tsx +117 -0
  595. package/test/util/FunnelUtils.spec.tsx +70 -0
  596. package/test/util/Global.spec.ts +11 -0
  597. package/test/util/LRUCache.spec.ts +81 -0
  598. package/test/util/LogUtils.spec.ts +45 -0
  599. package/test/util/PolarUtils.spec.ts +66 -0
  600. package/test/util/ReduceCssCalcPrototype.spec.ts +141 -0
  601. package/test/util/ShallowEqual.spec.ts +102 -0
  602. package/test/util/TickUtils.spec.ts +29 -0
  603. package/test/util/axisPropsAreEqual.spec.ts +93 -0
  604. package/test/util/createChartHelpers.spec.tsx +210 -0
  605. package/test/util/cursor/getCursorPoints.spec.ts +136 -0
  606. package/test/util/cursor/getCursorRectangle.spec.ts +50 -0
  607. package/test/util/cursor/getRadialCursorPoints.spec.ts +36 -0
  608. package/test/util/errorValue.spec.ts +69 -0
  609. package/test/util/getEveryNth.spec.ts +39 -0
  610. package/test/util/getRadiusAndStrokeWidthFromDot.spec.ts +51 -0
  611. package/test/util/getRelativeCoordinate.spec.ts +250 -0
  612. package/test/util/getSliced.spec.ts +45 -0
  613. package/test/util/isDomainSpecifiedByUser.spec.ts +207 -0
  614. package/test/util/isWellBehavedNumber.spec.ts +54 -0
  615. package/test/util/payload/getUniqPayload.spec.ts +56 -0
  616. package/test/util/propsAreEqual.spec.ts +75 -0
  617. package/test/util/round.spec.ts +112 -0
  618. package/test/util/scale/arithmetic.spec.ts +61 -0
  619. package/test/util/scale/createCategoricalInverse.spec.ts +84 -0
  620. package/test/util/scale/getNiceTickValues.spec.ts +421 -0
  621. package/test/util/scale/getTickValuesFixedDomain.spec.ts +155 -0
  622. package/test/util/svgPropertiesAndEvents.spec.tsx +206 -0
  623. package/test/util/svgPropertiesNoEvents.spec.tsx +228 -0
  624. package/test/util/tooltip/translate.spec.ts +396 -0
  625. package/test/util/useAnimationId.spec.tsx +59 -0
  626. package/test/util/useElementOffset.spec.tsx +173 -0
  627. package/test/util/usePrefersReducedMotion.spec.ts +54 -0
  628. package/test/util/useUniqueId.spec.ts +99 -0
  629. package/test/utils/diagnostics-allowlist.ts +18 -0
  630. package/test/utils/diagnostics.ts +58 -0
  631. package/test/zIndex/AllZIndexPortals.spec.tsx +83 -0
  632. package/test/zIndex/DefaultZIndexes.spec.ts +80 -0
  633. package/test/zIndex/DynamicZIndex.spec.tsx +102 -0
  634. package/test/zIndex/ZIndexLayer.portalOwner.spec.tsx +125 -0
  635. package/test/zIndex/componentZIndex.spec.tsx +255 -0
  636. package/test/zIndex/getZIndexFromUnknown.spec.ts +51 -0
  637. package/test/zIndex/multiChartZIndexIsolation.spec.tsx +90 -0
  638. package/test/zIndex/zIndexSelectors.spec.ts +172 -0
  639. package/tsconfig.json +11 -0
@@ -0,0 +1,2613 @@
1
+ // Ported from recharts 3.8.1 test/chart/ScatterChart.spec.tsx (commit
2
+ // 7a23854). Solid deviations: this first batch covers the base three-dimensional
3
+ // scatter render, clip path, empty data, and item mouse-enter callback.
4
+ import { describe, expect, it, test, vi } from "vitest";
5
+ import { createEffect, flush } from "solid-js";
6
+ import {
7
+ Bar,
8
+ Brush,
9
+ CartesianGrid,
10
+ ComposedChart,
11
+ Legend,
12
+ Scatter,
13
+ ScatterChart,
14
+ Symbols,
15
+ type SymbolsProps,
16
+ Tooltip,
17
+ XAxis,
18
+ YAxis,
19
+ ZAxis,
20
+ } from "../../src";
21
+ import { expectScatterPoints, expectScatterPointsUnordered } from "../helper/expectScatterPoints";
22
+ import { expectXAxisTicks, expectYAxisTicks } from "../helper/expectAxisTicks";
23
+ import { assertNotNull } from "../helper/assertNotNull";
24
+ import { fireEvent, render } from "../helper/render";
25
+ import { boxPlotData, PageData } from "../_data";
26
+ import { createSelectorTestCase } from "../helper/createSelectorTestCase";
27
+ import { expectLastCalledWith } from "../helper/expectLastCalledWith";
28
+ import { mockGetBoundingClientRect } from "../helper/mockGetBoundingClientRect";
29
+ import {
30
+ selectActiveCoordinate,
31
+ selectIsTooltipActive,
32
+ selectTooltipPayload,
33
+ selectTooltipPayloadConfigurations,
34
+ } from "../../src/state/selectors/tooltipSelectors";
35
+ import { selectChartDataWithIndexes } from "../../src/state/selectors/dataSelectors";
36
+ import { selectTooltipState } from "../../src/state/selectors/selectTooltipState";
37
+ import type { TooltipPayloadConfiguration, TooltipState } from "../../src/state/tooltipSlice";
38
+ import {
39
+ selectAxisDomain,
40
+ selectBaseAxis,
41
+ selectDisplayedData,
42
+ selectDomainOfStackGroups,
43
+ selectNumericalDomain,
44
+ selectTicksOfGraphicalItem,
45
+ selectZAxisWithScale,
46
+ } from "../../src/state/selectors/axisSelectors";
47
+ import { expectScale } from "../helper/expectScale";
48
+ import { useChartHeight, useChartWidth, useViewBox } from "../../src/context/chartLayoutContext";
49
+ import { useClipPathId } from "../../src/container/ClipPathProvider";
50
+ import {
51
+ expectTooltipCoordinate,
52
+ expectTooltipNotVisible,
53
+ expectTooltipPayload,
54
+ showTooltip,
55
+ } from "../component/Tooltip/tooltipTestHelpers";
56
+ import { scatterChartMouseHoverTooltipSelector } from "../component/Tooltip/tooltipMouseHoverSelectors";
57
+
58
+ describe("ScatterChart of three dimension data", () => {
59
+ const data01 = [
60
+ { x: 100, y: 200, z: 200 },
61
+ { x: 120, y: 100, z: 260 },
62
+ { x: 170, y: 300, z: 400 },
63
+ { x: 140, y: 250, z: 280 },
64
+ { x: 150, y: 400, z: 500 },
65
+ { x: 110, y: 280, z: 200 },
66
+ ];
67
+
68
+ const data02 = [
69
+ { x: 200, y: 260, z: 240 },
70
+ { x: 240, y: 290, z: 220 },
71
+ { x: 190, y: 290, z: 250 },
72
+ { x: 198, y: 250, z: 210 },
73
+ { x: 180, y: 280, z: 260 },
74
+ { x: 210, y: 220, z: 230 },
75
+ ];
76
+
77
+ test("Render 2 Scatter", () => {
78
+ const { container } = render(() => (
79
+ <ScatterChart width={400} height={400} margin={{ top: 20, right: 20, bottom: 20 }}>
80
+ <XAxis dataKey="x" name="stature" unit="cm" />
81
+ <YAxis dataKey="y" name="weight" unit="kg" />
82
+ <ZAxis dataKey="z" range={[4, 20]} name="score" unit="km" />
83
+ <CartesianGrid />
84
+ <Scatter name="A school" data={data01} fillOpacity={0.3} fill="#ff7300" />
85
+ <Scatter name="B school" data={data02} fill="#347300" />
86
+ <Tooltip />
87
+ <Legend />
88
+ </ScatterChart>
89
+ ));
90
+
91
+ expect(container.querySelectorAll(".recharts-scatter")).toHaveLength(2);
92
+ expect(container.querySelectorAll(".recharts-legend-item")).toHaveLength(2);
93
+ expect(container.querySelectorAll(".recharts-scatter-symbol")).toHaveLength(
94
+ data01.length + data02.length,
95
+ );
96
+ expect(container.querySelectorAll(".recharts-scatter-symbol path")).toHaveLength(
97
+ data01.length + data02.length,
98
+ );
99
+
100
+ expectScatterPoints(container, [
101
+ {
102
+ cx: "73.33333333333333",
103
+ cy: "185",
104
+ d: "M0,0",
105
+ height: "3.638913473173784",
106
+ transform: "translate(73.33333333333333, 185)",
107
+ width: "3.638913473173784",
108
+ },
109
+ {
110
+ cx: "100",
111
+ cy: "267.5",
112
+ d: "M0,0",
113
+ height: "3.960594802695323",
114
+ transform: "translate(100, 267.5)",
115
+ width: "3.960594802695323",
116
+ },
117
+ {
118
+ cx: "126.66666666666667",
119
+ cy: "102.5",
120
+ d: "M0,0",
121
+ height: "4.624978308224887",
122
+ transform: "translate(126.66666666666667, 102.5)",
123
+ width: "4.624978308224887",
124
+ },
125
+ {
126
+ cx: "153.33333333333334",
127
+ cy: "143.75",
128
+ d: "M0,0",
129
+ height: "4.062165001543845",
130
+ transform: "translate(153.33333333333334, 143.75)",
131
+ width: "4.062165001543845",
132
+ },
133
+ {
134
+ cx: "180.00000000000003",
135
+ cy: "20",
136
+ d: "M0,0",
137
+ height: "5.046265044040321",
138
+ transform: "translate(180.00000000000003, 20)",
139
+ width: "5.046265044040321",
140
+ },
141
+ {
142
+ cx: "206.66666666666669",
143
+ cy: "119.00000000000001",
144
+ d: "M0,0",
145
+ height: "3.638913473173784",
146
+ transform: "translate(206.66666666666669, 119.00000000000001)",
147
+ width: "3.638913473173784",
148
+ },
149
+ {
150
+ cx: "73.33333333333333",
151
+ cy: "135.5",
152
+ d: "M0,0",
153
+ height: "3.8563503319209342",
154
+ transform: "translate(73.33333333333333, 135.5)",
155
+ width: "3.8563503319209342",
156
+ },
157
+ {
158
+ cx: "100",
159
+ cy: "110.75000000000001",
160
+ d: "M0,0",
161
+ height: "3.749208526326083",
162
+ transform: "translate(100, 110.75000000000001)",
163
+ width: "3.749208526326083",
164
+ },
165
+ {
166
+ cx: "126.66666666666667",
167
+ cy: "110.75000000000001",
168
+ d: "M0,0",
169
+ height: "3.9088200952233594",
170
+ transform: "translate(126.66666666666667, 110.75000000000001)",
171
+ width: "3.9088200952233594",
172
+ },
173
+ {
174
+ cx: "153.33333333333334",
175
+ cy: "143.75",
176
+ d: "M0,0",
177
+ height: "3.694472617243352",
178
+ transform: "translate(153.33333333333334, 143.75)",
179
+ width: "3.694472617243352",
180
+ },
181
+ {
182
+ cx: "180.00000000000003",
183
+ cy: "119.00000000000001",
184
+ d: "M0,0",
185
+ height: "3.960594802695323",
186
+ transform: "translate(180.00000000000003, 119.00000000000001)",
187
+ width: "3.960594802695323",
188
+ },
189
+ {
190
+ cx: "206.66666666666669",
191
+ cy: "168.49999999999997",
192
+ d: "M0,0",
193
+ height: "3.803156745151513",
194
+ transform: "translate(206.66666666666669, 168.49999999999997)",
195
+ width: "3.803156745151513",
196
+ },
197
+ ]);
198
+ });
199
+
200
+ test("should render clipPath if one of axes has allowDataOverflow=true", () => {
201
+ const { container } = render(() => (
202
+ <ScatterChart width={400} height={400} margin={{ top: 10, right: 20, bottom: 30, left: 40 }}>
203
+ <XAxis dataKey="x" name="stature" unit="cm" allowDataOverflow />
204
+ <YAxis dataKey="y" name="weight" unit="kg" allowDataOverflow />
205
+ <ZAxis dataKey="z" range={[4, 20]} name="score" unit="km" />
206
+ <CartesianGrid />
207
+ <Scatter name="A school" data={[]} fillOpacity={0.3} fill="#ff7300" />
208
+ <Tooltip />
209
+ <Legend layout="vertical" />
210
+ </ScatterChart>
211
+ ));
212
+
213
+ const clipPath = container.querySelector("clipPath rect");
214
+ assertNotNull(clipPath);
215
+ expect(clipPath.getAttributeNames().sort()).toEqual(["height", "width", "x", "y"]);
216
+ expect(clipPath).toHaveAttribute("width", "280");
217
+ expect(clipPath).toHaveAttribute("height", "330");
218
+ expect(clipPath).toHaveAttribute("x", "100");
219
+ expect(clipPath).toHaveAttribute("y", "10");
220
+ });
221
+
222
+ test("Don't render any symbols when data is empty", () => {
223
+ const { container } = render(() => (
224
+ <ScatterChart width={400} height={400} margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
225
+ <XAxis dataKey="x" name="stature" unit="cm" />
226
+ <YAxis dataKey="y" name="weight" unit="kg" />
227
+ <ZAxis dataKey="z" range={[4, 20]} name="score" unit="km" />
228
+ <CartesianGrid />
229
+ <Scatter name="A school" data={[]} fillOpacity={0.3} fill="#ff7300" />
230
+ <Tooltip />
231
+ <Legend layout="vertical" />
232
+ </ScatterChart>
233
+ ));
234
+
235
+ expect(container.querySelectorAll(".recharts-symbol")).toHaveLength(0);
236
+ });
237
+
238
+ test("mouse enter on scatter symbol should call onMouseEnter from props", () => {
239
+ const onMouseEnter = vi.fn();
240
+ const { container } = render(() => (
241
+ <ScatterChart width={400} height={400} margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
242
+ <XAxis dataKey="x" name="stature" unit="cm" />
243
+ <YAxis dataKey="y" name="weight" unit="kg" />
244
+ <ZAxis dataKey="z" range={[4, 20]} name="score" unit="km" />
245
+ <CartesianGrid />
246
+ <Scatter
247
+ name="A school"
248
+ data={data01}
249
+ fillOpacity={0.3}
250
+ fill="#ff7300"
251
+ onMouseEnter={onMouseEnter}
252
+ />
253
+ <Scatter name="B school" data={data02} fill="#347300" />
254
+ <Tooltip />
255
+ <Legend />
256
+ </ScatterChart>
257
+ ));
258
+
259
+ const symbol = container.querySelectorAll(".recharts-scatter-symbol")[0];
260
+ assertNotNull(symbol);
261
+ fireEvent.mouseEnter(symbol);
262
+
263
+ expect(onMouseEnter).toHaveBeenCalled();
264
+ });
265
+ });
266
+
267
+ describe("ScatterChart of two dimension data", () => {
268
+ const data = [
269
+ { x: 100, y: 200, z: 200 },
270
+ { x: 120, y: 100, z: 260 },
271
+ { x: 170, y: 300, z: 400 },
272
+ { x: 140, y: 250, z: 280 },
273
+ { x: 150, y: 400, z: 500 },
274
+ { x: 110, y: 280, z: 200 },
275
+ ];
276
+
277
+ test("renders 6 circles in simple ScatterChart", () => {
278
+ const { container } = render(() => (
279
+ <ScatterChart width={400} height={400} margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
280
+ <XAxis dataKey="x" name="stature" unit="cm" />
281
+ <YAxis dataKey="y" name="weight" unit="kg" />
282
+ <Scatter line name="A school" data={data} fill="#ff7300" />
283
+ </ScatterChart>
284
+ ));
285
+
286
+ expect(container.querySelectorAll(".recharts-symbols")).toHaveLength(6);
287
+
288
+ expectScatterPoints(container, [
289
+ {
290
+ cx: "105",
291
+ cy: "185",
292
+ d: "M0,0",
293
+ height: "9.0270333367641",
294
+ transform: "translate(105, 185)",
295
+ width: "9.0270333367641",
296
+ },
297
+ {
298
+ cx: "155",
299
+ cy: "267.5",
300
+ d: "M0,0",
301
+ height: "9.0270333367641",
302
+ transform: "translate(155, 267.5)",
303
+ width: "9.0270333367641",
304
+ },
305
+ {
306
+ cx: "205",
307
+ cy: "102.5",
308
+ d: "M0,0",
309
+ height: "9.0270333367641",
310
+ transform: "translate(205, 102.5)",
311
+ width: "9.0270333367641",
312
+ },
313
+ {
314
+ cx: "255",
315
+ cy: "143.75",
316
+ d: "M0,0",
317
+ height: "9.0270333367641",
318
+ transform: "translate(255, 143.75)",
319
+ width: "9.0270333367641",
320
+ },
321
+ {
322
+ cx: "305",
323
+ cy: "20",
324
+ d: "M0,0",
325
+ height: "9.0270333367641",
326
+ transform: "translate(305, 20)",
327
+ width: "9.0270333367641",
328
+ },
329
+ {
330
+ cx: "355",
331
+ cy: "119.00000000000001",
332
+ d: "M0,0",
333
+ height: "9.0270333367641",
334
+ transform: "translate(355, 119.00000000000001)",
335
+ width: "9.0270333367641",
336
+ },
337
+ ]);
338
+ });
339
+
340
+ test("renders 6 circles in ScatterChart when data is defined on chart root", () => {
341
+ const { container } = render(() => (
342
+ <ScatterChart
343
+ width={400}
344
+ height={400}
345
+ margin={{ top: 20, right: 20, bottom: 20, left: 20 }}
346
+ data={data}
347
+ >
348
+ <XAxis dataKey="x" name="stature" unit="cm" />
349
+ <YAxis dataKey="y" name="weight" unit="kg" />
350
+ <Scatter line name="A school" fill="#ff7300" />
351
+ </ScatterChart>
352
+ ));
353
+
354
+ expectScatterPoints(container, [
355
+ {
356
+ cx: "105",
357
+ cy: "185",
358
+ d: "M0,0",
359
+ height: "9.0270333367641",
360
+ transform: "translate(105, 185)",
361
+ width: "9.0270333367641",
362
+ },
363
+ {
364
+ cx: "155",
365
+ cy: "267.5",
366
+ d: "M0,0",
367
+ height: "9.0270333367641",
368
+ transform: "translate(155, 267.5)",
369
+ width: "9.0270333367641",
370
+ },
371
+ {
372
+ cx: "205",
373
+ cy: "102.5",
374
+ d: "M0,0",
375
+ height: "9.0270333367641",
376
+ transform: "translate(205, 102.5)",
377
+ width: "9.0270333367641",
378
+ },
379
+ {
380
+ cx: "255",
381
+ cy: "143.75",
382
+ d: "M0,0",
383
+ height: "9.0270333367641",
384
+ transform: "translate(255, 143.75)",
385
+ width: "9.0270333367641",
386
+ },
387
+ {
388
+ cx: "305",
389
+ cy: "20",
390
+ d: "M0,0",
391
+ height: "9.0270333367641",
392
+ transform: "translate(305, 20)",
393
+ width: "9.0270333367641",
394
+ },
395
+ {
396
+ cx: "355",
397
+ cy: "119.00000000000001",
398
+ d: "M0,0",
399
+ height: "9.0270333367641",
400
+ transform: "translate(355, 119.00000000000001)",
401
+ width: "9.0270333367641",
402
+ },
403
+ ]);
404
+ });
405
+
406
+ test("renders 6 circles in ScatterChart when data is defined on chart root and there are no axes", () => {
407
+ const { container } = render(() => (
408
+ <ScatterChart width={400} height={400} data={data}>
409
+ <Scatter dataKey="y" />
410
+ </ScatterChart>
411
+ ));
412
+
413
+ expectScatterPoints(container, [
414
+ {
415
+ cx: "37.5",
416
+ cy: "200",
417
+ d: "M0,0",
418
+ height: "9.0270333367641",
419
+ transform: "translate(37.5, 200)",
420
+ width: "9.0270333367641",
421
+ },
422
+ {
423
+ cx: "102.5",
424
+ cy: "297.5",
425
+ d: "M0,0",
426
+ height: "9.0270333367641",
427
+ transform: "translate(102.5, 297.5)",
428
+ width: "9.0270333367641",
429
+ },
430
+ {
431
+ cx: "167.5",
432
+ cy: "102.5",
433
+ d: "M0,0",
434
+ height: "9.0270333367641",
435
+ transform: "translate(167.5, 102.5)",
436
+ width: "9.0270333367641",
437
+ },
438
+ {
439
+ cx: "232.5",
440
+ cy: "151.25",
441
+ d: "M0,0",
442
+ height: "9.0270333367641",
443
+ transform: "translate(232.5, 151.25)",
444
+ width: "9.0270333367641",
445
+ },
446
+ {
447
+ cx: "297.5",
448
+ cy: "5",
449
+ d: "M0,0",
450
+ height: "9.0270333367641",
451
+ transform: "translate(297.5, 5)",
452
+ width: "9.0270333367641",
453
+ },
454
+ {
455
+ cx: "362.5",
456
+ cy: "122.00000000000001",
457
+ d: "M0,0",
458
+ height: "9.0270333367641",
459
+ transform: "translate(362.5, 122.00000000000001)",
460
+ width: "9.0270333367641",
461
+ },
462
+ ]);
463
+ });
464
+
465
+ test("renders line when line prop=true", () => {
466
+ const { container } = render(() => (
467
+ <ScatterChart width={400} height={400} margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
468
+ <XAxis dataKey="x" name="stature" unit="cm" />
469
+ <YAxis dataKey="y" name="weight" unit="kg" />
470
+ <Scatter line name="A school" data={data} fill="#ff7300" />
471
+ </ScatterChart>
472
+ ));
473
+
474
+ const allLines = container.querySelectorAll(".recharts-scatter-line path");
475
+ expect(allLines).toHaveLength(1);
476
+ const line = allLines[0]!;
477
+ expect(line.getAttributeNames()).toEqual(["name", "fill", "stroke", "class", "d"]);
478
+ expect(line.getAttribute("name")).toEqual("A school");
479
+ expect(line.getAttribute("fill")).toEqual("none");
480
+ expect(line.getAttribute("stroke")).toEqual("#ff7300");
481
+ expect(line.getAttribute("class")).toEqual("recharts-curve");
482
+ expect(line.getAttribute("d")).toEqual(
483
+ "M105,185L155,267.5L205,102.5L255,143.75L305,20L355,119",
484
+ );
485
+ });
486
+
487
+ test("ignores points when data have nulls in it", () => {
488
+ const dataWithNulls: Array<{ x: number | null; y: number | null }> = [
489
+ { x: null, y: 2 },
490
+ { x: 3, y: 4 },
491
+ ];
492
+ const { container } = render(() => (
493
+ <ScatterChart width={400} height={400} margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
494
+ <XAxis dataKey="x" />
495
+ <YAxis dataKey="y" />
496
+ <Scatter name="A school" data={dataWithNulls} fill="#ff7300" />
497
+ </ScatterChart>
498
+ ));
499
+
500
+ expectScatterPoints(container, [
501
+ {
502
+ cx: "230",
503
+ cy: "185",
504
+ d: "M0,0",
505
+ height: "9.0270333367641",
506
+ transform: "translate(230, 185)",
507
+ width: "9.0270333367641",
508
+ },
509
+ ]);
510
+ });
511
+
512
+ // DEFERRED: Scatter does not yet mirror into the Brush panorama (the nested
513
+ // panorama ScatterChart renders no points). Tracked with the other panorama gaps.
514
+ // DEFERRED (PERMANENT-N/A for the Scatter cluster): the nested <ScatterChart>
515
+ // inside <Brush> creates its OWN store, so the panorama Scatter registers there
516
+ // instead of the outer chart's panorama surface — the 6 panorama points never
517
+ // render. Faithful panorama mirroring of a nested chart is cross-cutting Brush
518
+ // infra (RootSurface/store-sharing), tracked with the other panorama gaps.
519
+ test("renders scatter points in Brush panorama", () => {
520
+ const { container } = render(() => (
521
+ <ScatterChart width={400} height={400} data={data}>
522
+ <Scatter dataKey="y" />
523
+ <Brush>
524
+ <ScatterChart data={data}>
525
+ <Scatter dataKey="y" />
526
+ </ScatterChart>
527
+ </Brush>
528
+ </ScatterChart>
529
+ ));
530
+
531
+ expectScatterPointsUnordered(container, [
532
+ {
533
+ cx: "33.333333333333336",
534
+ cy: "20",
535
+ d: "M0,0",
536
+ height: "9.0270333367641",
537
+ transform: "translate(33.333333333333336, 20)",
538
+ width: "9.0270333367641",
539
+ },
540
+ {
541
+ cx: "98",
542
+ cy: "29.5",
543
+ d: "M0,0",
544
+ height: "9.0270333367641",
545
+ transform: "translate(98, 29.5)",
546
+ width: "9.0270333367641",
547
+ },
548
+ {
549
+ cx: "162.66666666666669",
550
+ cy: "10.5",
551
+ d: "M0,0",
552
+ height: "9.0270333367641",
553
+ transform: "translate(162.66666666666669, 10.5)",
554
+ width: "9.0270333367641",
555
+ },
556
+ {
557
+ cx: "227.33333333333334",
558
+ cy: "15.25",
559
+ d: "M0,0",
560
+ height: "9.0270333367641",
561
+ transform: "translate(227.33333333333334, 15.25)",
562
+ width: "9.0270333367641",
563
+ },
564
+ {
565
+ cx: "292",
566
+ cy: "1",
567
+ d: "M0,0",
568
+ height: "9.0270333367641",
569
+ transform: "translate(292, 1)",
570
+ width: "9.0270333367641",
571
+ },
572
+ {
573
+ cx: "356.6666666666667",
574
+ cy: "12.4",
575
+ d: "M0,0",
576
+ height: "9.0270333367641",
577
+ transform: "translate(356.6666666666667, 12.4)",
578
+ width: "9.0270333367641",
579
+ },
580
+ {
581
+ cx: "37.5",
582
+ cy: "180",
583
+ d: "M0,0",
584
+ height: "9.0270333367641",
585
+ transform: "translate(37.5, 180)",
586
+ width: "9.0270333367641",
587
+ },
588
+ {
589
+ cx: "102.5",
590
+ cy: "267.5",
591
+ d: "M0,0",
592
+ height: "9.0270333367641",
593
+ transform: "translate(102.5, 267.5)",
594
+ width: "9.0270333367641",
595
+ },
596
+ {
597
+ cx: "167.5",
598
+ cy: "92.5",
599
+ d: "M0,0",
600
+ height: "9.0270333367641",
601
+ transform: "translate(167.5, 92.5)",
602
+ width: "9.0270333367641",
603
+ },
604
+ {
605
+ cx: "232.5",
606
+ cy: "136.25",
607
+ d: "M0,0",
608
+ height: "9.0270333367641",
609
+ transform: "translate(232.5, 136.25)",
610
+ width: "9.0270333367641",
611
+ },
612
+ {
613
+ cx: "297.5",
614
+ cy: "5",
615
+ d: "M0,0",
616
+ height: "9.0270333367641",
617
+ transform: "translate(297.5, 5)",
618
+ width: "9.0270333367641",
619
+ },
620
+ {
621
+ cx: "362.5",
622
+ cy: "110.00000000000001",
623
+ d: "M0,0",
624
+ height: "9.0270333367641",
625
+ transform: "translate(362.5, 110.00000000000001)",
626
+ width: "9.0270333367641",
627
+ },
628
+ ]);
629
+ });
630
+ });
631
+
632
+ describe("ScatterChart with joint line", () => {
633
+ const data01 = [
634
+ { x: 10, y: 30, z: 120 },
635
+ { x: 30, y: 200, z: 190 },
636
+ { x: 45, y: 100, z: 32 },
637
+ { x: 50, y: 400, z: 67 },
638
+ { x: 70, y: 150, z: 109 },
639
+ { x: 100, y: 250, z: 120 },
640
+ ];
641
+ const data02 = [
642
+ { x: 30, y: 20, z: 190 },
643
+ { x: 50, y: 180, z: 32 },
644
+ { x: 75, y: 240, z: 67 },
645
+ { x: 100, y: 100, z: 109 },
646
+ { x: 120, y: 190, z: 120 },
647
+ ];
648
+
649
+ const renderTestCase = createSelectorTestCase((props) => (
650
+ <ScatterChart width={600} height={400}>
651
+ <CartesianGrid />
652
+ <XAxis type="number" dataKey="x" name="stature" unit="cm" />
653
+ <YAxis type="number" dataKey="y" name="weight" unit="kg" />
654
+ <ZAxis type="number" dataKey="z" range={[100, 200]} />
655
+ <Legend />
656
+ <Scatter name="A school" data={data01} fill="#8884d8" line shape="cross" />
657
+ <Scatter name="B school" data={data02} fill="#82ca9d" line shape="diamond" />
658
+ <Tooltip cursor={{ strokeDasharray: "3 3" }} />
659
+ {props.children}
660
+ </ScatterChart>
661
+ ));
662
+
663
+ it("should select ZAxis domain", () => {
664
+ const { spy } = renderTestCase((state) => selectNumericalDomain(state, "zAxis", 0, false));
665
+ expectLastCalledWith(spy, [0, 190]);
666
+ });
667
+
668
+ it("should select zAxis axis settings", () => {
669
+ const { spy } = renderTestCase((state) => selectZAxisWithScale(state, "zAxis", 0, false));
670
+ const settings = spy.mock.lastCall?.[0];
671
+ assertNotNull(settings);
672
+ // The port has no `toBeRechartsScale` matcher; assert the scale separately.
673
+ expect(settings).toMatchObject({
674
+ domain: undefined,
675
+ allowDataOverflow: false,
676
+ allowDuplicatedCategory: false,
677
+ dataKey: "z",
678
+ id: 0,
679
+ includeHidden: false,
680
+ name: undefined,
681
+ range: [100, 200],
682
+ reversed: false,
683
+ type: "number",
684
+ unit: undefined,
685
+ });
686
+ expectScale(settings.scale, { domain: [0, 190], range: [100, 200] });
687
+ });
688
+
689
+ it("should render scatter points", () => {
690
+ const { container } = renderTestCase();
691
+ expectScatterPoints(container, [
692
+ {
693
+ cx: "109.16666666666666",
694
+ cy: "338",
695
+ d: "M0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0Z",
696
+ height: "14.413156615213909",
697
+ transform: "translate(109.16666666666666, 338)",
698
+ width: "14.413156615213909",
699
+ },
700
+ {
701
+ cx: "197.5",
702
+ cy: "185",
703
+ d: "M0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0Z",
704
+ height: "15.957691216057308",
705
+ transform: "translate(197.5, 185)",
706
+ width: "15.957691216057308",
707
+ },
708
+ {
709
+ cx: "263.75",
710
+ cy: "275",
711
+ d: "M0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0Z",
712
+ height: "12.197048368812888",
713
+ transform: "translate(263.75, 275)",
714
+ width: "12.197048368812888",
715
+ },
716
+ {
717
+ cx: "285.83333333333337",
718
+ cy: "5",
719
+ d: "M0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0Z",
720
+ height: "13.12335329012121",
721
+ transform: "translate(285.83333333333337, 5)",
722
+ width: "13.12335329012121",
723
+ },
724
+ {
725
+ cx: "374.1666666666667",
726
+ cy: "230",
727
+ d: "M0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0Z",
728
+ height: "14.155129698337069",
729
+ transform: "translate(374.1666666666667, 230)",
730
+ width: "14.155129698337069",
731
+ },
732
+ {
733
+ cx: "506.6666666666667",
734
+ cy: "140",
735
+ d: "M0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0Z",
736
+ height: "14.413156615213909",
737
+ transform: "translate(506.6666666666667, 140)",
738
+ width: "14.413156615213909",
739
+ },
740
+ {
741
+ cx: "197.5",
742
+ cy: "347",
743
+ d: "M0,0L0,0L0,0L0,0Z",
744
+ height: "15.957691216057308",
745
+ transform: "translate(197.5, 347)",
746
+ width: "15.957691216057308",
747
+ },
748
+ {
749
+ cx: "285.83333333333337",
750
+ cy: "203.00000000000003",
751
+ d: "M0,0L0,0L0,0L0,0Z",
752
+ height: "12.197048368812888",
753
+ transform: "translate(285.83333333333337, 203.00000000000003)",
754
+ width: "12.197048368812888",
755
+ },
756
+ {
757
+ cx: "396.25",
758
+ cy: "149",
759
+ d: "M0,0L0,0L0,0L0,0Z",
760
+ height: "13.12335329012121",
761
+ transform: "translate(396.25, 149)",
762
+ width: "13.12335329012121",
763
+ },
764
+ {
765
+ cx: "506.6666666666667",
766
+ cy: "275",
767
+ d: "M0,0L0,0L0,0L0,0Z",
768
+ height: "14.155129698337069",
769
+ transform: "translate(506.6666666666667, 275)",
770
+ width: "14.155129698337069",
771
+ },
772
+ {
773
+ cx: "595",
774
+ cy: "194",
775
+ d: "M0,0L0,0L0,0L0,0Z",
776
+ height: "14.413156615213909",
777
+ transform: "translate(595, 194)",
778
+ width: "14.413156615213909",
779
+ },
780
+ ]);
781
+ });
782
+ });
783
+
784
+ describe("ScatterChart layout context", () => {
785
+ it("should provide viewBox", () => {
786
+ const spy = vi.fn();
787
+ const Comp = (): null => {
788
+ const viewBox = useViewBox();
789
+ createEffect(
790
+ () => viewBox(),
791
+ (v) => spy(v),
792
+ );
793
+ return null;
794
+ };
795
+ render(() => (
796
+ <ScatterChart width={100} height={50} barSize={20}>
797
+ <Comp />
798
+ </ScatterChart>
799
+ ));
800
+
801
+ expectLastCalledWith(spy, { x: 5, y: 5, width: 90, height: 40 });
802
+ });
803
+
804
+ it("should provide clipPathId", () => {
805
+ const spy = vi.fn();
806
+ const Comp = (): null => {
807
+ createEffect(
808
+ () => useClipPathId(),
809
+ (v) => spy(v),
810
+ );
811
+ return null;
812
+ };
813
+ render(() => (
814
+ <ScatterChart width={100} height={50} barSize={20}>
815
+ <Comp />
816
+ </ScatterChart>
817
+ ));
818
+
819
+ expect(spy).toHaveBeenCalledWith(expect.stringMatching(/recharts\d+-clip/));
820
+ });
821
+
822
+ it("should provide width", () => {
823
+ const spy = vi.fn();
824
+ const Comp = (): null => {
825
+ const width = useChartWidth();
826
+ createEffect(
827
+ () => width(),
828
+ (v) => spy(v),
829
+ );
830
+ return null;
831
+ };
832
+ render(() => (
833
+ <ScatterChart width={100} height={50} barSize={20}>
834
+ <Comp />
835
+ </ScatterChart>
836
+ ));
837
+
838
+ expect(spy).toHaveBeenCalledWith(100);
839
+ });
840
+
841
+ it("should provide height", () => {
842
+ const spy = vi.fn();
843
+ const Comp = (): null => {
844
+ const height = useChartHeight();
845
+ createEffect(
846
+ () => height(),
847
+ (v) => spy(v),
848
+ );
849
+ return null;
850
+ };
851
+ render(() => (
852
+ <ScatterChart width={100} height={50} barSize={20}>
853
+ <Comp />
854
+ </ScatterChart>
855
+ ));
856
+
857
+ expect(spy).toHaveBeenCalledWith(50);
858
+ });
859
+ });
860
+
861
+ describe("Tooltip integration", () => {
862
+ describe("with default Tooltip", () => {
863
+ const renderTestCase = createSelectorTestCase((props) => (
864
+ <ScatterChart width={100} height={100} data={PageData}>
865
+ <Scatter isAnimationActive={false} id="my-scatter" />
866
+ <XAxis dataKey="uv" />
867
+ <YAxis dataKey="pv" />
868
+ <Tooltip isAnimationActive={false} />
869
+ {props.children}
870
+ </ScatterChart>
871
+ ));
872
+
873
+ it("should return tooltip payload", () => {
874
+ // ScatterChart only allows item interaction
875
+ const { spy } = renderTestCase((state) => selectTooltipPayload(state, "item", "hover", "0"));
876
+ expectLastCalledWith(spy, [
877
+ {
878
+ color: undefined,
879
+ dataKey: "uv",
880
+ fill: undefined,
881
+ graphicalItemId: "my-scatter",
882
+ hide: false,
883
+ name: "uv",
884
+ nameKey: undefined,
885
+ payload: {
886
+ amt: 2400,
887
+ name: "Page A",
888
+ pv: 2400,
889
+ uv: 400,
890
+ },
891
+ stroke: undefined,
892
+ strokeWidth: undefined,
893
+ type: undefined,
894
+ unit: "",
895
+ value: 400,
896
+ },
897
+ {
898
+ color: undefined,
899
+ dataKey: "pv",
900
+ fill: undefined,
901
+ graphicalItemId: "my-scatter",
902
+ hide: false,
903
+ name: "pv",
904
+ nameKey: undefined,
905
+ payload: {
906
+ amt: 2400,
907
+ name: "Page A",
908
+ pv: 2400,
909
+ uv: 400,
910
+ },
911
+ stroke: undefined,
912
+ strokeWidth: undefined,
913
+ type: undefined,
914
+ unit: "",
915
+ value: 2400,
916
+ },
917
+ ]);
918
+ });
919
+
920
+ it("should not render tooltip before user interaction", () => {
921
+ const { container } = renderTestCase();
922
+ expectTooltipNotVisible(container);
923
+ });
924
+
925
+ it("should render tooltip after mouse hover", () => {
926
+ mockGetBoundingClientRect({ width: 10, height: 10 });
927
+ const { container } = renderTestCase();
928
+ showTooltip(container, scatterChartMouseHoverTooltipSelector);
929
+
930
+ expectTooltipPayload(container, "", ["pv : 2400", "uv : 400"]);
931
+ expectTooltipCoordinate(container, { x: 77.5, y: 30.6 });
932
+ });
933
+ });
934
+ });
935
+
936
+ describe("ScatterChart with multiple Y axes", () => {
937
+ it("should render points", () => {
938
+ const data01 = [
939
+ { x: 100, y: 200, z: 200 },
940
+ { x: 120, y: 100, z: 260 },
941
+ { x: 170, y: 300, z: 400 },
942
+ { x: 140, y: 250, z: 280 },
943
+ { x: 150, y: 400, z: 500 },
944
+ { x: 110, y: 280, z: 200 },
945
+ ];
946
+ const data02 = [
947
+ { x: 300, y: 300, z: 200 },
948
+ { x: 400, y: 500, z: 260 },
949
+ { x: 200, y: 700, z: 400 },
950
+ { x: 340, y: 350, z: 280 },
951
+ { x: 560, y: 500, z: 500 },
952
+ { x: 230, y: 780, z: 200 },
953
+ { x: 500, y: 400, z: 200 },
954
+ { x: 300, y: 500, z: 260 },
955
+ { x: 240, y: 300, z: 400 },
956
+ { x: 320, y: 550, z: 280 },
957
+ { x: 500, y: 400, z: 500 },
958
+ { x: 420, y: 280, z: 200 },
959
+ ];
960
+
961
+ const { container } = render(() => (
962
+ <ScatterChart
963
+ width={800}
964
+ height={400}
965
+ margin={{
966
+ top: 20,
967
+ right: 20,
968
+ bottom: 20,
969
+ left: 20,
970
+ }}
971
+ >
972
+ <CartesianGrid yAxisId="left" />
973
+ <XAxis type="number" dataKey="x" name="stature" unit="cm" />
974
+ <YAxis yAxisId="left" type="number" dataKey="y" name="weight" unit="kg" stroke="#8884d8" />
975
+ <YAxis
976
+ yAxisId="right"
977
+ type="number"
978
+ dataKey="y"
979
+ name="weight"
980
+ unit="kg"
981
+ orientation="right"
982
+ stroke="#82ca9d"
983
+ />
984
+ <Scatter yAxisId="left" name="A school" data={data01} fill="#8884d8" />
985
+ <Scatter yAxisId="right" name="A school" data={data02} fill="#82ca9d" />
986
+ <Tooltip cursor={{ strokeDasharray: "3 3" }} />
987
+ </ScatterChart>
988
+ ));
989
+
990
+ expectScatterPoints(container, [
991
+ {
992
+ cx: "186.66666666666669",
993
+ cy: "185",
994
+ d: "M0,0",
995
+ height: "9.0270333367641",
996
+ transform: "translate(186.66666666666669, 185)",
997
+ width: "9.0270333367641",
998
+ },
999
+ {
1000
+ cx: "208",
1001
+ cy: "267.5",
1002
+ d: "M0,0",
1003
+ height: "9.0270333367641",
1004
+ transform: "translate(208, 267.5)",
1005
+ width: "9.0270333367641",
1006
+ },
1007
+ {
1008
+ cx: "261.3333333333333",
1009
+ cy: "102.5",
1010
+ d: "M0,0",
1011
+ height: "9.0270333367641",
1012
+ transform: "translate(261.3333333333333, 102.5)",
1013
+ width: "9.0270333367641",
1014
+ },
1015
+ {
1016
+ cx: "229.33333333333331",
1017
+ cy: "143.75",
1018
+ d: "M0,0",
1019
+ height: "9.0270333367641",
1020
+ transform: "translate(229.33333333333331, 143.75)",
1021
+ width: "9.0270333367641",
1022
+ },
1023
+ {
1024
+ cx: "240",
1025
+ cy: "20",
1026
+ d: "M0,0",
1027
+ height: "9.0270333367641",
1028
+ transform: "translate(240, 20)",
1029
+ width: "9.0270333367641",
1030
+ },
1031
+ {
1032
+ cx: "197.33333333333331",
1033
+ cy: "119.00000000000001",
1034
+ d: "M0,0",
1035
+ height: "9.0270333367641",
1036
+ transform: "translate(197.33333333333331, 119.00000000000001)",
1037
+ width: "9.0270333367641",
1038
+ },
1039
+ {
1040
+ cx: "400",
1041
+ cy: "226.25",
1042
+ d: "M0,0",
1043
+ height: "9.0270333367641",
1044
+ transform: "translate(400, 226.25)",
1045
+ width: "9.0270333367641",
1046
+ },
1047
+ {
1048
+ cx: "506.6666666666667",
1049
+ cy: "143.75",
1050
+ d: "M0,0",
1051
+ height: "9.0270333367641",
1052
+ transform: "translate(506.6666666666667, 143.75)",
1053
+ width: "9.0270333367641",
1054
+ },
1055
+ {
1056
+ cx: "293.33333333333337",
1057
+ cy: "61.25",
1058
+ d: "M0,0",
1059
+ height: "9.0270333367641",
1060
+ transform: "translate(293.33333333333337, 61.25)",
1061
+ width: "9.0270333367641",
1062
+ },
1063
+ {
1064
+ cx: "442.6666666666667",
1065
+ cy: "205.625",
1066
+ d: "M0,0",
1067
+ height: "9.0270333367641",
1068
+ transform: "translate(442.6666666666667, 205.625)",
1069
+ width: "9.0270333367641",
1070
+ },
1071
+ {
1072
+ cx: "677.3333333333334",
1073
+ cy: "143.75",
1074
+ d: "M0,0",
1075
+ height: "9.0270333367641",
1076
+ transform: "translate(677.3333333333334, 143.75)",
1077
+ width: "9.0270333367641",
1078
+ },
1079
+ {
1080
+ cx: "325.3333333333333",
1081
+ cy: "28.250000000000007",
1082
+ d: "M0,0",
1083
+ height: "9.0270333367641",
1084
+ transform: "translate(325.3333333333333, 28.250000000000007)",
1085
+ width: "9.0270333367641",
1086
+ },
1087
+ {
1088
+ cx: "613.3333333333334",
1089
+ cy: "185",
1090
+ d: "M0,0",
1091
+ height: "9.0270333367641",
1092
+ transform: "translate(613.3333333333334, 185)",
1093
+ width: "9.0270333367641",
1094
+ },
1095
+ {
1096
+ cx: "400",
1097
+ cy: "143.75",
1098
+ d: "M0,0",
1099
+ height: "9.0270333367641",
1100
+ transform: "translate(400, 143.75)",
1101
+ width: "9.0270333367641",
1102
+ },
1103
+ {
1104
+ cx: "336",
1105
+ cy: "226.25",
1106
+ d: "M0,0",
1107
+ height: "9.0270333367641",
1108
+ transform: "translate(336, 226.25)",
1109
+ width: "9.0270333367641",
1110
+ },
1111
+ {
1112
+ cx: "421.3333333333333",
1113
+ cy: "123.125",
1114
+ d: "M0,0",
1115
+ height: "9.0270333367641",
1116
+ transform: "translate(421.3333333333333, 123.125)",
1117
+ width: "9.0270333367641",
1118
+ },
1119
+ {
1120
+ cx: "613.3333333333334",
1121
+ cy: "185",
1122
+ d: "M0,0",
1123
+ height: "9.0270333367641",
1124
+ transform: "translate(613.3333333333334, 185)",
1125
+ width: "9.0270333367641",
1126
+ },
1127
+ {
1128
+ cx: "528",
1129
+ cy: "234.5",
1130
+ d: "M0,0",
1131
+ height: "9.0270333367641",
1132
+ transform: "translate(528, 234.5)",
1133
+ width: "9.0270333367641",
1134
+ },
1135
+ ]);
1136
+ });
1137
+ });
1138
+
1139
+ describe("with Tooltip and defaultIndex=number", () => {
1140
+ const renderTestCase = createSelectorTestCase((props) => (
1141
+ <ScatterChart width={100} height={100} data={PageData}>
1142
+ <Scatter isAnimationActive={false} id="my-scatter" />
1143
+ <XAxis dataKey="uv" />
1144
+ <YAxis dataKey="pv" />
1145
+ <Tooltip defaultIndex={1} />
1146
+ {props.children}
1147
+ </ScatterChart>
1148
+ ));
1149
+
1150
+ it("should render tooltip before user interaction", () => {
1151
+ mockGetBoundingClientRect({
1152
+ width: 10,
1153
+ height: 10,
1154
+ });
1155
+ const { container } = renderTestCase();
1156
+ expectTooltipPayload(container, "", ["pv : 4567", "uv : 300"]);
1157
+ expectTooltipCoordinate(container, {
1158
+ x: 82.5,
1159
+ y: 47.598,
1160
+ });
1161
+ });
1162
+
1163
+ it("should select tooltip state", () => {
1164
+ const { spy } = renderTestCase(selectTooltipState);
1165
+ const expected: TooltipState = {
1166
+ axisInteraction: {
1167
+ click: {
1168
+ active: false,
1169
+ dataKey: undefined,
1170
+ index: null,
1171
+ coordinate: undefined,
1172
+ graphicalItemId: undefined,
1173
+ },
1174
+ hover: {
1175
+ active: false,
1176
+ dataKey: undefined,
1177
+ index: null,
1178
+ coordinate: undefined,
1179
+ graphicalItemId: undefined,
1180
+ },
1181
+ },
1182
+ itemInteraction: {
1183
+ click: {
1184
+ active: false,
1185
+ index: null,
1186
+ dataKey: undefined,
1187
+ coordinate: undefined,
1188
+ graphicalItemId: undefined,
1189
+ },
1190
+ hover: {
1191
+ active: false,
1192
+ index: null,
1193
+ dataKey: undefined,
1194
+ coordinate: undefined,
1195
+ graphicalItemId: undefined,
1196
+ },
1197
+ },
1198
+ keyboardInteraction: {
1199
+ active: false,
1200
+ dataKey: undefined,
1201
+ index: null,
1202
+ coordinate: undefined,
1203
+ graphicalItemId: undefined,
1204
+ },
1205
+ settings: {
1206
+ active: undefined,
1207
+ axisId: 0,
1208
+ shared: undefined,
1209
+ trigger: "hover",
1210
+ defaultIndex: "1",
1211
+ },
1212
+ syncInteraction: {
1213
+ active: false,
1214
+ dataKey: undefined,
1215
+ index: null,
1216
+ coordinate: undefined,
1217
+ label: undefined,
1218
+ sourceViewBox: undefined,
1219
+ graphicalItemId: undefined,
1220
+ },
1221
+ tooltipItemPayloads: [
1222
+ {
1223
+ dataDefinedOnItem: [
1224
+ [
1225
+ {
1226
+ dataKey: "uv",
1227
+ name: "uv",
1228
+ payload: {
1229
+ amt: 2400,
1230
+ name: "Page A",
1231
+ pv: 2400,
1232
+ uv: 400,
1233
+ },
1234
+ type: undefined,
1235
+ unit: "",
1236
+ value: 400,
1237
+ graphicalItemId: "my-scatter",
1238
+ },
1239
+ {
1240
+ dataKey: "pv",
1241
+ name: "pv",
1242
+ payload: {
1243
+ amt: 2400,
1244
+ name: "Page A",
1245
+ pv: 2400,
1246
+ uv: 400,
1247
+ },
1248
+ type: undefined,
1249
+ unit: "",
1250
+ value: 2400,
1251
+ graphicalItemId: "my-scatter",
1252
+ },
1253
+ ],
1254
+ [
1255
+ {
1256
+ dataKey: "uv",
1257
+ name: "uv",
1258
+ payload: {
1259
+ amt: 2400,
1260
+ name: "Page B",
1261
+ pv: 4567,
1262
+ uv: 300,
1263
+ },
1264
+ type: undefined,
1265
+ unit: "",
1266
+ value: 300,
1267
+ graphicalItemId: "my-scatter",
1268
+ },
1269
+ {
1270
+ dataKey: "pv",
1271
+ name: "pv",
1272
+ payload: {
1273
+ amt: 2400,
1274
+ name: "Page B",
1275
+ pv: 4567,
1276
+ uv: 300,
1277
+ },
1278
+ type: undefined,
1279
+ unit: "",
1280
+ value: 4567,
1281
+ graphicalItemId: "my-scatter",
1282
+ },
1283
+ ],
1284
+ [
1285
+ {
1286
+ dataKey: "uv",
1287
+ name: "uv",
1288
+ payload: {
1289
+ amt: 2400,
1290
+ name: "Page C",
1291
+ pv: 1398,
1292
+ uv: 300,
1293
+ },
1294
+ type: undefined,
1295
+ unit: "",
1296
+ value: 300,
1297
+ graphicalItemId: "my-scatter",
1298
+ },
1299
+ {
1300
+ dataKey: "pv",
1301
+ name: "pv",
1302
+ payload: {
1303
+ amt: 2400,
1304
+ name: "Page C",
1305
+ pv: 1398,
1306
+ uv: 300,
1307
+ },
1308
+ type: undefined,
1309
+ unit: "",
1310
+ value: 1398,
1311
+ graphicalItemId: "my-scatter",
1312
+ },
1313
+ ],
1314
+ [
1315
+ {
1316
+ dataKey: "uv",
1317
+ name: "uv",
1318
+ payload: {
1319
+ amt: 2400,
1320
+ name: "Page D",
1321
+ pv: 9800,
1322
+ uv: 200,
1323
+ },
1324
+ type: undefined,
1325
+ unit: "",
1326
+ value: 200,
1327
+ graphicalItemId: "my-scatter",
1328
+ },
1329
+ {
1330
+ dataKey: "pv",
1331
+ name: "pv",
1332
+ payload: {
1333
+ amt: 2400,
1334
+ name: "Page D",
1335
+ pv: 9800,
1336
+ uv: 200,
1337
+ },
1338
+ type: undefined,
1339
+ unit: "",
1340
+ value: 9800,
1341
+ graphicalItemId: "my-scatter",
1342
+ },
1343
+ ],
1344
+ [
1345
+ {
1346
+ dataKey: "uv",
1347
+ name: "uv",
1348
+ payload: {
1349
+ amt: 2400,
1350
+ name: "Page E",
1351
+ pv: 3908,
1352
+ uv: 278,
1353
+ },
1354
+ type: undefined,
1355
+ unit: "",
1356
+ value: 278,
1357
+ graphicalItemId: "my-scatter",
1358
+ },
1359
+ {
1360
+ dataKey: "pv",
1361
+ name: "pv",
1362
+ payload: {
1363
+ amt: 2400,
1364
+ name: "Page E",
1365
+ pv: 3908,
1366
+ uv: 278,
1367
+ },
1368
+ type: undefined,
1369
+ unit: "",
1370
+ value: 3908,
1371
+ graphicalItemId: "my-scatter",
1372
+ },
1373
+ ],
1374
+ [
1375
+ {
1376
+ dataKey: "uv",
1377
+ name: "uv",
1378
+ payload: {
1379
+ amt: 2400,
1380
+ name: "Page F",
1381
+ pv: 4800,
1382
+ uv: 189,
1383
+ },
1384
+ type: undefined,
1385
+ unit: "",
1386
+ value: 189,
1387
+ graphicalItemId: "my-scatter",
1388
+ },
1389
+ {
1390
+ dataKey: "pv",
1391
+ name: "pv",
1392
+ payload: {
1393
+ amt: 2400,
1394
+ name: "Page F",
1395
+ pv: 4800,
1396
+ uv: 189,
1397
+ },
1398
+ type: undefined,
1399
+ unit: "",
1400
+ value: 4800,
1401
+ graphicalItemId: "my-scatter",
1402
+ },
1403
+ ],
1404
+ ],
1405
+ getPosition: expect.functionReturning([
1406
+ ["0", { x: 67.5, y: 50.6 }],
1407
+ ["1", { x: 72.5, y: 37.598 }],
1408
+ ["2", { x: 77.5, y: 56.611999999999995 }],
1409
+ ["3", { x: 82.5, y: 6.200000000000001 }],
1410
+ ["4", { x: 87.5, y: 41.552 }],
1411
+ ["5", { x: 92.5, y: 36.2 }],
1412
+ ]),
1413
+ settings: {
1414
+ color: undefined,
1415
+ dataKey: undefined,
1416
+ fill: undefined,
1417
+ graphicalItemId: "my-scatter",
1418
+ hide: false,
1419
+ name: undefined,
1420
+ nameKey: undefined,
1421
+ stroke: undefined,
1422
+ strokeWidth: undefined,
1423
+ type: undefined,
1424
+ unit: "",
1425
+ },
1426
+ },
1427
+ ],
1428
+ };
1429
+ expectLastCalledWith(spy, expected);
1430
+ });
1431
+
1432
+ it("should select tooltip payload configurations", () => {
1433
+ const { spy } = renderTestCase((state) =>
1434
+ selectTooltipPayloadConfigurations(state, "axis", "hover", "0"),
1435
+ );
1436
+ // toHaveBeenCalledTimes dropped — Solid's fine-grained reactivity differs.
1437
+ expectLastCalledWith(spy, [
1438
+ {
1439
+ dataDefinedOnItem: [
1440
+ [
1441
+ {
1442
+ dataKey: "uv",
1443
+ name: "uv",
1444
+ payload: {
1445
+ amt: 2400,
1446
+ name: "Page A",
1447
+ pv: 2400,
1448
+ uv: 400,
1449
+ },
1450
+ type: undefined,
1451
+ unit: "",
1452
+ value: 400,
1453
+ graphicalItemId: "my-scatter",
1454
+ },
1455
+ {
1456
+ dataKey: "pv",
1457
+ name: "pv",
1458
+ payload: {
1459
+ amt: 2400,
1460
+ name: "Page A",
1461
+ pv: 2400,
1462
+ uv: 400,
1463
+ },
1464
+ type: undefined,
1465
+ unit: "",
1466
+ value: 2400,
1467
+ graphicalItemId: "my-scatter",
1468
+ },
1469
+ ],
1470
+ [
1471
+ {
1472
+ dataKey: "uv",
1473
+ name: "uv",
1474
+ payload: {
1475
+ amt: 2400,
1476
+ name: "Page B",
1477
+ pv: 4567,
1478
+ uv: 300,
1479
+ },
1480
+ type: undefined,
1481
+ unit: "",
1482
+ value: 300,
1483
+ graphicalItemId: "my-scatter",
1484
+ },
1485
+ {
1486
+ dataKey: "pv",
1487
+ name: "pv",
1488
+ payload: {
1489
+ amt: 2400,
1490
+ name: "Page B",
1491
+ pv: 4567,
1492
+ uv: 300,
1493
+ },
1494
+ type: undefined,
1495
+ unit: "",
1496
+ value: 4567,
1497
+ graphicalItemId: "my-scatter",
1498
+ },
1499
+ ],
1500
+ [
1501
+ {
1502
+ dataKey: "uv",
1503
+ name: "uv",
1504
+ payload: {
1505
+ amt: 2400,
1506
+ name: "Page C",
1507
+ pv: 1398,
1508
+ uv: 300,
1509
+ },
1510
+ type: undefined,
1511
+ unit: "",
1512
+ value: 300,
1513
+ graphicalItemId: "my-scatter",
1514
+ },
1515
+ {
1516
+ dataKey: "pv",
1517
+ name: "pv",
1518
+ payload: {
1519
+ amt: 2400,
1520
+ name: "Page C",
1521
+ pv: 1398,
1522
+ uv: 300,
1523
+ },
1524
+ type: undefined,
1525
+ unit: "",
1526
+ value: 1398,
1527
+ graphicalItemId: "my-scatter",
1528
+ },
1529
+ ],
1530
+ [
1531
+ {
1532
+ dataKey: "uv",
1533
+ name: "uv",
1534
+ payload: {
1535
+ amt: 2400,
1536
+ name: "Page D",
1537
+ pv: 9800,
1538
+ uv: 200,
1539
+ },
1540
+ type: undefined,
1541
+ unit: "",
1542
+ value: 200,
1543
+ graphicalItemId: "my-scatter",
1544
+ },
1545
+ {
1546
+ dataKey: "pv",
1547
+ name: "pv",
1548
+ payload: {
1549
+ amt: 2400,
1550
+ name: "Page D",
1551
+ pv: 9800,
1552
+ uv: 200,
1553
+ },
1554
+ type: undefined,
1555
+ unit: "",
1556
+ value: 9800,
1557
+ graphicalItemId: "my-scatter",
1558
+ },
1559
+ ],
1560
+ [
1561
+ {
1562
+ dataKey: "uv",
1563
+ name: "uv",
1564
+ payload: {
1565
+ amt: 2400,
1566
+ name: "Page E",
1567
+ pv: 3908,
1568
+ uv: 278,
1569
+ },
1570
+ type: undefined,
1571
+ unit: "",
1572
+ value: 278,
1573
+ graphicalItemId: "my-scatter",
1574
+ },
1575
+ {
1576
+ dataKey: "pv",
1577
+ name: "pv",
1578
+ payload: {
1579
+ amt: 2400,
1580
+ name: "Page E",
1581
+ pv: 3908,
1582
+ uv: 278,
1583
+ },
1584
+ type: undefined,
1585
+ unit: "",
1586
+ value: 3908,
1587
+ graphicalItemId: "my-scatter",
1588
+ },
1589
+ ],
1590
+ [
1591
+ {
1592
+ dataKey: "uv",
1593
+ name: "uv",
1594
+ payload: {
1595
+ amt: 2400,
1596
+ name: "Page F",
1597
+ pv: 4800,
1598
+ uv: 189,
1599
+ },
1600
+ type: undefined,
1601
+ unit: "",
1602
+ value: 189,
1603
+ graphicalItemId: "my-scatter",
1604
+ },
1605
+ {
1606
+ dataKey: "pv",
1607
+ name: "pv",
1608
+ payload: {
1609
+ amt: 2400,
1610
+ name: "Page F",
1611
+ pv: 4800,
1612
+ uv: 189,
1613
+ },
1614
+ type: undefined,
1615
+ unit: "",
1616
+ value: 4800,
1617
+ graphicalItemId: "my-scatter",
1618
+ },
1619
+ ],
1620
+ ],
1621
+ getPosition: expect.functionReturning([
1622
+ ["0", { x: 67.5, y: 50.6 }],
1623
+ ["1", { x: 72.5, y: 37.598 }],
1624
+ ["2", { x: 77.5, y: 56.611999999999995 }],
1625
+ ["3", { x: 82.5, y: 6.200000000000001 }],
1626
+ ["4", { x: 87.5, y: 41.552 }],
1627
+ ["5", { x: 92.5, y: 36.2 }],
1628
+ ]),
1629
+ settings: {
1630
+ color: undefined,
1631
+ dataKey: undefined,
1632
+ fill: undefined,
1633
+ graphicalItemId: "my-scatter",
1634
+ hide: false,
1635
+ name: undefined,
1636
+ nameKey: undefined,
1637
+ stroke: undefined,
1638
+ strokeWidth: undefined,
1639
+ type: undefined,
1640
+ unit: "",
1641
+ },
1642
+ },
1643
+ ]);
1644
+ });
1645
+
1646
+ it("should select active coordinate", () => {
1647
+ const { spy } = renderTestCase((state) => selectActiveCoordinate(state, "item", "hover", "0"));
1648
+ expectLastCalledWith(spy, {
1649
+ x: 67.5,
1650
+ y: 50.6,
1651
+ });
1652
+ });
1653
+
1654
+ it("should select tooltip data", () => {
1655
+ const { spy } = renderTestCase((state) =>
1656
+ selectTooltipPayloadConfigurations(state, "item", "hover", "0"),
1657
+ );
1658
+ const expected: ReadonlyArray<TooltipPayloadConfiguration> = [
1659
+ {
1660
+ getPosition: expect.functionReturning([
1661
+ ["0", { x: 67.5, y: 50.6 }],
1662
+ ["1", { x: 72.5, y: 37.598 }],
1663
+ ["2", { x: 77.5, y: 56.611999999999995 }],
1664
+ ["3", { x: 82.5, y: 6.200000000000001 }],
1665
+ ["4", { x: 87.5, y: 41.552 }],
1666
+ ["5", { x: 92.5, y: 36.2 }],
1667
+ ]),
1668
+ dataDefinedOnItem: [
1669
+ [
1670
+ {
1671
+ dataKey: "uv",
1672
+ name: "uv",
1673
+ payload: {
1674
+ amt: 2400,
1675
+ name: "Page A",
1676
+ pv: 2400,
1677
+ uv: 400,
1678
+ },
1679
+ type: undefined,
1680
+ unit: "",
1681
+ value: 400,
1682
+ graphicalItemId: "my-scatter",
1683
+ },
1684
+ {
1685
+ dataKey: "pv",
1686
+ name: "pv",
1687
+ payload: {
1688
+ amt: 2400,
1689
+ name: "Page A",
1690
+ pv: 2400,
1691
+ uv: 400,
1692
+ },
1693
+ type: undefined,
1694
+ unit: "",
1695
+ value: 2400,
1696
+ graphicalItemId: "my-scatter",
1697
+ },
1698
+ ],
1699
+ [
1700
+ {
1701
+ dataKey: "uv",
1702
+ name: "uv",
1703
+ payload: {
1704
+ amt: 2400,
1705
+ name: "Page B",
1706
+ pv: 4567,
1707
+ uv: 300,
1708
+ },
1709
+ type: undefined,
1710
+ unit: "",
1711
+ value: 300,
1712
+ graphicalItemId: "my-scatter",
1713
+ },
1714
+ {
1715
+ dataKey: "pv",
1716
+ name: "pv",
1717
+ payload: {
1718
+ amt: 2400,
1719
+ name: "Page B",
1720
+ pv: 4567,
1721
+ uv: 300,
1722
+ },
1723
+ type: undefined,
1724
+ unit: "",
1725
+ value: 4567,
1726
+ graphicalItemId: "my-scatter",
1727
+ },
1728
+ ],
1729
+ [
1730
+ {
1731
+ dataKey: "uv",
1732
+ name: "uv",
1733
+ payload: {
1734
+ amt: 2400,
1735
+ name: "Page C",
1736
+ pv: 1398,
1737
+ uv: 300,
1738
+ },
1739
+ type: undefined,
1740
+ unit: "",
1741
+ value: 300,
1742
+ graphicalItemId: "my-scatter",
1743
+ },
1744
+ {
1745
+ dataKey: "pv",
1746
+ name: "pv",
1747
+ payload: {
1748
+ amt: 2400,
1749
+ name: "Page C",
1750
+ pv: 1398,
1751
+ uv: 300,
1752
+ },
1753
+ type: undefined,
1754
+ unit: "",
1755
+ value: 1398,
1756
+ graphicalItemId: "my-scatter",
1757
+ },
1758
+ ],
1759
+ [
1760
+ {
1761
+ dataKey: "uv",
1762
+ name: "uv",
1763
+ payload: {
1764
+ amt: 2400,
1765
+ name: "Page D",
1766
+ pv: 9800,
1767
+ uv: 200,
1768
+ },
1769
+ type: undefined,
1770
+ unit: "",
1771
+ value: 200,
1772
+ graphicalItemId: "my-scatter",
1773
+ },
1774
+ {
1775
+ dataKey: "pv",
1776
+ name: "pv",
1777
+ payload: {
1778
+ amt: 2400,
1779
+ name: "Page D",
1780
+ pv: 9800,
1781
+ uv: 200,
1782
+ },
1783
+ type: undefined,
1784
+ unit: "",
1785
+ value: 9800,
1786
+ graphicalItemId: "my-scatter",
1787
+ },
1788
+ ],
1789
+ [
1790
+ {
1791
+ dataKey: "uv",
1792
+ name: "uv",
1793
+ payload: {
1794
+ amt: 2400,
1795
+ name: "Page E",
1796
+ pv: 3908,
1797
+ uv: 278,
1798
+ },
1799
+ type: undefined,
1800
+ unit: "",
1801
+ value: 278,
1802
+ graphicalItemId: "my-scatter",
1803
+ },
1804
+ {
1805
+ dataKey: "pv",
1806
+ name: "pv",
1807
+ payload: {
1808
+ amt: 2400,
1809
+ name: "Page E",
1810
+ pv: 3908,
1811
+ uv: 278,
1812
+ },
1813
+ type: undefined,
1814
+ unit: "",
1815
+ value: 3908,
1816
+ graphicalItemId: "my-scatter",
1817
+ },
1818
+ ],
1819
+ [
1820
+ {
1821
+ dataKey: "uv",
1822
+ name: "uv",
1823
+ payload: {
1824
+ amt: 2400,
1825
+ name: "Page F",
1826
+ pv: 4800,
1827
+ uv: 189,
1828
+ },
1829
+ type: undefined,
1830
+ unit: "",
1831
+ value: 189,
1832
+ graphicalItemId: "my-scatter",
1833
+ },
1834
+ {
1835
+ dataKey: "pv",
1836
+ name: "pv",
1837
+ payload: {
1838
+ amt: 2400,
1839
+ name: "Page F",
1840
+ pv: 4800,
1841
+ uv: 189,
1842
+ },
1843
+ type: undefined,
1844
+ unit: "",
1845
+ value: 4800,
1846
+ graphicalItemId: "my-scatter",
1847
+ },
1848
+ ],
1849
+ ],
1850
+ settings: {
1851
+ color: undefined,
1852
+ dataKey: undefined,
1853
+ fill: undefined,
1854
+ graphicalItemId: "my-scatter",
1855
+ hide: false,
1856
+ name: undefined,
1857
+ nameKey: undefined,
1858
+ stroke: undefined,
1859
+ strokeWidth: undefined,
1860
+ type: undefined,
1861
+ unit: "",
1862
+ },
1863
+ },
1864
+ ];
1865
+ expectLastCalledWith(spy, expected);
1866
+ });
1867
+ });
1868
+
1869
+ describe("ScatterChart with allowDuplicateCategory=false", () => {
1870
+ const data = [
1871
+ { x: 100, y: 100, z: 200 },
1872
+ { x: 100, y: 200, z: 200 },
1873
+ { x: 100, y: 300, z: 200 },
1874
+ ];
1875
+
1876
+ const renderTestCase = createSelectorTestCase((props) => (
1877
+ <ScatterChart width={500} height={500}>
1878
+ <CartesianGrid />
1879
+ <XAxis type="category" allowDuplicatedCategory={false} dataKey="x" name="stature" unit="cm" />
1880
+ <YAxis type="category" allowDuplicatedCategory={false} dataKey="y" name="weight" unit="kg" />
1881
+ <Scatter
1882
+ activeShape={{ fill: "red" }}
1883
+ name="A school"
1884
+ data={data}
1885
+ isAnimationActive={false}
1886
+ id="my-scatter"
1887
+ />
1888
+ <Tooltip shared={false} cursor={{ strokeDasharray: "3 3" }} />
1889
+ <Legend />
1890
+ {props.children}
1891
+ </ScatterChart>
1892
+ ));
1893
+
1894
+ it("should render three scatter points", () => {
1895
+ const { container } = renderTestCase();
1896
+ expectScatterPoints(container, [
1897
+ {
1898
+ cx: "280",
1899
+ cy: "388.33333333333337",
1900
+ d: "M4.514,0A4.514,4.514,0,1,1,-4.514,0A4.514,4.514,0,1,1,4.514,0",
1901
+ height: "9.0270333367641",
1902
+ transform: "translate(280, 388.33333333333337)",
1903
+ width: "9.0270333367641",
1904
+ },
1905
+ {
1906
+ cx: "280",
1907
+ cy: "235",
1908
+ d: "M4.514,0A4.514,4.514,0,1,1,-4.514,0A4.514,4.514,0,1,1,4.514,0",
1909
+ height: "9.0270333367641",
1910
+ transform: "translate(280, 235)",
1911
+ width: "9.0270333367641",
1912
+ },
1913
+ {
1914
+ cx: "280",
1915
+ cy: "81.66666666666667",
1916
+ d: "M4.514,0A4.514,4.514,0,1,1,-4.514,0A4.514,4.514,0,1,1,4.514,0",
1917
+ height: "9.0270333367641",
1918
+ transform: "translate(280, 81.66666666666667)",
1919
+ width: "9.0270333367641",
1920
+ },
1921
+ ]);
1922
+ });
1923
+
1924
+ it("should select tooltip active", () => {
1925
+ const { container, spy } = renderTestCase((state) =>
1926
+ selectIsTooltipActive(state, "item", "hover", undefined),
1927
+ );
1928
+ expectLastCalledWith(spy, { activeIndex: null, isActive: false });
1929
+
1930
+ showTooltip(container, scatterChartMouseHoverTooltipSelector);
1931
+ expectLastCalledWith(spy, { activeIndex: "0", isActive: true });
1932
+ });
1933
+
1934
+ it("should select tooltipPayloadConfigurations", () => {
1935
+ const { spy } = renderTestCase((state) =>
1936
+ selectTooltipPayloadConfigurations(state, "axis", "hover", undefined),
1937
+ );
1938
+ expectLastCalledWith(spy, [
1939
+ {
1940
+ dataDefinedOnItem: [
1941
+ [
1942
+ {
1943
+ dataKey: "x",
1944
+ name: "stature",
1945
+ payload: {
1946
+ x: 100,
1947
+ y: 100,
1948
+ z: 200,
1949
+ },
1950
+ type: undefined,
1951
+ unit: "cm",
1952
+ value: 100,
1953
+ graphicalItemId: "my-scatter",
1954
+ },
1955
+ {
1956
+ dataKey: "y",
1957
+ name: "weight",
1958
+ payload: {
1959
+ x: 100,
1960
+ y: 100,
1961
+ z: 200,
1962
+ },
1963
+ type: undefined,
1964
+ unit: "kg",
1965
+ value: 100,
1966
+ graphicalItemId: "my-scatter",
1967
+ },
1968
+ ],
1969
+ [
1970
+ {
1971
+ dataKey: "x",
1972
+ name: "stature",
1973
+ payload: {
1974
+ x: 100,
1975
+ y: 200,
1976
+ z: 200,
1977
+ },
1978
+ type: undefined,
1979
+ unit: "cm",
1980
+ value: 100,
1981
+ graphicalItemId: "my-scatter",
1982
+ },
1983
+ {
1984
+ dataKey: "y",
1985
+ name: "weight",
1986
+ payload: {
1987
+ x: 100,
1988
+ y: 200,
1989
+ z: 200,
1990
+ },
1991
+ type: undefined,
1992
+ unit: "kg",
1993
+ value: 200,
1994
+ graphicalItemId: "my-scatter",
1995
+ },
1996
+ ],
1997
+ [
1998
+ {
1999
+ dataKey: "x",
2000
+ name: "stature",
2001
+ payload: {
2002
+ x: 100,
2003
+ y: 300,
2004
+ z: 200,
2005
+ },
2006
+ type: undefined,
2007
+ unit: "cm",
2008
+ value: 100,
2009
+ graphicalItemId: "my-scatter",
2010
+ },
2011
+ {
2012
+ dataKey: "y",
2013
+ name: "weight",
2014
+ payload: {
2015
+ x: 100,
2016
+ y: 300,
2017
+ z: 200,
2018
+ },
2019
+ type: undefined,
2020
+ unit: "kg",
2021
+ value: 300,
2022
+ graphicalItemId: "my-scatter",
2023
+ },
2024
+ ],
2025
+ ],
2026
+ getPosition: expect.functionReturning([
2027
+ ["0", { x: 280, y: 388.33333333333337 }],
2028
+ ["1", { x: 280, y: 235 }],
2029
+ ["2", { x: 280, y: 81.66666666666667 }],
2030
+ ]),
2031
+ settings: {
2032
+ color: undefined,
2033
+ dataKey: undefined,
2034
+ fill: undefined,
2035
+ graphicalItemId: "my-scatter",
2036
+ hide: false,
2037
+ name: "A school",
2038
+ nameKey: undefined,
2039
+ stroke: undefined,
2040
+ strokeWidth: undefined,
2041
+ type: undefined,
2042
+ unit: "",
2043
+ },
2044
+ },
2045
+ ]);
2046
+ });
2047
+
2048
+ it("should select chartDataWithIndexes", () => {
2049
+ const { spy } = renderTestCase(selectChartDataWithIndexes);
2050
+ expectLastCalledWith(spy, {
2051
+ chartData: undefined,
2052
+ computedData: undefined,
2053
+ dataEndIndex: 0,
2054
+ dataStartIndex: 0,
2055
+ });
2056
+ });
2057
+
2058
+ it("should select tooltip payload", () => {
2059
+ const { container, spy } = renderTestCase((state) =>
2060
+ selectTooltipPayload(state, "item", "hover", undefined),
2061
+ );
2062
+ expect(spy).toHaveBeenCalledTimes(1);
2063
+ expectLastCalledWith(spy, undefined);
2064
+
2065
+ showTooltip(container, scatterChartMouseHoverTooltipSelector);
2066
+ expect(spy).toHaveBeenCalledTimes(2);
2067
+ expectLastCalledWith(spy, [
2068
+ {
2069
+ color: undefined,
2070
+ dataKey: "x",
2071
+ fill: undefined,
2072
+ graphicalItemId: "my-scatter",
2073
+ hide: false,
2074
+ name: "stature",
2075
+ nameKey: undefined,
2076
+ payload: {
2077
+ x: 100,
2078
+ y: 100,
2079
+ z: 200,
2080
+ },
2081
+ stroke: undefined,
2082
+ strokeWidth: undefined,
2083
+ type: undefined,
2084
+ unit: "cm",
2085
+ value: 100,
2086
+ },
2087
+ {
2088
+ color: undefined,
2089
+ dataKey: "y",
2090
+ fill: undefined,
2091
+ graphicalItemId: "my-scatter",
2092
+ hide: false,
2093
+ name: "weight",
2094
+ nameKey: undefined,
2095
+ payload: {
2096
+ x: 100,
2097
+ y: 100,
2098
+ z: 200,
2099
+ },
2100
+ stroke: undefined,
2101
+ strokeWidth: undefined,
2102
+ type: undefined,
2103
+ unit: "kg",
2104
+ value: 100,
2105
+ },
2106
+ ]);
2107
+ });
2108
+
2109
+ it("should show tooltip when hovering over a point", () => {
2110
+ const { container } = renderTestCase();
2111
+ showTooltip(container, scatterChartMouseHoverTooltipSelector);
2112
+ expectTooltipPayload(container, "", ["stature : 100cm", "weight : 100kg"]);
2113
+ });
2114
+
2115
+ it("should show different tooltip when hovering over the second point", () => {
2116
+ const { container } = renderTestCase();
2117
+ showTooltip(container, `${scatterChartMouseHoverTooltipSelector}:nth-child(2)`);
2118
+ expectTooltipPayload(container, "", ["stature : 100cm", "weight : 200kg"]);
2119
+ });
2120
+
2121
+ it("should render an empty chart with tick labels when ticks are provided and allowDataOverflow is set to true", () => {
2122
+ const { container } = render(() => (
2123
+ <ScatterChart width={400} height={400} margin={{ top: 10, right: 20, bottom: 30, left: 40 }}>
2124
+ <XAxis
2125
+ dataKey="x"
2126
+ name="stature"
2127
+ unit="cm"
2128
+ type="number"
2129
+ allowDataOverflow
2130
+ ticks={[150, 250, 350, 450]}
2131
+ />
2132
+ <YAxis
2133
+ dataKey="y"
2134
+ name="weight"
2135
+ unit="kg"
2136
+ type="number"
2137
+ allowDataOverflow
2138
+ ticks={[100, 200, 300, 400]}
2139
+ />
2140
+ <CartesianGrid />
2141
+ <Scatter name="A school" data={[]} fillOpacity={0.3} fill="#ff7300" />
2142
+ <Tooltip />
2143
+ <Legend layout="vertical" />
2144
+ </ScatterChart>
2145
+ ));
2146
+ expectScatterPoints(container, []);
2147
+
2148
+ expectXAxisTicks(container, [
2149
+ {
2150
+ textContent: "150cm",
2151
+ x: "100",
2152
+ y: "348",
2153
+ },
2154
+ {
2155
+ textContent: "250cm",
2156
+ x: "193.33333333333331",
2157
+ y: "348",
2158
+ },
2159
+ {
2160
+ textContent: "350cm",
2161
+ x: "286.66666666666663",
2162
+ y: "348",
2163
+ },
2164
+ {
2165
+ textContent: "450cm",
2166
+ x: "380",
2167
+ y: "348",
2168
+ },
2169
+ ]);
2170
+
2171
+ expectYAxisTicks(container, [
2172
+ {
2173
+ textContent: "100kg",
2174
+ x: "92",
2175
+ y: "340",
2176
+ },
2177
+ {
2178
+ textContent: "200kg",
2179
+ x: "92",
2180
+ y: "230.00000000000003",
2181
+ },
2182
+ {
2183
+ textContent: "300kg",
2184
+ x: "92",
2185
+ y: "120.00000000000001",
2186
+ },
2187
+ {
2188
+ textContent: "400kg",
2189
+ x: "92",
2190
+ y: "10",
2191
+ },
2192
+ ]);
2193
+ });
2194
+ });
2195
+
2196
+ describe("ScatterChart with data with type property", () => {
2197
+ // https://github.com/recharts/recharts/issues/6197
2198
+ const data = [
2199
+ { type: 1, x: 100, y: 200, z: 200 },
2200
+ { x: 120, y: 100, z: 260 },
2201
+ { x: 170, y: 300, z: 400 },
2202
+ { x: 140, y: 250, z: 280 },
2203
+ { x: 150, y: 400, z: 500 },
2204
+ { x: 110, y: 280, z: 200 },
2205
+ ];
2206
+
2207
+ const renderTestCase = createSelectorTestCase((props) => (
2208
+ <ScatterChart width={500} height={500}>
2209
+ <CartesianGrid />
2210
+ <XAxis type="number" dataKey="x" name="stature" unit="cm" />
2211
+ <YAxis type="number" dataKey="y" name="weight" unit="kg" />
2212
+ <Tooltip cursor={{ strokeDasharray: "3 3" }} />
2213
+ <Scatter name="A school" data={data} fill="#8884d8" />
2214
+ {props.children}
2215
+ </ScatterChart>
2216
+ ));
2217
+
2218
+ it("should render without throwing error", () => {
2219
+ const { container } = renderTestCase();
2220
+ expect(container).toBeInTheDocument();
2221
+ });
2222
+ });
2223
+
2224
+ describe("Composed chart when there are stacks but the stacks are smaller than the ZAxis dataKey", () => {
2225
+ const renderTestCase = createSelectorTestCase((props) => (
2226
+ <ComposedChart width={400} height={200} data={boxPlotData}>
2227
+ <Bar stackId="a" dataKey="min" />
2228
+ <ZAxis type="number" dataKey="size" range={[0, 250]} />
2229
+ <Scatter dataKey="average" />
2230
+ <XAxis />
2231
+ <YAxis />
2232
+ {props.children}
2233
+ </ComposedChart>
2234
+ ));
2235
+
2236
+ it("should select YAxis numerical domain", () => {
2237
+ const { spy } = renderTestCase((state) => selectNumericalDomain(state, "yAxis", 0, false));
2238
+ expectLastCalledWith(spy, [0, 550]);
2239
+ });
2240
+
2241
+ it("should select YAxis final domain", () => {
2242
+ const { spy } = renderTestCase((state) => selectAxisDomain(state, "yAxis", 0, false));
2243
+ expectLastCalledWith(spy, [0, 550]);
2244
+ });
2245
+
2246
+ it("should select YAxis ticks", () => {
2247
+ const { spy } = renderTestCase((state) => selectTicksOfGraphicalItem(state, "yAxis", 0, false));
2248
+ expectLastCalledWith(spy, [
2249
+ { index: 0, coordinate: 165, value: 0, offset: 0 },
2250
+ { index: 1, coordinate: 138.33333333333334, value: 100, offset: 0 },
2251
+ { index: 2, coordinate: 111.66666666666669, value: 200, offset: 0 },
2252
+ { index: 3, coordinate: 85, value: 300, offset: 0 },
2253
+ { index: 4, coordinate: 58.33333333333334, value: 400, offset: 0 },
2254
+ { index: 5, coordinate: 31.66666666666666, value: 500, offset: 0 },
2255
+ { index: 6, coordinate: 5, value: 600, offset: 0 },
2256
+ ]);
2257
+ });
2258
+
2259
+ it("should select ZAxis displayed data", () => {
2260
+ const { spy } = renderTestCase((state) => selectDisplayedData(state, "zAxis", 0, false));
2261
+ expectLastCalledWith(spy, [
2262
+ {
2263
+ average: 150,
2264
+ bottomBox: 50,
2265
+ bottomWhisker: 100,
2266
+ min: 100,
2267
+ size: 150,
2268
+ topBox: 200,
2269
+ topWhisker: 200,
2270
+ },
2271
+ {
2272
+ average: 550,
2273
+ bottomBox: 200,
2274
+ bottomWhisker: 200,
2275
+ min: 200,
2276
+ size: 250,
2277
+ topBox: 100,
2278
+ topWhisker: 100,
2279
+ },
2280
+ {
2281
+ average: 400,
2282
+ bottomBox: 200,
2283
+ bottomWhisker: 200,
2284
+ min: 0,
2285
+ size: 350,
2286
+ topBox: 200,
2287
+ topWhisker: 200,
2288
+ },
2289
+ ]);
2290
+ });
2291
+
2292
+ it("should select ZAxis stack groups domain", () => {
2293
+ const { spy } = renderTestCase((state) => selectDomainOfStackGroups(state, "zAxis", 0, false));
2294
+ expectLastCalledWith(spy, undefined);
2295
+ });
2296
+
2297
+ it("should select ZAxis numerical domain", () => {
2298
+ const { spy } = renderTestCase((state) => selectNumericalDomain(state, "zAxis", 0, false));
2299
+ expectLastCalledWith(spy, [0, 350]);
2300
+ });
2301
+
2302
+ it("should select ZAxis final domain", () => {
2303
+ const { spy } = renderTestCase((state) => selectAxisDomain(state, "zAxis", 0, false));
2304
+ expectLastCalledWith(spy, [0, 350]);
2305
+ });
2306
+
2307
+ it("should select ZAxis axis settings", () => {
2308
+ const { spy } = renderTestCase((state) => selectZAxisWithScale(state, "zAxis", 0, false));
2309
+ const settings = spy.mock.lastCall?.[0];
2310
+ assertNotNull(settings);
2311
+ expect(settings).toMatchObject({
2312
+ domain: undefined,
2313
+ allowDataOverflow: false,
2314
+ allowDuplicatedCategory: false,
2315
+ dataKey: "size",
2316
+ id: 0,
2317
+ includeHidden: false,
2318
+ name: undefined,
2319
+ range: [0, 250],
2320
+ reversed: false,
2321
+ type: "number",
2322
+ unit: undefined,
2323
+ });
2324
+ expectScale(settings.scale, { domain: [0, 350], range: [0, 250] });
2325
+ });
2326
+
2327
+ it("should render scatter points", () => {
2328
+ const { container } = renderTestCase();
2329
+ expectScatterPoints(container, [
2330
+ {
2331
+ cx: "120",
2332
+ cy: "125",
2333
+ d: "M0,0",
2334
+ height: "11.67983401638037",
2335
+ transform: "translate(120, 125)",
2336
+ width: "11.67983401638037",
2337
+ },
2338
+ {
2339
+ cx: "230",
2340
+ cy: "18.33333333333334",
2341
+ d: "M0,0",
2342
+ height: "15.078600877302687",
2343
+ transform: "translate(230, 18.33333333333334)",
2344
+ width: "15.078600877302687",
2345
+ },
2346
+ {
2347
+ cx: "340",
2348
+ cy: "58.33333333333334",
2349
+ d: "M0,0",
2350
+ height: "17.841241161527712",
2351
+ transform: "translate(340, 58.33333333333334)",
2352
+ width: "17.841241161527712",
2353
+ },
2354
+ ]);
2355
+ });
2356
+ });
2357
+
2358
+ describe("Composed chart when stacks are bigger than ZAxis dataKey", () => {
2359
+ const renderTestCase = createSelectorTestCase((props) => (
2360
+ <ComposedChart width={400} height={200} data={boxPlotData}>
2361
+ <Bar stackId="a" dataKey="min" />
2362
+ <Bar stackId="a" dataKey="bar" />
2363
+ <Bar stackId="a" dataKey="bottomWhisker" />
2364
+ <Bar stackId="a" dataKey="bottomBox" />
2365
+ <Bar stackId="a" dataKey="bar" />
2366
+ <Bar stackId="a" dataKey="topBox" />
2367
+ <Bar stackId="a" dataKey="topWhisker" />
2368
+ <Bar stackId="a" dataKey="bar" />
2369
+ <ZAxis type="number" dataKey="size" range={[0, 250]} />
2370
+
2371
+ <Scatter dataKey="average" />
2372
+ <XAxis />
2373
+ <YAxis />
2374
+
2375
+ {props.children}
2376
+ </ComposedChart>
2377
+ ));
2378
+
2379
+ it("should select YAxis numeric domain", () => {
2380
+ const { spy } = renderTestCase((state) => selectNumericalDomain(state, "yAxis", 0, false));
2381
+ expectLastCalledWith(spy, [0, 800]);
2382
+ });
2383
+
2384
+ it("should select YAxis final domain", () => {
2385
+ const { spy } = renderTestCase((state) => selectAxisDomain(state, "yAxis", 0, false));
2386
+ expectLastCalledWith(spy, [0, 800]);
2387
+ });
2388
+
2389
+ it("should select YAxis ticks", () => {
2390
+ const { spy } = renderTestCase((state) => selectTicksOfGraphicalItem(state, "yAxis", 0, false));
2391
+
2392
+ expectLastCalledWith(spy, [
2393
+ { index: 0, coordinate: 165, offset: 0, value: 0 },
2394
+ { index: 1, coordinate: 125, offset: 0, value: 200 },
2395
+ { index: 2, coordinate: 85, offset: 0, value: 400 },
2396
+ { index: 3, coordinate: 45, offset: 0, value: 600 },
2397
+ { index: 4, coordinate: 5, offset: 0, value: 800 },
2398
+ ]);
2399
+ });
2400
+
2401
+ it("should select ZAxis displayed data", () => {
2402
+ const { spy } = renderTestCase((state) => selectDisplayedData(state, "zAxis", 0, false));
2403
+ expectLastCalledWith(spy, [
2404
+ {
2405
+ average: 150,
2406
+ bottomBox: 50,
2407
+ bottomWhisker: 100,
2408
+ min: 100,
2409
+ size: 150,
2410
+ topBox: 200,
2411
+ topWhisker: 200,
2412
+ },
2413
+ {
2414
+ average: 550,
2415
+ bottomBox: 200,
2416
+ bottomWhisker: 200,
2417
+ min: 200,
2418
+ size: 250,
2419
+ topBox: 100,
2420
+ topWhisker: 100,
2421
+ },
2422
+ {
2423
+ average: 400,
2424
+ bottomBox: 200,
2425
+ bottomWhisker: 200,
2426
+ min: 0,
2427
+ size: 350,
2428
+ topBox: 200,
2429
+ topWhisker: 200,
2430
+ },
2431
+ ]);
2432
+ });
2433
+
2434
+ it("should select ZAxis stack groups domain", () => {
2435
+ const { spy } = renderTestCase((state) => selectDomainOfStackGroups(state, "zAxis", 0, false));
2436
+ expectLastCalledWith(spy, undefined);
2437
+ });
2438
+
2439
+ it("should select ZAxis numerical domain", () => {
2440
+ const { spy } = renderTestCase((state) => selectNumericalDomain(state, "zAxis", 0, false));
2441
+ expectLastCalledWith(spy, [0, 350]);
2442
+ });
2443
+
2444
+ it("should select ZAxis final domain", () => {
2445
+ const { spy } = renderTestCase((state) => selectAxisDomain(state, "zAxis", 0, false));
2446
+ expectLastCalledWith(spy, [0, 350]);
2447
+ });
2448
+
2449
+ it("should select ZAxis axis settings", () => {
2450
+ const { spy } = renderTestCase((state) => selectBaseAxis(state, "zAxis", 0));
2451
+ expectLastCalledWith(spy, {
2452
+ allowDataOverflow: false,
2453
+ allowDuplicatedCategory: false,
2454
+ dataKey: "size",
2455
+ id: 0,
2456
+ includeHidden: false,
2457
+ name: undefined,
2458
+ range: [0, 250],
2459
+ reversed: false,
2460
+ scale: "auto",
2461
+ type: "number",
2462
+ unit: undefined,
2463
+ domain: undefined,
2464
+ });
2465
+ });
2466
+
2467
+ it("should render Scatter points", () => {
2468
+ const { container } = renderTestCase();
2469
+ expectScatterPoints(container, [
2470
+ {
2471
+ cx: "120",
2472
+ cy: "135",
2473
+ d: "M0,0",
2474
+ height: "11.67983401638037",
2475
+ transform: "translate(120, 135)",
2476
+ width: "11.67983401638037",
2477
+ },
2478
+ {
2479
+ cx: "230",
2480
+ cy: "55",
2481
+ d: "M0,0",
2482
+ height: "15.078600877302687",
2483
+ transform: "translate(230, 55)",
2484
+ width: "15.078600877302687",
2485
+ },
2486
+ {
2487
+ cx: "340",
2488
+ cy: "85",
2489
+ d: "M0,0",
2490
+ height: "17.841241161527712",
2491
+ transform: "translate(340, 85)",
2492
+ width: "17.841241161527712",
2493
+ },
2494
+ ]);
2495
+ });
2496
+ });
2497
+
2498
+ describe("ScatterChart customized active shape", () => {
2499
+ const data = [
2500
+ { x: 100, y: 200, z: 200 },
2501
+ { x: 120, y: 100, z: 260 },
2502
+ { x: 170, y: 300, z: 400 },
2503
+ { x: 140, y: 250, z: 280 },
2504
+ { x: 150, y: 400, z: 500 },
2505
+ { x: 110, y: 280, z: 200 },
2506
+ ];
2507
+
2508
+ // recharts fires mouseOver on a point + mouseOut to dismiss; the port's per-item
2509
+ // Layers listen for the non-bubbling mouseEnter/mouseLeave, so adapt the events
2510
+ // (and flush() — Solid defers reactive propagation).
2511
+ function assertActiveShapeInteractions(container: HTMLElement): void {
2512
+ const sectorNodes = container.querySelectorAll(".recharts-scatter-symbol");
2513
+ expect(sectorNodes.length).toBeGreaterThanOrEqual(2);
2514
+ const sector1 = sectorNodes[0]!;
2515
+ fireEvent.mouseEnter(sector1, { clientX: 200, clientY: 200 });
2516
+ flush();
2517
+ expect(container.querySelectorAll(".recharts-active-shape")).toHaveLength(1);
2518
+
2519
+ const sector2 = container.querySelectorAll(".recharts-scatter-symbol")[1]!;
2520
+ fireEvent.mouseEnter(sector2, { clientX: 200, clientY: 200 });
2521
+ flush();
2522
+ expect(container.querySelectorAll(".recharts-active-shape")).toHaveLength(1);
2523
+
2524
+ fireEvent.mouseLeave(container.querySelectorAll(".recharts-scatter-symbol")[1]!);
2525
+ flush();
2526
+ expect(container.querySelectorAll(".recharts-active-shape")).toHaveLength(0);
2527
+ }
2528
+
2529
+ test("Renders customized active shape when activeShape set to be an object", () => {
2530
+ const { container } = render(() => (
2531
+ <ScatterChart width={400} height={400} margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
2532
+ <XAxis dataKey="x" name="stature" unit="cm" />
2533
+ <YAxis dataKey="y" name="weight" unit="kg" />
2534
+ <Scatter line name="A school" data={data} fill="#ff7300" activeShape={{ fill: "red" }} />
2535
+ <Tooltip />
2536
+ </ScatterChart>
2537
+ ));
2538
+
2539
+ assertActiveShapeInteractions(container);
2540
+ });
2541
+
2542
+ test("Renders customized active shape when activeShape set to be an object as symbols props", () => {
2543
+ const { container } = render(() => (
2544
+ <ScatterChart width={400} height={400} margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
2545
+ <XAxis dataKey="x" name="stature" unit="cm" />
2546
+ <YAxis dataKey="y" name="weight" unit="kg" />
2547
+ <Scatter
2548
+ line
2549
+ name="A school"
2550
+ data={data}
2551
+ fill="#ff7300"
2552
+ activeShape={{ type: "triangle", class: "triangle-symbols-type", fill: "red" }}
2553
+ />
2554
+ <Tooltip />
2555
+ </ScatterChart>
2556
+ ));
2557
+
2558
+ assertActiveShapeInteractions(container);
2559
+ });
2560
+
2561
+ test("Renders customized active shape when activeShape set to be a function", () => {
2562
+ const { container } = render(() => (
2563
+ <ScatterChart width={400} height={400} margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
2564
+ <XAxis dataKey="x" name="stature" unit="cm" />
2565
+ <YAxis dataKey="y" name="weight" unit="kg" />
2566
+ <Scatter
2567
+ line
2568
+ name="A school"
2569
+ data={data}
2570
+ fill="#ff7300"
2571
+ activeShape={(props: SymbolsProps) => <Symbols {...props} type="circle" fill="red" />}
2572
+ />
2573
+ <Tooltip />
2574
+ </ScatterChart>
2575
+ ));
2576
+
2577
+ assertActiveShapeInteractions(container);
2578
+ });
2579
+
2580
+ // DEFERRED: element-form activeShape={<Symbols/>} — Solid has no cloneElement and
2581
+ // elements aren't introspectable, so ActiveShape excludes the element constituent.
2582
+ test.skip("Renders customized active shape when activeShape set to be a ReactElement", () => {});
2583
+
2584
+ test("Renders customized active shape when activeShape is set to be a truthy boolean", () => {
2585
+ const { container } = render(() => (
2586
+ <ScatterChart width={400} height={400} margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
2587
+ <XAxis dataKey="x" name="stature" unit="cm" />
2588
+ <YAxis dataKey="y" name="weight" unit="kg" />
2589
+ <Scatter line name="A school" data={data} fill="#ff7300" activeShape />
2590
+ <Tooltip />
2591
+ </ScatterChart>
2592
+ ));
2593
+
2594
+ assertActiveShapeInteractions(container);
2595
+ });
2596
+
2597
+ test("Does not render customized active shape when activeShape set to be a falsy boolean", () => {
2598
+ const { container } = render(() => (
2599
+ <ScatterChart width={400} height={400} margin={{ top: 20, right: 20, bottom: 20, left: 20 }}>
2600
+ <XAxis dataKey="x" name="stature" unit="cm" />
2601
+ <YAxis dataKey="y" name="weight" unit="kg" />
2602
+ <Scatter line name="A school" data={data} fill="#ff7300" activeShape={false} />
2603
+ <Tooltip />
2604
+ </ScatterChart>
2605
+ ));
2606
+
2607
+ const sector = container.querySelectorAll(".recharts-scatter-symbol")[0]!;
2608
+ fireEvent.mouseEnter(sector, { clientX: 200, clientY: 200 });
2609
+ flush();
2610
+
2611
+ expect(container.querySelectorAll(".recharts-active-shape")).toHaveLength(0);
2612
+ });
2613
+ });