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