@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.
- package/dist/index.d.ts +40 -2
- package/dist/index.js +14238 -7174
- package/dist/{dev.js → index.jsx} +18367 -15900
- package/dist/server.js +48178 -0
- package/package.json +36 -19
- package/src/animation/AnimatedItems.tsx +0 -183
- package/src/animation/AnimationController.ts +0 -33
- package/src/animation/AnimationControllerImpl.ts +0 -36
- package/src/animation/AnimationHandle.ts +0 -307
- package/src/animation/CSSTransitionAnimate.tsx +0 -170
- package/src/animation/JavascriptAnimate.tsx +0 -119
- package/src/animation/easing.ts +0 -221
- package/src/animation/matchBy.ts +0 -164
- package/src/animation/timeoutController.ts +0 -70
- package/src/animation/useAnimationController.tsx +0 -34
- package/src/animation/useAnimationStartSnapshot.ts +0 -118
- package/src/animation/util.ts +0 -41
- package/src/cartesian/Area.tsx +0 -915
- package/src/cartesian/AreaRevealShape.tsx +0 -190
- package/src/cartesian/Bar.tsx +0 -1369
- package/src/cartesian/BarStack.tsx +0 -152
- package/src/cartesian/Brush.tsx +0 -951
- package/src/cartesian/CartesianAxis.tsx +0 -722
- package/src/cartesian/CartesianGrid.tsx +0 -711
- package/src/cartesian/ErrorBar.tsx +0 -361
- package/src/cartesian/Funnel.tsx +0 -803
- package/src/cartesian/GraphicalItemClipPath.tsx +0 -67
- package/src/cartesian/Line.tsx +0 -863
- package/src/cartesian/LineDrawShape.tsx +0 -89
- package/src/cartesian/ReferenceArea.tsx +0 -331
- package/src/cartesian/ReferenceDot.tsx +0 -304
- package/src/cartesian/ReferenceLine.tsx +0 -474
- package/src/cartesian/Scatter.tsx +0 -888
- package/src/cartesian/XAxis.tsx +0 -433
- package/src/cartesian/YAxis.tsx +0 -443
- package/src/cartesian/ZAxis.tsx +0 -155
- package/src/cartesian/cartesianPositionToCSSTranslate.tsx +0 -29
- package/src/cartesian/cartesianViewBoxToTrapezoid.tsx +0 -21
- package/src/cartesian/getCartesianPosition.tsx +0 -267
- package/src/cartesian/getEquidistantTicks.ts +0 -144
- package/src/cartesian/getTicks.ts +0 -225
- package/src/cartesian/isOutsidePosition.ts +0 -15
- package/src/cartesian/useAnimatedLineLength.ts +0 -54
- package/src/chart/AreaChart.tsx +0 -29
- package/src/chart/BarChart.tsx +0 -29
- package/src/chart/CartesianChart.tsx +0 -131
- package/src/chart/CategoricalChart.tsx +0 -94
- package/src/chart/ComposedChart.tsx +0 -29
- package/src/chart/FunnelChart.tsx +0 -29
- package/src/chart/LineChart.tsx +0 -29
- package/src/chart/PieChart.tsx +0 -50
- package/src/chart/PolarChart.tsx +0 -164
- package/src/chart/RadarChart.tsx +0 -70
- package/src/chart/RadialBarChart.tsx +0 -46
- package/src/chart/RechartsWrapper.tsx +0 -551
- package/src/chart/Sankey.tsx +0 -1534
- package/src/chart/ScatterChart.tsx +0 -29
- package/src/chart/SunburstChart.tsx +0 -504
- package/src/chart/Treemap.tsx +0 -1223
- package/src/chart/createInitialRootProps.ts +0 -24
- package/src/chart/types.ts +0 -53
- package/src/component/ActivePoints.tsx +0 -144
- package/src/component/Cell.tsx +0 -37
- package/src/component/Cursor.tsx +0 -185
- package/src/component/Customized.tsx +0 -50
- package/src/component/DefaultLegendContent.tsx +0 -348
- package/src/component/DefaultTooltipContent.tsx +0 -224
- package/src/component/Dots.tsx +0 -157
- package/src/component/Label.tsx +0 -636
- package/src/component/LabelList.tsx +0 -375
- package/src/component/Legend.tsx +0 -512
- package/src/component/ResponsiveContainer.tsx +0 -348
- package/src/component/Text.tsx +0 -541
- package/src/component/Tooltip.tsx +0 -470
- package/src/component/TooltipBoundingBox.tsx +0 -146
- package/src/component/responsiveContainerUtils.ts +0 -134
- package/src/container/ClipPathProvider.tsx +0 -51
- package/src/container/Layer.tsx +0 -38
- package/src/container/RootSurface.tsx +0 -120
- package/src/container/Surface.tsx +0 -61
- package/src/context/CellsContext.tsx +0 -54
- package/src/context/ErrorBarContext.tsx +0 -146
- package/src/context/GraphicalItemChildrenScope.tsx +0 -18
- package/src/context/PanoramaContext.tsx +0 -9
- package/src/context/RegisterGraphicalItemId.tsx +0 -30
- package/src/context/accessibilityContext.tsx +0 -6
- package/src/context/brushUpdateContext.tsx +0 -9
- package/src/context/chartDataContext.tsx +0 -97
- package/src/context/chartLayoutContext.tsx +0 -201
- package/src/context/legendPayloadContext.tsx +0 -20
- package/src/context/legendPortalContext.tsx +0 -12
- package/src/context/tooltipContext.tsx +0 -89
- package/src/context/tooltipPortalContext.tsx +0 -12
- package/src/context/useTooltipAxis.ts +0 -22
- package/src/hooks.ts +0 -476
- package/src/index.ts +0 -280
- package/src/polar/Pie.tsx +0 -1360
- package/src/polar/PolarAngleAxis.tsx +0 -616
- package/src/polar/PolarGrid.tsx +0 -312
- package/src/polar/PolarRadiusAxis.tsx +0 -547
- package/src/polar/Radar.tsx +0 -734
- package/src/polar/RadialBar.tsx +0 -917
- package/src/polar/defaultPolarAngleAxisProps.tsx +0 -27
- package/src/polar/defaultPolarRadiusAxisProps.tsx +0 -25
- package/src/shape/Cross.tsx +0 -89
- package/src/shape/Curve.tsx +0 -343
- package/src/shape/Dot.tsx +0 -70
- package/src/shape/Polygon.tsx +0 -195
- package/src/shape/Rectangle.tsx +0 -470
- package/src/shape/Sector.tsx +0 -347
- package/src/shape/Symbols.tsx +0 -139
- package/src/shape/Trapezoid.tsx +0 -280
- package/src/state/RechartsStateContext.tsx +0 -12
- package/src/state/RechartsStateProvider.tsx +0 -87
- package/src/state/RechartsStoreContext.tsx +0 -25
- package/src/state/RechartsStoreProvider.tsx +0 -35
- package/src/state/ReportChartProps.tsx +0 -40
- package/src/state/ReportEventSettings.tsx +0 -30
- package/src/state/ReportMainChartProps.tsx +0 -61
- package/src/state/ReportPolarOptions.tsx +0 -35
- package/src/state/SetGraphicalItem.ts +0 -79
- package/src/state/SetLegendPayload.ts +0 -134
- package/src/state/SetTooltipEntrySettings.tsx +0 -72
- package/src/state/actions.ts +0 -464
- package/src/state/brushSlice.ts +0 -13
- package/src/state/cartesianAxisSlice.ts +0 -141
- package/src/state/chartDataSlice.ts +0 -50
- package/src/state/chartState.ts +0 -297
- package/src/state/errorBarSlice.ts +0 -29
- package/src/state/eventSettingsSlice.ts +0 -8
- package/src/state/events.ts +0 -76
- package/src/state/externalEventsMiddleware.ts +0 -255
- package/src/state/graphicalItemsSlice.ts +0 -74
- package/src/state/hooks/useChartSelectors.tsx +0 -45
- package/src/state/keyboardEventsMiddleware.ts +0 -228
- package/src/state/layoutSlice.ts +0 -21
- package/src/state/legendSlice.ts +0 -57
- package/src/state/mouseEventsMiddleware.ts +0 -185
- package/src/state/optionsSlice.ts +0 -47
- package/src/state/polarAxisSlice.ts +0 -10
- package/src/state/polarOptionsSlice.ts +0 -12
- package/src/state/rawData.ts +0 -26
- package/src/state/referenceElementsSlice.ts +0 -40
- package/src/state/renderedTicksSlice.ts +0 -15
- package/src/state/rootPropsSlice.ts +0 -47
- package/src/state/selectors/areaSelectors.ts +0 -240
- package/src/state/selectors/arrayEqualityCheck.ts +0 -29
- package/src/state/selectors/axisSelectors.ts +0 -2157
- package/src/state/selectors/barSelectors.ts +0 -310
- package/src/state/selectors/barStackSelectors.ts +0 -77
- package/src/state/selectors/brushSelectors.ts +0 -33
- package/src/state/selectors/chartSelector.ts +0 -185
- package/src/state/selectors/combiners/combineActiveLabel.ts +0 -16
- package/src/state/selectors/combiners/combineActiveTooltipIndex.ts +0 -95
- package/src/state/selectors/combiners/combineAllBarPositions.ts +0 -122
- package/src/state/selectors/combiners/combineAxisRangeWithReverse.ts +0 -16
- package/src/state/selectors/combiners/combineBarPosition.ts +0 -23
- package/src/state/selectors/combiners/combineBarSizeList.ts +0 -80
- package/src/state/selectors/combiners/combineCheckedDomain.ts +0 -48
- package/src/state/selectors/combiners/combineConfiguredScale.ts +0 -111
- package/src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts +0 -45
- package/src/state/selectors/combiners/combineDisplayedStackedData.ts +0 -50
- package/src/state/selectors/combiners/combineInverseScaleFunction.ts +0 -16
- package/src/state/selectors/combiners/combineRealScaleType.ts +0 -44
- package/src/state/selectors/combiners/combineStackedData.ts +0 -27
- package/src/state/selectors/combiners/combineTooltipInteractionState.ts +0 -86
- package/src/state/selectors/combiners/combineTooltipPayload.ts +0 -205
- package/src/state/selectors/combiners/combineTooltipPayloadConfigurations.ts +0 -58
- package/src/state/selectors/containerSelectors.ts +0 -12
- package/src/state/selectors/dataSelectors.ts +0 -88
- package/src/state/selectors/funnelSelectors.ts +0 -75
- package/src/state/selectors/graphicalItemSelectors.ts +0 -30
- package/src/state/selectors/legendSelectors.ts +0 -29
- package/src/state/selectors/lineSelectors.ts +0 -134
- package/src/state/selectors/numberDomainEqualityCheck.ts +0 -14
- package/src/state/selectors/pickAxisId.ts +0 -5
- package/src/state/selectors/pickAxisType.ts +0 -3
- package/src/state/selectors/pieSelectors.ts +0 -97
- package/src/state/selectors/polarAxisSelectors.ts +0 -201
- package/src/state/selectors/polarGridSelectors.ts +0 -28
- package/src/state/selectors/polarScaleSelectors.ts +0 -133
- package/src/state/selectors/polarSelectors.ts +0 -219
- package/src/state/selectors/radarSelectors.ts +0 -191
- package/src/state/selectors/radialBarSelectors.ts +0 -435
- package/src/state/selectors/rootPropsSelectors.ts +0 -25
- package/src/state/selectors/scatterSelectors.ts +0 -96
- package/src/state/selectors/selectActivePropsFromChartPointer.ts +0 -26
- package/src/state/selectors/selectAllAxes.ts +0 -17
- package/src/state/selectors/selectChartOffset.ts +0 -16
- package/src/state/selectors/selectChartOffsetInternal.ts +0 -136
- package/src/state/selectors/selectLegendArea.ts +0 -20
- package/src/state/selectors/selectPlotArea.ts +0 -22
- package/src/state/selectors/selectTooltipAxisId.ts +0 -7
- package/src/state/selectors/selectTooltipAxisType.ts +0 -32
- package/src/state/selectors/selectTooltipEventType.ts +0 -48
- package/src/state/selectors/selectTooltipPayloadSearcher.ts +0 -6
- package/src/state/selectors/selectTooltipSettings.ts +0 -39
- package/src/state/selectors/selectTooltipState.ts +0 -8
- package/src/state/selectors/selectors.ts +0 -271
- package/src/state/selectors/tooltipSelectors.ts +0 -578
- package/src/state/selectors/touchSelectors.ts +0 -31
- package/src/state/store.ts +0 -29
- package/src/state/storeIdentity.ts +0 -9
- package/src/state/teardownWrite.ts +0 -10
- package/src/state/tooltipInteraction.ts +0 -23
- package/src/state/tooltipSlice.ts +0 -334
- package/src/state/touchEventsMiddleware.ts +0 -214
- package/src/state/types/AnimationSettings.ts +0 -20
- package/src/state/types/AreaSettings.ts +0 -14
- package/src/state/types/BarSettings.ts +0 -15
- package/src/state/types/LineSettings.ts +0 -9
- package/src/state/types/PieSettings.ts +0 -34
- package/src/state/types/RadarSettings.ts +0 -5
- package/src/state/types/RadialBarSettings.ts +0 -10
- package/src/state/types/ScatterSettings.ts +0 -12
- package/src/state/types/StackedGraphicalItem.ts +0 -34
- package/src/state/useChartState.ts +0 -17
- package/src/state/zIndexSlice.ts +0 -39
- package/src/synchronisation/syncSelectors.ts +0 -7
- package/src/synchronisation/types.ts +0 -44
- package/src/synchronisation/useChartSynchronisation.tsx +0 -404
- package/src/theme/RechartsTheme.ts +0 -16
- package/src/theme/RechartsThemeContext.ts +0 -19
- package/src/theme/darkTheme.ts +0 -13
- package/src/theme/graphicalItemIdentity.ts +0 -70
- package/src/theme/legacyTheme.ts +0 -17
- package/src/theme/lightTheme.ts +0 -13
- package/src/types.ts +0 -54
- package/src/util/ActiveShapeUtils.tsx +0 -162
- package/src/util/BarUtils.tsx +0 -62
- package/src/util/BarePortal.tsx +0 -50
- package/src/util/CamelCaseSVGAttrs.ts +0 -34
- package/src/util/CartesianUtils.ts +0 -48
- package/src/util/ChartUtils.ts +0 -802
- package/src/util/Constants.ts +0 -42
- package/src/util/CssPrefixUtils.ts +0 -20
- package/src/util/DOMUtils.ts +0 -129
- package/src/util/DataUtils.ts +0 -216
- package/src/util/Events.ts +0 -16
- package/src/util/FunnelUtils.tsx +0 -15
- package/src/util/Global.ts +0 -12
- package/src/util/IfOverflow.ts +0 -15
- package/src/util/LRUCache.ts +0 -41
- package/src/util/LogUtils.ts +0 -22
- package/src/util/PolarUtils.ts +0 -132
- package/src/util/RadialBarUtils.tsx +0 -24
- package/src/util/ReactUtils.ts +0 -95
- package/src/util/ReduceCSSCalc.ts +0 -187
- package/src/util/ScatterUtils.tsx +0 -52
- package/src/util/ShapeElementProps.tsx +0 -87
- package/src/util/TickUtils.ts +0 -60
- package/src/util/XAxisUtils.ts +0 -48
- package/src/util/YAxisUtils.ts +0 -48
- package/src/util/axisPropsAreEqual.ts +0 -48
- package/src/util/createCartesianCharts.tsx +0 -150
- package/src/util/createEventProxy.ts +0 -20
- package/src/util/createPolarCharts.tsx +0 -112
- package/src/util/cursor/getCursorPoints.ts +0 -46
- package/src/util/cursor/getCursorRectangle.ts +0 -28
- package/src/util/cursor/getRadialCursorPoints.ts +0 -32
- package/src/util/excludeEventProps.ts +0 -171
- package/src/util/getActiveCoordinate.ts +0 -213
- package/src/util/getAxisTypeBasedOnLayout.ts +0 -21
- package/src/util/getClassNameFromUnknown.ts +0 -6
- package/src/util/getEveryNth.ts +0 -27
- package/src/util/getRadiusAndStrokeWidthFromDot.ts +0 -35
- package/src/util/getRelativeCoordinate.ts +0 -80
- package/src/util/getSliced.ts +0 -13
- package/src/util/hoverDedupe.ts +0 -41
- package/src/util/isDomainSpecifiedByUser.ts +0 -219
- package/src/util/isWellBehavedNumber.ts +0 -7
- package/src/util/pathTotalLength.ts +0 -25
- package/src/util/payload/getUniqPayload.ts +0 -28
- package/src/util/propsAreEqual.ts +0 -121
- package/src/util/resolveDefaultProps.ts +0 -161
- package/src/util/round.ts +0 -32
- package/src/util/scale/CartesianScaleHelper.ts +0 -72
- package/src/util/scale/CustomScaleDefinition.ts +0 -81
- package/src/util/scale/RechartsScale.ts +0 -130
- package/src/util/scale/createCategoricalInverse.ts +0 -72
- package/src/util/scale/getNiceTickValues.ts +0 -311
- package/src/util/scale/index.ts +0 -2
- package/src/util/scale/util/arithmetic.ts +0 -54
- package/src/util/solid-1-compat.ts +0 -310
- package/src/util/solidJsxCamelAugment.d.ts +0 -84
- package/src/util/stacks/getStackSeriesIdentifier.ts +0 -21
- package/src/util/stacks/stackTypes.ts +0 -60
- package/src/util/structurallyEqual.ts +0 -31
- package/src/util/svgPropertiesAndEvents.ts +0 -53
- package/src/util/svgPropertiesNoEvents.ts +0 -571
- package/src/util/tooltip/translate.ts +0 -171
- package/src/util/typedDataKey.ts +0 -48
- package/src/util/types.ts +0 -1560
- package/src/util/useAnimationId.ts +0 -31
- package/src/util/useElementOffset.ts +0 -110
- package/src/util/useId.ts +0 -8
- package/src/util/usePrefersReducedMotion.ts +0 -48
- package/src/util/useReportScale.ts +0 -24
- package/src/util/useUniqueId.ts +0 -30
- package/src/zIndex/DefaultZIndexes.ts +0 -84
- package/src/zIndex/ZIndexLayer.tsx +0 -121
- package/src/zIndex/ZIndexPortal.tsx +0 -79
- package/src/zIndex/getZIndexFromUnknown.ts +0 -14
- package/src/zIndex/zIndexSelectors.ts +0 -48
package/src/component/Text.tsx
DELETED
|
@@ -1,541 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import/no-cycle */
|
|
2
|
-
import { createMemo, For, Show } from 'solid-js';
|
|
3
|
-
import { splitProps } from "../util/solid-1-compat"
|
|
4
|
-
import type { WithoutRemoveFalse } from "../util/types"
|
|
5
|
-
import type { CamelCaseSVGAttrs } from "../util/CamelCaseSVGAttrs"
|
|
6
|
-
import type { JSX } from '@solidjs/web';
|
|
7
|
-
import { clsx } from "clsx"
|
|
8
|
-
import { isNullish, isNumber, isNumOrStr } from "../util/DataUtils"
|
|
9
|
-
import { Global } from "../util/Global"
|
|
10
|
-
import { getStringSize } from "../util/DOMUtils"
|
|
11
|
-
import { reduceCSSCalc } from "../util/ReduceCSSCalc"
|
|
12
|
-
import { svgPropertiesAndEvents } from "../util/svgPropertiesAndEvents"
|
|
13
|
-
import { resolveDefaultProps } from "../util/resolveDefaultProps"
|
|
14
|
-
import { isWellBehavedNumber } from "../util/isWellBehavedNumber"
|
|
15
|
-
|
|
16
|
-
const BREAKING_SPACES = /[ \f\n\r\t\v\u2028\u2029]+/
|
|
17
|
-
|
|
18
|
-
interface Words {
|
|
19
|
-
words: Array<string>
|
|
20
|
-
width: number | undefined
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
interface WordsWithWidth {
|
|
24
|
-
words: Array<string>
|
|
25
|
-
width: number
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
interface WordWithComputedWidth {
|
|
29
|
-
word: string
|
|
30
|
-
width: number
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
interface CalculatedWordWidths {
|
|
34
|
-
wordsWithComputedWidth: Array<WordWithComputedWidth>
|
|
35
|
-
spaceWidth: number
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
type CalculateWordWidthsParam = Pick<Props, "children" | "breakAll" | "style">
|
|
39
|
-
|
|
40
|
-
const calculateWordWidths = (param: CalculateWordWidthsParam): CalculatedWordWidths | null => {
|
|
41
|
-
try {
|
|
42
|
-
let words: string[] = []
|
|
43
|
-
if (!isNullish(param.children)) {
|
|
44
|
-
if (param.breakAll) {
|
|
45
|
-
words = param.children.toString().split("")
|
|
46
|
-
} else {
|
|
47
|
-
words = param.children.toString().split(BREAKING_SPACES)
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const wordsWithComputedWidth = words.map((word) => ({
|
|
52
|
-
width: getStringSize(word, param.style).width,
|
|
53
|
-
word,
|
|
54
|
-
}))
|
|
55
|
-
|
|
56
|
-
const spaceWidth = param.breakAll ? 0 : getStringSize("\u00A0", param.style).width
|
|
57
|
-
|
|
58
|
-
return { spaceWidth, wordsWithComputedWidth }
|
|
59
|
-
} catch {
|
|
60
|
-
return null
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* @inline
|
|
66
|
-
*/
|
|
67
|
-
export type TextAnchor = "start" | "middle" | "end" | "inherit"
|
|
68
|
-
|
|
69
|
-
export function isValidTextAnchor(value: string | undefined): value is TextAnchor {
|
|
70
|
-
return value === "start" || value === "middle" || value === "end" || value === "inherit"
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* @inline
|
|
75
|
-
*/
|
|
76
|
-
export type TextVerticalAnchor = "start" | "middle" | "end"
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* @inline
|
|
80
|
-
*/
|
|
81
|
-
export type RenderableText = string | number | boolean | null | undefined
|
|
82
|
-
|
|
83
|
-
export function isRenderableText(val: unknown): val is RenderableText {
|
|
84
|
-
return (
|
|
85
|
-
isNullish(val) || typeof val === "string" || typeof val === "number" || typeof val === "boolean"
|
|
86
|
-
)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
interface TextProps {
|
|
90
|
-
/**
|
|
91
|
-
* When true, scales the text to fit within the specified width.
|
|
92
|
-
* The text will be scaled down proportionally to fit the available space.
|
|
93
|
-
*
|
|
94
|
-
* **Important interactions:**
|
|
95
|
-
* - Requires `width` to be defined to have any effect. If width is undefined, scaleToFit does nothing.
|
|
96
|
-
* - When enabled, `maxLines` restrictions are bypassed and ellipsis truncation is disabled.
|
|
97
|
-
* - Uses the first line's width to calculate the scale factor.
|
|
98
|
-
* - The scaling transform is applied as `scale(width / lineWidth)`.
|
|
99
|
-
*
|
|
100
|
-
* @defaultValue false
|
|
101
|
-
*/
|
|
102
|
-
scaleToFit?: boolean
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Text rotation angle in degrees.
|
|
106
|
-
* Positive values rotate clockwise, negative values rotate counterclockwise.
|
|
107
|
-
*
|
|
108
|
-
* @defaultValue 0
|
|
109
|
-
*/
|
|
110
|
-
angle?: number
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Horizontal text alignment within the text element.
|
|
114
|
-
* - 'start': Text starts at the x coordinate (left-aligned for LTR text)
|
|
115
|
-
* - 'middle': Text is centered on the x coordinate
|
|
116
|
-
* - 'end': Text ends at the x coordinate (right-aligned for LTR text)
|
|
117
|
-
* - 'inherit': Inherits the text-anchor from parent element
|
|
118
|
-
*
|
|
119
|
-
* **Note:** This controls horizontal alignment only and does not affect RTL text behavior.
|
|
120
|
-
* @defaultValue 'start'
|
|
121
|
-
*/
|
|
122
|
-
textAnchor?: TextAnchor
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Vertical text alignment relative to the y coordinate.
|
|
126
|
-
* - 'start': Text baseline starts at y coordinate (text appears below the y position)
|
|
127
|
-
* - 'middle': Text is vertically centered on the y coordinate
|
|
128
|
-
* - 'end': Text baseline ends at y coordinate (text appears above the y position)
|
|
129
|
-
*
|
|
130
|
-
* **Note:** This controls vertical positioning only and does not affect RTL (right-to-left) text behavior.
|
|
131
|
-
* The alignment calculation uses capHeight and lineHeight to determine the starting dy offset.
|
|
132
|
-
*
|
|
133
|
-
* @defaultValue 'end'
|
|
134
|
-
*/
|
|
135
|
-
verticalAnchor?: TextVerticalAnchor
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* CSS styles to apply to the text element.
|
|
139
|
-
* These styles are used for text measurement calculations when width constraints or scaleToFit are used.
|
|
140
|
-
* Font-related properties (fontSize, fontFamily, fontWeight, etc.) are particularly important for accurate measurements.
|
|
141
|
-
*/
|
|
142
|
-
style?: JSX.CSSProperties
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Line height for multi-line text.
|
|
146
|
-
* Can be a number (height in pixels) or a string with CSS units.
|
|
147
|
-
* Used to calculate spacing between lines when text wraps to multiple lines.
|
|
148
|
-
* Also used in verticalAnchor calculations for positioning the text block.
|
|
149
|
-
* @defaultValue '1em'
|
|
150
|
-
*/
|
|
151
|
-
lineHeight?: number | string
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* When true, enables character-level breaking instead of word-level breaking.
|
|
155
|
-
* - false: Text breaks at word boundaries (spaces, tabs, etc.)
|
|
156
|
-
* - true: Text can break between any characters, useful for languages without spaces
|
|
157
|
-
*
|
|
158
|
-
* **Note:** Only effective when `width` is defined to enable line breaking.
|
|
159
|
-
* @defaultValue false
|
|
160
|
-
*/
|
|
161
|
-
breakAll?: boolean
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* The text content to render.
|
|
165
|
-
* Can be a string or number. Numbers will be converted to strings.
|
|
166
|
-
* undefined or null values will result in no text being rendered.
|
|
167
|
-
*/
|
|
168
|
-
children?: RenderableText
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Maximum number of lines to display when text wrapping is enabled.
|
|
172
|
-
* When text exceeds this limit, it will be truncated with an ellipsis (...).
|
|
173
|
-
*
|
|
174
|
-
* **Important requirements for ellipsis truncation:**
|
|
175
|
-
* - `width` must be defined (no effect when width is undefined)
|
|
176
|
-
* - `scaleToFit` must be false (when scaleToFit is true, maxLines is bypassed)
|
|
177
|
-
* - Text must actually overflow the specified maxLines or width constraints
|
|
178
|
-
*
|
|
179
|
-
* **Truncation behavior:**
|
|
180
|
-
* - Uses binary search to find the optimal truncation point
|
|
181
|
-
* - Adds ellipsis (...) at the end of the truncated text
|
|
182
|
-
* - Ensures the truncated text + ellipsis fits within the constraints
|
|
183
|
-
*
|
|
184
|
-
* **Interaction with other props:**
|
|
185
|
-
* - When `scaleToFit` is true, this property is ignored
|
|
186
|
-
* - Requires `width` to be set for line breaking to occur
|
|
187
|
-
*/
|
|
188
|
-
maxLines?: number
|
|
189
|
-
/**
|
|
190
|
-
* When width is specified, the text will automatically wrap by calculating the width of text.
|
|
191
|
-
*/
|
|
192
|
-
width?: number | string
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export type Props = WithoutRemoveFalse<
|
|
196
|
-
Omit<
|
|
197
|
-
JSX.TextSVGAttributes<SVGTextElement>,
|
|
198
|
-
"textAnchor" | "text-anchor" | "children" | "ref" | "style" | "x" | "y" | "dx" | "dy" | "width"
|
|
199
|
-
>
|
|
200
|
-
> &
|
|
201
|
-
CamelCaseSVGAttrs &
|
|
202
|
-
TextProps & {
|
|
203
|
-
x?: number | string
|
|
204
|
-
y?: number | string
|
|
205
|
-
dx?: number | string
|
|
206
|
-
dy?: number | string
|
|
207
|
-
className?: string
|
|
208
|
-
ref?: SVGTextElement | ((el: SVGTextElement) => void)
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
type CalculateWordsByLinesProps = Pick<Props, "maxLines" | "children" | "style" | "breakAll">
|
|
212
|
-
|
|
213
|
-
const calculate = (
|
|
214
|
-
words: ReadonlyArray<WordWithComputedWidth>,
|
|
215
|
-
lineWidth: number | string | undefined,
|
|
216
|
-
spaceWidth: number,
|
|
217
|
-
scaleToFit: boolean,
|
|
218
|
-
): ReadonlyArray<WordsWithWidth> =>
|
|
219
|
-
words.reduce((result: Array<WordsWithWidth>, { word, width }) => {
|
|
220
|
-
const currentLine = result[result.length - 1]
|
|
221
|
-
|
|
222
|
-
if (
|
|
223
|
-
currentLine &&
|
|
224
|
-
width != null &&
|
|
225
|
-
(lineWidth == null ||
|
|
226
|
-
scaleToFit ||
|
|
227
|
-
currentLine.width + width + spaceWidth < Number(lineWidth))
|
|
228
|
-
) {
|
|
229
|
-
/* Word can be added to an existing line */
|
|
230
|
-
currentLine.words.push(word)
|
|
231
|
-
currentLine.width += width + spaceWidth
|
|
232
|
-
} else {
|
|
233
|
-
/* Add first word to line or word is too long to scaleToFit on existing line */
|
|
234
|
-
const newLine: WordsWithWidth = { width, words: [word] }
|
|
235
|
-
result.push(newLine)
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
return result
|
|
239
|
-
}, [])
|
|
240
|
-
|
|
241
|
-
const findLongestLine = (words: ReadonlyArray<WordsWithWidth>): WordsWithWidth =>
|
|
242
|
-
words.reduce((a: WordsWithWidth, b: WordsWithWidth) => (a.width > b.width ? a : b))
|
|
243
|
-
|
|
244
|
-
const suffix = "\u2026"
|
|
245
|
-
|
|
246
|
-
const checkOverflow = (
|
|
247
|
-
text: string,
|
|
248
|
-
index: number,
|
|
249
|
-
breakAll: TextProps["breakAll"],
|
|
250
|
-
style: TextProps["style"],
|
|
251
|
-
maxLines: number,
|
|
252
|
-
lineWidth: number | string | undefined,
|
|
253
|
-
spaceWidth: number,
|
|
254
|
-
scaleToFit: boolean,
|
|
255
|
-
): [boolean, ReadonlyArray<Words>] => {
|
|
256
|
-
const tempText = text.slice(0, index)
|
|
257
|
-
|
|
258
|
-
const words = calculateWordWidths({
|
|
259
|
-
breakAll,
|
|
260
|
-
children: tempText + suffix,
|
|
261
|
-
style,
|
|
262
|
-
})
|
|
263
|
-
|
|
264
|
-
if (!words) {
|
|
265
|
-
return [false, []]
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const result: ReadonlyArray<WordsWithWidth> = calculate(
|
|
269
|
-
words.wordsWithComputedWidth,
|
|
270
|
-
lineWidth,
|
|
271
|
-
spaceWidth,
|
|
272
|
-
scaleToFit,
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
const doesOverflow = result.length > maxLines || findLongestLine(result).width > Number(lineWidth)
|
|
276
|
-
|
|
277
|
-
return [doesOverflow, result]
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const calculateWordsByLines = (
|
|
281
|
-
lineProps: CalculateWordsByLinesProps,
|
|
282
|
-
initialWordsWithComputedWith: ReadonlyArray<WordWithComputedWidth>,
|
|
283
|
-
spaceWidth: number,
|
|
284
|
-
lineWidth: number | string | undefined,
|
|
285
|
-
scaleToFit: boolean,
|
|
286
|
-
): ReadonlyArray<Words> => {
|
|
287
|
-
const shouldLimitLines = isNumber(lineProps.maxLines)
|
|
288
|
-
const text = String(lineProps.children)
|
|
289
|
-
|
|
290
|
-
const originalResult: ReadonlyArray<WordsWithWidth> = calculate(
|
|
291
|
-
initialWordsWithComputedWith,
|
|
292
|
-
lineWidth,
|
|
293
|
-
spaceWidth,
|
|
294
|
-
scaleToFit,
|
|
295
|
-
)
|
|
296
|
-
|
|
297
|
-
if (!shouldLimitLines || scaleToFit) {
|
|
298
|
-
return originalResult
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const overflows =
|
|
302
|
-
originalResult.length > (lineProps.maxLines ?? 0) ||
|
|
303
|
-
findLongestLine(originalResult).width > Number(lineWidth)
|
|
304
|
-
if (!overflows) {
|
|
305
|
-
return originalResult
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
let start = 0
|
|
309
|
-
let end = text.length - 1
|
|
310
|
-
|
|
311
|
-
let iterations = 0
|
|
312
|
-
let trimmedResult
|
|
313
|
-
|
|
314
|
-
while (start <= end && iterations <= text.length - 1) {
|
|
315
|
-
const middle = Math.floor((start + end) / 2)
|
|
316
|
-
const prev = middle - 1
|
|
317
|
-
|
|
318
|
-
const [doesPrevOverflow, result] = checkOverflow(
|
|
319
|
-
text,
|
|
320
|
-
prev,
|
|
321
|
-
lineProps.breakAll,
|
|
322
|
-
lineProps.style,
|
|
323
|
-
lineProps.maxLines ?? 0,
|
|
324
|
-
lineWidth,
|
|
325
|
-
spaceWidth,
|
|
326
|
-
scaleToFit,
|
|
327
|
-
)
|
|
328
|
-
const [doesMiddleOverflow] = checkOverflow(
|
|
329
|
-
text,
|
|
330
|
-
middle,
|
|
331
|
-
lineProps.breakAll,
|
|
332
|
-
lineProps.style,
|
|
333
|
-
lineProps.maxLines ?? 0,
|
|
334
|
-
lineWidth,
|
|
335
|
-
spaceWidth,
|
|
336
|
-
scaleToFit,
|
|
337
|
-
)
|
|
338
|
-
|
|
339
|
-
if (!doesPrevOverflow && !doesMiddleOverflow) {
|
|
340
|
-
start = middle + 1
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
if (doesPrevOverflow && doesMiddleOverflow) {
|
|
344
|
-
end = middle - 1
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if (!doesPrevOverflow && doesMiddleOverflow) {
|
|
348
|
-
trimmedResult = result
|
|
349
|
-
break
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
iterations++
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/* Fallback to originalResult (result without trimming) if we cannot find the
|
|
356
|
-
* where to trim. This should not happen :tm: */
|
|
357
|
-
return trimmedResult || originalResult
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
const getWordsWithoutCalculate = (children: RenderableText): Array<Words> => {
|
|
361
|
-
const words = !isNullish(children) ? children.toString().split(BREAKING_SPACES) : []
|
|
362
|
-
return [{ width: undefined, words }]
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
type GetWordsByLinesProps = Pick<
|
|
366
|
-
Props,
|
|
367
|
-
"width" | "scaleToFit" | "children" | "style" | "breakAll" | "maxLines"
|
|
368
|
-
>
|
|
369
|
-
|
|
370
|
-
export const getWordsByLines = (p: GetWordsByLinesProps) => {
|
|
371
|
-
/* Only perform calculations if using features that require them (multiline, scaleToFit) */
|
|
372
|
-
if ((p.width || p.scaleToFit) && !Global.isSsr) {
|
|
373
|
-
let wordsWithComputedWidth: ReadonlyArray<WordWithComputedWidth>
|
|
374
|
-
let spaceWidth: number
|
|
375
|
-
|
|
376
|
-
const wordWidths = calculateWordWidths({
|
|
377
|
-
breakAll: p.breakAll,
|
|
378
|
-
children: p.children,
|
|
379
|
-
style: p.style,
|
|
380
|
-
})
|
|
381
|
-
|
|
382
|
-
if (wordWidths) {
|
|
383
|
-
const { wordsWithComputedWidth: wcw, spaceWidth: sw } = wordWidths
|
|
384
|
-
|
|
385
|
-
wordsWithComputedWidth = wcw
|
|
386
|
-
spaceWidth = sw
|
|
387
|
-
} else {
|
|
388
|
-
return getWordsWithoutCalculate(p.children)
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
return calculateWordsByLines(
|
|
392
|
-
{ breakAll: p.breakAll, children: p.children, maxLines: p.maxLines, style: p.style },
|
|
393
|
-
wordsWithComputedWidth,
|
|
394
|
-
spaceWidth,
|
|
395
|
-
p.width,
|
|
396
|
-
Boolean(p.scaleToFit),
|
|
397
|
-
)
|
|
398
|
-
}
|
|
399
|
-
return getWordsWithoutCalculate(p.children)
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
const DEFAULT_FILL = "#808080"
|
|
403
|
-
|
|
404
|
-
export const textDefaultProps = {
|
|
405
|
-
angle: 0,
|
|
406
|
-
breakAll: false,
|
|
407
|
-
/* Magic number from d3 */
|
|
408
|
-
capHeight: "0.71em",
|
|
409
|
-
fill: DEFAULT_FILL,
|
|
410
|
-
lineHeight: "1em",
|
|
411
|
-
scaleToFit: false,
|
|
412
|
-
textAnchor: "start",
|
|
413
|
-
/* Maintain compat with existing charts / default SVG behavior */
|
|
414
|
-
verticalAnchor: "end",
|
|
415
|
-
x: 0,
|
|
416
|
-
y: 0,
|
|
417
|
-
} as const satisfies Partial<Props>
|
|
418
|
-
|
|
419
|
-
export function Text(outsideProps: Props) {
|
|
420
|
-
const resolved = resolveDefaultProps(outsideProps, textDefaultProps)
|
|
421
|
-
|
|
422
|
-
const wordsByLines = createMemo((): ReadonlyArray<Words> => {
|
|
423
|
-
return getWordsByLines({
|
|
424
|
-
breakAll: resolved.breakAll as boolean | undefined,
|
|
425
|
-
children: resolved.children as RenderableText,
|
|
426
|
-
maxLines: resolved.maxLines as number | undefined,
|
|
427
|
-
scaleToFit: resolved.scaleToFit as boolean | undefined,
|
|
428
|
-
style: resolved.style as JSX.CSSProperties | undefined,
|
|
429
|
-
width: resolved.width as number | string | undefined,
|
|
430
|
-
})
|
|
431
|
-
})
|
|
432
|
-
|
|
433
|
-
const propsX = () => resolved.x
|
|
434
|
-
const propsY = () => resolved.y
|
|
435
|
-
const lineHeight = () => resolved.lineHeight
|
|
436
|
-
const capHeight = () => resolved.capHeight
|
|
437
|
-
const fill = () => resolved.fill
|
|
438
|
-
const scaleToFit = () => resolved.scaleToFit
|
|
439
|
-
const textAnchor = () => resolved.textAnchor as string
|
|
440
|
-
const verticalAnchor = () => resolved.verticalAnchor
|
|
441
|
-
|
|
442
|
-
return (
|
|
443
|
-
<Show when={isNumOrStr(propsX()) && isNumOrStr(propsY()) && wordsByLines().length > 0}>
|
|
444
|
-
{(() => {
|
|
445
|
-
const x = () => Number(propsX()) + (isNumber(resolved.dx) ? resolved.dx : 0)
|
|
446
|
-
const y = () => Number(propsY()) + (isNumber(resolved.dy) ? resolved.dy : 0)
|
|
447
|
-
|
|
448
|
-
return (
|
|
449
|
-
<Show when={isWellBehavedNumber(x()) && isWellBehavedNumber(y())}>
|
|
450
|
-
{(() => {
|
|
451
|
-
const startDy = createMemo(() => {
|
|
452
|
-
const lines = wordsByLines()
|
|
453
|
-
switch (verticalAnchor()) {
|
|
454
|
-
case "start":
|
|
455
|
-
return reduceCSSCalc(`calc(${capHeight()})`)
|
|
456
|
-
case "middle":
|
|
457
|
-
return reduceCSSCalc(
|
|
458
|
-
`calc(${(lines.length - 1) / 2} * -${lineHeight()} + (${capHeight()} / 2))`,
|
|
459
|
-
)
|
|
460
|
-
default:
|
|
461
|
-
return reduceCSSCalc(`calc(${lines.length - 1} * -${lineHeight()})`)
|
|
462
|
-
}
|
|
463
|
-
})
|
|
464
|
-
|
|
465
|
-
const computedTransform = createMemo(() => {
|
|
466
|
-
const transforms: string[] = []
|
|
467
|
-
const lines = wordsByLines()
|
|
468
|
-
const firstLine = lines[0]
|
|
469
|
-
if (scaleToFit() && firstLine != null) {
|
|
470
|
-
const lineWidth = firstLine.width
|
|
471
|
-
const w = resolved.width
|
|
472
|
-
transforms.push(
|
|
473
|
-
`scale(${isNumber(w) && isNumber(lineWidth) ? Number(w) / lineWidth : 1})`,
|
|
474
|
-
)
|
|
475
|
-
}
|
|
476
|
-
if (resolved.angle) {
|
|
477
|
-
transforms.push(`rotate(${resolved.angle}, ${x()}, ${y()})`)
|
|
478
|
-
}
|
|
479
|
-
return transforms.length ? transforms.join(" ") : (resolved.transform as string | undefined)
|
|
480
|
-
})
|
|
481
|
-
|
|
482
|
-
/* `width` MUST stay on textProps — upstream forwards it as the SVG attr,
|
|
483
|
-
tests assert `toHaveAttribute("width", "78")`. The excluded keys are
|
|
484
|
-
handled separately; splitProps excludes them without reading them (a
|
|
485
|
-
rest-destructure would re-run the `children` getter). */
|
|
486
|
-
const [, rest] = splitProps(resolved as Record<string, unknown>, [
|
|
487
|
-
"dx",
|
|
488
|
-
"dy",
|
|
489
|
-
"angle",
|
|
490
|
-
"className",
|
|
491
|
-
"breakAll",
|
|
492
|
-
"maxLines",
|
|
493
|
-
"scaleToFit",
|
|
494
|
-
"children",
|
|
495
|
-
"style",
|
|
496
|
-
"x",
|
|
497
|
-
"y",
|
|
498
|
-
"lineHeight",
|
|
499
|
-
"verticalAnchor",
|
|
500
|
-
"textAnchor",
|
|
501
|
-
"capHeight",
|
|
502
|
-
"fill",
|
|
503
|
-
"ref",
|
|
504
|
-
])
|
|
505
|
-
const filteredProps = () => svgPropertiesAndEvents(rest)
|
|
506
|
-
|
|
507
|
-
return (
|
|
508
|
-
<text
|
|
509
|
-
{...filteredProps()}
|
|
510
|
-
ref={resolved.ref as ((el: SVGTextElement) => void) | undefined}
|
|
511
|
-
x={x()}
|
|
512
|
-
y={y()}
|
|
513
|
-
class={clsx("recharts-text", resolved.className as string | undefined)}
|
|
514
|
-
text-anchor={textAnchor() as "start" | "middle" | "end" | "inherit"}
|
|
515
|
-
fill={(fill() as string).includes("url") ? DEFAULT_FILL : (fill() as string)}
|
|
516
|
-
transform={computedTransform()}
|
|
517
|
-
>
|
|
518
|
-
<For each={wordsByLines() as Words[]}>
|
|
519
|
-
{(line, index) => {
|
|
520
|
-
const words = () => line.words.join(resolved.breakAll ? "" : " ")
|
|
521
|
-
return (
|
|
522
|
-
<tspan
|
|
523
|
-
x={x()}
|
|
524
|
-
dy={index() === 0 ? startDy() : (lineHeight() as string | number)}
|
|
525
|
-
>
|
|
526
|
-
{words()}
|
|
527
|
-
</tspan>
|
|
528
|
-
)
|
|
529
|
-
}}
|
|
530
|
-
</For>
|
|
531
|
-
</text>
|
|
532
|
-
)
|
|
533
|
-
})()}
|
|
534
|
-
</Show>
|
|
535
|
-
)
|
|
536
|
-
})()}
|
|
537
|
-
</Show>
|
|
538
|
-
)
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
Text.displayName = "Text"
|