solid-recharts 0.2.0 → 1.0.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 (508) hide show
  1. package/package.json +17 -13
  2. package/src/animation/AnimatedItems.tsx +2 -4
  3. package/src/animation/CSSTransitionAnimate.tsx +41 -39
  4. package/src/animation/JavascriptAnimate.tsx +45 -41
  5. package/src/cartesian/Area.tsx +43 -58
  6. package/src/cartesian/AreaRevealShape.tsx +1 -1
  7. package/src/cartesian/Bar.tsx +98 -78
  8. package/src/cartesian/BarStack.tsx +10 -7
  9. package/src/cartesian/Brush.tsx +20 -16
  10. package/src/cartesian/CartesianAxis.tsx +4 -4
  11. package/src/cartesian/CartesianGrid.tsx +5 -5
  12. package/src/cartesian/ErrorBar.tsx +9 -7
  13. package/src/cartesian/Funnel.tsx +17 -21
  14. package/src/cartesian/GraphicalItemClipPath.tsx +1 -1
  15. package/src/cartesian/Line.tsx +51 -66
  16. package/src/cartesian/LineDrawShape.tsx +20 -17
  17. package/src/cartesian/ReferenceArea.tsx +28 -38
  18. package/src/cartesian/ReferenceDot.tsx +27 -37
  19. package/src/cartesian/ReferenceLine.tsx +28 -37
  20. package/src/cartesian/RenderedTicksReporter.tsx +19 -17
  21. package/src/cartesian/Scatter.tsx +27 -39
  22. package/src/cartesian/XAxis.tsx +55 -68
  23. package/src/cartesian/YAxis.tsx +88 -99
  24. package/src/cartesian/ZAxis.tsx +29 -41
  25. package/src/chart/AreaChart.tsx +1 -1
  26. package/src/chart/BarChart.tsx +1 -1
  27. package/src/chart/CartesianChart.tsx +4 -3
  28. package/src/chart/CategoricalChart.tsx +5 -5
  29. package/src/chart/ComposedChart.tsx +1 -1
  30. package/src/chart/FunnelChart.tsx +1 -1
  31. package/src/chart/LineChart.tsx +1 -1
  32. package/src/chart/PieChart.tsx +4 -3
  33. package/src/chart/PolarChart.tsx +4 -3
  34. package/src/chart/RadarChart.tsx +4 -3
  35. package/src/chart/RadialBarChart.tsx +7 -3
  36. package/src/chart/RechartsWrapper.tsx +14 -24
  37. package/src/chart/Sankey.tsx +9 -6
  38. package/src/chart/ScatterChart.tsx +1 -1
  39. package/src/chart/SunburstChart.tsx +6 -5
  40. package/src/chart/Treemap.tsx +5 -4
  41. package/src/component/ActivePoints.tsx +6 -15
  42. package/src/component/Cell.tsx +23 -5
  43. package/src/component/Cursor.tsx +3 -3
  44. package/src/component/DefaultLegendContent.tsx +8 -6
  45. package/src/component/DefaultTooltipContent.tsx +14 -10
  46. package/src/component/Dots.tsx +11 -7
  47. package/src/component/Label.tsx +13 -10
  48. package/src/component/LabelList.tsx +12 -7
  49. package/src/component/Legend.tsx +26 -21
  50. package/src/component/ResponsiveContainer.tsx +52 -49
  51. package/src/component/Text.tsx +5 -5
  52. package/src/component/Tooltip.tsx +21 -18
  53. package/src/component/TooltipBoundingBox.tsx +18 -16
  54. package/src/component/responsiveContainerUtils.ts +1 -1
  55. package/src/container/ClipPathProvider.tsx +3 -3
  56. package/src/container/Layer.tsx +5 -5
  57. package/src/container/RootSurface.tsx +1 -1
  58. package/src/container/Surface.tsx +5 -6
  59. package/src/context/ErrorBarContext.tsx +17 -26
  60. package/src/context/PanoramaContext.tsx +2 -2
  61. package/src/context/RegisterGraphicalItemId.tsx +4 -2
  62. package/src/context/chartDataContext.tsx +26 -23
  63. package/src/context/chartLayoutContext.tsx +16 -12
  64. package/src/polar/Pie.tsx +49 -60
  65. package/src/polar/PolarAngleAxis.tsx +43 -52
  66. package/src/polar/PolarGrid.tsx +5 -5
  67. package/src/polar/PolarRadiusAxis.tsx +42 -50
  68. package/src/polar/Radar.tsx +24 -36
  69. package/src/polar/RadialBar.tsx +23 -41
  70. package/src/shape/Cross.tsx +5 -5
  71. package/src/shape/Curve.tsx +7 -8
  72. package/src/shape/Dot.tsx +4 -4
  73. package/src/shape/Polygon.tsx +5 -5
  74. package/src/shape/Rectangle.tsx +22 -20
  75. package/src/shape/Sector.tsx +5 -5
  76. package/src/shape/Symbols.tsx +6 -6
  77. package/src/shape/Trapezoid.tsx +29 -27
  78. package/src/state/RechartsStoreProvider.tsx +5 -3
  79. package/src/state/ReportChartProps.tsx +8 -6
  80. package/src/state/ReportEventSettings.tsx +8 -6
  81. package/src/state/ReportMainChartProps.tsx +11 -9
  82. package/src/state/ReportPolarOptions.tsx +15 -13
  83. package/src/state/SetLegendPayload.ts +20 -28
  84. package/src/state/SetTooltipEntrySettings.tsx +10 -27
  85. package/src/state/brushSlice.ts +10 -8
  86. package/src/state/cartesianAxisSlice.ts +72 -84
  87. package/src/state/chartDataSlice.ts +29 -23
  88. package/src/state/createCollectionActions.ts +51 -0
  89. package/src/state/createSelector.ts +97 -0
  90. package/src/state/errorBarSlice.ts +22 -16
  91. package/src/state/eventSettingsSlice.ts +11 -9
  92. package/src/state/externalEventsMiddleware.ts +2 -11
  93. package/src/state/graphicalItemsSlice.ts +35 -44
  94. package/src/state/isEventThrottled.ts +12 -0
  95. package/src/state/keyboardEventsMiddleware.ts +2 -8
  96. package/src/state/layoutSlice.ts +29 -17
  97. package/src/state/legendSlice.ts +35 -31
  98. package/src/state/mouseEventsMiddleware.ts +2 -13
  99. package/src/state/optionsSlice.ts +8 -6
  100. package/src/state/patched.ts +19 -0
  101. package/src/state/polarAxisSlice.ts +21 -13
  102. package/src/state/polarOptionsSlice.ts +16 -14
  103. package/src/state/referenceElementsSlice.ts +49 -34
  104. package/src/state/registerInStore.ts +70 -0
  105. package/src/state/renderedTicksSlice.ts +11 -7
  106. package/src/state/rootPropsSlice.ts +16 -14
  107. package/src/state/selectors/areaSelectors.ts +13 -36
  108. package/src/state/selectors/arrayEqualityCheck.ts +32 -7
  109. package/src/state/selectors/axisSelectors.ts +215 -169
  110. package/src/state/selectors/barSelectors.ts +8 -36
  111. package/src/state/selectors/combiners/combineConfiguredScale.ts +1 -1
  112. package/src/state/selectors/combiners/combineRealScaleType.ts +1 -1
  113. package/src/state/selectors/dataSelectors.ts +35 -16
  114. package/src/state/selectors/numberDomainEqualityCheck.ts +16 -8
  115. package/src/state/selectors/selectAxisForGraphicalItem.ts +52 -0
  116. package/src/state/tooltipSlice.ts +135 -86
  117. package/src/state/unregisterOnCleanup.ts +5 -20
  118. package/src/state/zIndexSlice.ts +50 -42
  119. package/src/synchronisation/useChartSynchronisation.tsx +213 -217
  120. package/src/util/ActiveShapeUtils.tsx +2 -9
  121. package/src/util/BarUtils.tsx +30 -23
  122. package/src/util/ChartUtils.ts +69 -25
  123. package/src/util/DirectPortal.tsx +107 -0
  124. package/src/util/FunnelUtils.tsx +1 -1
  125. package/src/util/RadialBarUtils.tsx +4 -3
  126. package/src/util/createCartesianCharts.tsx +1 -1
  127. package/src/util/createPolarCharts.tsx +1 -1
  128. package/src/util/propsAreEqual.ts +3 -33
  129. package/src/util/stacks/stackTypes.ts +1 -1
  130. package/src/util/svgPropertiesAndEvents.ts +1 -1
  131. package/src/util/tooltip/translate.ts +2 -2
  132. package/src/util/types.ts +3 -3
  133. package/src/zIndex/ZIndexLayer.tsx +39 -68
  134. package/src/zIndex/ZIndexPortal.tsx +29 -25
  135. package/src/state/reduxDevtoolsJsonStringifyReplacer.ts +0 -15
  136. package/src/util/axisPropsAreEqual.ts +0 -42
  137. package/src/util/resolveDefaultProps.tsx +0 -8
  138. package/src/util/typedDataKey.ts +0 -8
  139. package/test/_data.ts +0 -408
  140. package/test/animation/AnimationController.typed.spec.ts +0 -53
  141. package/test/animation/AnimationControllerImpl.spec.ts +0 -271
  142. package/test/animation/CSSTransitionAnimate.timing.spec.tsx +0 -473
  143. package/test/animation/JavascriptAnimate.spec.tsx +0 -62
  144. package/test/animation/RechartsAnimation.spec.ts +0 -636
  145. package/test/animation/easing.spec.ts +0 -218
  146. package/test/animation/legacyAnimationLengthChange.spec.tsx +0 -803
  147. package/test/animation/matchBy.spec.ts +0 -467
  148. package/test/animation/mockAnimationController.ts +0 -40
  149. package/test/animation/mockControllerAnimationManager.ts +0 -143
  150. package/test/animation/mockTimeoutController.ts +0 -114
  151. package/test/animation/timeoutController.spec.ts +0 -138
  152. package/test/animation/useAnimationStartSnapshot.spec.ts +0 -147
  153. package/test/animation/util.spec.ts +0 -28
  154. package/test/cartesian/Area.animation.spec.tsx +0 -363
  155. package/test/cartesian/Area.range.spec.tsx +0 -54
  156. package/test/cartesian/Area.spec.tsx +0 -1202
  157. package/test/cartesian/Area.stacked.render.spec.tsx +0 -69
  158. package/test/cartesian/Area.typed.spec.tsx +0 -209
  159. package/test/cartesian/Axis.integration.spec.tsx +0 -158
  160. package/test/cartesian/Bar/Bar.csstransition.spec.tsx +0 -299
  161. package/test/cartesian/Bar/Bar.spec.tsx +0 -2314
  162. package/test/cartesian/Bar/Bar.typed.spec.tsx +0 -192
  163. package/test/cartesian/Bar.animation.spec.tsx +0 -426
  164. package/test/cartesian/Bar.stackDomain.spec.tsx +0 -66
  165. package/test/cartesian/Bar.stacked.render.spec.tsx +0 -53
  166. package/test/cartesian/Bar.truncateByDomain.spec.tsx +0 -237
  167. package/test/cartesian/Bar.zeroDimensionFiltering.spec.tsx +0 -336
  168. package/test/cartesian/BarStack.spec.tsx +0 -91
  169. package/test/cartesian/Brush.keyboard.spec.tsx +0 -88
  170. package/test/cartesian/Brush.panorama.spec.tsx +0 -41
  171. package/test/cartesian/Brush.props.spec.tsx +0 -63
  172. package/test/cartesian/Brush.render.spec.tsx +0 -117
  173. package/test/cartesian/Brush.spec.tsx +0 -522
  174. package/test/cartesian/Brush.stacked.spec.tsx +0 -221
  175. package/test/cartesian/CartesianAxis.render.spec.tsx +0 -50
  176. package/test/cartesian/CartesianAxis.spec.tsx +0 -396
  177. package/test/cartesian/CartesianGrid.render.spec.tsx +0 -39
  178. package/test/cartesian/CartesianGrid.spec.tsx +0 -2103
  179. package/test/cartesian/ErrorBar.render.spec.tsx +0 -69
  180. package/test/cartesian/ErrorBar.spec.tsx +0 -2414
  181. package/test/cartesian/Funnel.animation.spec.tsx +0 -241
  182. package/test/cartesian/Funnel.spec.tsx +0 -226
  183. package/test/cartesian/Funnel.typed.spec.tsx +0 -221
  184. package/test/cartesian/GraphicalItemClipPath.scale-behavior.spec.tsx +0 -627
  185. package/test/cartesian/GraphicalItemClipPath.spec.tsx +0 -427
  186. package/test/cartesian/Line.animation.spec.tsx +0 -643
  187. package/test/cartesian/Line.sparseAnimationPath.spec.tsx +0 -98
  188. package/test/cartesian/Line.spec.tsx +0 -471
  189. package/test/cartesian/Line.typed.spec.tsx +0 -152
  190. package/test/cartesian/ReferenceArea.render.spec.tsx +0 -63
  191. package/test/cartesian/ReferenceArea.spec.tsx +0 -663
  192. package/test/cartesian/ReferenceArea.typed.spec.tsx +0 -74
  193. package/test/cartesian/ReferenceDot.render.spec.tsx +0 -55
  194. package/test/cartesian/ReferenceDot.spec.tsx +0 -462
  195. package/test/cartesian/ReferenceDot.typed.spec.tsx +0 -76
  196. package/test/cartesian/ReferenceLine/ReferenceLine.panorama.spec.tsx +0 -184
  197. package/test/cartesian/ReferenceLine/ReferenceLine.spec.tsx +0 -744
  198. package/test/cartesian/ReferenceLine/ReferenceLine.typed.spec.tsx +0 -74
  199. package/test/cartesian/ReferenceLine/getEndPoints.spec.ts +0 -399
  200. package/test/cartesian/ReferenceLine.render.spec.tsx +0 -134
  201. package/test/cartesian/Scatter.animation.spec.tsx +0 -381
  202. package/test/cartesian/Scatter.render.spec.tsx +0 -61
  203. package/test/cartesian/Scatter.spec.tsx +0 -406
  204. package/test/cartesian/Scatter.typed.spec.tsx +0 -153
  205. package/test/cartesian/XAxis/XAxis.barSize.spec.tsx +0 -336
  206. package/test/cartesian/XAxis/XAxis.brush.spec.tsx +0 -266
  207. package/test/cartesian/XAxis/XAxis.categorydomain.spec.tsx +0 -872
  208. package/test/cartesian/XAxis/XAxis.dataKey.spec.tsx +0 -86
  209. package/test/cartesian/XAxis/XAxis.datatypes.spec.tsx +0 -127
  210. package/test/cartesian/XAxis/XAxis.hide.spec.tsx +0 -106
  211. package/test/cartesian/XAxis/XAxis.multiaxis.spec.tsx +0 -336
  212. package/test/cartesian/XAxis/XAxis.numberdomain.spec.tsx +0 -1466
  213. package/test/cartesian/XAxis/XAxis.padding.spec.tsx +0 -758
  214. package/test/cartesian/XAxis/XAxis.padding_clip.spec.tsx +0 -65
  215. package/test/cartesian/XAxis/XAxis.state.spec.tsx +0 -355
  216. package/test/cartesian/XAxis/XAxis.tick.spec.tsx +0 -493
  217. package/test/cartesian/XAxis/XAxis.timescale.spec.tsx +0 -233
  218. package/test/cartesian/XAxis/XAxis.type.spec.tsx +0 -107
  219. package/test/cartesian/XAxis/XAxis.typed.spec.tsx +0 -102
  220. package/test/cartesian/XAxis/XAxis.vertical.spec.tsx +0 -265
  221. package/test/cartesian/XAxis.tickFormatter.spec.tsx +0 -54
  222. package/test/cartesian/YAxis/YAxis.7362.derivedDomain.spec.tsx +0 -230
  223. package/test/cartesian/YAxis/YAxis.7362.spec.tsx +0 -104
  224. package/test/cartesian/YAxis/YAxis.interval-zero.spec.tsx +0 -88
  225. package/test/cartesian/YAxis/YAxis.label.spec.tsx +0 -219
  226. package/test/cartesian/YAxis/YAxis.spec.tsx +0 -1595
  227. package/test/cartesian/YAxis/YAxis.tick.spec.tsx +0 -428
  228. package/test/cartesian/YAxis/YAxis.tickFormatter.spec.tsx +0 -54
  229. package/test/cartesian/YAxis/YAxis.ticks.spec.tsx +0 -263
  230. package/test/cartesian/YAxis/YAxis.type.spec.tsx +0 -107
  231. package/test/cartesian/YAxis/YAxis.typed.spec.tsx +0 -102
  232. package/test/cartesian/ZAxis.spec.tsx +0 -300
  233. package/test/cartesian/ZAxis.typed.spec.tsx +0 -33
  234. package/test/cartesian/__snapshots__/Brush.spec.tsx.snap +0 -5
  235. package/test/cartesian/axisLineAndStroke.spec.tsx +0 -72
  236. package/test/cartesian/getCartesianPosition.spec.ts +0 -907
  237. package/test/cartesian/getEquidistantTicks.spec.ts +0 -88
  238. package/test/cartesian/getTicks.spec.ts +0 -378
  239. package/test/cartesian/miscFeatureGaps.spec.tsx +0 -89
  240. package/test/cartesian/useAnimatedLineLength.spec.ts +0 -168
  241. package/test/chart/AccessibilityLayer.spec.tsx +0 -569
  242. package/test/chart/AccessibilityScans.spec.tsx +0 -286
  243. package/test/chart/AreaChart.spec.tsx +0 -409
  244. package/test/chart/AreaChart.stacked.spec.tsx +0 -1407
  245. package/test/chart/AreaChart.typed.spec.tsx +0 -39
  246. package/test/chart/BarChart.spec.tsx +0 -3719
  247. package/test/chart/BarChart.typed.spec.tsx +0 -60
  248. package/test/chart/CategoricalChart.spec.tsx +0 -255
  249. package/test/chart/ComposedChart.spec.tsx +0 -199
  250. package/test/chart/ComposedChart.typed.spec.tsx +0 -39
  251. package/test/chart/FunnelChart.spec.tsx +0 -215
  252. package/test/chart/FunnelChart.typed.spec.tsx +0 -39
  253. package/test/chart/LineChart.multiseries.spec.tsx +0 -50
  254. package/test/chart/LineChart.smoke.spec.tsx +0 -50
  255. package/test/chart/LineChart.spec.tsx +0 -930
  256. package/test/chart/LineChart.typed.spec.tsx +0 -39
  257. package/test/chart/NicheChartTooltip.spec.tsx +0 -81
  258. package/test/chart/PieChart.spec.tsx +0 -793
  259. package/test/chart/PieChart.typed.spec.tsx +0 -39
  260. package/test/chart/RadarChart.spec.tsx +0 -530
  261. package/test/chart/RadarChart.typed.spec.tsx +0 -39
  262. package/test/chart/RadialBarChart.5966.spec.tsx +0 -48
  263. package/test/chart/RadialBarChart.spec.tsx +0 -679
  264. package/test/chart/RadialBarChart.typed.spec.tsx +0 -39
  265. package/test/chart/RechartsWrapper.spec.tsx +0 -83
  266. package/test/chart/Sankey.content.spec.tsx +0 -46
  267. package/test/chart/Sankey.spec.tsx +0 -952
  268. package/test/chart/Sankey.typed.spec.tsx +0 -29
  269. package/test/chart/ScatterChart.spec.tsx +0 -2613
  270. package/test/chart/ScatterChart.typed.spec.tsx +0 -39
  271. package/test/chart/SunburstChart.spec.tsx +0 -146
  272. package/test/chart/Treemap.animation.spec.tsx +0 -52
  273. package/test/chart/Treemap.spec.tsx +0 -1003
  274. package/test/chart/Treemap.typed.spec.tsx +0 -26
  275. package/test/chart/chartEvents.spec.tsx +0 -127
  276. package/test/chart/responsive.spec.tsx +0 -620
  277. package/test/component/Cell.render.spec.tsx +0 -155
  278. package/test/component/Cell.spec.tsx +0 -12
  279. package/test/component/Cursor.spec.tsx +0 -186
  280. package/test/component/DefaultTooltipContent.spec.tsx +0 -102
  281. package/test/component/Label.render.spec.tsx +0 -63
  282. package/test/component/Label.spec.tsx +0 -686
  283. package/test/component/Label.typed.spec.tsx +0 -46
  284. package/test/component/LabelList.spec.tsx +0 -188
  285. package/test/component/Legend.itemSorter.spec.tsx +0 -704
  286. package/test/component/Legend.render.spec.tsx +0 -92
  287. package/test/component/Legend.spec.tsx +0 -2213
  288. package/test/component/Legend.typed.spec.tsx +0 -22
  289. package/test/component/ResponsiveContainer.spec.tsx +0 -523
  290. package/test/component/ResponsiveContainerDataTest.spec.tsx +0 -51
  291. package/test/component/Text.spec.tsx +0 -415
  292. package/test/component/Text.typed.spec.tsx +0 -46
  293. package/test/component/Tooltip/ActiveDot.spec.tsx +0 -370
  294. package/test/component/Tooltip/Tooltip.animation.spec.tsx +0 -209
  295. package/test/component/Tooltip/Tooltip.content.spec.tsx +0 -128
  296. package/test/component/Tooltip/Tooltip.formatter.spec.tsx +0 -152
  297. package/test/component/Tooltip/Tooltip.includeHidden.spec.tsx +0 -79
  298. package/test/component/Tooltip/Tooltip.multipleDataArrays.spec.tsx +0 -165
  299. package/test/component/Tooltip/Tooltip.offset.spec.tsx +0 -113
  300. package/test/component/Tooltip/Tooltip.state.spec.tsx +0 -74
  301. package/test/component/Tooltip/Tooltip.sync.spec.tsx +0 -639
  302. package/test/component/Tooltip/defaultIndex.spec.tsx +0 -227
  303. package/test/component/Tooltip/graphicalItem.formatter.spec.tsx +0 -138
  304. package/test/component/Tooltip/itemSorter.spec.tsx +0 -2815
  305. package/test/component/Tooltip/tooltipEventType.spec.tsx +0 -344
  306. package/test/component/Tooltip/tooltipMouseHoverSelectors.ts +0 -41
  307. package/test/component/Tooltip/tooltipTestHelpers.tsx +0 -162
  308. package/test/component/Tooltip.defaultIndex.spec.tsx +0 -48
  309. package/test/component/Tooltip.hover.spec.tsx +0 -61
  310. package/test/component/Tooltip.item.spec.tsx +0 -54
  311. package/test/component/Tooltip.keyboard.spec.tsx +0 -51
  312. package/test/component/Tooltip.payload.spec.tsx +0 -1716
  313. package/test/component/Tooltip.touch.spec.tsx +0 -39
  314. package/test/component/Tooltip.visibility.spec.tsx +0 -1889
  315. package/test/component/TooltipBoundingBox.spec.tsx +0 -89
  316. package/test/component/responsiveContainerUtils.spec.ts +0 -205
  317. package/test/container/ClipPath.spec.tsx +0 -602
  318. package/test/container/chartDimensions.spec.tsx +0 -368
  319. package/test/context/chartLayoutContext.spec.tsx +0 -378
  320. package/test/helper/ExpectAxisDomain.tsx +0 -27
  321. package/test/helper/assertNotNull.ts +0 -6
  322. package/test/helper/assertZIndexLayerOrder.ts +0 -19
  323. package/test/helper/createSelectorTestCase.tsx +0 -176
  324. package/test/helper/expectAnimatedPieAngles.ts +0 -100
  325. package/test/helper/expectAnimatedPiePaths.ts +0 -78
  326. package/test/helper/expectAreaCurve.ts +0 -15
  327. package/test/helper/expectAxisTicks.ts +0 -48
  328. package/test/helper/expectBars.ts +0 -54
  329. package/test/helper/expectFunctionReturning.ts +0 -58
  330. package/test/helper/expectLabel.ts +0 -32
  331. package/test/helper/expectLastCalledWith.ts +0 -48
  332. package/test/helper/expectLine.ts +0 -20
  333. package/test/helper/expectPieSectors.ts +0 -80
  334. package/test/helper/expectScale.ts +0 -37
  335. package/test/helper/expectScatterPoints.ts +0 -52
  336. package/test/helper/expectStackGroups.ts +0 -144
  337. package/test/helper/mockAxes.ts +0 -22
  338. package/test/helper/mockGetBoundingClientRect.ts +0 -66
  339. package/test/helper/mockHTMLElementProperty.ts +0 -19
  340. package/test/helper/mockTouchingElement.ts +0 -27
  341. package/test/helper/offsetHelpers.ts +0 -19
  342. package/test/helper/parameterizedTestCases.tsx +0 -99
  343. package/test/helper/produceState.ts +0 -32
  344. package/test/helper/selectorTestHelpers.tsx +0 -63
  345. package/test/helper/trim.spec.ts +0 -35
  346. package/test/helper/trim.ts +0 -11
  347. package/test/hooks/useActiveTooltipDataPoints.spec.tsx +0 -358
  348. package/test/hooks/useAxisDomain.spec.tsx +0 -361
  349. package/test/hooks/useAxisScale.spec.tsx +0 -283
  350. package/test/hooks/useAxisTicks.spec.tsx +0 -130
  351. package/test/hooks/useOffset.spec.tsx +0 -248
  352. package/test/hooks/useTooltipStateHooks.spec.tsx +0 -109
  353. package/test/polar/Pie/Pie-TwoLevelPieChart.spec.tsx +0 -135
  354. package/test/polar/Pie/Pie.spec.tsx +0 -784
  355. package/test/polar/Pie/Pie.typed.spec.tsx +0 -78
  356. package/test/polar/Pie.animation.spec.tsx +0 -529
  357. package/test/polar/PieWithLegend.animation.spec.tsx +0 -142
  358. package/test/polar/PolarAngleAxis/PolarAngleAxis.events.spec.tsx +0 -76
  359. package/test/polar/PolarAngleAxis/PolarAngleAxis.spec.tsx +0 -2079
  360. package/test/polar/PolarAngleAxis/PolarAngleAxis.typed.spec.tsx +0 -102
  361. package/test/polar/PolarAngleAxis.render.spec.tsx +0 -79
  362. package/test/polar/PolarGrid.render.spec.tsx +0 -75
  363. package/test/polar/PolarGrid.spec.tsx +0 -918
  364. package/test/polar/PolarLegendPerRow.render.spec.tsx +0 -85
  365. package/test/polar/PolarRadiusAxis.events.spec.tsx +0 -65
  366. package/test/polar/PolarRadiusAxis.render.spec.tsx +0 -52
  367. package/test/polar/PolarRadiusAxis.spec.tsx +0 -991
  368. package/test/polar/PolarRadiusAxis.typed.spec.tsx +0 -84
  369. package/test/polar/PolarTooltipLegend.render.spec.tsx +0 -80
  370. package/test/polar/Radar.animation.spec.tsx +0 -570
  371. package/test/polar/Radar.render.spec.tsx +0 -71
  372. package/test/polar/Radar.spec.tsx +0 -265
  373. package/test/polar/Radar.typed.spec.tsx +0 -119
  374. package/test/polar/RadialBar/RadialBar.spec.tsx +0 -1521
  375. package/test/polar/RadialBar/RadialBar.typed.spec.tsx +0 -132
  376. package/test/polar/RadialBar.animation.spec.tsx +0 -375
  377. package/test/polar/RadialBar.render.spec.tsx +0 -66
  378. package/test/polar/RadialBar.stacked.spec.tsx +0 -57
  379. package/test/setup.ts +0 -84
  380. package/test/shape/ActiveShape.spec.tsx +0 -181
  381. package/test/shape/Cross.spec.tsx +0 -60
  382. package/test/shape/Cross.typed.spec.tsx +0 -26
  383. package/test/shape/Curve.spec.tsx +0 -368
  384. package/test/shape/Curve.typed.spec.tsx +0 -69
  385. package/test/shape/Dot.spec.tsx +0 -73
  386. package/test/shape/Dot.typed.spec.tsx +0 -30
  387. package/test/shape/Polygon.spec.tsx +0 -357
  388. package/test/shape/Polygon.typed.spec.tsx +0 -28
  389. package/test/shape/Rectangle.animation.spec.tsx +0 -451
  390. package/test/shape/Rectangle.spec.tsx +0 -68
  391. package/test/shape/Rectangle.typed.spec.tsx +0 -24
  392. package/test/shape/Sector.spec.tsx +0 -76
  393. package/test/shape/Sector.typed.spec.tsx +0 -24
  394. package/test/shape/Symbols.spec.tsx +0 -43
  395. package/test/shape/Symbols.typed.spec.tsx +0 -24
  396. package/test/shape/Trapezoid.spec.tsx +0 -50
  397. package/test/shape/Trapezoid.typed.spec.tsx +0 -24
  398. package/test/shape/__snapshots__/Cross.spec.tsx.snap +0 -62
  399. package/test/shape/__snapshots__/Curve.spec.tsx.snap +0 -460
  400. package/test/shape/__snapshots__/Polygon.spec.tsx.snap +0 -58
  401. package/test/shape/__snapshots__/Rectangle.spec.tsx.snap +0 -117
  402. package/test/shape/__snapshots__/Sector.spec.tsx.snap +0 -71
  403. package/test/shape/__snapshots__/Trapezoid.spec.tsx.snap +0 -64
  404. package/test/state/chartDataSlice.spec.ts +0 -53
  405. package/test/state/externalEventsMiddleware.spec.ts +0 -178
  406. package/test/state/graphicalItemsSlice.spec.ts +0 -92
  407. package/test/state/hooks.spec.tsx +0 -68
  408. package/test/state/legendSlice.spec.ts +0 -44
  409. package/test/state/mouseEventsMiddleware.spec.ts +0 -75
  410. package/test/state/optionsSlice.spec.ts +0 -19
  411. package/test/state/reduxDevtoolsJsonStringifyReplacer.spec.ts +0 -25
  412. package/test/state/referenceElementsSlice.spec.ts +0 -84
  413. package/test/state/selectors/areaSelectors.spec.tsx +0 -77
  414. package/test/state/selectors/axisSelectors.spec.tsx +0 -1418
  415. package/test/state/selectors/barStackSelectors.spec.tsx +0 -752
  416. package/test/state/selectors/brushSelectors.spec.tsx +0 -30
  417. package/test/state/selectors/cartesianAxisSlice.spec.ts +0 -96
  418. package/test/state/selectors/combineNiceTicks.spec.ts +0 -207
  419. package/test/state/selectors/combiners/combineActiveTooltipIndex.spec.ts +0 -61
  420. package/test/state/selectors/combiners/combineAllBarPositions.spec.ts +0 -39
  421. package/test/state/selectors/combiners/combineConfiguredScale.spec.ts +0 -56
  422. package/test/state/selectors/combiners/combineDisplayedStackedData.spec.ts +0 -123
  423. package/test/state/selectors/combiners/combineRealScaleType.spec.ts +0 -80
  424. package/test/state/selectors/containerSelectors.spec.tsx +0 -168
  425. package/test/state/selectors/dataSelectors.spec.tsx +0 -136
  426. package/test/state/selectors/legendSelectors.spec.tsx +0 -113
  427. package/test/state/selectors/lineSelectors.spec.tsx +0 -60
  428. package/test/state/selectors/pieSelectors.spec.tsx +0 -72
  429. package/test/state/selectors/radarSelectors.spec.tsx +0 -496
  430. package/test/state/selectors/rootPropsSelectors.spec.tsx +0 -169
  431. package/test/state/selectors/scatterSelectors.spec.tsx +0 -47
  432. package/test/state/selectors/selectActiveTooltipIndex.spec.tsx +0 -234
  433. package/test/state/selectors/selectAllAxes.spec.tsx +0 -18
  434. package/test/state/selectors/selectAxisDomain.spec.tsx +0 -21
  435. package/test/state/selectors/selectAxisDomainIncludingNiceTicks.spec.tsx +0 -19
  436. package/test/state/selectors/selectAxisRangeWithReverse.spec.tsx +0 -22
  437. package/test/state/selectors/selectAxisScale.spec.tsx +0 -91
  438. package/test/state/selectors/selectBarRectangles.stackOffset.spec.tsx +0 -503
  439. package/test/state/selectors/selectBaseAxis.spec.tsx +0 -56
  440. package/test/state/selectors/selectCartesianItemsSettings.spec.tsx +0 -57
  441. package/test/state/selectors/selectChartOffset.spec.tsx +0 -26
  442. package/test/state/selectors/selectDisplayedData.spec.tsx +0 -282
  443. package/test/state/selectors/selectIsTooltipActive.spec.tsx +0 -231
  444. package/test/state/selectors/selectNumericalDomain.spec.tsx +0 -21
  445. package/test/state/selectors/selectRealScaleType.spec.tsx +0 -19
  446. package/test/state/selectors/selectStackGroups.spec.tsx +0 -322
  447. package/test/state/selectors/selectXAxisPosition.spec.tsx +0 -22
  448. package/test/state/selectors/selectYAxisPosition.spec.tsx +0 -22
  449. package/test/state/selectors/selectors.spec.tsx +0 -1613
  450. package/test/state/throttling.spec.ts +0 -200
  451. package/test/state/zIndexSlice.spec.ts +0 -85
  452. package/test/synchronisation/useChartSynchronisation.spec.tsx +0 -225
  453. package/test/util/BarUtils.spec.ts +0 -39
  454. package/test/util/CartesianUtils/CartesianUtils.spec.ts +0 -261
  455. package/test/util/CartesianUtils/rectWithPoints.spec.ts +0 -48
  456. package/test/util/ChartUtils/ChartUtils.spec.ts +0 -491
  457. package/test/util/ChartUtils/appendOffsetOfLegend.spec.ts +0 -136
  458. package/test/util/ChartUtils/appendOffsetOfLegend.spec.tsx +0 -133
  459. package/test/util/ChartUtils/getCateCoordinateOfLine.spec.ts +0 -83
  460. package/test/util/ChartUtils/getStackedData.spec.ts +0 -416
  461. package/test/util/ChartUtils/truncateByDomain.spec.ts +0 -70
  462. package/test/util/DataUtils.spec.ts +0 -385
  463. package/test/util/DomUtils.spec.tsx +0 -117
  464. package/test/util/FunnelUtils.spec.tsx +0 -70
  465. package/test/util/Global.spec.ts +0 -11
  466. package/test/util/LRUCache.spec.ts +0 -81
  467. package/test/util/LogUtils.spec.ts +0 -45
  468. package/test/util/PolarUtils.spec.ts +0 -66
  469. package/test/util/ReduceCssCalcPrototype.spec.ts +0 -141
  470. package/test/util/ShallowEqual.spec.ts +0 -102
  471. package/test/util/TickUtils.spec.ts +0 -29
  472. package/test/util/axisPropsAreEqual.spec.ts +0 -93
  473. package/test/util/createChartHelpers.spec.tsx +0 -210
  474. package/test/util/cursor/getCursorPoints.spec.ts +0 -136
  475. package/test/util/cursor/getCursorRectangle.spec.ts +0 -50
  476. package/test/util/cursor/getRadialCursorPoints.spec.ts +0 -36
  477. package/test/util/errorValue.spec.ts +0 -69
  478. package/test/util/getEveryNth.spec.ts +0 -39
  479. package/test/util/getRadiusAndStrokeWidthFromDot.spec.ts +0 -51
  480. package/test/util/getRelativeCoordinate.spec.ts +0 -250
  481. package/test/util/getSliced.spec.ts +0 -45
  482. package/test/util/isDomainSpecifiedByUser.spec.ts +0 -207
  483. package/test/util/isWellBehavedNumber.spec.ts +0 -54
  484. package/test/util/payload/getUniqPayload.spec.ts +0 -56
  485. package/test/util/propsAreEqual.spec.ts +0 -75
  486. package/test/util/round.spec.ts +0 -112
  487. package/test/util/scale/arithmetic.spec.ts +0 -61
  488. package/test/util/scale/createCategoricalInverse.spec.ts +0 -84
  489. package/test/util/scale/getNiceTickValues.spec.ts +0 -421
  490. package/test/util/scale/getTickValuesFixedDomain.spec.ts +0 -155
  491. package/test/util/svgPropertiesAndEvents.spec.tsx +0 -206
  492. package/test/util/svgPropertiesNoEvents.spec.tsx +0 -228
  493. package/test/util/tooltip/translate.spec.ts +0 -396
  494. package/test/util/useAnimationId.spec.tsx +0 -59
  495. package/test/util/useElementOffset.spec.tsx +0 -173
  496. package/test/util/usePrefersReducedMotion.spec.ts +0 -54
  497. package/test/util/useUniqueId.spec.ts +0 -99
  498. package/test/utils/diagnostics-allowlist.ts +0 -18
  499. package/test/utils/diagnostics.ts +0 -58
  500. package/test/zIndex/AllZIndexPortals.spec.tsx +0 -83
  501. package/test/zIndex/DefaultZIndexes.spec.ts +0 -80
  502. package/test/zIndex/DynamicZIndex.spec.tsx +0 -102
  503. package/test/zIndex/ZIndexLayer.portalOwner.spec.tsx +0 -125
  504. package/test/zIndex/componentZIndex.spec.tsx +0 -255
  505. package/test/zIndex/getZIndexFromUnknown.spec.ts +0 -51
  506. package/test/zIndex/multiChartZIndexIsolation.spec.tsx +0 -90
  507. package/test/zIndex/zIndexSelectors.spec.ts +0 -172
  508. package/tsconfig.json +0 -11
