@solidports/recharts 0.1.0 → 0.1.1

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 (304) hide show
  1. package/dist/index.d.ts +40 -2
  2. package/dist/index.js +14238 -7174
  3. package/dist/{dev.js → index.jsx} +18367 -15900
  4. package/dist/server.js +48178 -0
  5. package/package.json +36 -19
  6. package/src/animation/AnimatedItems.tsx +0 -183
  7. package/src/animation/AnimationController.ts +0 -33
  8. package/src/animation/AnimationControllerImpl.ts +0 -36
  9. package/src/animation/AnimationHandle.ts +0 -307
  10. package/src/animation/CSSTransitionAnimate.tsx +0 -170
  11. package/src/animation/JavascriptAnimate.tsx +0 -119
  12. package/src/animation/easing.ts +0 -221
  13. package/src/animation/matchBy.ts +0 -164
  14. package/src/animation/timeoutController.ts +0 -70
  15. package/src/animation/useAnimationController.tsx +0 -34
  16. package/src/animation/useAnimationStartSnapshot.ts +0 -118
  17. package/src/animation/util.ts +0 -41
  18. package/src/cartesian/Area.tsx +0 -915
  19. package/src/cartesian/AreaRevealShape.tsx +0 -190
  20. package/src/cartesian/Bar.tsx +0 -1369
  21. package/src/cartesian/BarStack.tsx +0 -152
  22. package/src/cartesian/Brush.tsx +0 -951
  23. package/src/cartesian/CartesianAxis.tsx +0 -722
  24. package/src/cartesian/CartesianGrid.tsx +0 -711
  25. package/src/cartesian/ErrorBar.tsx +0 -361
  26. package/src/cartesian/Funnel.tsx +0 -803
  27. package/src/cartesian/GraphicalItemClipPath.tsx +0 -67
  28. package/src/cartesian/Line.tsx +0 -863
  29. package/src/cartesian/LineDrawShape.tsx +0 -89
  30. package/src/cartesian/ReferenceArea.tsx +0 -331
  31. package/src/cartesian/ReferenceDot.tsx +0 -304
  32. package/src/cartesian/ReferenceLine.tsx +0 -474
  33. package/src/cartesian/Scatter.tsx +0 -888
  34. package/src/cartesian/XAxis.tsx +0 -433
  35. package/src/cartesian/YAxis.tsx +0 -443
  36. package/src/cartesian/ZAxis.tsx +0 -155
  37. package/src/cartesian/cartesianPositionToCSSTranslate.tsx +0 -29
  38. package/src/cartesian/cartesianViewBoxToTrapezoid.tsx +0 -21
  39. package/src/cartesian/getCartesianPosition.tsx +0 -267
  40. package/src/cartesian/getEquidistantTicks.ts +0 -144
  41. package/src/cartesian/getTicks.ts +0 -225
  42. package/src/cartesian/isOutsidePosition.ts +0 -15
  43. package/src/cartesian/useAnimatedLineLength.ts +0 -54
  44. package/src/chart/AreaChart.tsx +0 -29
  45. package/src/chart/BarChart.tsx +0 -29
  46. package/src/chart/CartesianChart.tsx +0 -131
  47. package/src/chart/CategoricalChart.tsx +0 -94
  48. package/src/chart/ComposedChart.tsx +0 -29
  49. package/src/chart/FunnelChart.tsx +0 -29
  50. package/src/chart/LineChart.tsx +0 -29
  51. package/src/chart/PieChart.tsx +0 -50
  52. package/src/chart/PolarChart.tsx +0 -164
  53. package/src/chart/RadarChart.tsx +0 -70
  54. package/src/chart/RadialBarChart.tsx +0 -46
  55. package/src/chart/RechartsWrapper.tsx +0 -551
  56. package/src/chart/Sankey.tsx +0 -1534
  57. package/src/chart/ScatterChart.tsx +0 -29
  58. package/src/chart/SunburstChart.tsx +0 -504
  59. package/src/chart/Treemap.tsx +0 -1223
  60. package/src/chart/createInitialRootProps.ts +0 -24
  61. package/src/chart/types.ts +0 -53
  62. package/src/component/ActivePoints.tsx +0 -144
  63. package/src/component/Cell.tsx +0 -37
  64. package/src/component/Cursor.tsx +0 -185
  65. package/src/component/Customized.tsx +0 -50
  66. package/src/component/DefaultLegendContent.tsx +0 -348
  67. package/src/component/DefaultTooltipContent.tsx +0 -224
  68. package/src/component/Dots.tsx +0 -157
  69. package/src/component/Label.tsx +0 -636
  70. package/src/component/LabelList.tsx +0 -375
  71. package/src/component/Legend.tsx +0 -512
  72. package/src/component/ResponsiveContainer.tsx +0 -348
  73. package/src/component/Text.tsx +0 -541
  74. package/src/component/Tooltip.tsx +0 -470
  75. package/src/component/TooltipBoundingBox.tsx +0 -146
  76. package/src/component/responsiveContainerUtils.ts +0 -134
  77. package/src/container/ClipPathProvider.tsx +0 -51
  78. package/src/container/Layer.tsx +0 -38
  79. package/src/container/RootSurface.tsx +0 -120
  80. package/src/container/Surface.tsx +0 -61
  81. package/src/context/CellsContext.tsx +0 -54
  82. package/src/context/ErrorBarContext.tsx +0 -146
  83. package/src/context/GraphicalItemChildrenScope.tsx +0 -18
  84. package/src/context/PanoramaContext.tsx +0 -9
  85. package/src/context/RegisterGraphicalItemId.tsx +0 -30
  86. package/src/context/accessibilityContext.tsx +0 -6
  87. package/src/context/brushUpdateContext.tsx +0 -9
  88. package/src/context/chartDataContext.tsx +0 -97
  89. package/src/context/chartLayoutContext.tsx +0 -201
  90. package/src/context/legendPayloadContext.tsx +0 -20
  91. package/src/context/legendPortalContext.tsx +0 -12
  92. package/src/context/tooltipContext.tsx +0 -89
  93. package/src/context/tooltipPortalContext.tsx +0 -12
  94. package/src/context/useTooltipAxis.ts +0 -22
  95. package/src/hooks.ts +0 -476
  96. package/src/index.ts +0 -280
  97. package/src/polar/Pie.tsx +0 -1360
  98. package/src/polar/PolarAngleAxis.tsx +0 -616
  99. package/src/polar/PolarGrid.tsx +0 -312
  100. package/src/polar/PolarRadiusAxis.tsx +0 -547
  101. package/src/polar/Radar.tsx +0 -734
  102. package/src/polar/RadialBar.tsx +0 -917
  103. package/src/polar/defaultPolarAngleAxisProps.tsx +0 -27
  104. package/src/polar/defaultPolarRadiusAxisProps.tsx +0 -25
  105. package/src/shape/Cross.tsx +0 -89
  106. package/src/shape/Curve.tsx +0 -343
  107. package/src/shape/Dot.tsx +0 -70
  108. package/src/shape/Polygon.tsx +0 -195
  109. package/src/shape/Rectangle.tsx +0 -470
  110. package/src/shape/Sector.tsx +0 -347
  111. package/src/shape/Symbols.tsx +0 -139
  112. package/src/shape/Trapezoid.tsx +0 -280
  113. package/src/state/RechartsStateContext.tsx +0 -12
  114. package/src/state/RechartsStateProvider.tsx +0 -87
  115. package/src/state/RechartsStoreContext.tsx +0 -25
  116. package/src/state/RechartsStoreProvider.tsx +0 -35
  117. package/src/state/ReportChartProps.tsx +0 -40
  118. package/src/state/ReportEventSettings.tsx +0 -30
  119. package/src/state/ReportMainChartProps.tsx +0 -61
  120. package/src/state/ReportPolarOptions.tsx +0 -35
  121. package/src/state/SetGraphicalItem.ts +0 -79
  122. package/src/state/SetLegendPayload.ts +0 -134
  123. package/src/state/SetTooltipEntrySettings.tsx +0 -72
  124. package/src/state/actions.ts +0 -464
  125. package/src/state/brushSlice.ts +0 -13
  126. package/src/state/cartesianAxisSlice.ts +0 -141
  127. package/src/state/chartDataSlice.ts +0 -50
  128. package/src/state/chartState.ts +0 -297
  129. package/src/state/errorBarSlice.ts +0 -29
  130. package/src/state/eventSettingsSlice.ts +0 -8
  131. package/src/state/events.ts +0 -76
  132. package/src/state/externalEventsMiddleware.ts +0 -255
  133. package/src/state/graphicalItemsSlice.ts +0 -74
  134. package/src/state/hooks/useChartSelectors.tsx +0 -45
  135. package/src/state/keyboardEventsMiddleware.ts +0 -228
  136. package/src/state/layoutSlice.ts +0 -21
  137. package/src/state/legendSlice.ts +0 -57
  138. package/src/state/mouseEventsMiddleware.ts +0 -185
  139. package/src/state/optionsSlice.ts +0 -47
  140. package/src/state/polarAxisSlice.ts +0 -10
  141. package/src/state/polarOptionsSlice.ts +0 -12
  142. package/src/state/rawData.ts +0 -26
  143. package/src/state/referenceElementsSlice.ts +0 -40
  144. package/src/state/renderedTicksSlice.ts +0 -15
  145. package/src/state/rootPropsSlice.ts +0 -47
  146. package/src/state/selectors/areaSelectors.ts +0 -240
  147. package/src/state/selectors/arrayEqualityCheck.ts +0 -29
  148. package/src/state/selectors/axisSelectors.ts +0 -2157
  149. package/src/state/selectors/barSelectors.ts +0 -310
  150. package/src/state/selectors/barStackSelectors.ts +0 -77
  151. package/src/state/selectors/brushSelectors.ts +0 -33
  152. package/src/state/selectors/chartSelector.ts +0 -185
  153. package/src/state/selectors/combiners/combineActiveLabel.ts +0 -16
  154. package/src/state/selectors/combiners/combineActiveTooltipIndex.ts +0 -95
  155. package/src/state/selectors/combiners/combineAllBarPositions.ts +0 -122
  156. package/src/state/selectors/combiners/combineAxisRangeWithReverse.ts +0 -16
  157. package/src/state/selectors/combiners/combineBarPosition.ts +0 -23
  158. package/src/state/selectors/combiners/combineBarSizeList.ts +0 -80
  159. package/src/state/selectors/combiners/combineCheckedDomain.ts +0 -48
  160. package/src/state/selectors/combiners/combineConfiguredScale.ts +0 -111
  161. package/src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts +0 -45
  162. package/src/state/selectors/combiners/combineDisplayedStackedData.ts +0 -50
  163. package/src/state/selectors/combiners/combineInverseScaleFunction.ts +0 -16
  164. package/src/state/selectors/combiners/combineRealScaleType.ts +0 -44
  165. package/src/state/selectors/combiners/combineStackedData.ts +0 -27
  166. package/src/state/selectors/combiners/combineTooltipInteractionState.ts +0 -86
  167. package/src/state/selectors/combiners/combineTooltipPayload.ts +0 -205
  168. package/src/state/selectors/combiners/combineTooltipPayloadConfigurations.ts +0 -58
  169. package/src/state/selectors/containerSelectors.ts +0 -12
  170. package/src/state/selectors/dataSelectors.ts +0 -88
  171. package/src/state/selectors/funnelSelectors.ts +0 -75
  172. package/src/state/selectors/graphicalItemSelectors.ts +0 -30
  173. package/src/state/selectors/legendSelectors.ts +0 -29
  174. package/src/state/selectors/lineSelectors.ts +0 -134
  175. package/src/state/selectors/numberDomainEqualityCheck.ts +0 -14
  176. package/src/state/selectors/pickAxisId.ts +0 -5
  177. package/src/state/selectors/pickAxisType.ts +0 -3
  178. package/src/state/selectors/pieSelectors.ts +0 -97
  179. package/src/state/selectors/polarAxisSelectors.ts +0 -201
  180. package/src/state/selectors/polarGridSelectors.ts +0 -28
  181. package/src/state/selectors/polarScaleSelectors.ts +0 -133
  182. package/src/state/selectors/polarSelectors.ts +0 -219
  183. package/src/state/selectors/radarSelectors.ts +0 -191
  184. package/src/state/selectors/radialBarSelectors.ts +0 -435
  185. package/src/state/selectors/rootPropsSelectors.ts +0 -25
  186. package/src/state/selectors/scatterSelectors.ts +0 -96
  187. package/src/state/selectors/selectActivePropsFromChartPointer.ts +0 -26
  188. package/src/state/selectors/selectAllAxes.ts +0 -17
  189. package/src/state/selectors/selectChartOffset.ts +0 -16
  190. package/src/state/selectors/selectChartOffsetInternal.ts +0 -136
  191. package/src/state/selectors/selectLegendArea.ts +0 -20
  192. package/src/state/selectors/selectPlotArea.ts +0 -22
  193. package/src/state/selectors/selectTooltipAxisId.ts +0 -7
  194. package/src/state/selectors/selectTooltipAxisType.ts +0 -32
  195. package/src/state/selectors/selectTooltipEventType.ts +0 -48
  196. package/src/state/selectors/selectTooltipPayloadSearcher.ts +0 -6
  197. package/src/state/selectors/selectTooltipSettings.ts +0 -39
  198. package/src/state/selectors/selectTooltipState.ts +0 -8
  199. package/src/state/selectors/selectors.ts +0 -271
  200. package/src/state/selectors/tooltipSelectors.ts +0 -578
  201. package/src/state/selectors/touchSelectors.ts +0 -31
  202. package/src/state/store.ts +0 -29
  203. package/src/state/storeIdentity.ts +0 -9
  204. package/src/state/teardownWrite.ts +0 -10
  205. package/src/state/tooltipInteraction.ts +0 -23
  206. package/src/state/tooltipSlice.ts +0 -334
  207. package/src/state/touchEventsMiddleware.ts +0 -214
  208. package/src/state/types/AnimationSettings.ts +0 -20
  209. package/src/state/types/AreaSettings.ts +0 -14
  210. package/src/state/types/BarSettings.ts +0 -15
  211. package/src/state/types/LineSettings.ts +0 -9
  212. package/src/state/types/PieSettings.ts +0 -34
  213. package/src/state/types/RadarSettings.ts +0 -5
  214. package/src/state/types/RadialBarSettings.ts +0 -10
  215. package/src/state/types/ScatterSettings.ts +0 -12
  216. package/src/state/types/StackedGraphicalItem.ts +0 -34
  217. package/src/state/useChartState.ts +0 -17
  218. package/src/state/zIndexSlice.ts +0 -39
  219. package/src/synchronisation/syncSelectors.ts +0 -7
  220. package/src/synchronisation/types.ts +0 -44
  221. package/src/synchronisation/useChartSynchronisation.tsx +0 -404
  222. package/src/theme/RechartsTheme.ts +0 -16
  223. package/src/theme/RechartsThemeContext.ts +0 -19
  224. package/src/theme/darkTheme.ts +0 -13
  225. package/src/theme/graphicalItemIdentity.ts +0 -70
  226. package/src/theme/legacyTheme.ts +0 -17
  227. package/src/theme/lightTheme.ts +0 -13
  228. package/src/types.ts +0 -54
  229. package/src/util/ActiveShapeUtils.tsx +0 -162
  230. package/src/util/BarUtils.tsx +0 -62
  231. package/src/util/BarePortal.tsx +0 -50
  232. package/src/util/CamelCaseSVGAttrs.ts +0 -34
  233. package/src/util/CartesianUtils.ts +0 -48
  234. package/src/util/ChartUtils.ts +0 -802
  235. package/src/util/Constants.ts +0 -42
  236. package/src/util/CssPrefixUtils.ts +0 -20
  237. package/src/util/DOMUtils.ts +0 -129
  238. package/src/util/DataUtils.ts +0 -216
  239. package/src/util/Events.ts +0 -16
  240. package/src/util/FunnelUtils.tsx +0 -15
  241. package/src/util/Global.ts +0 -12
  242. package/src/util/IfOverflow.ts +0 -15
  243. package/src/util/LRUCache.ts +0 -41
  244. package/src/util/LogUtils.ts +0 -22
  245. package/src/util/PolarUtils.ts +0 -132
  246. package/src/util/RadialBarUtils.tsx +0 -24
  247. package/src/util/ReactUtils.ts +0 -95
  248. package/src/util/ReduceCSSCalc.ts +0 -187
  249. package/src/util/ScatterUtils.tsx +0 -52
  250. package/src/util/ShapeElementProps.tsx +0 -87
  251. package/src/util/TickUtils.ts +0 -60
  252. package/src/util/XAxisUtils.ts +0 -48
  253. package/src/util/YAxisUtils.ts +0 -48
  254. package/src/util/axisPropsAreEqual.ts +0 -48
  255. package/src/util/createCartesianCharts.tsx +0 -150
  256. package/src/util/createEventProxy.ts +0 -20
  257. package/src/util/createPolarCharts.tsx +0 -112
  258. package/src/util/cursor/getCursorPoints.ts +0 -46
  259. package/src/util/cursor/getCursorRectangle.ts +0 -28
  260. package/src/util/cursor/getRadialCursorPoints.ts +0 -32
  261. package/src/util/excludeEventProps.ts +0 -171
  262. package/src/util/getActiveCoordinate.ts +0 -213
  263. package/src/util/getAxisTypeBasedOnLayout.ts +0 -21
  264. package/src/util/getClassNameFromUnknown.ts +0 -6
  265. package/src/util/getEveryNth.ts +0 -27
  266. package/src/util/getRadiusAndStrokeWidthFromDot.ts +0 -35
  267. package/src/util/getRelativeCoordinate.ts +0 -80
  268. package/src/util/getSliced.ts +0 -13
  269. package/src/util/hoverDedupe.ts +0 -41
  270. package/src/util/isDomainSpecifiedByUser.ts +0 -219
  271. package/src/util/isWellBehavedNumber.ts +0 -7
  272. package/src/util/pathTotalLength.ts +0 -25
  273. package/src/util/payload/getUniqPayload.ts +0 -28
  274. package/src/util/propsAreEqual.ts +0 -121
  275. package/src/util/resolveDefaultProps.ts +0 -161
  276. package/src/util/round.ts +0 -32
  277. package/src/util/scale/CartesianScaleHelper.ts +0 -72
  278. package/src/util/scale/CustomScaleDefinition.ts +0 -81
  279. package/src/util/scale/RechartsScale.ts +0 -130
  280. package/src/util/scale/createCategoricalInverse.ts +0 -72
  281. package/src/util/scale/getNiceTickValues.ts +0 -311
  282. package/src/util/scale/index.ts +0 -2
  283. package/src/util/scale/util/arithmetic.ts +0 -54
  284. package/src/util/solid-1-compat.ts +0 -310
  285. package/src/util/solidJsxCamelAugment.d.ts +0 -84
  286. package/src/util/stacks/getStackSeriesIdentifier.ts +0 -21
  287. package/src/util/stacks/stackTypes.ts +0 -60
  288. package/src/util/structurallyEqual.ts +0 -31
  289. package/src/util/svgPropertiesAndEvents.ts +0 -53
  290. package/src/util/svgPropertiesNoEvents.ts +0 -571
  291. package/src/util/tooltip/translate.ts +0 -171
  292. package/src/util/typedDataKey.ts +0 -48
  293. package/src/util/types.ts +0 -1560
  294. package/src/util/useAnimationId.ts +0 -31
  295. package/src/util/useElementOffset.ts +0 -110
  296. package/src/util/useId.ts +0 -8
  297. package/src/util/usePrefersReducedMotion.ts +0 -48
  298. package/src/util/useReportScale.ts +0 -24
  299. package/src/util/useUniqueId.ts +0 -30
  300. package/src/zIndex/DefaultZIndexes.ts +0 -84
  301. package/src/zIndex/ZIndexLayer.tsx +0 -121
  302. package/src/zIndex/ZIndexPortal.tsx +0 -79
  303. package/src/zIndex/getZIndexFromUnknown.ts +0 -14
  304. package/src/zIndex/zIndexSelectors.ts +0 -48