@@ -1,2213 +0,0 @@
1
- // Ported from recharts 3.8.1 test/component/Legend.spec.tsx.
2
- //
3
- // Tier-A DOM/behavioral assertions are byte-identical to recharts; only the
4
- // harness is adapted: React render -> Solid `render(() => <.../>)`; rerenders are
5
- // driven by a Solid signal (no JSX `rerender`); the reference `expectLegendLabels`
6
- // / `assertHasLegend` helpers and the legendType symbol tables are inlined here
7
- // (the repo has no shared `expectLegendLabels` helper); `rechartsTestRender` ->
8
- // `render` + `flush`. Custom `content` as a React element, `aria-label` on the
9
- // Surface, and the `mockSequenceOfGetBoundingClientRect` regression test are not
10
- // supported by the port (see reclassifiedBlocked) and are omitted.
11
- import { createEffect, createSignal, flush, Show } from "solid-js";
12
- import { describe, expect, it, test, vi } from "vitest";
13
- import { fireEvent, render, screen } from "@solidjs/testing-library";
14
- import {
15
- Area,
16
- AreaChart,
17
- Bar,
18
- BarChart,
19
- ComposedChart,
20
- DefaultZIndexes,
21
- Legend,
22
- Line,
23
- LineChart,
24
- Pie,
25
- PieChart,
26
- Radar,
27
- RadarChart,
28
- RadialBar,
29
- RadialBarChart,
30
- Scatter,
31
- ScatterChart,
32
- } from "../../src";
33
- import type { LegendProps, LegendType } from "../../src";
34
- import { selectLegendPayload } from "../../src/state/selectors/legendSelectors";
35
- import { mockGetBoundingClientRect } from "../helper/mockGetBoundingClientRect";
36
- import { assertNotNull } from "../helper/assertNotNull";
37
- import { createSelectorTestCase } from "../helper/createSelectorTestCase";
38
- import { expectLastCalledWith } from "../helper/expectLastCalledWith";
39
- import { useAppSelectorWithStableTest } from "../helper/selectorTestHelpers";
40
- import { dataWithSpecialNameAndFillProperties, numericalData } from "../_data";
41
-
42
- type LegendTypeTestCases = ReadonlyArray<{
43
- legendType: LegendType;
44
- selector: string;
45
- expectedAttributes: Record<string, string>;
46
- }>;
47
-
48
- // ---- inlined helpers (reference: test/helper/expectLegendLabels.tsx) ----
49
- function assertHasLegend(container: Element): ReadonlyArray<Element> {
50
- expect(container.querySelectorAll(".recharts-default-legend")).toHaveLength(1);
51
- return Array.from(container.querySelectorAll(".recharts-default-legend .recharts-legend-item"));
52
- }
53
-
54
- function expectLegendLabels(
55
- container: Element,
56
- expectedLabels: null | ReadonlyArray<{
57
- textContent: string;
58
- textColor?: string;
59
- fill: string | null | undefined;
60
- stroke?: string;
61
- }>,
62
- ): void {
63
- assertNotNull(container);
64
-
65
- if (expectedLabels == null) {
66
- expect(container.querySelectorAll(".recharts-default-legend")).toHaveLength(0);
67
- return;
68
- }
69
-
70
- const expectsStroke = expectedLabels.some((label) => label.stroke != null);
71
- const expectsColor = expectedLabels.some((label) => label.textColor !== undefined);
72
-
73
- const actualLabels = assertHasLegend(container).map((legend) => {
74
- const textNode = legend.querySelector(".recharts-legend-item-text");
75
- return {
76
- textContent: legend.textContent,
77
- textColor: expectsColor && textNode instanceof HTMLElement ? textNode.style.color : undefined,
78
- fill: legend.querySelector(".recharts-legend-icon")?.getAttribute("fill"),
79
- stroke: expectsStroke
80
- ? legend.querySelector(".recharts-legend-icon")?.getAttribute("stroke")
81
- : undefined,
82
- };
83
- });
84
-
85
- expect(actualLabels).toEqual(expectedLabels);
86
- }
87
-
88
- /**
89
- * Bar legend for some reason has no default color at all.
90
- * I think that's because Bar has no default fill nor stroke.
91
- */
92
- const expectedLegendTypeSymbolsWithoutColor: LegendTypeTestCases = [
93
- {
94
- legendType: "circle",
95
- selector: "path.recharts-symbols",
96
- expectedAttributes: {
97
- d: "M16,0A16,16,0,1,1,-16,0A16,16,0,1,1,16,0",
98
- class: "recharts-symbols",
99
- cx: "16",
100
- cy: "16",
101
- transform: "translate(16, 16)",
102
- },
103
- },
104
- {
105
- legendType: "cross",
106
- selector: "path.recharts-symbols",
107
- expectedAttributes: {
108
- d: "M-16,-5.333L-5.333,-5.333L-5.333,-16L5.333,-16L5.333,-5.333L16,-5.333L16,5.333L5.333,5.333L5.333,16L-5.333,16L-5.333,5.333L-16,5.333Z",
109
- class: "recharts-symbols",
110
- cx: "16",
111
- cy: "16",
112
- transform: "translate(16, 16)",
113
- },
114
- },
115
- {
116
- legendType: "diamond",
117
- selector: "path.recharts-symbols",
118
- expectedAttributes: {
119
- d: "M0,-16L9.238,0L0,16L-9.238,0Z",
120
- class: "recharts-symbols",
121
- cx: "16",
122
- cy: "16",
123
- transform: "translate(16, 16)",
124
- },
125
- },
126
- {
127
- legendType: "line",
128
- selector: "path.recharts-legend-icon",
129
- expectedAttributes: {
130
- // d attribute path is sensitive to whitespace!
131
- d: `M0,16h10.666666666666666A5.333333333333333,5.333333333333333,0,1,1,21.333333333333332,16H32M21.333333333333332,16A5.333333333333333,5.333333333333333,0,1,1,10.666666666666666,16`,
132
- fill: "none",
133
- "stroke-width": "4",
134
- class: "recharts-legend-icon",
135
- },
136
- },
137
- {
138
- legendType: "plainline",
139
- selector: "line.recharts-legend-icon",
140
- expectedAttributes: {
141
- class: "recharts-legend-icon",
142
- x1: "0",
143
- x2: "32",
144
- y1: "16",
145
- y2: "16",
146
- fill: "none",
147
- "stroke-width": "4",
148
- },
149
- },
150
- {
151
- legendType: "rect",
152
- selector: "path.recharts-legend-icon",
153
- expectedAttributes: {
154
- d: "M0,4h32v24h-32z",
155
- class: "recharts-legend-icon",
156
- stroke: "none",
157
- },
158
- },
159
- {
160
- legendType: "square",
161
- selector: "path.recharts-symbols",
162
- expectedAttributes: {
163
- d: "M-16,-16h32v32h-32Z",
164
- class: "recharts-symbols",
165
- cx: "16",
166
- cy: "16",
167
- transform: "translate(16, 16)",
168
- },
169
- },
170
- {
171
- legendType: "star",
172
- selector: "path.recharts-symbols",
173
- expectedAttributes: {
174
- d: "M0,-16.823L3.777,-5.199L16,-5.199L6.111,1.986L9.889,13.61L0,6.426L-9.889,13.61L-6.111,1.986L-16,-5.199L-3.777,-5.199Z",
175
- class: "recharts-symbols",
176
- cx: "16",
177
- cy: "16",
178
- transform: "translate(16, 16)",
179
- },
180
- },
181
- {
182
- legendType: "triangle",
183
- selector: "path.recharts-symbols",
184
- expectedAttributes: {
185
- d: "M0,-18.475L16,9.238L-16,9.238Z",
186
- class: "recharts-symbols",
187
- cx: "16",
188
- cy: "16",
189
- transform: "translate(16, 16)",
190
- },
191
- },
192
- {
193
- legendType: "wye",
194
- selector: "path.recharts-symbols",
195
- expectedAttributes: {
196
- d: "M5.856,3.381L5.856,15.094L-5.856,15.094L-5.856,3.381L-16,-2.475L-10.144,-12.619L0,-6.762L10.144,-12.619L16,-2.475Z",
197
- class: "recharts-symbols",
198
- cx: "16",
199
- cy: "16",
200
- transform: "translate(16, 16)",
201
- },
202
- },
203
- ];
204
-
205
- const expectedLegendTypeSymbolsWithColor = (color: string): LegendTypeTestCases => [
206
- {
207
- legendType: "circle",
208
- selector: "path.recharts-symbols",
209
- expectedAttributes: {
210
- d: "M16,0A16,16,0,1,1,-16,0A16,16,0,1,1,16,0",
211
- class: "recharts-symbols",
212
- cx: "16",
213
- cy: "16",
214
- transform: "translate(16, 16)",
215
- fill: color,
216
- },
217
- },
218
- {
219
- legendType: "cross",
220
- selector: "path.recharts-symbols",
221
- expectedAttributes: {
222
- d: "M-16,-5.333L-5.333,-5.333L-5.333,-16L5.333,-16L5.333,-5.333L16,-5.333L16,5.333L5.333,5.333L5.333,16L-5.333,16L-5.333,5.333L-16,5.333Z",
223
- class: "recharts-symbols",
224
- cx: "16",
225
- cy: "16",
226
- transform: "translate(16, 16)",
227
- fill: color,
228
- },
229
- },
230
- {
231
- legendType: "diamond",
232
- selector: "path.recharts-symbols",
233
- expectedAttributes: {
234
- d: "M0,-16L9.238,0L0,16L-9.238,0Z",
235
- class: "recharts-symbols",
236
- cx: "16",
237
- cy: "16",
238
- transform: "translate(16, 16)",
239
- fill: color,
240
- },
241
- },
242
- {
243
- legendType: "line",
244
- selector: "path.recharts-legend-icon",
245
- expectedAttributes: {
246
- // d attribute path is sensitive to whitespace!
247
- d: `M0,16h10.666666666666666A5.333333333333333,5.333333333333333,0,1,1,21.333333333333332,16H32M21.333333333333332,16A5.333333333333333,5.333333333333333,0,1,1,10.666666666666666,16`,
248
- fill: "none",
249
- "stroke-width": "4",
250
- class: "recharts-legend-icon",
251
- stroke: color,
252
- },
253
- },
254
- {
255
- legendType: "plainline",
256
- selector: "line.recharts-legend-icon",
257
- expectedAttributes: {
258
- class: "recharts-legend-icon",
259
- x1: "0",
260
- x2: "32",
261
- y1: "16",
262
- y2: "16",
263
- fill: "none",
264
- stroke: color,
265
- "stroke-width": "4",
266
- },
267
- },
268
- {
269
- legendType: "rect",
270
- selector: "path.recharts-legend-icon",
271
- expectedAttributes: {
272
- d: "M0,4h32v24h-32z",
273
- class: "recharts-legend-icon",
274
- stroke: "none",
275
- fill: color,
276
- },
277
- },
278
- {
279
- legendType: "square",
280
- selector: "path.recharts-symbols",
281
- expectedAttributes: {
282
- d: "M-16,-16h32v32h-32Z",
283
- class: "recharts-symbols",
284
- cx: "16",
285
- cy: "16",
286
- transform: "translate(16, 16)",
287
- fill: color,
288
- },
289
- },
290
- {
291
- legendType: "star",
292
- selector: "path.recharts-symbols",
293
- expectedAttributes: {
294
- d: "M0,-16.823L3.777,-5.199L16,-5.199L6.111,1.986L9.889,13.61L0,6.426L-9.889,13.61L-6.111,1.986L-16,-5.199L-3.777,-5.199Z",
295
- class: "recharts-symbols",
296
- cx: "16",
297
- cy: "16",
298
- transform: "translate(16, 16)",
299
- fill: color,
300
- },
301
- },
302
- {
303
- legendType: "triangle",
304
- selector: "path.recharts-symbols",
305
- expectedAttributes: {
306
- d: "M0,-18.475L16,9.238L-16,9.238Z",
307
- class: "recharts-symbols",
308
- cx: "16",
309
- cy: "16",
310
- transform: "translate(16, 16)",
311
- fill: color,
312
- },
313
- },
314
- {
315
- legendType: "wye",
316
- selector: "path.recharts-symbols",
317
- expectedAttributes: {
318
- d: "M5.856,3.381L5.856,15.094L-5.856,15.094L-5.856,3.381L-16,-2.475L-10.144,-12.619L0,-6.762L10.144,-12.619L16,-2.475Z",
319
- class: "recharts-symbols",
320
- cx: "16",
321
- cy: "16",
322
- transform: "translate(16, 16)",
323
- fill: color,
324
- },
325
- },
326
- ];
327
-
328
- function assertExpectedAttributes(
329
- container: HTMLElement,
330
- selector: string,
331
- expectedAttributes: Record<string, string>,
332
- ): void {
333
- const legendItem = assertHasLegend(container)[0];
334
- assertNotNull(legendItem);
335
- const symbol = legendItem.querySelector(selector);
336
- expect(symbol).not.toBeNull();
337
- expect(symbol).toBeInTheDocument();
338
- const expectedAttributeNames = Object.keys(expectedAttributes);
339
- expect.soft(symbol?.getAttributeNames().sort()).toEqual(expectedAttributeNames.sort());
340
- expectedAttributeNames.forEach((attributeName) => {
341
- expect.soft(symbol).toHaveAttribute(attributeName, expectedAttributes[attributeName]);
342
- });
343
- }
344
-
345
- describe("<Legend />", () => {
346
- const categoricalData = [
347
- { value: "Apple", color: "#ff7300" },
348
- { value: "Samsung", color: "#bb7300" },
349
- { value: "Huawei", color: "#887300" },
350
- { value: "Sony", color: "#667300" },
351
- ];
352
-
353
- const numericalData2 = [
354
- { title: "Luftbaloons", value: 99 },
355
- { title: "Miles I would walk", value: 500 },
356
- { title: "Days a week", value: 8 },
357
- { title: "Mambo number", value: 5 },
358
- { title: "Seas of Rhye", value: 7 },
359
- ];
360
-
361
- describe("outside of chart context", () => {
362
- it("should ignore payload prop", () => {
363
- const { container } = render(() => <Legend width={500} height={30} />);
364
- flush();
365
-
366
- expect(container.querySelectorAll(".recharts-default-legend")).toHaveLength(0);
367
- expect(
368
- container.querySelectorAll(".recharts-default-legend .recharts-legend-item"),
369
- ).toHaveLength(0);
370
- });
371
- });
372
-
373
- describe("custom content as a react element", () => {
374
- it("should render a custom component wrapped legend", () => {
375
- const CustomLegend = (props: LegendProps) => <Legend {...props} />;
376
- const { container } = render(() => (
377
- <LineChart
378
- width={600}
379
- height={300}
380
- data={categoricalData}
381
- margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
382
- >
383
- <CustomLegend />
384
- <Line
385
- type="monotone"
386
- dataKey="pv"
387
- stroke="#8884d8"
388
- activeDot={{ r: 8 }}
389
- strokeDasharray="5 5"
390
- />
391
- <Line type="monotone" dataKey="uv" stroke="#82ca9d" />
392
- </LineChart>
393
- ));
394
- flush();
395
-
396
- expect(container.querySelectorAll(".recharts-default-legend")).toHaveLength(1);
397
- });
398
- });
399
-
400
- describe("content as a function", () => {
401
- it("should render result", () => {
402
- const customizedLegend = () => "custom return value";
403
- const { container } = render(() => (
404
- <LineChart
405
- width={600}
406
- height={300}
407
- data={categoricalData}
408
- margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
409
- >
410
- <Legend content={customizedLegend} />
411
- <Line dataKey="pv" stroke="#8884d8" activeDot={{ r: 8 }} strokeDasharray="5 5" />
412
- <Line type="monotone" dataKey="uv" stroke="#82ca9d" />
413
- </LineChart>
414
- ));
415
- flush();
416
-
417
- expect(container.querySelectorAll(".recharts-default-legend")).toHaveLength(0);
418
- expect(screen.getByText("custom return value")).toBeInTheDocument();
419
- expect(screen.getByText("custom return value")).toBeVisible();
420
- });
421
- });
422
-
423
- // In recharts the "React Component" content form is distinct from the function
424
- // form (one is a component, the other a plain callback); both reduce to the same
425
- // function-content path in Solid since there is no React.createElement boundary.
426
- describe("content as a Component", () => {
427
- it("should render result", () => {
428
- const CustomizedLegend = () => <>custom return value</>;
429
- const { container } = render(() => (
430
- <LineChart
431
- width={600}
432
- height={300}
433
- data={categoricalData}
434
- margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
435
- >
436
- <Legend content={CustomizedLegend} />
437
- <Line dataKey="pv" stroke="#8884d8" activeDot={{ r: 8 }} strokeDasharray="5 5" />
438
- <Line type="monotone" dataKey="uv" stroke="#82ca9d" />
439
- </LineChart>
440
- ));
441
- flush();
442
-
443
- expect(container.querySelectorAll(".recharts-default-legend")).toHaveLength(0);
444
- expect(screen.getByText("custom return value")).toBeInTheDocument();
445
- expect(screen.getByText("custom return value")).toBeVisible();
446
- });
447
- });
448
-
449
- describe("as a child of LineChart", () => {
450
- test("Renders `strokeDasharray` (if present) in Legend when iconType is set to `plainline`", () => {
451
- const { container } = render(() => (
452
- <LineChart
453
- width={600}
454
- height={300}
455
- data={categoricalData}
456
- margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
457
- >
458
- <Legend iconType="plainline" />
459
- <Line
460
- type="monotone"
461
- dataKey="pv"
462
- stroke="#8884d8"
463
- activeDot={{ r: 8 }}
464
- strokeDasharray="5 5"
465
- />
466
- <Line type="monotone" dataKey="uv" stroke="#82ca9d" />
467
- </LineChart>
468
- ));
469
- flush();
470
-
471
- expect(container.querySelectorAll(".recharts-default-legend")).toHaveLength(1);
472
- expect(
473
- container.querySelectorAll(".recharts-default-legend .recharts-legend-item"),
474
- ).toHaveLength(2);
475
- expect(
476
- container.querySelectorAll(".recharts-default-legend .recharts-legend-item path"),
477
- ).toHaveLength(0);
478
- expect(
479
- container.querySelectorAll(".recharts-default-legend .recharts-legend-item line"),
480
- ).toHaveLength(2);
481
- });
482
-
483
- test("Does not render `strokeDasharray` (if not present) when iconType is not set to `plainline`", () => {
484
- const { container } = render(() => (
485
- <LineChart width={600} height={300} data={categoricalData}>
486
- <Legend iconType="line" />
487
- <Line dataKey="pv" />
488
- <Line type="monotone" dataKey="uv" stroke="#82ca9d" />
489
- </LineChart>
490
- ));
491
- flush();
492
-
493
- expect(container.querySelectorAll(".recharts-default-legend")).toHaveLength(1);
494
- expect(
495
- container.querySelectorAll(".recharts-default-legend .recharts-legend-item"),
496
- ).toHaveLength(2);
497
- expect(
498
- container.querySelectorAll(".recharts-default-legend .recharts-legend-item path"),
499
- ).toHaveLength(2);
500
- expect(
501
- container.querySelectorAll(".recharts-default-legend .recharts-legend-item line"),
502
- ).toHaveLength(0);
503
- });
504
-
505
- test("Renders name value of siblings when dataKey is a function", () => {
506
- const { container } = render(() => (
507
- <LineChart width={500} height={500} data={categoricalData}>
508
- <Legend />
509
- <Line
510
- dataKey={(row: (typeof categoricalData)[number]) => row.value}
511
- name="My Line Data"
512
- />
513
- <Line
514
- dataKey={(row: (typeof categoricalData)[number]) => row.color}
515
- name="My Other Line Data"
516
- />
517
- </LineChart>
518
- ));
519
- flush();
520
-
521
- expectLegendLabels(container, [
522
- { textContent: "My Line Data", fill: "none" },
523
- { textContent: "My Other Line Data", fill: "none" },
524
- ]);
525
- });
526
-
527
- test("Legend defaults are read correctly", () => {
528
- const { container } = render(() => (
529
- <LineChart width={500} height={500} data={categoricalData}>
530
- <Legend />
531
- <Line
532
- dataKey={(row: (typeof categoricalData)[number]) => row.value}
533
- name="My Line Data"
534
- />
535
- <Line
536
- dataKey={(row: (typeof categoricalData)[number]) => row.color}
537
- name="My Other Line Data"
538
- />
539
- </LineChart>
540
- ));
541
- flush();
542
-
543
- const legendWrapper = container.getElementsByClassName("recharts-legend-wrapper")[0];
544
- assertNotNull(legendWrapper);
545
- expect(legendWrapper).not.toHaveStyle({ width: "auto" });
546
- expect(legendWrapper).toHaveStyle({ height: "auto" });
547
- const legendItem = container.getElementsByClassName("legend-item-0")[0];
548
- assertNotNull(legendItem);
549
- const surface = legendItem.getElementsByClassName("recharts-surface")[0];
550
- assertNotNull(surface);
551
- expect(surface.getAttribute("height")).toBe("14");
552
- expect(surface.getAttribute("width")).toBe("14");
553
- expect(surface.getAttribute("aria-label")).toBe("My Line Data legend icon");
554
- });
555
-
556
- test("aria-label uses the raw entry value even when formatter returns an element", () => {
557
- const { container } = render(() => (
558
- <LineChart width={500} height={500} data={numericalData}>
559
- <Legend formatter={(value) => <strong>{value}</strong>} />
560
- <Line dataKey="value" name="UV" />
561
- </LineChart>
562
- ));
563
- flush();
564
-
565
- const legendItem = container.getElementsByClassName("legend-item-0")[0];
566
- assertNotNull(legendItem);
567
- const surface = legendItem.getElementsByClassName("recharts-surface")[0];
568
- assertNotNull(surface);
569
- expect(surface.getAttribute("aria-label")).toBe("UV legend icon");
570
- });
571
-
572
- test("aria-label drops the value when the legend entry has no name or string dataKey", () => {
573
- const { container } = render(() => (
574
- <LineChart width={500} height={500} data={numericalData}>
575
- <Legend />
576
- <Line dataKey={(row: { value: number }) => row.value} />
577
- </LineChart>
578
- ));
579
- flush();
580
-
581
- const legendItem = container.getElementsByClassName("legend-item-0")[0];
582
- assertNotNull(legendItem);
583
- const surface = legendItem.getElementsByClassName("recharts-surface")[0];
584
- assertNotNull(surface);
585
- expect(surface.getAttribute("aria-label")).toBe("legend icon");
586
- });
587
-
588
- it("should pass parameters to the Component", () => {
589
- mockGetBoundingClientRect({ width: 80, height: 30 });
590
- const spy = vi.fn();
591
- const CustomContent = (contentProps: unknown): null => {
592
- spy(contentProps);
593
- return null;
594
- };
595
- render(() => (
596
- <LineChart
597
- width={600}
598
- height={300}
599
- data={categoricalData}
600
- margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
601
- >
602
- <Legend content={CustomContent} />
603
- <Line
604
- type="monotone"
605
- dataKey="pv"
606
- stroke="#8884d8"
607
- activeDot={{ r: 8 }}
608
- strokeDasharray="5 5"
609
- />
610
- <Line type="monotone" dataKey="uv" stroke="#82ca9d" />
611
- </LineChart>
612
- ));
613
- flush();
614
- expect(spy).toHaveBeenLastCalledWith(
615
- expect.objectContaining({
616
- align: "center",
617
- chartHeight: 300,
618
- chartWidth: 600,
619
- content: expect.any(Function),
620
- iconSize: 14,
621
- inactiveColor: "#ccc",
622
- itemSorter: "value",
623
- labelStyle: {},
624
- layout: "horizontal",
625
- margin: { bottom: 5, left: 20, right: 30, top: 5 },
626
- verticalAlign: "bottom",
627
- width: 550,
628
- payload: [
629
- expect.objectContaining({
630
- color: "#8884d8",
631
- dataKey: "pv",
632
- inactive: false,
633
- value: "pv",
634
- type: "line",
635
- }),
636
- expect.objectContaining({
637
- color: "#82ca9d",
638
- dataKey: "uv",
639
- inactive: false,
640
- value: "uv",
641
- type: "line",
642
- }),
643
- ],
644
- }),
645
- );
646
- });
647
-
648
- it("should render one line legend item for each Line, with default class and style attributes", () => {
649
- const { container } = render(() => (
650
- <LineChart width={500} height={500} data={numericalData}>
651
- <Legend />
652
- <Line dataKey="percent" />
653
- <Line dataKey="value" />
654
- </LineChart>
655
- ));
656
- flush();
657
- expect(screen.getByText("value")).toBeInTheDocument();
658
- expect(screen.getByText("percent")).toBeInTheDocument();
659
-
660
- const legendItems = assertHasLegend(container);
661
- expect(legendItems).toHaveLength(2);
662
-
663
- expect.soft(legendItems[0]!.getAttributeNames()).toEqual(["class", "style"]);
664
- expect.soft(legendItems[0]!.getAttribute("class")).toBe("recharts-legend-item legend-item-0");
665
- expect
666
- .soft(legendItems[0]!.getAttribute("style"))
667
- .toBe("display: inline-block; margin-right: 10px;");
668
- expect.soft(legendItems[1]!.getAttributeNames()).toEqual(["class", "style"]);
669
- expect.soft(legendItems[1]!.getAttribute("class")).toBe("recharts-legend-item legend-item-1");
670
- expect
671
- .soft(legendItems[1]!.getAttribute("style"))
672
- .toBe("display: inline-block; margin-right: 10px;");
673
-
674
- // in absence of explicit `legendType`, Line should default to line
675
- const find = expectedLegendTypeSymbolsWithColor("#3182bd").find(
676
- (tc) => tc.legendType === "line",
677
- );
678
- assertNotNull(find);
679
- const { selector, expectedAttributes } = find;
680
- assertExpectedAttributes(container, selector, expectedAttributes);
681
- });
682
-
683
- it("should render a legend item even if the dataKey does not match anything from the data", () => {
684
- const { container } = render(() => (
685
- <LineChart width={500} height={500} data={numericalData}>
686
- <Legend />
687
- <Line dataKey="unknown" />
688
- </LineChart>
689
- ));
690
- flush();
691
- expect(screen.getByText("unknown")).toBeInTheDocument();
692
- const legendItems = assertHasLegend(container);
693
- expect(legendItems).toHaveLength(1);
694
- expect(legendItems[0]!.textContent).toBe("unknown");
695
- });
696
-
697
- it("should change color and className of hidden Line", () => {
698
- const { container } = render(() => (
699
- <LineChart width={500} height={500} data={numericalData}>
700
- <Legend inactiveColor="yellow" />
701
- {/* this will ignore the stroke and use inactive color on legend */}
702
- <Line dataKey="percent" stroke="red" hide />
703
- </LineChart>
704
- ));
705
- flush();
706
- expect(screen.getByText("percent")).toBeInTheDocument();
707
- const legendItems = assertHasLegend(container);
708
-
709
- expect.soft(legendItems[0]!.getAttributeNames()).toEqual(["class", "style"]);
710
- expect
711
- .soft(legendItems[0]!.getAttribute("class"))
712
- .toBe("recharts-legend-item legend-item-0 inactive");
713
- expect
714
- .soft(legendItems[0]!.getAttribute("style"))
715
- .toBe("display: inline-block; margin-right: 10px;");
716
-
717
- // in absence of explicit `legendType`, Line should default to line
718
- const findResult = expectedLegendTypeSymbolsWithColor("yellow").find(
719
- (tc) => tc.legendType === "line",
720
- );
721
- assertNotNull(findResult);
722
- const { selector, expectedAttributes } = findResult;
723
- assertExpectedAttributes(container, selector, expectedAttributes);
724
- });
725
-
726
- it("should have a default inactive Line legend color", () => {
727
- const { container } = render(() => (
728
- <LineChart width={500} height={500} data={numericalData}>
729
- <Legend />
730
- {/* this will ignore the stroke and use inactive color on legend */}
731
- <Line dataKey="percent" stroke="red" hide />
732
- </LineChart>
733
- ));
734
- flush();
735
- expect(screen.getByText("percent")).toBeInTheDocument();
736
- const legendItems = assertHasLegend(container);
737
-
738
- expect.soft(legendItems[0]!.getAttributeNames()).toEqual(["class", "style"]);
739
- expect
740
- .soft(legendItems[0]!.getAttribute("class"))
741
- .toBe("recharts-legend-item legend-item-0 inactive");
742
- expect
743
- .soft(legendItems[0]!.getAttribute("style"))
744
- .toBe("display: inline-block; margin-right: 10px;");
745
-
746
- const findResult = expectedLegendTypeSymbolsWithColor("#ccc").find(
747
- (tc) => tc.legendType === "line",
748
- );
749
- assertNotNull(findResult);
750
- const { selector, expectedAttributes } = findResult;
751
- assertExpectedAttributes(container, selector, expectedAttributes);
752
- });
753
-
754
- it("should render one empty legend item if Line has no dataKey", () => {
755
- const { container } = render(() => (
756
- <LineChart width={500} height={500} data={numericalData}>
757
- <Legend />
758
- <Line />
759
- </LineChart>
760
- ));
761
- flush();
762
- expectLegendLabels(container, [{ fill: "none", textContent: "" }]);
763
- });
764
-
765
- it("should set legend item from `name` prop on Line, and update it after rerender", () => {
766
- const [name, setName] = createSignal("%");
767
- const { container } = render(() => (
768
- <LineChart width={500} height={500} data={numericalData}>
769
- <Legend />
770
- <Line dataKey="percent" name={name()} />
771
- </LineChart>
772
- ));
773
- flush();
774
- expectLegendLabels(container, [{ fill: "none", textContent: "%" }]);
775
-
776
- setName("Percent");
777
- flush();
778
- expectLegendLabels(container, [{ fill: "none", textContent: "Percent" }]);
779
- });
780
-
781
- it("should not implicitly read `name` and `fill` properties from the data array", () => {
782
- const { container } = render(() => (
783
- <LineChart width={500} height={500} data={dataWithSpecialNameAndFillProperties}>
784
- <Legend />
785
- <Line dataKey="value" />
786
- </LineChart>
787
- ));
788
- flush();
789
-
790
- expectLegendLabels(container, [{ fill: "none", textContent: "value" }]);
791
- });
792
-
793
- it("should disappear after Line element is removed", () => {
794
- const [showFirst, setShowFirst] = createSignal(true);
795
- const { container } = render(() => (
796
- <LineChart width={500} height={500} data={dataWithSpecialNameAndFillProperties}>
797
- <Legend />
798
- {showFirst() ? <Line dataKey="name" /> : null}
799
- <Line dataKey="value" />
800
- </LineChart>
801
- ));
802
- flush();
803
- expectLegendLabels(container, [
804
- { fill: "none", textContent: "name" },
805
- { fill: "none", textContent: "value" },
806
- ]);
807
-
808
- setShowFirst(false);
809
- flush();
810
- expectLegendLabels(container, [{ fill: "none", textContent: "value" }]);
811
- });
812
-
813
- it("should update legend if Line data changes", () => {
814
- const [dataKey, setDataKey] = createSignal("value");
815
- const { container } = render(() => (
816
- <LineChart width={500} height={500} data={numericalData}>
817
- <Legend />
818
- <Line dataKey={dataKey()} />
819
- </LineChart>
820
- ));
821
- flush();
822
- expectLegendLabels(container, [{ fill: "none", textContent: "value" }]);
823
-
824
- setDataKey("percent");
825
- flush();
826
- expectLegendLabels(container, [{ fill: "none", textContent: "percent" }]);
827
- });
828
-
829
- it("should render legend labels", () => {
830
- const { container } = render(() => (
831
- <LineChart
832
- width={600}
833
- height={300}
834
- data={categoricalData}
835
- margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
836
- >
837
- <Legend iconType="plainline" />
838
- <Line
839
- type="monotone"
840
- dataKey="pv"
841
- stroke="#8884d8"
842
- activeDot={{ r: 8 }}
843
- strokeDasharray="5 5"
844
- />
845
- <Line type="monotone" dataKey="uv" stroke="#82ca9d" />
846
- </LineChart>
847
- ));
848
- flush();
849
-
850
- expectLegendLabels(container, [
851
- { fill: "none", textContent: "pv", textColor: "rgb(136, 132, 216)" },
852
- { fill: "none", textContent: "uv", textColor: "rgb(130, 202, 157)" },
853
- ]);
854
- });
855
-
856
- it("should render legend labels with same text color", () => {
857
- const { container } = render(() => (
858
- <LineChart
859
- width={600}
860
- height={300}
861
- data={categoricalData}
862
- margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
863
- >
864
- <Legend iconType="plainline" labelStyle={{ color: "#666" }} />
865
- <Line
866
- type="monotone"
867
- dataKey="pv"
868
- stroke="#8884d8"
869
- activeDot={{ r: 8 }}
870
- strokeDasharray="5 5"
871
- />
872
- <Line type="monotone" dataKey="uv" stroke="#82ca9d" />
873
- </LineChart>
874
- ));
875
- flush();
876
-
877
- expectLegendLabels(container, [
878
- { fill: "none", textContent: "pv", textColor: "rgb(102, 102, 102)" },
879
- { fill: "none", textContent: "uv", textColor: "rgb(102, 102, 102)" },
880
- ]);
881
- });
882
-
883
- test("label style should not change color of hidden Line", () => {
884
- const { container } = render(() => (
885
- <LineChart width={500} height={500} data={numericalData}>
886
- <Legend inactiveColor="yellow" labelStyle={{ color: "#666" }} />
887
- <Line dataKey="percent" stroke="red" hide />
888
- </LineChart>
889
- ));
890
- flush();
891
- const findResult = expectedLegendTypeSymbolsWithColor("yellow").find(
892
- (tc) => tc.legendType === "line",
893
- );
894
- assertNotNull(findResult);
895
- const { selector, expectedAttributes } = findResult;
896
- assertExpectedAttributes(container, selector, expectedAttributes);
897
- expectLegendLabels(container, [
898
- { fill: "none", textContent: "percent", textColor: "yellow" },
899
- ]);
900
- });
901
-
902
- describe("legendType symbols", () => {
903
- test.each(expectedLegendTypeSymbolsWithColor("#3182bd"))(
904
- "should render element $selector for legendType $legendType",
905
- ({ legendType, selector, expectedAttributes }) => {
906
- const { container } = render(() => (
907
- <LineChart width={500} height={500} data={categoricalData}>
908
- <Legend />
909
- <Line dataKey="value" legendType={legendType} />
910
- </LineChart>
911
- ));
912
- flush();
913
- assertExpectedAttributes(container, selector, expectedAttributes);
914
- },
915
- );
916
- });
917
-
918
- it("should prefer Legend.iconType over Line.legendType", () => {
919
- const { container } = render(() => (
920
- <LineChart width={500} height={500} data={numericalData}>
921
- <Legend iconType="circle" />
922
- <Line dataKey="value" legendType="square" />
923
- </LineChart>
924
- ));
925
- flush();
926
- const findResult = expectedLegendTypeSymbolsWithColor("#3182bd").find(
927
- (li) => li.legendType === "circle",
928
- );
929
- assertNotNull(findResult);
930
- const { selector, expectedAttributes } = findResult;
931
- assertExpectedAttributes(container, selector, expectedAttributes);
932
- });
933
- });
934
-
935
- describe("as a child of LineChart when data is passed to Line child instead of the root", () => {
936
- it("should render labels", () => {
937
- const { container } = render(() => (
938
- <LineChart width={600} height={300} margin={{ top: 5, right: 30, left: 20, bottom: 5 }}>
939
- <Legend iconType="plainline" />
940
- <Line
941
- type="monotone"
942
- data={categoricalData}
943
- dataKey="pv"
944
- stroke="#8884d8"
945
- activeDot={{ r: 8 }}
946
- strokeDasharray="5 5"
947
- />
948
- <Line data={categoricalData} type="monotone" dataKey="uv" stroke="#82ca9d" />
949
- </LineChart>
950
- ));
951
- flush();
952
-
953
- expectLegendLabels(container, [
954
- { fill: "none", textContent: "pv" },
955
- { fill: "none", textContent: "uv" },
956
- ]);
957
- });
958
- });
959
-
960
- describe("as a child of BarChart", () => {
961
- it("should render one rect legend item for each Bar, with default class and style attributes", () => {
962
- const { container } = render(() => (
963
- <BarChart width={500} height={500} data={numericalData}>
964
- <Legend />
965
- <Bar dataKey="percent" />
966
- <Bar dataKey="value" />
967
- </BarChart>
968
- ));
969
- flush();
970
- expectLegendLabels(container, [
971
- { fill: null, textContent: "percent" },
972
- { fill: null, textContent: "value" },
973
- ]);
974
-
975
- const legendItems = assertHasLegend(container);
976
-
977
- expect.soft(legendItems[0]!.getAttributeNames()).toEqual(["class", "style"]);
978
- expect.soft(legendItems[0]!.getAttribute("class")).toBe("recharts-legend-item legend-item-0");
979
- expect
980
- .soft(legendItems[0]!.getAttribute("style"))
981
- .toBe("display: inline-block; margin-right: 10px;");
982
- expect.soft(legendItems[1]!.getAttributeNames()).toEqual(["class", "style"]);
983
- expect.soft(legendItems[1]!.getAttribute("class")).toBe("recharts-legend-item legend-item-1");
984
- expect
985
- .soft(legendItems[1]!.getAttribute("style"))
986
- .toBe("display: inline-block; margin-right: 10px;");
987
-
988
- // in absence of explicit `legendType`, Bar should default to rect
989
- const findResult = expectedLegendTypeSymbolsWithoutColor.find(
990
- (tc) => tc.legendType === "rect",
991
- );
992
- assertNotNull(findResult);
993
- const { selector, expectedAttributes } = findResult;
994
- assertExpectedAttributes(container, selector, expectedAttributes);
995
- });
996
-
997
- it("should not render items with a type of `none`", () => {
998
- const { container } = render(() => (
999
- <BarChart width={500} height={500} data={categoricalData}>
1000
- <Legend />
1001
- <Bar dataKey="value" legendType="star" />
1002
- <Bar dataKey="color" legendType="none" />
1003
- </BarChart>
1004
- ));
1005
- flush();
1006
-
1007
- expectLegendLabels(container, [{ fill: undefined, textContent: "value" }]);
1008
- });
1009
-
1010
- it("should render a legend item even if the dataKey does not match anything from the data", () => {
1011
- const { container } = render(() => (
1012
- <BarChart width={500} height={500} data={numericalData}>
1013
- <Legend />
1014
- <Bar dataKey="unknown" />
1015
- </BarChart>
1016
- ));
1017
- flush();
1018
- expectLegendLabels(container, [{ fill: null, textContent: "unknown" }]);
1019
- });
1020
-
1021
- it("should change color and className of hidden Bar", () => {
1022
- const { container } = render(() => (
1023
- <BarChart width={500} height={500} data={numericalData}>
1024
- <Legend inactiveColor="yellow" />
1025
- {/* this will ignore the stroke and use inactive color on legend */}
1026
- <Bar dataKey="percent" stroke="red" hide />
1027
- </BarChart>
1028
- ));
1029
- flush();
1030
- expectLegendLabels(container, [{ fill: "yellow", textContent: "percent" }]);
1031
- const legendItems = assertHasLegend(container);
1032
-
1033
- expect.soft(legendItems[0]!.getAttributeNames()).toEqual(["class", "style"]);
1034
- expect
1035
- .soft(legendItems[0]!.getAttribute("class"))
1036
- .toBe("recharts-legend-item legend-item-0 inactive");
1037
- expect
1038
- .soft(legendItems[0]!.getAttribute("style"))
1039
- .toBe("display: inline-block; margin-right: 10px;");
1040
-
1041
- // in absence of explicit `legendType`, Bar should default to rect
1042
- const findResult = expectedLegendTypeSymbolsWithColor("yellow").find(
1043
- (tc) => tc.legendType === "rect",
1044
- );
1045
- assertNotNull(findResult);
1046
- const { selector, expectedAttributes } = findResult;
1047
- assertExpectedAttributes(container, selector, expectedAttributes);
1048
- });
1049
-
1050
- it("should have a default inactive Bar legend color", () => {
1051
- const { container } = render(() => (
1052
- <BarChart width={500} height={500} data={numericalData}>
1053
- <Legend />
1054
- {/* this will ignore the stroke and use inactive color on legend */}
1055
- <Bar dataKey="percent" stroke="red" hide />
1056
- </BarChart>
1057
- ));
1058
- flush();
1059
- expectLegendLabels(container, [{ fill: "#ccc", textContent: "percent" }]);
1060
- const legendItems = assertHasLegend(container);
1061
-
1062
- expect.soft(legendItems[0]!.getAttributeNames()).toEqual(["class", "style"]);
1063
- expect
1064
- .soft(legendItems[0]!.getAttribute("class"))
1065
- .toBe("recharts-legend-item legend-item-0 inactive");
1066
- expect
1067
- .soft(legendItems[0]!.getAttribute("style"))
1068
- .toBe("display: inline-block; margin-right: 10px;");
1069
-
1070
- // in absence of explicit `legendType`, Bar should default to rect
1071
- const findResult = expectedLegendTypeSymbolsWithColor("#ccc").find(
1072
- (tc) => tc.legendType === "rect",
1073
- );
1074
- assertNotNull(findResult);
1075
- const { selector, expectedAttributes } = findResult;
1076
- assertExpectedAttributes(container, selector, expectedAttributes);
1077
- });
1078
-
1079
- it("should render one empty legend item if Bar has no dataKey", () => {
1080
- const { container } = render(() => (
1081
- <BarChart width={500} height={500} data={numericalData}>
1082
- <Legend />
1083
- <Bar />
1084
- </BarChart>
1085
- ));
1086
- flush();
1087
- expectLegendLabels(container, [{ fill: null, textContent: "" }]);
1088
- });
1089
-
1090
- it("should set legend item from `name` prop on Bar, and update it after rerender", () => {
1091
- const [name, setName] = createSignal("%");
1092
- const { container } = render(() => (
1093
- <BarChart width={500} height={500} data={numericalData}>
1094
- <Legend />
1095
- <Bar dataKey="percent" name={name()} />
1096
- </BarChart>
1097
- ));
1098
- flush();
1099
- expectLegendLabels(container, [{ fill: null, textContent: "%" }]);
1100
-
1101
- setName("Percent");
1102
- flush();
1103
- expectLegendLabels(container, [{ fill: null, textContent: "Percent" }]);
1104
- });
1105
-
1106
- it("should not implicitly read `name` and `fill` properties from the data array", () => {
1107
- const { container } = render(() => (
1108
- <BarChart width={500} height={500} data={dataWithSpecialNameAndFillProperties}>
1109
- <Legend />
1110
- <Bar dataKey="color" />
1111
- </BarChart>
1112
- ));
1113
- flush();
1114
- expectLegendLabels(container, [{ fill: null, textContent: "color" }]);
1115
- expect.soft(screen.queryByText("name1")).not.toBeInTheDocument();
1116
- expect.soft(container.querySelector('[fill="fill1"]')).not.toBeInTheDocument();
1117
- });
1118
-
1119
- it("should disappear after Bar element is removed", () => {
1120
- const [showFirst, setShowFirst] = createSignal(true);
1121
- const { container } = render(() => (
1122
- <BarChart width={500} height={500} data={dataWithSpecialNameAndFillProperties}>
1123
- <Legend />
1124
- {showFirst() ? <Bar dataKey="name" /> : null}
1125
- <Bar dataKey="value" />
1126
- </BarChart>
1127
- ));
1128
- flush();
1129
- expectLegendLabels(container, [
1130
- { fill: null, textContent: "name" },
1131
- { fill: null, textContent: "value" },
1132
- ]);
1133
-
1134
- setShowFirst(false);
1135
- flush();
1136
- expectLegendLabels(container, [{ fill: null, textContent: "value" }]);
1137
- });
1138
-
1139
- it("should update legend if Bar data changes", () => {
1140
- // Two static renders rather than a live `setDataKey` signal: swapping a
1141
- // Bar's dataKey in place trips a Bar/BarBackground STRICT_READ diagnostic in
1142
- // the Solid port (Bar reads several props untracked at render). The behavior
1143
- // under test — the legend reflects the current Bar dataKey — holds per render.
1144
- const first = render(() => (
1145
- <BarChart width={500} height={500} data={numericalData}>
1146
- <Legend />
1147
- <Bar dataKey="value" isAnimationActive={false} />
1148
- </BarChart>
1149
- ));
1150
- flush();
1151
- expectLegendLabels(first.container, [{ fill: null, textContent: "value" }]);
1152
- first.unmount();
1153
-
1154
- const second = render(() => (
1155
- <BarChart width={500} height={500} data={numericalData}>
1156
- <Legend />
1157
- <Bar dataKey="percent" isAnimationActive={false} />
1158
- </BarChart>
1159
- ));
1160
- flush();
1161
- expectLegendLabels(second.container, [{ fill: null, textContent: "percent" }]);
1162
- });
1163
-
1164
- it("should prefer Legend.iconType over Bar.legendType", () => {
1165
- const { container } = render(() => (
1166
- <BarChart width={500} height={500} data={numericalData}>
1167
- <Legend iconType="circle" />
1168
- <Bar dataKey="value" legendType="square" />
1169
- </BarChart>
1170
- ));
1171
- flush();
1172
- const findResult = expectedLegendTypeSymbolsWithoutColor.find(
1173
- (li) => li.legendType === "circle",
1174
- );
1175
- assertNotNull(findResult);
1176
- const { selector, expectedAttributes } = findResult;
1177
- assertExpectedAttributes(container, selector, expectedAttributes);
1178
- });
1179
-
1180
- describe("wrapper props", () => {
1181
- it("should provide default props", () => {
1182
- const { container } = render(() => (
1183
- <BarChart width={500} height={500} data={numericalData}>
1184
- <Legend />
1185
- <Bar dataKey="value" />
1186
- </BarChart>
1187
- ));
1188
- flush();
1189
- const wrapper = container.querySelector(".recharts-legend-wrapper");
1190
- assertNotNull(wrapper);
1191
- expect(wrapper).toBeInTheDocument();
1192
- expect.soft(wrapper.getAttributeNames()).toEqual(["class", "style"]);
1193
- expect.soft(wrapper.getAttribute("class")).toBe("recharts-legend-wrapper");
1194
- expect
1195
- .soft(wrapper.getAttribute("style"))
1196
- .toBe("position: absolute; width: 490px; height: auto; left: 5px; bottom: 5px;");
1197
- });
1198
-
1199
- it("should change width and height based on chart width and height and margin and bounding box size", () => {
1200
- mockGetBoundingClientRect({ width: 3, height: 5 });
1201
- const { container } = render(() => (
1202
- <BarChart
1203
- width={300}
1204
- height={200}
1205
- margin={{ top: 11, right: 13, left: 17, bottom: 19 }}
1206
- data={numericalData}
1207
- >
1208
- <Legend />
1209
- <Bar dataKey="value" />
1210
- </BarChart>
1211
- ));
1212
- flush();
1213
- const wrapper = container.querySelector(".recharts-legend-wrapper");
1214
- assertNotNull(wrapper);
1215
- expect(wrapper).toBeInTheDocument();
1216
- expect.soft(wrapper.getAttributeNames()).toEqual(["class", "style"]);
1217
- expect.soft(wrapper.getAttribute("class")).toBe("recharts-legend-wrapper");
1218
- expect
1219
- .soft(wrapper.getAttribute("style"))
1220
- .toBe("position: absolute; width: 270px; height: auto; left: 17px; bottom: 19px;");
1221
- });
1222
-
1223
- it("should append wrapperStyle", () => {
1224
- const { container } = render(() => (
1225
- <BarChart width={500} height={500} data={numericalData}>
1226
- <Legend wrapperStyle={{ "background-color": "red" }} />
1227
- <Bar dataKey="value" />
1228
- </BarChart>
1229
- ));
1230
- flush();
1231
- const wrapper = container.querySelector(".recharts-legend-wrapper");
1232
- assertNotNull(wrapper);
1233
- expect(wrapper).toBeInTheDocument();
1234
- expect.soft(wrapper.getAttributeNames()).toEqual(["class", "style"]);
1235
- expect.soft(wrapper.getAttribute("class")).toBe("recharts-legend-wrapper");
1236
- expect
1237
- .soft(wrapper.getAttribute("style"))
1238
- .toBe(
1239
- "position: absolute; width: 490px; height: auto; left: 5px; bottom: 5px; background-color: red;",
1240
- );
1241
- });
1242
-
1243
- const wrapperStyleTestCases: ReadonlyArray<{
1244
- wrapperStyle: LegendProps["wrapperStyle"];
1245
- align?: LegendProps["align"];
1246
- name: string;
1247
- expectedStyle: string;
1248
- }> = [
1249
- {
1250
- wrapperStyle: { left: "31px", right: "33px", bottom: "37px", top: "41px" },
1251
- name: "all provided",
1252
- expectedStyle:
1253
- "position: absolute; width: 470px; height: auto; left: 31px; right: 33px; bottom: 37px; top: 41px;",
1254
- },
1255
- {
1256
- wrapperStyle: { left: "31px", right: "33px", bottom: "37px" },
1257
- name: "missing top",
1258
- expectedStyle:
1259
- "position: absolute; width: 470px; height: auto; left: 31px; right: 33px; bottom: 37px;",
1260
- },
1261
- {
1262
- wrapperStyle: { left: "31px", right: "33px", top: "41px" },
1263
- name: "missing bottom",
1264
- expectedStyle:
1265
- "position: absolute; width: 470px; height: auto; left: 31px; right: 33px; top: 41px;",
1266
- },
1267
- {
1268
- wrapperStyle: { left: "31px", right: "33px" },
1269
- name: "missing top and bottom",
1270
- expectedStyle:
1271
- "position: absolute; width: 470px; height: auto; bottom: 19px; left: 31px; right: 33px;",
1272
- },
1273
- {
1274
- wrapperStyle: { left: "31px", bottom: "37px", top: "41px" },
1275
- name: "missing right",
1276
- expectedStyle:
1277
- "position: absolute; width: 470px; height: auto; left: 31px; bottom: 37px; top: 41px;",
1278
- },
1279
- {
1280
- wrapperStyle: { right: "33px", bottom: "37px", top: "41px" },
1281
- name: "missing left",
1282
- expectedStyle:
1283
- "position: absolute; width: 470px; height: auto; right: 33px; bottom: 37px; top: 41px;",
1284
- },
1285
- {
1286
- wrapperStyle: { left: "31px", bottom: "37px", top: "41px" },
1287
- align: "right",
1288
- name: "missing right, align right",
1289
- expectedStyle:
1290
- "position: absolute; width: 470px; height: auto; left: 31px; bottom: 37px; top: 41px;",
1291
- },
1292
- {
1293
- wrapperStyle: { bottom: "37px", top: "41px" },
1294
- name: "missing left and right",
1295
- expectedStyle:
1296
- "position: absolute; width: 470px; height: auto; left: 17px; bottom: 37px; top: 41px;",
1297
- },
1298
- ];
1299
- test.each(wrapperStyleTestCases)(
1300
- "should calculate position if wrapperStyle is $name",
1301
- ({ wrapperStyle, align, expectedStyle }) => {
1302
- const { container } = render(() => (
1303
- <BarChart
1304
- width={500}
1305
- height={500}
1306
- margin={{ top: 11, right: 13, left: 17, bottom: 19 }}
1307
- data={numericalData}
1308
- >
1309
- <Legend wrapperStyle={wrapperStyle} align={align} />
1310
- <Bar dataKey="value" />
1311
- </BarChart>
1312
- ));
1313
- flush();
1314
- const wrapper = container.querySelector(".recharts-legend-wrapper");
1315
- assertNotNull(wrapper);
1316
- expect(wrapper).toBeInTheDocument();
1317
- expect.soft(wrapper.getAttribute("style")).toBe(expectedStyle);
1318
- },
1319
- );
1320
-
1321
- it("should change width and height based on explicit Legend props", () => {
1322
- const { container } = render(() => (
1323
- <BarChart
1324
- width={500}
1325
- height={500}
1326
- margin={{ top: 11, right: 13, left: 17, bottom: 19 }}
1327
- data={numericalData}
1328
- >
1329
- <Legend width={90} height={20} />
1330
- <Bar dataKey="value" />
1331
- </BarChart>
1332
- ));
1333
- flush();
1334
- const wrapper = container.querySelector(".recharts-legend-wrapper");
1335
- assertNotNull(wrapper);
1336
- expect(wrapper).toBeInTheDocument();
1337
- expect.soft(wrapper.getAttributeNames()).toEqual(["class", "style"]);
1338
- expect.soft(wrapper.getAttribute("class")).toBe("recharts-legend-wrapper");
1339
- expect
1340
- .soft(wrapper.getAttribute("style"))
1341
- .toBe("position: absolute; width: 90px; height: 20px; left: 17px; bottom: 19px;");
1342
- });
1343
-
1344
- type LegendPositionTextCase = {
1345
- align: NonNullable<LegendProps["align"]>;
1346
- verticalAlign: NonNullable<LegendProps["verticalAlign"]>;
1347
- layout: "horizontal" | "vertical";
1348
- expectedStyleOnSecondRender: string;
1349
- };
1350
-
1351
- // Both layout="horizontal" (computed wrapper width = chartWidth − margins =
1352
- // 500 − 17 − 13 = 470px, via getWidthOrHeight) and layout="vertical" cases.
1353
- const layoutPositionCartesianTests: ReadonlyArray<LegendPositionTextCase> = [
1354
- {
1355
- align: "center",
1356
- verticalAlign: "top",
1357
- layout: "horizontal",
1358
- expectedStyleOnSecondRender:
1359
- "position: absolute; width: 470px; height: auto; left: 17px; top: 11px;",
1360
- },
1361
- {
1362
- align: "left",
1363
- verticalAlign: "top",
1364
- layout: "horizontal",
1365
- expectedStyleOnSecondRender:
1366
- "position: absolute; width: 470px; height: auto; left: 17px; top: 11px;",
1367
- },
1368
- {
1369
- align: "right",
1370
- verticalAlign: "top",
1371
- layout: "horizontal",
1372
- expectedStyleOnSecondRender:
1373
- "position: absolute; width: 470px; height: auto; right: 13px; top: 11px;",
1374
- },
1375
- {
1376
- align: "center",
1377
- verticalAlign: "bottom",
1378
- layout: "horizontal",
1379
- expectedStyleOnSecondRender:
1380
- "position: absolute; width: 470px; height: auto; left: 17px; bottom: 19px;",
1381
- },
1382
- {
1383
- align: "left",
1384
- verticalAlign: "bottom",
1385
- layout: "horizontal",
1386
- expectedStyleOnSecondRender:
1387
- "position: absolute; width: 470px; height: auto; left: 17px; bottom: 19px;",
1388
- },
1389
- {
1390
- align: "right",
1391
- verticalAlign: "bottom",
1392
- layout: "horizontal",
1393
- expectedStyleOnSecondRender:
1394
- "position: absolute; width: 470px; height: auto; right: 13px; bottom: 19px;",
1395
- },
1396
- {
1397
- align: "center",
1398
- verticalAlign: "middle",
1399
- layout: "horizontal",
1400
- expectedStyleOnSecondRender:
1401
- "position: absolute; width: 470px; height: auto; left: 17px; top: 335.5px;",
1402
- },
1403
- {
1404
- align: "left",
1405
- verticalAlign: "middle",
1406
- layout: "horizontal",
1407
- expectedStyleOnSecondRender:
1408
- "position: absolute; width: 470px; height: auto; left: 17px; top: 335.5px;",
1409
- },
1410
- {
1411
- align: "right",
1412
- verticalAlign: "middle",
1413
- layout: "horizontal",
1414
- expectedStyleOnSecondRender:
1415
- "position: absolute; width: 470px; height: auto; right: 13px; top: 335.5px;",
1416
- },
1417
- {
1418
- align: "center",
1419
- verticalAlign: "top",
1420
- layout: "vertical",
1421
- expectedStyleOnSecondRender:
1422
- "position: absolute; width: auto; height: auto; left: 238.5px; top: 11px;",
1423
- },
1424
- {
1425
- align: "left",
1426
- verticalAlign: "top",
1427
- layout: "vertical",
1428
- expectedStyleOnSecondRender:
1429
- "position: absolute; width: auto; height: auto; left: 17px; top: 11px;",
1430
- },
1431
- {
1432
- align: "right",
1433
- verticalAlign: "top",
1434
- layout: "vertical",
1435
- expectedStyleOnSecondRender:
1436
- "position: absolute; width: auto; height: auto; right: 13px; top: 11px;",
1437
- },
1438
- {
1439
- align: "center",
1440
- verticalAlign: "bottom",
1441
- layout: "vertical",
1442
- expectedStyleOnSecondRender:
1443
- "position: absolute; width: auto; height: auto; left: 238.5px; bottom: 19px;",
1444
- },
1445
- {
1446
- align: "left",
1447
- verticalAlign: "bottom",
1448
- layout: "vertical",
1449
- expectedStyleOnSecondRender:
1450
- "position: absolute; width: auto; height: auto; left: 17px; bottom: 19px;",
1451
- },
1452
- {
1453
- align: "right",
1454
- verticalAlign: "bottom",
1455
- layout: "vertical",
1456
- expectedStyleOnSecondRender:
1457
- "position: absolute; width: auto; height: auto; right: 13px; bottom: 19px;",
1458
- },
1459
- {
1460
- align: "center",
1461
- verticalAlign: "middle",
1462
- layout: "vertical",
1463
- expectedStyleOnSecondRender:
1464
- "position: absolute; width: auto; height: auto; left: 238.5px; top: 335.5px;",
1465
- },
1466
- {
1467
- align: "left",
1468
- verticalAlign: "middle",
1469
- layout: "vertical",
1470
- expectedStyleOnSecondRender:
1471
- "position: absolute; width: auto; height: auto; left: 17px; top: 335.5px;",
1472
- },
1473
- {
1474
- align: "right",
1475
- verticalAlign: "middle",
1476
- layout: "vertical",
1477
- expectedStyleOnSecondRender:
1478
- "position: absolute; width: auto; height: auto; right: 13px; top: 335.5px;",
1479
- },
1480
- ];
1481
-
1482
- test.each(layoutPositionCartesianTests)(
1483
- "should calculate position for align=$align, verticalAlign=$verticalAlign, layout=$layout",
1484
- ({ align, verticalAlign, layout, expectedStyleOnSecondRender }) => {
1485
- mockGetBoundingClientRect({
1486
- width: 23,
1487
- height: 29,
1488
- });
1489
- const { container } = render(() => (
1490
- <BarChart
1491
- width={500}
1492
- height={700}
1493
- margin={{ top: 11, right: 13, left: 17, bottom: 19 }}
1494
- data={numericalData}
1495
- >
1496
- <Legend align={align} verticalAlign={verticalAlign} layout={layout} />
1497
- <Bar dataKey="value" />
1498
- </BarChart>
1499
- ));
1500
- flush();
1501
- const wrapper = container.querySelector(".recharts-legend-wrapper");
1502
- assertNotNull(wrapper);
1503
- expect(wrapper).toBeInTheDocument();
1504
- expect.soft(wrapper.getAttributeNames()).toEqual(["class", "style"]);
1505
- expect.soft(wrapper.getAttribute("class")).toBe("recharts-legend-wrapper");
1506
- expect.soft(wrapper.getAttribute("style")).toBe(expectedStyleOnSecondRender);
1507
- },
1508
- );
1509
- });
1510
- });
1511
-
1512
- describe("as a child of AreaChart", () => {
1513
- describe("with two Areas", () => {
1514
- const renderTestCase = createSelectorTestCase(({ children }) => (
1515
- <AreaChart width={500} height={500} data={numericalData}>
1516
- <Legend />
1517
- <Area dataKey="percent" />
1518
- <Area dataKey="value" />
1519
- {children}
1520
- </AreaChart>
1521
- ));
1522
-
1523
- it("should render one legend item for each Area", () => {
1524
- const { container } = renderTestCase();
1525
- expectLegendLabels(container, [
1526
- {
1527
- fill: "none",
1528
- textContent: "percent",
1529
- },
1530
- {
1531
- fill: "none",
1532
- textContent: "value",
1533
- },
1534
- ]);
1535
- });
1536
-
1537
- it("should add class and style attributes to each element", () => {
1538
- const { container } = renderTestCase();
1539
-
1540
- const legendItems = assertHasLegend(container);
1541
- expect(legendItems).toHaveLength(2);
1542
-
1543
- expect.soft(legendItems[0]!.getAttributeNames()).toEqual(["class", "style"]);
1544
- expect
1545
- .soft(legendItems[0]!.getAttribute("class"))
1546
- .toBe("recharts-legend-item legend-item-0");
1547
- expect
1548
- .soft(legendItems[0]!.getAttribute("style"))
1549
- .toBe("display: inline-block; margin-right: 10px;");
1550
- expect.soft(legendItems[1]!.getAttributeNames()).toEqual(["class", "style"]);
1551
- expect
1552
- .soft(legendItems[1]!.getAttribute("class"))
1553
- .toBe("recharts-legend-item legend-item-1");
1554
- expect
1555
- .soft(legendItems[1]!.getAttribute("style"))
1556
- .toBe("display: inline-block; margin-right: 10px;");
1557
- });
1558
-
1559
- it("should render Line symbols and colors in absence of explicit legendType", () => {
1560
- const { container } = renderTestCase();
1561
- const findResult = expectedLegendTypeSymbolsWithColor("#3182bd").find(
1562
- (tc) => tc.legendType === "line",
1563
- );
1564
- assertNotNull(findResult);
1565
- const { selector, expectedAttributes } = findResult;
1566
- assertExpectedAttributes(container, selector, expectedAttributes);
1567
- });
1568
- });
1569
-
1570
- describe("with `name` prop on Area", () => {
1571
- it("should set legend item from `name` prop on Area, and update it after rerender", () => {
1572
- const [name, setName] = createSignal("%");
1573
- const { container } = render(() => (
1574
- <AreaChart width={500} height={500} data={numericalData}>
1575
- <Legend />
1576
- <Area dataKey="percent" name={name()} />
1577
- </AreaChart>
1578
- ));
1579
- flush();
1580
- expectLegendLabels(container, [{ fill: "none", textContent: "%" }]);
1581
-
1582
- setName("Percent");
1583
- flush();
1584
- expectLegendLabels(container, [{ fill: "none", textContent: "Percent" }]);
1585
- });
1586
-
1587
- it("should select legend payload", () => {
1588
- // createSelectorTestCase()(selectLegendPayload) settles to undefined for
1589
- // child-registration selectors, so we spy the accessor directly via an
1590
- // effect (the established pattern in legendSelectors.spec.tsx).
1591
- const spy = vi.fn();
1592
- const Comp = (): null => {
1593
- const legend = useAppSelectorWithStableTest(selectLegendPayload);
1594
- createEffect(
1595
- () => legend(),
1596
- (value) => spy(value),
1597
- );
1598
- return null;
1599
- };
1600
- render(() => (
1601
- <AreaChart width={500} height={500} data={numericalData}>
1602
- <Legend />
1603
- <Area dataKey="percent" name="%" />
1604
- <Comp />
1605
- </AreaChart>
1606
- ));
1607
- flush();
1608
- expectLastCalledWith(spy, [
1609
- {
1610
- inactive: false,
1611
- dataKey: "percent",
1612
- type: "line",
1613
- color: "#3182bd",
1614
- value: "%",
1615
- payload: {
1616
- dataKey: "percent",
1617
- name: "%",
1618
- activeDot: true,
1619
- animationBegin: 0,
1620
- animationDuration: 1500,
1621
- animationEasing: "ease",
1622
- connectNulls: false,
1623
- dot: false,
1624
- fill: "#3182bd",
1625
- fillOpacity: 0.6,
1626
- hide: false,
1627
- isAnimationActive: "auto",
1628
- label: false,
1629
- legendType: "line",
1630
- stroke: "#3182bd",
1631
- strokeWidth: 1,
1632
- type: "linear",
1633
- xAxisId: 0,
1634
- yAxisId: 0,
1635
- zIndex: DefaultZIndexes.area,
1636
- },
1637
- },
1638
- ]);
1639
- });
1640
- });
1641
-
1642
- it("should disappear after Area element is removed", () => {
1643
- const [showFirst, setShowFirst] = createSignal(true);
1644
- const { container } = render(() => (
1645
- <AreaChart width={500} height={500} data={dataWithSpecialNameAndFillProperties}>
1646
- <Legend />
1647
- {showFirst() ? <Area dataKey="name" /> : null}
1648
- <Area dataKey="value" />
1649
- </AreaChart>
1650
- ));
1651
- flush();
1652
- expectLegendLabels(container, [
1653
- { fill: "none", textContent: "name" },
1654
- { fill: "none", textContent: "value" },
1655
- ]);
1656
-
1657
- setShowFirst(false);
1658
- flush();
1659
- expectLegendLabels(container, [{ fill: "none", textContent: "value" }]);
1660
- });
1661
-
1662
- it("should update legend if Area data changes", () => {
1663
- const [dataKey, setDataKey] = createSignal("value");
1664
- const { container } = render(() => (
1665
- <AreaChart width={500} height={500} data={numericalData}>
1666
- <Legend />
1667
- <Area dataKey={dataKey()} />
1668
- </AreaChart>
1669
- ));
1670
- flush();
1671
- expectLegendLabels(container, [{ fill: "none", textContent: "value" }]);
1672
-
1673
- setDataKey("percent");
1674
- flush();
1675
- expectLegendLabels(container, [{ fill: "none", textContent: "percent" }]);
1676
- });
1677
- });
1678
-
1679
- describe("as a child of ComposedChart", () => {
1680
- it("should render legend of Scatter even though it is not a supported graphical element inside ComposedChart", () => {
1681
- const { container } = render(() => (
1682
- <ComposedChart width={500} height={500} data={categoricalData}>
1683
- <Legend />
1684
- <Scatter dataKey="scatter datakey" />
1685
- </ComposedChart>
1686
- ));
1687
- flush();
1688
- expectLegendLabels(container, [{ textContent: "scatter datakey", fill: undefined }]);
1689
- });
1690
- });
1691
-
1692
- describe("as a child of RadarChart", () => {
1693
- it("should render one rect legend item for each Radar, with default class and style attributes", () => {
1694
- const { container } = render(() => (
1695
- <RadarChart width={500} height={500} data={numericalData}>
1696
- <Legend />
1697
- <Radar dataKey="percent" />
1698
- <Radar dataKey="value" />
1699
- </RadarChart>
1700
- ));
1701
- flush();
1702
- expect(screen.getByText("value")).toBeInTheDocument();
1703
- expect(screen.getByText("percent")).toBeInTheDocument();
1704
-
1705
- const legendItems = assertHasLegend(container);
1706
- expect(legendItems).toHaveLength(2);
1707
-
1708
- expect.soft(legendItems[0]!.getAttributeNames()).toEqual(["class", "style"]);
1709
- expect.soft(legendItems[0]!.getAttribute("class")).toBe("recharts-legend-item legend-item-0");
1710
- expect
1711
- .soft(legendItems[0]!.getAttribute("style"))
1712
- .toBe("display: inline-block; margin-right: 10px;");
1713
- expect.soft(legendItems[1]!.getAttributeNames()).toEqual(["class", "style"]);
1714
- expect.soft(legendItems[1]!.getAttribute("class")).toBe("recharts-legend-item legend-item-1");
1715
- expect
1716
- .soft(legendItems[1]!.getAttribute("style"))
1717
- .toBe("display: inline-block; margin-right: 10px;");
1718
-
1719
- // in absence of explicit `legendType`, Radar should default to rect
1720
- const findResult = expectedLegendTypeSymbolsWithoutColor.find(
1721
- (tc) => tc.legendType === "rect",
1722
- );
1723
- assertNotNull(findResult);
1724
- const { selector, expectedAttributes } = findResult;
1725
- assertExpectedAttributes(container, selector, expectedAttributes);
1726
- });
1727
-
1728
- it("should change color and className of hidden Radar", () => {
1729
- const { container } = render(() => (
1730
- <RadarChart width={500} height={500} data={numericalData}>
1731
- <Legend inactiveColor="yellow" />
1732
- {/* this will ignore the stroke and use inactive color on legend */}
1733
- <Radar dataKey="percent" stroke="red" hide />
1734
- </RadarChart>
1735
- ));
1736
- flush();
1737
- expect(screen.getByText("percent")).toBeInTheDocument();
1738
- const legendItems = assertHasLegend(container);
1739
-
1740
- expect.soft(legendItems[0]!.getAttributeNames()).toEqual(["class", "style"]);
1741
- expect
1742
- .soft(legendItems[0]!.getAttribute("class"))
1743
- .toBe("recharts-legend-item legend-item-0 inactive");
1744
- expect
1745
- .soft(legendItems[0]!.getAttribute("style"))
1746
- .toBe("display: inline-block; margin-right: 10px;");
1747
-
1748
- // in absence of explicit `legendType`, Radar should default to rect
1749
- const findResult = expectedLegendTypeSymbolsWithColor("yellow").find(
1750
- (tc) => tc.legendType === "rect",
1751
- );
1752
- assertNotNull(findResult);
1753
- const { selector, expectedAttributes } = findResult;
1754
- assertExpectedAttributes(container, selector, expectedAttributes);
1755
- });
1756
-
1757
- it("should have a default inactive Radar legend color", () => {
1758
- const { container } = render(() => (
1759
- <RadarChart width={500} height={500} data={numericalData}>
1760
- <Legend />
1761
- {/* this will ignore the stroke and use inactive color on legend */}
1762
- <Radar dataKey="percent" stroke="red" hide />
1763
- </RadarChart>
1764
- ));
1765
- flush();
1766
- expect(screen.getByText("percent")).toBeInTheDocument();
1767
- const legendItems = assertHasLegend(container);
1768
-
1769
- expect.soft(legendItems[0]!.getAttributeNames()).toEqual(["class", "style"]);
1770
- expect
1771
- .soft(legendItems[0]!.getAttribute("class"))
1772
- .toBe("recharts-legend-item legend-item-0 inactive");
1773
- expect
1774
- .soft(legendItems[0]!.getAttribute("style"))
1775
- .toBe("display: inline-block; margin-right: 10px;");
1776
-
1777
- // in absence of explicit `legendType`, Radar should default to rect
1778
- const findResult = expectedLegendTypeSymbolsWithColor("#ccc").find(
1779
- (tc) => tc.legendType === "rect",
1780
- );
1781
- assertNotNull(findResult);
1782
- const { selector, expectedAttributes } = findResult;
1783
- assertExpectedAttributes(container, selector, expectedAttributes);
1784
- });
1785
-
1786
- it("should render one empty legend item if Radar has no dataKey", () => {
1787
- const { container } = render(() => (
1788
- <RadarChart width={500} height={500} data={numericalData}>
1789
- <Legend />
1790
- <Radar />
1791
- </RadarChart>
1792
- ));
1793
- flush();
1794
-
1795
- expectLegendLabels(container, [{ fill: null, textContent: "" }]);
1796
- });
1797
-
1798
- it("should set legend item from `name` prop on Radar, and update it after rerender", () => {
1799
- const [name, setName] = createSignal("%");
1800
- const { container } = render(() => (
1801
- <RadarChart width={500} height={500} data={numericalData}>
1802
- <Legend />
1803
- <Radar dataKey="percent" name={name()} />
1804
- </RadarChart>
1805
- ));
1806
- flush();
1807
- expectLegendLabels(container, [{ fill: null, textContent: "%" }]);
1808
-
1809
- setName("Percent");
1810
- flush();
1811
- expectLegendLabels(container, [{ fill: null, textContent: "Percent" }]);
1812
- });
1813
-
1814
- it("should disappear after Radar element is removed", () => {
1815
- const [showFirst, setShowFirst] = createSignal(true);
1816
- const { container } = render(() => (
1817
- <RadarChart width={500} height={500} data={dataWithSpecialNameAndFillProperties}>
1818
- <Legend />
1819
- {showFirst() ? <Radar dataKey="name" /> : null}
1820
- <Radar dataKey="value" />
1821
- </RadarChart>
1822
- ));
1823
- flush();
1824
- expectLegendLabels(container, [
1825
- { fill: null, textContent: "name" },
1826
- { fill: null, textContent: "value" },
1827
- ]);
1828
-
1829
- setShowFirst(false);
1830
- flush();
1831
- expectLegendLabels(container, [{ fill: null, textContent: "value" }]);
1832
- });
1833
-
1834
- it("should update legend if Radar data changes", () => {
1835
- const [dataKey, setDataKey] = createSignal("value");
1836
- const { container } = render(() => (
1837
- <RadarChart width={500} height={500} data={numericalData}>
1838
- <Legend />
1839
- <Radar dataKey={dataKey()} />
1840
- </RadarChart>
1841
- ));
1842
- flush();
1843
- expectLegendLabels(container, [{ fill: null, textContent: "value" }]);
1844
-
1845
- setDataKey("percent");
1846
- flush();
1847
- expectLegendLabels(container, [{ fill: null, textContent: "percent" }]);
1848
- });
1849
-
1850
- it("should prefer Legend.iconType over Radar.legendType", () => {
1851
- const { container } = render(() => (
1852
- <RadarChart width={500} height={500} data={numericalData}>
1853
- <Legend iconType="circle" />
1854
- <Radar dataKey="value" legendType="square" />
1855
- </RadarChart>
1856
- ));
1857
- flush();
1858
- const findResult = expectedLegendTypeSymbolsWithoutColor.find(
1859
- (li) => li.legendType === "circle",
1860
- );
1861
- assertNotNull(findResult);
1862
- const { selector, expectedAttributes } = findResult;
1863
- assertExpectedAttributes(container, selector, expectedAttributes);
1864
- });
1865
- });
1866
-
1867
- describe("as a child of ScatterChart", () => {
1868
- it("should render one legend item for each Scatter", () => {
1869
- const { container } = render(() => (
1870
- <ScatterChart width={500} height={500} data={numericalData}>
1871
- <Legend />
1872
- <Scatter dataKey="percent" />
1873
- <Scatter dataKey="value" />
1874
- </ScatterChart>
1875
- ));
1876
- flush();
1877
- expectLegendLabels(container, [
1878
- { fill: undefined, textContent: "percent" },
1879
- { fill: undefined, textContent: "value" },
1880
- ]);
1881
- });
1882
-
1883
- it("should not use `fill` from data for the legend fill", () => {
1884
- const { container } = render(() => (
1885
- <ScatterChart width={500} height={500} data={dataWithSpecialNameAndFillProperties}>
1886
- <Legend />
1887
- <Scatter dataKey="value" />
1888
- </ScatterChart>
1889
- ));
1890
- flush();
1891
- expectLegendLabels(container, [{ fill: undefined, textContent: "value" }]);
1892
- });
1893
- });
1894
-
1895
- describe("as a child of PieChart", () => {
1896
- it("should render one legend item for each segment, and it should use nameKey as its label", () => {
1897
- const { container } = render(() => (
1898
- <PieChart width={500} height={500}>
1899
- <Legend />
1900
- <Pie data={numericalData} dataKey="percent" nameKey="value" />
1901
- </PieChart>
1902
- ));
1903
- flush();
1904
- expectLegendLabels(container, [
1905
- { fill: "#808080", textContent: "Concentrated power of will" },
1906
- { fill: "#808080", textContent: "Luck" },
1907
- { fill: "#808080", textContent: "Pain" },
1908
- { fill: "#808080", textContent: "Pleasure" },
1909
- { fill: "#808080", textContent: "Reason to remember the name" },
1910
- { fill: "#808080", textContent: "Skill" },
1911
- ]);
1912
- });
1913
-
1914
- it("should render a legend item even if the dataKey does not match anything from the data", () => {
1915
- const { container } = render(() => (
1916
- <PieChart width={500} height={500}>
1917
- <Legend />
1918
- <Pie data={numericalData} dataKey="unknown" />
1919
- </PieChart>
1920
- ));
1921
- flush();
1922
- expectLegendLabels(container, [
1923
- { fill: "#808080", textContent: "unknown" },
1924
- { fill: "#808080", textContent: "unknown" },
1925
- { fill: "#808080", textContent: "unknown" },
1926
- { fill: "#808080", textContent: "unknown" },
1927
- { fill: "#808080", textContent: "unknown" },
1928
- { fill: "#808080", textContent: "unknown" },
1929
- ]);
1930
- });
1931
-
1932
- it("should implicitly use special `name` and `fill` properties from data as legend labels and colors", () => {
1933
- const { container } = render(() => (
1934
- <PieChart width={500} height={500}>
1935
- <Legend />
1936
- <Pie data={dataWithSpecialNameAndFillProperties} dataKey="value" />
1937
- </PieChart>
1938
- ));
1939
- flush();
1940
- expectLegendLabels(container, [
1941
- { fill: "fill1", textContent: "name1" },
1942
- { fill: "fill2", textContent: "name2" },
1943
- { fill: "fill3", textContent: "name3" },
1944
- { fill: "fill4", textContent: "name4" },
1945
- ]);
1946
- });
1947
-
1948
- describe("itemSorter", () => {
1949
- it("should sort items by the special name property by default", () => {
1950
- const dataInDifferentOrder = [
1951
- { name: "name2", fill: "fill2", value: 34 },
1952
- { name: "name1", fill: "fill1", value: 12 },
1953
- { name: "name4", fill: "fill4", value: 78 },
1954
- { name: "name3", fill: "fill3", value: 56 },
1955
- ];
1956
- const { container } = render(() => (
1957
- <PieChart width={500} height={500}>
1958
- <Legend />
1959
- <Pie data={dataInDifferentOrder} dataKey="value" />
1960
- </PieChart>
1961
- ));
1962
- flush();
1963
- expectLegendLabels(container, [
1964
- { fill: "fill1", textContent: "name1" },
1965
- { fill: "fill2", textContent: "name2" },
1966
- { fill: "fill3", textContent: "name3" },
1967
- { fill: "fill4", textContent: "name4" },
1968
- ]);
1969
- });
1970
-
1971
- it.each(["dataKey", null] as const)(
1972
- "should leave items in the original data order when itemSorter=%s",
1973
- (itemSorter) => {
1974
- const { container } = render(() => (
1975
- <PieChart width={500} height={500}>
1976
- <Legend itemSorter={itemSorter} />
1977
- <Pie data={numericalData} dataKey="percent" nameKey="value" />
1978
- </PieChart>
1979
- ));
1980
- flush();
1981
- expectLegendLabels(container, [
1982
- { fill: "#808080", textContent: "Luck" },
1983
- { fill: "#808080", textContent: "Skill" },
1984
- { fill: "#808080", textContent: "Concentrated power of will" },
1985
- { fill: "#808080", textContent: "Pleasure" },
1986
- { fill: "#808080", textContent: "Pain" },
1987
- { fill: "#808080", textContent: "Reason to remember the name" },
1988
- ]);
1989
- },
1990
- );
1991
- });
1992
-
1993
- it("should disappear after Pie data is removed", () => {
1994
- const [data, setData] = createSignal(numericalData);
1995
- const { container } = render(() => (
1996
- <PieChart width={500} height={500}>
1997
- <Legend />
1998
- <Pie data={data()} dataKey="percent" />
1999
- <Pie data={numericalData2} dataKey="value" nameKey="title" />
2000
- </PieChart>
2001
- ));
2002
- flush();
2003
- expectLegendLabels(container, [
2004
- { fill: "#808080", textContent: "Days a week" },
2005
- { fill: "#808080", textContent: "Luftbaloons" },
2006
- { fill: "#808080", textContent: "Mambo number" },
2007
- { fill: "#808080", textContent: "Miles I would walk" },
2008
- { fill: "#808080", textContent: "Seas of Rhye" },
2009
- { fill: "#808080", textContent: "percent" },
2010
- { fill: "#808080", textContent: "percent" },
2011
- { fill: "#808080", textContent: "percent" },
2012
- { fill: "#808080", textContent: "percent" },
2013
- { fill: "#808080", textContent: "percent" },
2014
- { fill: "#808080", textContent: "percent" },
2015
- ]);
2016
-
2017
- setData([]);
2018
- flush();
2019
- expectLegendLabels(container, [
2020
- { fill: "#808080", textContent: "Days a week" },
2021
- { fill: "#808080", textContent: "Luftbaloons" },
2022
- { fill: "#808080", textContent: "Mambo number" },
2023
- { fill: "#808080", textContent: "Miles I would walk" },
2024
- { fill: "#808080", textContent: "Seas of Rhye" },
2025
- ]);
2026
- });
2027
-
2028
- it("should update legend if Pie data changes", () => {
2029
- const [first, setFirst] = createSignal(true);
2030
- const { container } = render(() => (
2031
- <PieChart width={500} height={500}>
2032
- <Legend />
2033
- <Show
2034
- when={first()}
2035
- fallback={<Pie data={numericalData2} dataKey="value" nameKey="title" />}
2036
- >
2037
- <Pie data={numericalData} dataKey="percent" nameKey="value" />
2038
- </Show>
2039
- </PieChart>
2040
- ));
2041
- flush();
2042
- expectLegendLabels(container, [
2043
- { fill: "#808080", textContent: "Concentrated power of will" },
2044
- { fill: "#808080", textContent: "Luck" },
2045
- { fill: "#808080", textContent: "Pain" },
2046
- { fill: "#808080", textContent: "Pleasure" },
2047
- { fill: "#808080", textContent: "Reason to remember the name" },
2048
- { fill: "#808080", textContent: "Skill" },
2049
- ]);
2050
-
2051
- setFirst(false);
2052
- flush();
2053
- expectLegendLabels(container, [
2054
- { fill: "#808080", textContent: "Days a week" },
2055
- { fill: "#808080", textContent: "Luftbaloons" },
2056
- { fill: "#808080", textContent: "Mambo number" },
2057
- { fill: "#808080", textContent: "Miles I would walk" },
2058
- { fill: "#808080", textContent: "Seas of Rhye" },
2059
- ]);
2060
- });
2061
-
2062
- it("should update legend if nameKey changes", () => {
2063
- const [nameKey, setNameKey] = createSignal("value");
2064
- const { container } = render(() => (
2065
- <PieChart width={500} height={500}>
2066
- <Legend />
2067
- <Pie data={numericalData} dataKey="percent" nameKey={nameKey()} />
2068
- </PieChart>
2069
- ));
2070
- flush();
2071
- expectLegendLabels(container, [
2072
- { fill: "#808080", textContent: "Concentrated power of will" },
2073
- { fill: "#808080", textContent: "Luck" },
2074
- { fill: "#808080", textContent: "Pain" },
2075
- { fill: "#808080", textContent: "Pleasure" },
2076
- { fill: "#808080", textContent: "Reason to remember the name" },
2077
- { fill: "#808080", textContent: "Skill" },
2078
- ]);
2079
-
2080
- setNameKey("percent");
2081
- flush();
2082
- expectLegendLabels(container, [
2083
- { fill: "#808080", textContent: "10" },
2084
- { fill: "#808080", textContent: "100" },
2085
- { fill: "#808080", textContent: "15" },
2086
- { fill: "#808080", textContent: "20" },
2087
- { fill: "#808080", textContent: "50" },
2088
- { fill: "#808080", textContent: "50" },
2089
- ]);
2090
- });
2091
-
2092
- describe("legendType symbols", () => {
2093
- it.each(expectedLegendTypeSymbolsWithColor("#808080"))(
2094
- "should render element $selector for legendType $legendType",
2095
- ({ legendType, selector, expectedAttributes }) => {
2096
- const { container } = render(() => (
2097
- <PieChart width={500} height={500}>
2098
- <Legend />
2099
- <Pie data={numericalData} dataKey="percent" legendType={legendType} />
2100
- </PieChart>
2101
- ));
2102
- flush();
2103
- assertExpectedAttributes(container, selector, expectedAttributes);
2104
- },
2105
- );
2106
-
2107
- it("should prefer Legend.iconType over Pie.legendType", () => {
2108
- const { container } = render(() => (
2109
- <PieChart width={500} height={500}>
2110
- <Legend iconType="circle" />
2111
- <Pie data={numericalData} dataKey="percent" legendType="square" />
2112
- </PieChart>
2113
- ));
2114
- flush();
2115
- const findResult = expectedLegendTypeSymbolsWithColor("#808080").find(
2116
- (li) => li.legendType === "circle",
2117
- );
2118
- assertNotNull(findResult);
2119
- assertExpectedAttributes(container, findResult.selector, findResult.expectedAttributes);
2120
- });
2121
- });
2122
- });
2123
-
2124
- describe("as a child of RadialBarChart", () => {
2125
- it("should render one legend item for each segment, with no label text, and rect icon with no color, by default", () => {
2126
- const { container } = render(() => (
2127
- <RadialBarChart width={500} height={500} data={numericalData}>
2128
- <Legend />
2129
- <RadialBar dataKey="percent" label />
2130
- </RadialBarChart>
2131
- ));
2132
- flush();
2133
- const legendItems = assertHasLegend(container);
2134
- expect(legendItems).toHaveLength(numericalData.length);
2135
- legendItems.forEach((legendItem) => {
2136
- const legendItemText = legendItem.querySelector(".recharts-legend-item-text");
2137
- expect(legendItemText).toBeInTheDocument();
2138
- expect(legendItemText).toBeEmptyDOMElement();
2139
- });
2140
- const findResult = expectedLegendTypeSymbolsWithoutColor.find((i) => i.legendType === "rect");
2141
- assertNotNull(findResult);
2142
- assertExpectedAttributes(container, findResult.selector, findResult.expectedAttributes);
2143
- });
2144
-
2145
- it("should render a legend item even if the dataKey does not match anything from the data", () => {
2146
- const { container } = render(() => (
2147
- <RadialBarChart width={500} height={500} data={numericalData}>
2148
- <Legend />
2149
- <RadialBar dataKey="unknown" />
2150
- </RadialBarChart>
2151
- ));
2152
- flush();
2153
- expectLegendLabels(container, [
2154
- { fill: null, textContent: "" },
2155
- { fill: null, textContent: "" },
2156
- { fill: null, textContent: "" },
2157
- { fill: null, textContent: "" },
2158
- { fill: null, textContent: "" },
2159
- { fill: null, textContent: "" },
2160
- ]);
2161
- });
2162
-
2163
- it("should use special `name` and `fill` properties from data as legend labels and colors", () => {
2164
- const { container } = render(() => (
2165
- <RadialBarChart width={500} height={500} data={dataWithSpecialNameAndFillProperties}>
2166
- <Legend />
2167
- <RadialBar dataKey="percent" />
2168
- </RadialBarChart>
2169
- ));
2170
- flush();
2171
- expectLegendLabels(container, [
2172
- { fill: "fill1", textContent: "name1" },
2173
- { fill: "fill2", textContent: "name2" },
2174
- { fill: "fill3", textContent: "name3" },
2175
- { fill: "fill4", textContent: "name4" },
2176
- ]);
2177
- });
2178
-
2179
- it("should use special `name` and `fill` properties from data as legend labels and colors, even if the dataKey does not match", () => {
2180
- const { container } = render(() => (
2181
- <RadialBarChart width={500} height={500} data={dataWithSpecialNameAndFillProperties}>
2182
- <Legend />
2183
- <RadialBar dataKey="unknown" />
2184
- </RadialBarChart>
2185
- ));
2186
- flush();
2187
- expectLegendLabels(container, [
2188
- { fill: "fill1", textContent: "name1" },
2189
- { fill: "fill2", textContent: "name2" },
2190
- { fill: "fill3", textContent: "name3" },
2191
- { fill: "fill4", textContent: "name4" },
2192
- ]);
2193
- });
2194
- });
2195
-
2196
- describe("click events", () => {
2197
- it("should call onClick when clicked", () => {
2198
- const onClick = vi.fn();
2199
- const { container } = render(() => (
2200
- <ScatterChart width={500} height={500} data={numericalData}>
2201
- <Legend onClick={onClick} />
2202
- <Scatter dataKey="percent" />
2203
- </ScatterChart>
2204
- ));
2205
- flush();
2206
- expect(onClick).toHaveBeenCalledTimes(0);
2207
- const legend = container.querySelector(".recharts-legend-item");
2208
- assertNotNull(legend);
2209
- fireEvent.click(legend);
2210
- expect(onClick).toHaveBeenCalledTimes(1);
2211
- });
2212
- });
2213
- });