@@ -1,1223 +0,0 @@
1
- /* eslint-disable import/no-cycle, sort-keys */
2
- import { createMemo, createSignal, For, Show, untrack } from 'solid-js';
3
- import type { JSX } from '@solidjs/web';
4
- import omit from "es-toolkit/compat/omit"
5
- import get from "es-toolkit/compat/get"
6
-
7
- import { Layer } from "../container/Layer"
8
- import { Surface } from "../container/Surface"
9
- import { Polygon } from "../shape/Polygon"
10
- import { Rectangle } from "../shape/Rectangle"
11
- import { getValueByDataKey } from "../util/ChartUtils"
12
- import { COLOR_PANEL } from "../util/Constants"
13
- import { isNan, noop } from "../util/DataUtils"
14
- import { getStringSize } from "../util/DOMUtils"
15
- import type {
16
- AnimationDuration,
17
- AnimationTiming,
18
- Coordinate,
19
- DataConsumer,
20
- DataKey,
21
- EventThrottlingProps,
22
- Margin,
23
- Percent,
24
- RectanglePosition,
25
- } from "../util/types"
26
- import { ReportChartMargin, useChartHeight, useChartWidth } from "../context/chartLayoutContext"
27
- import { RechartsWrapper } from "./RechartsWrapper"
28
- import type {
29
- TooltipIndex,
30
- TooltipPayloadConfiguration,
31
- TooltipPayloadSearcher,
32
- } from "../state/tooltipSlice"
33
- import { SetTooltipEntrySettings } from "../state/SetTooltipEntrySettings"
34
- import type { ChartOptions } from "../state/optionsSlice"
35
- import { RechartsStateProvider } from "../state/RechartsStateProvider"
36
- import { createInitialLayoutState } from "../state/chartState"
37
- import { ReportEventSettings } from "../state/ReportEventSettings"
38
- import { useOptionalChartState } from "../state/useChartState"
39
- import { isPositiveNumber } from "../util/isWellBehavedNumber"
40
- import { svgPropertiesNoEvents } from "../util/svgPropertiesNoEvents"
41
- import { CSSTransitionAnimate, extractCssEasing } from "../animation/CSSTransitionAnimate"
42
- import type { RequiresDefaultProps } from "../util/resolveDefaultProps"
43
- import { resolveDefaultProps } from "../util/resolveDefaultProps"
44
- import { RegisterGraphicalItemId } from "../context/RegisterGraphicalItemId"
45
- import type { GraphicalItemId } from "../state/graphicalItemsSlice"
46
- import { initialEventSettingsState } from "../state/eventSettingsSlice"
47
-
48
- import { splitProps } from '../util/solid-1-compat';
49
- import { setTooltipInteraction } from "../state/tooltipInteraction"
50
- const NODE_VALUE_KEY = "value"
51
-
52
- /**
53
- * This is what end users defines as `data` on Treemap.
54
- */
55
- export interface TreemapDataType {
56
- children?: ReadonlyArray<TreemapDataType>
57
-
58
- [key: string]: unknown
59
- }
60
-
61
- /**
62
- * This is what is returned from `squarify`, the final treemap data structure
63
- * that gets rendered and is stored in
64
- */
65
- export interface TreemapNode {
66
- children: ReadonlyArray<TreemapNode> | null
67
- value: number
68
- depth: number
69
- index: number
70
- x: number
71
- y: number
72
- width: number
73
- height: number
74
- name: string
75
- tooltipIndex: TooltipIndex
76
- root?: TreemapNode
77
-
78
- [k: string]: unknown
79
- }
80
-
81
- function isTreemapNode(value: unknown): value is TreemapNode {
82
- return (
83
- value != null &&
84
- typeof value === "object" &&
85
- "x" in value &&
86
- "y" in value &&
87
- "width" in value &&
88
- "height" in value &&
89
- typeof value.x === "number" &&
90
- typeof value.y === "number" &&
91
- typeof value.width === "number" &&
92
- typeof value.height === "number"
93
- )
94
- }
95
-
96
- export const treemapPayloadSearcher: TooltipPayloadSearcher = (
97
- data: unknown,
98
- activeIndex: TooltipIndex,
99
- ): TreemapNode | undefined => {
100
- if (data == null || activeIndex == null) {
101
- return undefined
102
- }
103
- return get(data, activeIndex)
104
- }
105
-
106
- export const addToTreemapNodeIndex = (
107
- indexInChildrenArr: number,
108
- activeTooltipIndexSoFar: TooltipIndex | undefined = "",
109
- ): TooltipIndex => {
110
- return `${activeTooltipIndexSoFar}children[${indexInChildrenArr}]`
111
- }
112
-
113
- const chartOptions: ChartOptions = {
114
- chartName: "Treemap",
115
- defaultTooltipEventType: "item",
116
- eventEmitter: undefined,
117
- tooltipPayloadSearcher: treemapPayloadSearcher,
118
- validateTooltipEventTypes: ["item"],
119
- }
120
-
121
- export const computeNode = <DataPointType extends TreemapDataType, DataValueType>({
122
- depth,
123
- node,
124
- index,
125
- dataKey,
126
- nameKey,
127
- nestedActiveTooltipIndex,
128
- }: {
129
- depth: number
130
- node: TreemapNode
131
- index: number
132
- dataKey: DataKey<DataPointType, DataValueType>
133
- nameKey: DataKey<DataPointType, DataValueType>
134
- nestedActiveTooltipIndex?: TooltipIndex | undefined
135
- }): TreemapNode => {
136
- const currentTooltipIndex =
137
- depth === 0 ? "" : addToTreemapNodeIndex(index, nestedActiveTooltipIndex)
138
- const { children } = node
139
- const childDepth = depth + 1
140
- const computedChildren =
141
- children && children.length
142
- ? children.map((child: TreemapNode, i: number) =>
143
- computeNode({
144
- dataKey,
145
- depth: childDepth,
146
- index: i,
147
- nameKey,
148
- nestedActiveTooltipIndex: currentTooltipIndex,
149
- node: child,
150
- }),
151
- )
152
- : null
153
- let nodeValue: number
154
-
155
- if (computedChildren && computedChildren.length) {
156
- nodeValue = computedChildren.reduce(
157
- (result: number, child: TreemapNode) => result + child.value,
158
- 0,
159
- )
160
- } else {
161
- /* TODO need to verify dataKey */
162
- const rawNodeValue = node[dataKey as string]
163
- const numericValue = typeof rawNodeValue === "number" ? rawNodeValue : 0
164
- nodeValue = isNan(numericValue) || numericValue <= 0 ? 0 : numericValue
165
- }
166
-
167
- return {
168
- ...node,
169
- children: computedChildren,
170
- name: getValueByDataKey(
171
- node as Record<string, unknown>,
172
- nameKey as DataKey<unknown>,
173
- "",
174
- ) as string,
175
- [NODE_VALUE_KEY]: nodeValue,
176
- depth,
177
- index,
178
- tooltipIndex: currentTooltipIndex,
179
- }
180
- }
181
-
182
- const filterRect = (node: TreemapNode): RectanglePosition => ({
183
- height: node.height,
184
- width: node.width,
185
- x: node.x,
186
- y: node.y,
187
- })
188
-
189
- const NEST_INDEX_HEIGHT = 30
190
-
191
- const getTreemapRenderHeight = (height: number, type: Props["type"]) => {
192
- if (type === "nest") {
193
- return height - NEST_INDEX_HEIGHT
194
- }
195
- return height
196
- }
197
-
198
- const insetRect = (rect: RectanglePosition, nodeInset: number): RectanglePosition => {
199
- if (!Number.isFinite(nodeInset) || nodeInset <= 0) {
200
- return rect
201
- }
202
-
203
- const clampedPadding = Math.min(nodeInset, rect.width / 2, rect.height / 2)
204
-
205
- return {
206
- x: rect.x + clampedPadding,
207
- y: rect.y + clampedPadding,
208
- width: Math.max(rect.width - clampedPadding * 2, 0),
209
- height: Math.max(rect.height - clampedPadding * 2, 0),
210
- }
211
- }
212
-
213
- const applyGapToChildren = (
214
- children: ReadonlyArray<TreemapNodeWithArea>,
215
- parentRect: RectanglePosition,
216
- nodeGap: number,
217
- ): ReadonlyArray<TreemapNodeWithArea> => {
218
- if (!Number.isFinite(nodeGap) || nodeGap <= 0) {
219
- return children
220
- }
221
-
222
- const halfGap = nodeGap / 2
223
- const parentRight = parentRect.x + parentRect.width
224
- const parentBottom = parentRect.y + parentRect.height
225
-
226
- return children.map((child) => {
227
- const childRight = child.x + child.width
228
- const childBottom = child.y + child.height
229
- const leftInset = child.x > parentRect.x ? halfGap : 0
230
- const rightInset = childRight < parentRight ? halfGap : 0
231
- const topInset = child.y > parentRect.y ? halfGap : 0
232
- const bottomInset = childBottom < parentBottom ? halfGap : 0
233
-
234
- return {
235
- ...child,
236
- x: child.x + leftInset,
237
- y: child.y + topInset,
238
- width: Math.max(child.width - leftInset - rightInset, 0),
239
- height: Math.max(child.height - topInset - bottomInset, 0),
240
- }
241
- })
242
- }
243
-
244
- type TreemapNodeWithArea = TreemapNode & { area: number }
245
-
246
- /* Compute the area for each child based on value & scale. */
247
- const getAreaOfChildren = (
248
- children: ReadonlyArray<TreemapNode>,
249
- areaValueRatio: number,
250
- ): ReadonlyArray<TreemapNodeWithArea> => {
251
- const ratio = areaValueRatio < 0 ? 0 : areaValueRatio
252
-
253
- return children.map((child: TreemapNode) => {
254
- const area = child[NODE_VALUE_KEY] * ratio
255
-
256
- return {
257
- ...child,
258
- area: isNan(area) || area <= 0 ? 0 : area,
259
- }
260
- })
261
- }
262
-
263
- /* Computes the score for the specified row, as the worst aspect ratio. */
264
- const getWorstScore = (
265
- row: AreaArray<TreemapNodeWithArea>,
266
- parentSize: number,
267
- aspectRatio: number,
268
- ): number => {
269
- const parentArea = parentSize * parentSize
270
- const rowArea = row.area * row.area
271
- const { min, max } = row.reduce(
272
- (result: { min: number; max: number }, child: TreemapNodeWithArea) => ({
273
- max: Math.max(result.max, child.area),
274
- min: Math.min(result.min, child.area),
275
- }),
276
- { max: 0, min: Infinity },
277
- )
278
-
279
- return rowArea
280
- ? Math.max(
281
- (parentArea * max * aspectRatio) / rowArea,
282
- rowArea / (parentArea * min * aspectRatio),
283
- )
284
- : Infinity
285
- }
286
-
287
- const horizontalPosition = (
288
- row: AreaArray<TreemapNodeWithArea>,
289
- parentSize: number,
290
- parentRect: RectanglePosition,
291
- isFlush: boolean,
292
- ): RectanglePosition => {
293
- let rowHeight = parentSize ? Math.round(row.area / parentSize) : 0
294
-
295
- if (isFlush || rowHeight > parentRect.height) {
296
- rowHeight = parentRect.height
297
- }
298
-
299
- let curX = parentRect.x
300
- let child
301
- for (let i = 0, len = row.length; i < len; i++) {
302
- child = row[i]
303
- if (child == null) {
304
- continue
305
- }
306
- child.x = curX
307
- child.y = parentRect.y
308
- child.height = rowHeight
309
- child.width = Math.min(
310
- rowHeight ? Math.round(child.area / rowHeight) : 0,
311
- parentRect.x + parentRect.width - curX,
312
- )
313
- curX += child.width
314
- }
315
- /* add the remain x to the last one of row */
316
- if (child != null) {
317
- child.width += parentRect.x + parentRect.width - curX
318
- }
319
-
320
- return {
321
- ...parentRect,
322
- height: parentRect.height - rowHeight,
323
- y: parentRect.y + rowHeight,
324
- }
325
- }
326
-
327
- const verticalPosition = (
328
- row: AreaArray<TreemapNodeWithArea>,
329
- parentSize: number,
330
- parentRect: RectanglePosition,
331
- isFlush: boolean,
332
- ): RectanglePosition => {
333
- let rowWidth = parentSize ? Math.round(row.area / parentSize) : 0
334
-
335
- if (isFlush || rowWidth > parentRect.width) {
336
- rowWidth = parentRect.width
337
- }
338
-
339
- let curY = parentRect.y
340
- let child
341
- for (let i = 0, len = row.length; i < len; i++) {
342
- child = row[i]
343
- if (child == null) {
344
- continue
345
- }
346
- child.x = parentRect.x
347
- child.y = curY
348
- child.width = rowWidth
349
- child.height = Math.min(
350
- rowWidth ? Math.round(child.area / rowWidth) : 0,
351
- parentRect.y + parentRect.height - curY,
352
- )
353
- curY += child.height
354
- }
355
- if (child) {
356
- child.height += parentRect.y + parentRect.height - curY
357
- }
358
-
359
- return {
360
- ...parentRect,
361
- width: parentRect.width - rowWidth,
362
- x: parentRect.x + rowWidth,
363
- }
364
- }
365
-
366
- const position = (
367
- row: AreaArray<TreemapNodeWithArea>,
368
- parentSize: number,
369
- parentRect: RectanglePosition,
370
- isFlush: boolean,
371
- ): RectanglePosition => {
372
- if (parentSize === parentRect.width) {
373
- return horizontalPosition(row, parentSize, parentRect, isFlush)
374
- }
375
-
376
- return verticalPosition(row, parentSize, parentRect, isFlush)
377
- }
378
-
379
- type AreaArray<T> = Array<T> & { area: number }
380
-
381
- /* Recursively arranges the specified node's children into squarified rows. */
382
- const squarify = (
383
- node: TreemapNode,
384
- aspectRatio: number,
385
- nodeInset: number,
386
- nodeGap: number,
387
- ): TreemapNode => {
388
- const { children } = node
389
-
390
- if (children && children.length) {
391
- const layoutRect: RectanglePosition = insetRect(filterRect(node), nodeInset)
392
- let rect: RectanglePosition = layoutRect
393
- const row = [] as unknown as AreaArray<TreemapNodeWithArea>
394
- let best = Infinity
395
- let child, score
396
- let size = Math.min(rect.width, rect.height)
397
- const scaleChildren = getAreaOfChildren(
398
- children,
399
- (rect.width * rect.height) / node[NODE_VALUE_KEY],
400
- )
401
- const tempChildren = scaleChildren.slice()
402
-
403
- /* why are we setting static properties on an array? */
404
- row.area = 0
405
-
406
- while (tempChildren.length > 0) {
407
- ;[child] = tempChildren
408
- if (child == null) {
409
- continue
410
- }
411
- /* row first */
412
- row.push(child)
413
- row.area += child.area
414
-
415
- score = getWorstScore(row, size, aspectRatio)
416
- if (score <= best) {
417
- /* continue with this orientation */
418
- tempChildren.shift()
419
- best = score
420
- } else {
421
- /* abort, and try a different orientation */
422
- row.area -= row.pop()?.area ?? 0
423
- rect = position(row, size, rect, false)
424
- size = Math.min(rect.width, rect.height)
425
- row.length = row.area = 0
426
- best = Infinity
427
- }
428
- }
429
-
430
- if (row.length) {
431
- rect = position(row, size, rect, true)
432
- row.length = row.area = 0
433
- }
434
-
435
- const childrenWithGaps = applyGapToChildren(scaleChildren, layoutRect, nodeGap)
436
-
437
- return {
438
- ...node,
439
- children: childrenWithGaps.map((c) => squarify(c, aspectRatio, nodeInset, nodeGap)),
440
- }
441
- }
442
-
443
- return node
444
- }
445
-
446
- export type TreemapContentType = JSX.Element | ((props: TreemapNode) => JSX.Element)
447
-
448
- export interface Props<
449
- DataPointType extends TreemapDataType = TreemapDataType,
450
- DataValueType = unknown,
451
- >
452
- extends DataConsumer<DataPointType, DataValueType>, EventThrottlingProps {
453
- /**
454
- * The width of chart container.
455
- * Can be a number or a percent string like "100%".
456
- */
457
- width?: number | Percent
458
-
459
- /**
460
- * The height of chart container.
461
- * Can be a number or a percent string like "100%".
462
- */
463
- height?: number | Percent
464
-
465
- /**
466
- * The source data. Each element should be an object.
467
- * The properties of each object represent the values of different data dimensions.
468
- *
469
- * Use the `dataKey` prop to specify which properties to use.
470
- *
471
- * If the `children` property is present on an element, it will be treated as a nested treemap.
472
- */
473
- data?: ReadonlyArray<DataPointType>
474
-
475
- /**
476
- * @deprecated unused prop, doesn't do anything, use `key` instead
477
- */
478
- animationId?: number
479
-
480
- style?: JSX.CSSProperties
481
-
482
- /**
483
- * The treemap will try to keep every single rectangle's aspect ratio near the aspectRatio given.
484
- * @default 1.618033988749895
485
- */
486
- aspectRatio?: number
487
-
488
- /**
489
- * The inset between a parent node and its child nodes.
490
- *
491
- * Insets a parent node's available area before laying out its children.
492
- * This creates space between a parent boundary and its child nodes.
493
- * @default 0
494
- */
495
- nodeInset?: number
496
-
497
- /**
498
- * The gap between the nodes.
499
- *
500
- * Adds spacing between sibling nodes at the same depth level.
501
- * This does not inset children from their parent boundary.
502
- * @default 0
503
- */
504
- nodeGap?: number
505
-
506
- /**
507
- * If set to a function, the function will be called to render the content.
508
- */
509
- content?: TreemapContentType
510
-
511
- fill?: string
512
-
513
- stroke?: string
514
-
515
- class?: string
516
-
517
- /**
518
- * Name represents each sector in the tooltip.
519
- * This allows you to extract the name from the data:
520
- *
521
- * - `string`: the name of the field in the data object;
522
- * - `number`: the index of the field in the data;
523
- * - `function`: a function that receives the data object and returns the name.
524
- *
525
- * @defaultValue 'name'
526
- */
527
- nameKey?: DataKey<DataPointType, DataValueType>
528
-
529
- /**
530
- * Decides how to extract the value of this Treemap from the data:
531
- * - `string`: the name of the field in the data object;
532
- * - `number`: the index of the field in the data;
533
- * - `function`: a function that receives the data object and returns the value of this Treemap.
534
- *
535
- * @defaultValue 'value'
536
- */
537
- dataKey?: DataKey<DataPointType, DataValueType>
538
-
539
- children?: JSX.Element
540
-
541
- /**
542
- * The type of treemap to render.
543
- *
544
- * - 'flat': Renders the entire treemap at once, with all leaf nodes visible.
545
- * - 'nest': Renders an interactive, nested treemap. Clicking on a parent node will "zoom in" to show its children,
546
- * and a breadcrumb navigation will be displayed to allow navigating back up the hierarchy.
547
- *
548
- * @default 'flat'
549
- */
550
- type?: "flat" | "nest"
551
-
552
- colorPanel?: ReadonlyArray<string>
553
-
554
- /* customize nest index content */
555
- nestIndexContent?: (item: TreemapNode, i: number) => JSX.Element
556
-
557
- /**
558
- * The customized event handler of animation start
559
- */
560
- onAnimationStart?: () => void
561
-
562
- /**
563
- * The customized event handler of animation end
564
- */
565
- onAnimationEnd?: () => void
566
-
567
- onMouseEnter?: (node: TreemapNode, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
568
-
569
- onMouseLeave?: (node: TreemapNode, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
570
-
571
- onClick?: (node: TreemapNode) => void
572
-
573
- /**
574
- * If set false, animation of treemap will be disabled.
575
- * If set "auto", animation is disabled during SSR and when the user prefers reduced motion.
576
- * @default 'auto'
577
- */
578
- isAnimationActive?: boolean | "auto"
579
-
580
- isUpdateAnimationActive?: boolean | "auto"
581
-
582
- /**
583
- * Specifies when the animation should begin, the unit of this option is ms.
584
- * @default 0
585
- */
586
- animationBegin?: number
587
-
588
- /**
589
- * Specifies the duration of animation, the unit of this option is ms.
590
- * @default 1500
591
- */
592
- animationDuration?: AnimationDuration
593
-
594
- /**
595
- * The type of easing function.
596
- * @default 'linear'
597
- */
598
- animationEasing?: AnimationTiming
599
-
600
- id?: string
601
- }
602
-
603
- type ContentItemProps = {
604
- id: GraphicalItemId
605
- content: TreemapContentType | undefined
606
- nodeProps: TreemapNode
607
- type: string
608
- colorPanel: ReadonlyArray<string> | undefined
609
- dataKey: DataKey<unknown>
610
- onClick?: (e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
611
- onMouseEnter?: (e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
612
- onMouseLeave?: (e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
613
- onMouseOver?: (e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
614
- onMouseOut?: (e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
615
- }
616
-
617
- /* eslint-disable solid/reactivity -- ContentItem reads are structural checks at setup; props are stable per render since component is created fresh per node */
618
- function ContentItem(props: ContentItemProps): JSX.Element {
619
- if (typeof props.content === "function") {
620
- return (
621
- <Layer
622
- onMouseEnter={props.onMouseEnter}
623
- onMouseOver={props.onMouseOver}
624
- onMouseLeave={props.onMouseLeave}
625
- onMouseOut={props.onMouseOut}
626
- onClick={props.onClick}
627
- >
628
- {(props.content as (p: TreemapNode) => JSX.Element)(props.nodeProps)}
629
- </Layer>
630
- )
631
- }
632
- /* optimize default shape */
633
- const { x, y, width, height, index } = untrack(() => ({
634
- height: props.nodeProps.height,
635
- index: props.nodeProps.index,
636
- width: props.nodeProps.width,
637
- x: props.nodeProps.x,
638
- y: props.nodeProps.y,
639
- }))
640
- let arrow: JSX.Element | null = null
641
- if (
642
- width > 10 &&
643
- height > 10 &&
644
- props.nodeProps.children &&
645
- props.type === "nest" &&
646
- props.nodeProps.depth > 0
647
- ) {
648
- arrow = (
649
- <Polygon
650
- points={[
651
- { x: x + 2, y: y + height / 2 },
652
- { x: x + 6, y: y + height / 2 + 3 },
653
- { x: x + 2, y: y + height / 2 + 6 },
654
- ]}
655
- />
656
- )
657
- }
658
- let text: JSX.Element | null = null
659
- const nameSize = getStringSize(props.nodeProps.name)
660
- if (width > 20 && height > 20 && nameSize.width < width && nameSize.height < height) {
661
- text = (
662
- <text x={x + 8} y={y + height / 2 + 7} font-size={String(14)}>
663
- {props.nodeProps.name}
664
- </text>
665
- )
666
- }
667
-
668
- const colors = props.colorPanel || COLOR_PANEL
669
- const rectProps = untrack(() => omit(props.nodeProps, ["children"]))
670
- return (
671
- <g>
672
- <Rectangle
673
- fill={untrack(() =>
674
- props.nodeProps.depth < 2 ? colors[index % colors.length] : "rgba(255,255,255,0)",
675
- )}
676
- stroke="#fff"
677
- {...rectProps}
678
- onMouseEnter={props.onMouseEnter}
679
- onMouseOver={props.onMouseOver}
680
- onMouseLeave={props.onMouseLeave}
681
- onMouseOut={props.onMouseOut}
682
- onClick={props.onClick}
683
- data-recharts-item-index={props.nodeProps.tooltipIndex}
684
- />
685
- {arrow}
686
- {text}
687
- </g>
688
- )
689
- }
690
- /* eslint-enable solid/reactivity */
691
-
692
- function ContentItemWithEvents(props: ContentItemProps): JSX.Element {
693
- const newCtx = useOptionalChartState()
694
- /* GOTCHA-005: createMemo so reactive nodeProps flow into coordinate. */
695
- const activeCoordinate = createMemo<Coordinate>(() => ({
696
- x: props.nodeProps.x + props.nodeProps.width / 2,
697
- y: props.nodeProps.y + props.nodeProps.height / 2,
698
- }))
699
-
700
- /* GOTCHA-016-C: dedupe enter/over so user.hover only fires dispatch once. */
701
- let entered = false
702
- const fireEnter = () => {
703
- if (entered) return
704
- entered = true
705
- const hoverPayload = {
706
- active: true,
707
- coordinate: activeCoordinate(),
708
- dataKey: props.dataKey,
709
- graphicalItemId: props.id,
710
- index: props.nodeProps.tooltipIndex,
711
- }
712
- if (newCtx != null) setTooltipInteraction(newCtx.setState, "itemInteraction", "hover", hoverPayload)
713
- }
714
- const fireLeave = () => {
715
- if (!entered) return
716
- entered = false
717
- /*
718
- * clearing state on mouseLeaveItem causes re-rendering issues
719
- * we don't actually want to do this for TreeMap - we clear state when we leave the entire chart instead
720
- */
721
- }
722
- const onClick = () => {
723
- const clickPayload = {
724
- active: true,
725
- coordinate: activeCoordinate(),
726
- dataKey: props.dataKey,
727
- graphicalItemId: props.id,
728
- index: props.nodeProps.tooltipIndex,
729
- }
730
- if (newCtx != null) setTooltipInteraction(newCtx.setState, "itemInteraction", "click", clickPayload)
731
- }
732
- return (
733
- <ContentItem
734
- {...props}
735
- onMouseEnter={fireEnter}
736
- onMouseOver={fireEnter}
737
- onMouseLeave={fireLeave}
738
- onMouseOut={fireLeave}
739
- onClick={onClick}
740
- />
741
- )
742
- }
743
-
744
- function SetTreemapTooltipEntrySettings(props: {
745
- dataKey: DataKey<unknown>
746
- nameKey: DataKey<unknown>
747
- stroke: string | undefined
748
- fill: string | undefined
749
- currentRoot: TreemapNode | undefined
750
- id: GraphicalItemId
751
- }): JSX.Element {
752
- /* GOTCHA-005: createMemo so reactive props flow into the settings object. */
753
- const tooltipEntrySettings = createMemo<TooltipPayloadConfiguration>(() => ({
754
- dataDefinedOnItem: props.currentRoot,
755
- getPosition: noop,
756
- settings: {
757
- color: props.fill,
758
- dataKey: props.dataKey,
759
- fill: props.fill,
760
- graphicalItemId: props.id,
761
- hide: false,
762
- name: undefined,
763
- nameKey: props.nameKey,
764
- stroke: props.stroke,
765
- strokeWidth: undefined,
766
- type: undefined,
767
- unit: "",
768
- },
769
- }))
770
- return <SetTooltipEntrySettings tooltipEntrySettings={tooltipEntrySettings()} />
771
- }
772
-
773
- /* Why is margin not a treemap prop? No clue. Probably it should be */
774
- const defaultTreemapMargin: Margin = {
775
- bottom: 0,
776
- left: 0,
777
- right: 0,
778
- top: 0,
779
- }
780
-
781
- export const defaultTreeMapProps = {
782
- animationBegin: 0,
783
- animationDuration: 1500,
784
- animationEasing: "linear",
785
- aspectRatio: 0.5 * (1 + Math.sqrt(5)),
786
- dataKey: "value",
787
- isAnimationActive: "auto",
788
- isUpdateAnimationActive: "auto",
789
- nameKey: "name",
790
- nodeGap: 0,
791
- nodeInset: 0,
792
- type: "flat",
793
- ...initialEventSettingsState,
794
- } as const satisfies Partial<Props>
795
-
796
- type InternalTreemapProps = RequiresDefaultProps<Props, typeof defaultTreeMapProps> & {
797
- width: number
798
- height: number
799
- id: GraphicalItemId
800
- }
801
-
802
- /* eslint-disable solid/reactivity -- itemProps.nodeProps destructure and treemapProps reads are stable at component setup; TreemapItem is created fresh per node */
803
- function TreemapItem(itemProps: {
804
- content: TreemapContentType | undefined
805
- nodeProps: TreemapNode
806
- isLeaf: boolean
807
- treemapProps: InternalTreemapProps
808
- onNestClick: (node: TreemapNode) => void
809
- }): JSX.Element {
810
- const { width, height, x, y } = itemProps.nodeProps
811
- const translateX = -x - width
812
- const translateY = 0
813
-
814
- const onMouseEnter = (e: MouseEvent & { currentTarget: SVGGraphicsElement }) => {
815
- if (
816
- (itemProps.isLeaf || itemProps.treemapProps.type === "nest") &&
817
- typeof itemProps.treemapProps.onMouseEnter === "function"
818
- ) {
819
- itemProps.treemapProps.onMouseEnter(itemProps.nodeProps, e)
820
- }
821
- }
822
-
823
- const onMouseLeave = (e: MouseEvent & { currentTarget: SVGGraphicsElement }) => {
824
- if (
825
- (itemProps.isLeaf || itemProps.treemapProps.type === "nest") &&
826
- typeof itemProps.treemapProps.onMouseLeave === "function"
827
- ) {
828
- itemProps.treemapProps.onMouseLeave(itemProps.nodeProps, e)
829
- }
830
- }
831
-
832
- const onClick = () => {
833
- if (itemProps.treemapProps.type === "nest" && itemProps.nodeProps.depth > 0) {
834
- itemProps.onNestClick(itemProps.nodeProps)
835
- }
836
- if (
837
- (itemProps.isLeaf || itemProps.treemapProps.type === "nest") &&
838
- typeof itemProps.treemapProps.onClick === "function"
839
- ) {
840
- itemProps.treemapProps.onClick(itemProps.nodeProps)
841
- }
842
- }
843
-
844
- /* One object per item: an inline JSX object literal is a getter that re-spreads on every
845
- `props.nodeProps` read downstream. ContentItem snapshots node props at setup, and
846
- x/y/width/height above are setup constants, so a setup snapshot reads the same. */
847
- const contentNodeProps = untrack(() => ({
848
- ...itemProps.nodeProps,
849
- height,
850
- isAnimationActive: itemProps.treemapProps.isAnimationActive,
851
- isUpdateAnimationActive: !itemProps.treemapProps.isUpdateAnimationActive,
852
- width,
853
- x,
854
- y,
855
- }))
856
-
857
- function handleAnimationEnd() {
858
- if (typeof itemProps.treemapProps.onAnimationEnd === "function") {
859
- itemProps.treemapProps.onAnimationEnd()
860
- }
861
- }
862
-
863
- function handleAnimationStart() {
864
- if (typeof itemProps.treemapProps.onAnimationStart === "function") {
865
- itemProps.treemapProps.onAnimationStart()
866
- }
867
- }
868
-
869
- return (
870
- <CSSTransitionAnimate
871
- animationId={`treemap-${itemProps.nodeProps.tooltipIndex}`}
872
- from={`translate(${translateX}px, ${translateY}px)`}
873
- to="translate(0, 0)"
874
- attributeName="transform"
875
- begin={itemProps.treemapProps.animationBegin}
876
- easing={extractCssEasing(itemProps.treemapProps.animationEasing)}
877
- isActive={itemProps.treemapProps.isAnimationActive}
878
- duration={itemProps.treemapProps.animationDuration}
879
- onAnimationStart={handleAnimationStart}
880
- onAnimationEnd={handleAnimationEnd}
881
- >
882
- {(style) => (
883
- <Layer
884
- onMouseEnter={onMouseEnter}
885
- onMouseLeave={onMouseLeave}
886
- onClick={onClick}
887
- style={{ ...style(), "transform-origin": `${x} ${y}` }}
888
- >
889
- <ContentItemWithEvents
890
- id={itemProps.treemapProps.id}
891
- content={itemProps.content}
892
- dataKey={itemProps.treemapProps.dataKey as DataKey<unknown>}
893
- nodeProps={contentNodeProps}
894
- type={itemProps.treemapProps.type}
895
- colorPanel={itemProps.treemapProps.colorPanel}
896
- />
897
- </Layer>
898
- )}
899
- </CSSTransitionAnimate>
900
- )
901
- }
902
- /* eslint-enable solid/reactivity */
903
-
904
- function TreemapWithState(props: InternalTreemapProps): JSX.Element {
905
- const newCtx = useOptionalChartState()
906
-
907
- const derivedTree = createMemo(() => {
908
- const root: TreemapNode = computeNode({
909
- dataKey: props.dataKey,
910
- depth: 0,
911
- index: 0,
912
- nameKey: props.nameKey,
913
- node: {
914
- children: props.data,
915
- height: getTreemapRenderHeight(props.height, props.type),
916
- width: props.width,
917
- x: 0,
918
- y: 0,
919
- } as unknown as TreemapNode,
920
- })
921
- const fRoot: TreemapNode = squarify(
922
- root,
923
- props.aspectRatio,
924
- props.nodeInset,
925
- props.nodeGap,
926
- )
927
- return { currentRoot: root, formatRoot: fRoot }
928
- })
929
-
930
- const [nest, setNest] = createSignal<{
931
- currentRoot: TreemapNode
932
- formatRoot: TreemapNode
933
- nestIndex: Array<TreemapNode>
934
- } | null>(null)
935
-
936
- const formatRoot = createMemo(
937
- () => nest()?.formatRoot ?? derivedTree().formatRoot,
938
- )
939
- const currentRoot = createMemo(
940
- () => nest()?.currentRoot ?? derivedTree().currentRoot,
941
- )
942
- const nestIndex = createMemo(
943
- () => nest()?.nestIndex ?? [derivedTree().currentRoot],
944
- )
945
-
946
- function handleClick(node: TreemapNode) {
947
- if (props.type === "nest" && node.children) {
948
- const root = computeNode({
949
- depth: 0,
950
- node: {
951
- ...node,
952
- height: getTreemapRenderHeight(props.height, props.type),
953
- width: props.width,
954
- x: 0,
955
- y: 0,
956
- },
957
- index: 0,
958
- dataKey: props.dataKey,
959
- nameKey: props.nameKey,
960
- /* with Treemap nesting, should this continue nesting the index or start from empty string? */
961
- nestedActiveTooltipIndex: node.tooltipIndex,
962
- })
963
-
964
- const fRoot = squarify(root, props.aspectRatio, props.nodeInset, props.nodeGap)
965
- setNest({
966
- currentRoot: root,
967
- formatRoot: fRoot,
968
- nestIndex: [...nestIndex(), node],
969
- })
970
- }
971
- if (props.onClick) {
972
- props.onClick(node)
973
- }
974
- }
975
-
976
- function handleNestIndex(node: TreemapNode, i: number) {
977
- const root = computeNode({
978
- depth: 0,
979
- node: {
980
- ...node,
981
- height: getTreemapRenderHeight(props.height, props.type),
982
- width: props.width,
983
- x: 0,
984
- y: 0,
985
- },
986
- index: 0,
987
- dataKey: props.dataKey,
988
- nameKey: props.nameKey,
989
- /* with Treemap nesting, should this continue nesting the index or start from empty string? */
990
- nestedActiveTooltipIndex: node.tooltipIndex,
991
- })
992
-
993
- const fRoot = squarify(root, props.aspectRatio, props.nodeInset, props.nodeGap)
994
- setNest({
995
- currentRoot: node,
996
- formatRoot: fRoot,
997
- nestIndex: nestIndex().slice(0, i + 1),
998
- })
999
- }
1000
-
1001
- /* The chart's SVG props are the same for every node; filter the props view once. */
1002
- const chartSvgProps = createMemo(() => svgPropertiesNoEvents(props))
1003
-
1004
- function renderNode(root: TreemapNode, node: TreemapNode): JSX.Element | null {
1005
- const nodeProps = untrack(() => ({ ...chartSvgProps(), ...node, root }))
1006
- const isLeaf = node.children == null || node.children.length === 0
1007
-
1008
- const curRoot = untrack(() => currentRoot())
1009
- const isCurrentRootChild = (curRoot?.children || []).filter(
1010
- (item: TreemapNode) => item.depth === node.depth && item.name === node.name,
1011
- )
1012
-
1013
- if (isCurrentRootChild.length === 0 && root.depth && props.type === "nest") {
1014
- return null
1015
- }
1016
-
1017
- return (
1018
- <Layer class={`recharts-treemap-depth-${node.depth}`}>
1019
- <TreemapItem
1020
- isLeaf={isLeaf}
1021
- content={props.content}
1022
- nodeProps={nodeProps}
1023
- treemapProps={props}
1024
- onNestClick={handleClick}
1025
- />
1026
- <Show when={node.children && node.children.length}>
1027
- <For each={node.children as TreemapNode[]}>
1028
- {(child: TreemapNode) => renderNode(node, child)}
1029
- </For>
1030
- </Show>
1031
- </Layer>
1032
- )
1033
- }
1034
-
1035
- function renderAllNodes(): JSX.Element | null {
1036
- const fRoot = formatRoot()
1037
-
1038
- if (fRoot == null) {
1039
- return null
1040
- }
1041
-
1042
- return renderNode(fRoot, fRoot)
1043
- }
1044
-
1045
- function renderNestIndexContent(item: TreemapNode, i: number): JSX.Element | string {
1046
- if (typeof props.nestIndexContent === "function") {
1047
- return props.nestIndexContent(item, i)
1048
- }
1049
- /* TODO need to verify nameKey type */
1050
- const rawName = get(item, props.nameKey as string, "root")
1051
- return typeof rawName === "string" ? rawName : "root"
1052
- }
1053
-
1054
- /* render nest treemap */
1055
- function renderNestIndex(): JSX.Element {
1056
- return (
1057
- <div
1058
- class="recharts-treemap-nest-index-wrapper"
1059
- style={{ "margin-top": "8px", "text-align": "center" }}
1060
- >
1061
- <For each={nestIndex()}>
1062
- {(item: TreemapNode, i) => (
1063
- <div
1064
- onClick={() => handleNestIndex(item, i())}
1065
- class="recharts-treemap-nest-index-box"
1066
- style={{
1067
- background: "#000",
1068
- color: "#fff",
1069
- cursor: "pointer",
1070
- display: "inline-block",
1071
- "margin-right": "3px",
1072
- padding: "0 7px",
1073
- }}
1074
- >
1075
- {renderNestIndexContent(item, i())}
1076
- </div>
1077
- )}
1078
- </For>
1079
- </div>
1080
- )
1081
- }
1082
-
1083
- function handleTouchMove(e: TouchEvent) {
1084
- const touchEvent = e.touches[0]
1085
- if (touchEvent == null) {
1086
- return
1087
- }
1088
- const target = document.elementFromPoint(touchEvent.clientX, touchEvent.clientY)
1089
- if (target == null || typeof target.getAttribute !== "function" || formatRoot() == null) {
1090
- return
1091
- }
1092
- const itemIndex = target.getAttribute("data-recharts-item-index")
1093
- const activeNode: unknown = treemapPayloadSearcher(formatRoot(), itemIndex)
1094
- if (isTreemapNode(activeNode) === false) {
1095
- return
1096
- }
1097
- const treemapNode = activeNode as TreemapNode
1098
-
1099
- const activeCoordinate = {
1100
- x: treemapNode.x + treemapNode.width / 2,
1101
- y: treemapNode.y + treemapNode.height / 2,
1102
- }
1103
-
1104
- const itemPayload = {
1105
- active: true,
1106
- coordinate: activeCoordinate,
1107
- dataKey: props.dataKey as DataKey<unknown>,
1108
- graphicalItemId: props.id,
1109
- index: itemIndex,
1110
- }
1111
- if (newCtx != null) setTooltipInteraction(newCtx.setState, "itemInteraction", "hover", itemPayload)
1112
- }
1113
-
1114
- const attrs = () => svgPropertiesNoEvents(props)
1115
-
1116
- return (
1117
- <>
1118
- <SetTreemapTooltipEntrySettings
1119
- dataKey={props.dataKey as DataKey<unknown>}
1120
- nameKey={props.nameKey as DataKey<unknown>}
1121
- stroke={props.stroke}
1122
- fill={props.fill}
1123
- currentRoot={currentRoot()}
1124
- id={props.id}
1125
- />
1126
- <Surface
1127
- {...attrs()}
1128
- width={props.width}
1129
- height={getTreemapRenderHeight(props.height, props.type)}
1130
- onTouchMove={handleTouchMove}
1131
- >
1132
- {renderAllNodes()}
1133
- {props.children}
1134
- </Surface>
1135
- <Show when={props.type === "nest"}>{renderNestIndex()}</Show>
1136
- </>
1137
- )
1138
- }
1139
-
1140
- function TreemapDispatchInject(
1141
- props: RequiresDefaultProps<Props, typeof defaultTreeMapProps> & { children?: JSX.Element },
1142
- ): JSX.Element | null {
1143
- /* width/height arrive after layout dispatch; gate on Show so the body
1144
- re-evaluates once dimensions populate. See GOTCHA-011. */
1145
- const width = createMemo(() => useChartWidth())
1146
- const height = createMemo(() => useChartHeight())
1147
- const hasSize = createMemo(
1148
- () => isPositiveNumber(width()) && isPositiveNumber(height()),
1149
- )
1150
- const [childrenSplit, restProps] = splitProps(props, ["children"])
1151
- return (
1152
- <Show when={hasSize()}>
1153
- <RegisterGraphicalItemId id={restProps.id} type="treemap">
1154
- {(id) => (
1155
- <TreemapWithState
1156
- {...restProps}
1157
- id={id}
1158
- width={width() as number}
1159
- height={height() as number}
1160
- >
1161
- {childrenSplit.children}
1162
- </TreemapWithState>
1163
- )}
1164
- </RegisterGraphicalItemId>
1165
- </Show>
1166
- )
1167
- }
1168
-
1169
- /**
1170
- * The Treemap chart is used to visualize hierarchical data using nested rectangles.
1171
- *
1172
- * @consumes ResponsiveContainerContext
1173
- * @provides TooltipEntrySettings
1174
- */
1175
- export function Treemap(outsideProps: Props): JSX.Element {
1176
- /* GOTCHA-005-B: split children to avoid spread-induced enumeration that would
1177
- instantiate user JSX (Tooltip, etc.) under outer owner. */
1178
- const [childrenSplit, restProps] = splitProps(outsideProps, ["children"])
1179
- const props = resolveDefaultProps(restProps, defaultTreeMapProps)
1180
-
1181
- return (
1182
- <RechartsStateProvider
1183
- preloadedState={{
1184
- layout: untrack(() =>
1185
- createInitialLayoutState({ height: props.height, margin: defaultTreemapMargin, width: props.width }),
1186
- ),
1187
- options: chartOptions,
1188
- }}
1189
- >
1190
- <ReportChartMargin margin={defaultTreemapMargin} />
1191
- <ReportEventSettings
1192
- throttleDelay={props.throttleDelay}
1193
- throttledEvents={props.throttledEvents}
1194
- />
1195
- <RechartsWrapper
1196
- dispatchTouchEvents={false}
1197
- class={props.class}
1198
- style={props.style}
1199
- width={props.width}
1200
- height={props.height}
1201
- /*
1202
- * Treemap has a bug where it doesn't include strokeWidth in its dimension calculation
1203
- * which makes the actual chart exactly {strokeWidth} larger than asked for.
1204
- * It's not a huge deal usually, but it makes the responsive option cycle infinitely.
1205
- */
1206
- responsive={false}
1207
- onMouseEnter={undefined}
1208
- onMouseLeave={undefined}
1209
- onClick={undefined}
1210
- onMouseMove={undefined}
1211
- onMouseDown={undefined}
1212
- onMouseUp={undefined}
1213
- onContextMenu={undefined}
1214
- onDoubleClick={undefined}
1215
- onTouchStart={undefined}
1216
- onTouchMove={undefined}
1217
- onTouchEnd={undefined}
1218
- >
1219
- <TreemapDispatchInject {...props}>{childrenSplit.children}</TreemapDispatchInject>
1220
- </RechartsWrapper>
1221
- </RechartsStateProvider>
1222
- )
1223
- }