@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/cartesian/Funnel.tsx
DELETED
|
@@ -1,803 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import/no-cycle, sort-keys */
|
|
2
|
-
import type { Formatter } from "../component/DefaultTooltipContent"
|
|
3
|
-
import { createMemo, For, Show, untrack } from 'solid-js';
|
|
4
|
-
import { createHoverDedupe } from "../util/hoverDedupe"
|
|
5
|
-
import type { JSX } from '@solidjs/web';
|
|
6
|
-
import omit from "es-toolkit/compat/omit"
|
|
7
|
-
import { clsx } from "clsx"
|
|
8
|
-
import { selectActiveIndex } from "../state/selectors/selectors"
|
|
9
|
-
import { useChartStore } from "../state/RechartsStoreContext"
|
|
10
|
-
import { readChartState } from "../state/chartState"
|
|
11
|
-
import { Layer } from "../container/Layer"
|
|
12
|
-
import type { Props as TrapezoidProps } from "../shape/Trapezoid"
|
|
13
|
-
import {
|
|
14
|
-
LabelListContextBridge,
|
|
15
|
-
CartesianLabelListContextProvider,
|
|
16
|
-
type CartesianLabelListEntry,
|
|
17
|
-
type ImplicitLabelListType,
|
|
18
|
-
LabelListFromLabelProp,
|
|
19
|
-
} from "../component/LabelList"
|
|
20
|
-
import { getPercentValue, interpolate } from "../util/DataUtils"
|
|
21
|
-
import { getValueByDataKey } from "../util/ChartUtils"
|
|
22
|
-
import {
|
|
23
|
-
type ActiveShape,
|
|
24
|
-
adaptEventsOfChild,
|
|
25
|
-
type AnimationDuration,
|
|
26
|
-
type AnimationTiming,
|
|
27
|
-
type CartesianViewBoxRequired,
|
|
28
|
-
type ChartOffsetInternal,
|
|
29
|
-
type Coordinate,
|
|
30
|
-
type DataConsumer,
|
|
31
|
-
type DataKey,
|
|
32
|
-
type DataProvider,
|
|
33
|
-
type LegendType,
|
|
34
|
-
type PresentationAttributesAdaptChildEvent,
|
|
35
|
-
type TooltipType,
|
|
36
|
-
type TrapezoidViewBox,
|
|
37
|
-
} from "../util/types"
|
|
38
|
-
import { FunnelTrapezoid, type FunnelTrapezoidProps } from "../util/FunnelUtils"
|
|
39
|
-
import {
|
|
40
|
-
useMouseClickItemDispatch,
|
|
41
|
-
useMouseEnterItemDispatch,
|
|
42
|
-
useMouseLeaveItemDispatch,
|
|
43
|
-
} from "../context/tooltipContext"
|
|
44
|
-
import type { TooltipPayload, TooltipPayloadConfiguration } from "../state/tooltipSlice"
|
|
45
|
-
import { SetTooltipEntrySettings } from "../state/SetTooltipEntrySettings"
|
|
46
|
-
import {
|
|
47
|
-
type ResolvedFunnelSettings,
|
|
48
|
-
selectFunnelTrapezoids,
|
|
49
|
-
} from "../state/selectors/funnelSelectors"
|
|
50
|
-
import { CellsContextProvider, createCellsRegistry } from "../context/CellsContext"
|
|
51
|
-
import type { CellsRegistry } from "../context/CellsContext"
|
|
52
|
-
import type { RequiresDefaultProps } from "../util/resolveDefaultProps"
|
|
53
|
-
import { resolveDefaultProps } from "../util/resolveDefaultProps"
|
|
54
|
-
import { usePlotArea } from "../hooks"
|
|
55
|
-
import { svgPropertiesNoEvents } from "../util/svgPropertiesNoEvents"
|
|
56
|
-
import { AnimatedItems, useAnimationCallbacks } from "../animation/AnimatedItems"
|
|
57
|
-
import type { AnimationInterpolateFn } from "../animation/AnimatedItems"
|
|
58
|
-
import { matchAppend } from "../animation/matchBy"
|
|
59
|
-
import type { AnimationMatchByProp } from "../animation/matchBy"
|
|
60
|
-
import { useCartesianChartLayout } from "../context/chartLayoutContext"
|
|
61
|
-
import type { CartesianLayout, ShapeAnimationProps } from "../util/types"
|
|
62
|
-
import type { GraphicalItemId } from "../state/graphicalItemsSlice"
|
|
63
|
-
import { RegisterGraphicalItemId } from "../context/RegisterGraphicalItemId"
|
|
64
|
-
import type { WithIdRequired } from "../util/useUniqueId"
|
|
65
|
-
|
|
66
|
-
import { splitProps } from '../util/solid-1-compat';
|
|
67
|
-
export type FunnelTrapezoidItem = TrapezoidProps &
|
|
68
|
-
TrapezoidViewBox & {
|
|
69
|
-
value?: number | string
|
|
70
|
-
payload?: unknown
|
|
71
|
-
tooltipPosition: Coordinate
|
|
72
|
-
name: string
|
|
73
|
-
labelViewBox: TrapezoidViewBox
|
|
74
|
-
parentViewBox: CartesianViewBoxRequired
|
|
75
|
-
val: number | ReadonlyArray<number>
|
|
76
|
-
tooltipPayload: TooltipPayload
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Internal props, combination of external props + defaultProps + private Recharts state
|
|
81
|
-
*/
|
|
82
|
-
type InternalFunnelProps = RequiresDefaultProps<FunnelProps, typeof defaultFunnelProps> & {
|
|
83
|
-
id: GraphicalItemId
|
|
84
|
-
trapezoids: ReadonlyArray<FunnelTrapezoidItem>
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* External props, intended for end users to fill in
|
|
89
|
-
*/
|
|
90
|
-
interface FunnelProps<DataPointType = unknown, DataValueType = unknown>
|
|
91
|
-
extends DataProvider<DataPointType>, Required<DataConsumer<DataPointType, DataValueType>> {
|
|
92
|
-
/**
|
|
93
|
-
* This component is rendered when this graphical item is activated
|
|
94
|
-
* (could be by mouse hover, touch, keyboard, programmatically).
|
|
95
|
-
*/
|
|
96
|
-
activeShape?: ActiveShape<FunnelTrapezoidItem, SVGPathElement>
|
|
97
|
-
/**
|
|
98
|
-
* Specifies when the animation should begin, the unit of this option is ms.
|
|
99
|
-
* @defaultValue 400
|
|
100
|
-
*/
|
|
101
|
-
animationBegin?: number
|
|
102
|
-
/**
|
|
103
|
-
* Specifies the duration of animation, the unit of this option is ms.
|
|
104
|
-
* @defaultValue 1500
|
|
105
|
-
*/
|
|
106
|
-
animationDuration?: AnimationDuration
|
|
107
|
-
/**
|
|
108
|
-
* The type of easing function.
|
|
109
|
-
* @defaultValue ease
|
|
110
|
-
*/
|
|
111
|
-
animationEasing?: AnimationTiming
|
|
112
|
-
/**
|
|
113
|
-
* Custom animation function for interpolating data items.
|
|
114
|
-
* When provided, this replaces the default animation interpolation.
|
|
115
|
-
*
|
|
116
|
-
* @since 3.9
|
|
117
|
-
* @see {@link https://recharts.github.io/en-US/guide/animations/ Animations guide}
|
|
118
|
-
*/
|
|
119
|
-
animationInterpolateFn?: AnimationInterpolateFn<FunnelTrapezoidItem, CartesianLayout>
|
|
120
|
-
/**
|
|
121
|
-
* Strategy for matching previous items to next items during animation.
|
|
122
|
-
*
|
|
123
|
-
* - `matchAppend` (default): match sequentially by index and treat newly appended items as new
|
|
124
|
-
* - `matchByIndex`: match by array position with proportional stretching
|
|
125
|
-
* - `matchByDataKey('someKey')`: match by a data key from the payload
|
|
126
|
-
* - Custom function `(item, index) => key`: match by the returned key
|
|
127
|
-
*
|
|
128
|
-
* @defaultValue append
|
|
129
|
-
*/
|
|
130
|
-
animationMatchBy?: AnimationMatchByProp<FunnelTrapezoidItem>
|
|
131
|
-
className?: string
|
|
132
|
-
/**
|
|
133
|
-
* Hides the whole graphical element when true.
|
|
134
|
-
*
|
|
135
|
-
* Hiding an element is different from removing it from the chart:
|
|
136
|
-
* Hidden graphical elements are still visible in Legend,
|
|
137
|
-
* and can be included in axis domain calculations,
|
|
138
|
-
* depending on `includeHidden` props of your XAxis/YAxis.
|
|
139
|
-
*
|
|
140
|
-
* @defaultValue false
|
|
141
|
-
*/
|
|
142
|
-
hide?: boolean
|
|
143
|
-
/**
|
|
144
|
-
* Unique identifier of this component.
|
|
145
|
-
* Used as an HTML attribute `id`, and also to identify this element internally.
|
|
146
|
-
*
|
|
147
|
-
* If undefined, Recharts will generate a unique ID automatically.
|
|
148
|
-
*/
|
|
149
|
-
id?: string
|
|
150
|
-
/**
|
|
151
|
-
* If set false, animation of funnel will be disabled.
|
|
152
|
-
* If set "auto", animation is disabled during SSR and when the user prefers reduced motion.
|
|
153
|
-
* @defaultValue auto
|
|
154
|
-
*/
|
|
155
|
-
isAnimationActive?: boolean | "auto"
|
|
156
|
-
label?: ImplicitLabelListType
|
|
157
|
-
/**
|
|
158
|
-
* @defaultValue triangle
|
|
159
|
-
*/
|
|
160
|
-
lastShapeType?: "triangle" | "rectangle"
|
|
161
|
-
/**
|
|
162
|
-
* The type of icon in legend. If set to 'none', no legend item will be rendered.
|
|
163
|
-
* @defaultValue rect
|
|
164
|
-
*/
|
|
165
|
-
legendType?: LegendType
|
|
166
|
-
/**
|
|
167
|
-
* The name of this graphical item, used in tooltip and legend.
|
|
168
|
-
*/
|
|
169
|
-
name?: string | number
|
|
170
|
-
/**
|
|
171
|
-
* Name represents each sector in the tooltip.
|
|
172
|
-
* This allows you to extract the name from the data:
|
|
173
|
-
*
|
|
174
|
-
* - `string`: the name of the field in the data object;
|
|
175
|
-
* - `number`: the index of the field in the data;
|
|
176
|
-
* - `function`: a function that receives the data object and returns the name.
|
|
177
|
-
*
|
|
178
|
-
* @defaultValue name
|
|
179
|
-
*/
|
|
180
|
-
nameKey?: DataKey<DataPointType, DataValueType>
|
|
181
|
-
/**
|
|
182
|
-
* The customized event handler of animation end
|
|
183
|
-
*/
|
|
184
|
-
onAnimationEnd?: () => void
|
|
185
|
-
/**
|
|
186
|
-
* The customized event handler of animation start
|
|
187
|
-
*/
|
|
188
|
-
onAnimationStart?: () => void
|
|
189
|
-
reversed?: boolean
|
|
190
|
-
/**
|
|
191
|
-
* If set a ReactElement, the shape of funnel can be customized.
|
|
192
|
-
* If set a function, the function will be called to render customized shape.
|
|
193
|
-
*/
|
|
194
|
-
shape?: ActiveShape<FunnelTrapezoidItem, SVGPathElement>
|
|
195
|
-
tooltipType?: TooltipType
|
|
196
|
-
/**
|
|
197
|
-
* Formats the value displayed in the tooltip for this Funnel.
|
|
198
|
-
* When set, takes precedence over the `formatter` prop on the Tooltip component.
|
|
199
|
-
*/
|
|
200
|
-
formatter?: Formatter
|
|
201
|
-
/**
|
|
202
|
-
* The customized event handler of click on the area in this group
|
|
203
|
-
*/
|
|
204
|
-
onClick?: (data: FunnelTrapezoidItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
205
|
-
/**
|
|
206
|
-
* The customized event handler of mousedown on the area in this group
|
|
207
|
-
*/
|
|
208
|
-
onMouseDown?: (data: FunnelTrapezoidItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
209
|
-
/**
|
|
210
|
-
* The customized event handler of mouseup on the area in this group
|
|
211
|
-
*/
|
|
212
|
-
onMouseUp?: (data: FunnelTrapezoidItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
213
|
-
/**
|
|
214
|
-
* The customized event handler of mousemove on the area in this group
|
|
215
|
-
*/
|
|
216
|
-
onMouseMove?: (data: FunnelTrapezoidItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
217
|
-
/**
|
|
218
|
-
* The customized event handler of mouseover on the area in this group
|
|
219
|
-
*/
|
|
220
|
-
onMouseOver?: (data: FunnelTrapezoidItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
221
|
-
/**
|
|
222
|
-
* The customized event handler of mouseout on the area in this group
|
|
223
|
-
*/
|
|
224
|
-
onMouseOut?: (data: FunnelTrapezoidItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
225
|
-
/**
|
|
226
|
-
* The customized event handler of mouseenter on the area in this group
|
|
227
|
-
*/
|
|
228
|
-
onMouseEnter?: (data: FunnelTrapezoidItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
229
|
-
/**
|
|
230
|
-
* The customized event handler of mouseleave on the area in this group
|
|
231
|
-
*/
|
|
232
|
-
onMouseLeave?: (data: FunnelTrapezoidItem, index: number, e: MouseEvent & { currentTarget: SVGGraphicsElement }) => void
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
type FunnelSvgProps = Omit<
|
|
236
|
-
PresentationAttributesAdaptChildEvent<FunnelTrapezoidItem, SVGPathElement>,
|
|
237
|
-
"ref"
|
|
238
|
-
>
|
|
239
|
-
|
|
240
|
-
type InternalProps = FunnelSvgProps & InternalFunnelProps
|
|
241
|
-
|
|
242
|
-
/* eslint-disable-next-line typescript-eslint/no-explicit-any -- upstream contract: untyped items accept any data */
|
|
243
|
-
export type Props<DataPointType = any, DataValueType = any> = FunnelSvgProps & FunnelProps<DataPointType, DataValueType>
|
|
244
|
-
|
|
245
|
-
type RealFunnelData = unknown
|
|
246
|
-
|
|
247
|
-
type FunnelTrapezoidsProps = ShapeAnimationProps & {
|
|
248
|
-
trapezoids: ReadonlyArray<FunnelTrapezoidItem>
|
|
249
|
-
allOtherFunnelProps: InternalProps
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
function SetFunnelTooltipEntrySettings(props: {
|
|
253
|
-
dataKey: InternalProps["dataKey"]
|
|
254
|
-
nameKey: InternalProps["nameKey"]
|
|
255
|
-
stroke: string | undefined
|
|
256
|
-
strokeWidth: number | string | undefined
|
|
257
|
-
fill: string | undefined
|
|
258
|
-
name: string | number | undefined
|
|
259
|
-
hide: boolean | undefined
|
|
260
|
-
tooltipType: InternalProps["tooltipType"]
|
|
261
|
-
formatter: Formatter | undefined
|
|
262
|
-
data: InternalProps["data"]
|
|
263
|
-
id: InternalProps["id"]
|
|
264
|
-
trapezoids: ReadonlyArray<FunnelTrapezoidItem>
|
|
265
|
-
}) {
|
|
266
|
-
/* GOTCHA-005: createMemo so reactive props flow into the settings object. */
|
|
267
|
-
const tooltipEntrySettings = createMemo<TooltipPayloadConfiguration>(() => ({
|
|
268
|
-
dataDefinedOnItem: props.data,
|
|
269
|
-
getPosition: (index) => props.trapezoids[Number(index)]?.tooltipPosition,
|
|
270
|
-
settings: {
|
|
271
|
-
color: props.fill,
|
|
272
|
-
dataKey: props.dataKey,
|
|
273
|
-
fill: props.fill,
|
|
274
|
-
formatter: props.formatter,
|
|
275
|
-
graphicalItemId: props.id,
|
|
276
|
-
hide: props.hide,
|
|
277
|
-
name: props.name,
|
|
278
|
-
nameKey: props.nameKey,
|
|
279
|
-
stroke: props.stroke,
|
|
280
|
-
strokeWidth: props.strokeWidth,
|
|
281
|
-
type: props.tooltipType,
|
|
282
|
-
unit: "",
|
|
283
|
-
},
|
|
284
|
-
}))
|
|
285
|
-
return <SetTooltipEntrySettings tooltipEntrySettings={tooltipEntrySettings()} />
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
function FunnelLabelListProvider(props: {
|
|
289
|
-
showLabels: boolean
|
|
290
|
-
trapezoids: ReadonlyArray<FunnelTrapezoidItem> | undefined
|
|
291
|
-
children: JSX.Element
|
|
292
|
-
}) {
|
|
293
|
-
const labelListEntries = createMemo((): ReadonlyArray<CartesianLabelListEntry> | undefined => {
|
|
294
|
-
if (!props.showLabels) {
|
|
295
|
-
return undefined
|
|
296
|
-
}
|
|
297
|
-
return props.trapezoids?.map((entry): CartesianLabelListEntry => {
|
|
298
|
-
const viewBox: TrapezoidViewBox = entry.labelViewBox
|
|
299
|
-
|
|
300
|
-
return {
|
|
301
|
-
...viewBox,
|
|
302
|
-
fill: entry.fill,
|
|
303
|
-
parentViewBox: entry.parentViewBox,
|
|
304
|
-
payload: entry.payload,
|
|
305
|
-
value: entry.name,
|
|
306
|
-
viewBox,
|
|
307
|
-
}
|
|
308
|
-
})
|
|
309
|
-
})
|
|
310
|
-
|
|
311
|
-
/* eslint-disable solid/reactivity -- labelListEntries() in JSX tracked scope; linter can't trace through Context.Provider value prop */
|
|
312
|
-
return (
|
|
313
|
-
<CartesianLabelListContextProvider value={labelListEntries()}>
|
|
314
|
-
{props.children}
|
|
315
|
-
</CartesianLabelListContextProvider>
|
|
316
|
-
)
|
|
317
|
-
/* eslint-enable solid/reactivity */
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
function FunnelTrapezoids(funnelTrapProps: FunnelTrapezoidsProps) {
|
|
321
|
-
/* GOTCHA-016-C: one entry per pointer move across both event pairs, shared by all items. */
|
|
322
|
-
const hover = createHoverDedupe()
|
|
323
|
-
const ctx = useChartStore()
|
|
324
|
-
const activeItemIndex = createMemo(() =>
|
|
325
|
-
ctx
|
|
326
|
-
? selectActiveIndex(
|
|
327
|
-
ctx.store,
|
|
328
|
-
"item",
|
|
329
|
-
readChartState(ctx.store).tooltip.settings.trigger,
|
|
330
|
-
undefined,
|
|
331
|
-
)
|
|
332
|
-
: undefined,
|
|
333
|
-
)
|
|
334
|
-
|
|
335
|
-
/* eslint-disable solid/reactivity -- id is a stable identifier; handler and dataKey sources are accessors read at event time */
|
|
336
|
-
const onMouseEnterFromContext = useMouseEnterItemDispatch(
|
|
337
|
-
() => funnelTrapProps.allOtherFunnelProps.onMouseEnter,
|
|
338
|
-
() => funnelTrapProps.allOtherFunnelProps.dataKey,
|
|
339
|
-
funnelTrapProps.allOtherFunnelProps.id,
|
|
340
|
-
)
|
|
341
|
-
const onMouseLeaveFromContext = useMouseLeaveItemDispatch(
|
|
342
|
-
() => funnelTrapProps.allOtherFunnelProps.onMouseLeave,
|
|
343
|
-
)
|
|
344
|
-
const onClickFromContext = useMouseClickItemDispatch(
|
|
345
|
-
() => funnelTrapProps.allOtherFunnelProps.onClick,
|
|
346
|
-
() => funnelTrapProps.allOtherFunnelProps.dataKey,
|
|
347
|
-
funnelTrapProps.allOtherFunnelProps.id,
|
|
348
|
-
)
|
|
349
|
-
/* eslint-enable solid/reactivity */
|
|
350
|
-
|
|
351
|
-
return (
|
|
352
|
-
<For each={funnelTrapProps.trapezoids}>
|
|
353
|
-
{(entry: FunnelTrapezoidItem, i) => {
|
|
354
|
-
const isActiveIndex = () =>
|
|
355
|
-
Boolean(funnelTrapProps.allOtherFunnelProps.activeShape) &&
|
|
356
|
-
activeItemIndex() === String(i())
|
|
357
|
-
const trapezoidOptions = () =>
|
|
358
|
-
isActiveIndex()
|
|
359
|
-
? funnelTrapProps.allOtherFunnelProps.activeShape
|
|
360
|
-
: funnelTrapProps.allOtherFunnelProps.shape
|
|
361
|
-
|
|
362
|
-
const trapezoidProps = (): Omit<FunnelTrapezoidProps, "id"> => ({
|
|
363
|
-
...entry,
|
|
364
|
-
animationElapsedTime: funnelTrapProps.animationElapsedTime,
|
|
365
|
-
isActive: isActiveIndex(),
|
|
366
|
-
isAnimating: funnelTrapProps.isAnimating,
|
|
367
|
-
isEntrance: funnelTrapProps.isEntrance,
|
|
368
|
-
/* read lazily where Shape renders it (an element option mints a shape per read) */
|
|
369
|
-
get option() {
|
|
370
|
-
return trapezoidOptions()
|
|
371
|
-
},
|
|
372
|
-
stroke: entry.stroke,
|
|
373
|
-
})
|
|
374
|
-
|
|
375
|
-
/* Event handlers bind once per item, like a keyed list. */
|
|
376
|
-
const handlerIndex = untrack(i)
|
|
377
|
-
/* GOTCHA-016-C: bind both pairs, dedupe per-instance. Compose adapted user handlers. */
|
|
378
|
-
const adapted = untrack(
|
|
379
|
-
() =>
|
|
380
|
-
(adaptEventsOfChild(funnelTrapProps.allOtherFunnelProps, entry, handlerIndex) ??
|
|
381
|
-
{}) as Record<string, ((e: Event) => void) | undefined>,
|
|
382
|
-
)
|
|
383
|
-
const enter = onMouseEnterFromContext(entry, handlerIndex)
|
|
384
|
-
const leave = onMouseLeaveFromContext(entry, handlerIndex)
|
|
385
|
-
const userOver = adapted.onMouseOver
|
|
386
|
-
const userOut = adapted.onMouseOut
|
|
387
|
-
const fireEnter = (e: MouseEvent & { currentTarget: SVGGraphicsElement }) => {
|
|
388
|
-
if (!hover.enter(e)) return
|
|
389
|
-
userOver?.(e)
|
|
390
|
-
enter(e)
|
|
391
|
-
}
|
|
392
|
-
const fireLeave = (e: MouseEvent & { currentTarget: SVGGraphicsElement }) => {
|
|
393
|
-
if (!hover.leave(e)) return
|
|
394
|
-
userOut?.(e)
|
|
395
|
-
leave(e)
|
|
396
|
-
}
|
|
397
|
-
return (
|
|
398
|
-
<Layer
|
|
399
|
-
class="recharts-funnel-trapezoid"
|
|
400
|
-
{...adapted}
|
|
401
|
-
onMouseEnter={fireEnter}
|
|
402
|
-
onMouseOver={fireEnter}
|
|
403
|
-
onMouseLeave={fireLeave}
|
|
404
|
-
onMouseOut={fireLeave}
|
|
405
|
-
onClick={onClickFromContext(entry, handlerIndex)}
|
|
406
|
-
>
|
|
407
|
-
<FunnelTrapezoid {...trapezoidProps()} />
|
|
408
|
-
</Layer>
|
|
409
|
-
)
|
|
410
|
-
}}
|
|
411
|
-
</For>
|
|
412
|
-
)
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
const defaultFunnelAnimateItems: AnimationInterpolateFn<FunnelTrapezoidItem, CartesianLayout> = (
|
|
416
|
-
items,
|
|
417
|
-
animationElapsedTime,
|
|
418
|
-
) => {
|
|
419
|
-
if (items == null) return []
|
|
420
|
-
if (animationElapsedTime === 1) {
|
|
421
|
-
return items.flatMap((item) => (item.status === "removed" ? [] : [item.next]))
|
|
422
|
-
}
|
|
423
|
-
return items.flatMap((item) => {
|
|
424
|
-
if (item.status === "removed") return []
|
|
425
|
-
if (item.status === "matched") {
|
|
426
|
-
return [
|
|
427
|
-
{
|
|
428
|
-
...item.next,
|
|
429
|
-
height: interpolate(item.prev.height, item.next.height, animationElapsedTime),
|
|
430
|
-
lowerWidth: interpolate(item.prev.lowerWidth, item.next.lowerWidth, animationElapsedTime),
|
|
431
|
-
upperWidth: interpolate(item.prev.upperWidth, item.next.upperWidth, animationElapsedTime),
|
|
432
|
-
x: interpolate(item.prev.x, item.next.x, animationElapsedTime),
|
|
433
|
-
y: interpolate(item.prev.y, item.next.y, animationElapsedTime),
|
|
434
|
-
},
|
|
435
|
-
]
|
|
436
|
-
}
|
|
437
|
-
// added
|
|
438
|
-
const { next } = item
|
|
439
|
-
return [
|
|
440
|
-
{
|
|
441
|
-
...next,
|
|
442
|
-
height: interpolate(0, next.height, animationElapsedTime),
|
|
443
|
-
lowerWidth: interpolate(0, next.lowerWidth, animationElapsedTime),
|
|
444
|
-
upperWidth: interpolate(0, next.upperWidth, animationElapsedTime),
|
|
445
|
-
x: interpolate(next.x + next.upperWidth / 2, next.x, animationElapsedTime),
|
|
446
|
-
y: interpolate(next.y + next.height / 2, next.y, animationElapsedTime),
|
|
447
|
-
},
|
|
448
|
-
]
|
|
449
|
-
})
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
function TrapezoidsWithAnimation(animProps: {
|
|
453
|
-
props: InternalProps
|
|
454
|
-
previousTrapezoidsRef: { current: ReadonlyArray<FunnelTrapezoidItem> | undefined }
|
|
455
|
-
}) {
|
|
456
|
-
const layout = createMemo(() => useCartesianChartLayout())
|
|
457
|
-
const { isAnimating, handleAnimationStart, handleAnimationEnd } = useAnimationCallbacks(
|
|
458
|
-
() => animProps.props.onAnimationStart,
|
|
459
|
-
() => animProps.props.onAnimationEnd,
|
|
460
|
-
)
|
|
461
|
-
|
|
462
|
-
return (
|
|
463
|
-
<Show when={layout()}>
|
|
464
|
-
{(cartesianLayout) => (
|
|
465
|
-
<FunnelLabelListProvider showLabels={!isAnimating()} trapezoids={animProps.props.trapezoids}>
|
|
466
|
-
<AnimatedItems
|
|
467
|
-
animationInput={animProps.props.trapezoids}
|
|
468
|
-
animationIdPrefix="recharts-funnel-"
|
|
469
|
-
items={animProps.props.trapezoids}
|
|
470
|
-
previousItemsRef={animProps.previousTrapezoidsRef}
|
|
471
|
-
isAnimationActive={animProps.props.isAnimationActive}
|
|
472
|
-
animationBegin={animProps.props.animationBegin}
|
|
473
|
-
animationDuration={animProps.props.animationDuration}
|
|
474
|
-
animationEasing={animProps.props.animationEasing}
|
|
475
|
-
onAnimationStart={handleAnimationStart}
|
|
476
|
-
onAnimationEnd={handleAnimationEnd}
|
|
477
|
-
animationInterpolateFn={animProps.props.animationInterpolateFn}
|
|
478
|
-
animationMatchBy={animProps.props.animationMatchBy}
|
|
479
|
-
layout={cartesianLayout()}
|
|
480
|
-
>
|
|
481
|
-
{(stepData, animationElapsedTime, isEntrance) => (
|
|
482
|
-
<Layer>
|
|
483
|
-
<FunnelTrapezoids
|
|
484
|
-
trapezoids={stepData()}
|
|
485
|
-
allOtherFunnelProps={animProps.props}
|
|
486
|
-
animationElapsedTime={animationElapsedTime()}
|
|
487
|
-
isAnimating={isAnimating() || animationElapsedTime() < 1}
|
|
488
|
-
isEntrance={isEntrance()}
|
|
489
|
-
/>
|
|
490
|
-
</Layer>
|
|
491
|
-
)}
|
|
492
|
-
</AnimatedItems>
|
|
493
|
-
<LabelListFromLabelProp label={animProps.props.label} />
|
|
494
|
-
{animProps.props.children}
|
|
495
|
-
</FunnelLabelListProvider>
|
|
496
|
-
)}
|
|
497
|
-
</Show>
|
|
498
|
-
)
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
function RenderTrapezoids(props: InternalProps) {
|
|
502
|
-
const previousTrapezoidsRef: { current: ReadonlyArray<FunnelTrapezoidItem> | undefined } = {
|
|
503
|
-
current: undefined,
|
|
504
|
-
}
|
|
505
|
-
return <TrapezoidsWithAnimation props={props} previousTrapezoidsRef={previousTrapezoidsRef} />
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
const getRealWidthHeight = (
|
|
509
|
-
customWidth: number | string | undefined,
|
|
510
|
-
offset: ChartOffsetInternal,
|
|
511
|
-
) => {
|
|
512
|
-
const realWidth: number = getPercentValue(customWidth, offset.width, offset.width)
|
|
513
|
-
|
|
514
|
-
return {
|
|
515
|
-
offsetX: offset.left,
|
|
516
|
-
offsetY: offset.top,
|
|
517
|
-
realHeight: offset.height,
|
|
518
|
-
realWidth,
|
|
519
|
-
}
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
export const defaultFunnelProps = {
|
|
523
|
-
animationBegin: 400,
|
|
524
|
-
animationDuration: 1500,
|
|
525
|
-
animationEasing: "ease",
|
|
526
|
-
animationInterpolateFn: defaultFunnelAnimateItems,
|
|
527
|
-
animationMatchBy: matchAppend,
|
|
528
|
-
fill: "#808080",
|
|
529
|
-
hide: false,
|
|
530
|
-
isAnimationActive: "auto",
|
|
531
|
-
lastShapeType: "triangle",
|
|
532
|
-
legendType: "rect",
|
|
533
|
-
nameKey: "name",
|
|
534
|
-
reversed: false,
|
|
535
|
-
stroke: "#fff",
|
|
536
|
-
} as const satisfies Partial<Props>
|
|
537
|
-
|
|
538
|
-
function FunnelImpl(
|
|
539
|
-
props: WithIdRequired<RequiresDefaultProps<Props, typeof defaultFunnelProps>> & { cellsRegistry: CellsRegistry },
|
|
540
|
-
) {
|
|
541
|
-
const plotArea = createMemo(() => usePlotArea())
|
|
542
|
-
const ctx = useChartStore()
|
|
543
|
-
|
|
544
|
-
/* The graphical item id identifies the Funnel, not each trapezoid; keep it out
|
|
545
|
-
of the per-entry presentation props so trapezoids carry no duplicate `id`. */
|
|
546
|
-
const presentationProps = (() => {
|
|
547
|
-
const { id: _id, ...rest } = svgPropertiesNoEvents(props) as Record<string, unknown>
|
|
548
|
-
return rest
|
|
549
|
-
})()
|
|
550
|
-
const cells = createMemo(() => {
|
|
551
|
-
const list = props.cellsRegistry.cells()
|
|
552
|
-
return list.map((cell) => cell.props)
|
|
553
|
-
})
|
|
554
|
-
|
|
555
|
-
const funnelSettings = createMemo(
|
|
556
|
-
(): ResolvedFunnelSettings => ({
|
|
557
|
-
cells: cells(),
|
|
558
|
-
customWidth: props.width,
|
|
559
|
-
data: props.data,
|
|
560
|
-
dataKey: props.dataKey,
|
|
561
|
-
id: props.id,
|
|
562
|
-
lastShapeType: props.lastShapeType,
|
|
563
|
-
nameKey: props.nameKey,
|
|
564
|
-
presentationProps,
|
|
565
|
-
reversed: props.reversed,
|
|
566
|
-
tooltipType: props.tooltipType,
|
|
567
|
-
}),
|
|
568
|
-
)
|
|
569
|
-
|
|
570
|
-
const trapezoids = () =>
|
|
571
|
-
ctx ? selectFunnelTrapezoids(ctx.store, funnelSettings()) : undefined
|
|
572
|
-
|
|
573
|
-
return (
|
|
574
|
-
<Show
|
|
575
|
-
when={!props.hide && (trapezoids()?.length ?? 0) > 0 && plotArea()}
|
|
576
|
-
fallback={null}
|
|
577
|
-
>
|
|
578
|
-
{(() => {
|
|
579
|
-
const viewBox = plotArea()
|
|
580
|
-
const { height, width } = viewBox as { height: number; width: number }
|
|
581
|
-
const layerClass = () => clsx("recharts-trapezoids", props.className)
|
|
582
|
-
const tz = (): ReadonlyArray<FunnelTrapezoidItem> => trapezoids() ?? []
|
|
583
|
-
|
|
584
|
-
return (
|
|
585
|
-
<>
|
|
586
|
-
<SetFunnelTooltipEntrySettings
|
|
587
|
-
dataKey={props.dataKey}
|
|
588
|
-
nameKey={props.nameKey}
|
|
589
|
-
stroke={props.stroke}
|
|
590
|
-
strokeWidth={props["stroke-width"]}
|
|
591
|
-
fill={props.fill}
|
|
592
|
-
name={props.name}
|
|
593
|
-
hide={props.hide}
|
|
594
|
-
tooltipType={props.tooltipType}
|
|
595
|
-
formatter={props.formatter}
|
|
596
|
-
data={props.data}
|
|
597
|
-
trapezoids={tz()}
|
|
598
|
-
id={props.id}
|
|
599
|
-
/>
|
|
600
|
-
<Layer class={layerClass()}>
|
|
601
|
-
<RenderTrapezoids
|
|
602
|
-
{...props}
|
|
603
|
-
height={height}
|
|
604
|
-
width={width}
|
|
605
|
-
trapezoids={tz()}
|
|
606
|
-
/>
|
|
607
|
-
</Layer>
|
|
608
|
-
</>
|
|
609
|
-
)
|
|
610
|
-
})()}
|
|
611
|
-
</Show>
|
|
612
|
-
)
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
export function computeFunnelTrapezoids({
|
|
616
|
-
dataKey,
|
|
617
|
-
nameKey,
|
|
618
|
-
displayedData,
|
|
619
|
-
tooltipType,
|
|
620
|
-
lastShapeType,
|
|
621
|
-
reversed,
|
|
622
|
-
offset,
|
|
623
|
-
customWidth,
|
|
624
|
-
graphicalItemId,
|
|
625
|
-
}: {
|
|
626
|
-
dataKey: Props["dataKey"]
|
|
627
|
-
nameKey: Props["nameKey"]
|
|
628
|
-
offset: ChartOffsetInternal
|
|
629
|
-
displayedData: ReadonlyArray<RealFunnelData>
|
|
630
|
-
tooltipType?: TooltipType
|
|
631
|
-
lastShapeType?: Props["lastShapeType"]
|
|
632
|
-
reversed?: boolean
|
|
633
|
-
customWidth: number | string | undefined
|
|
634
|
-
graphicalItemId: GraphicalItemId
|
|
635
|
-
}): ReadonlyArray<FunnelTrapezoidItem> {
|
|
636
|
-
const { realHeight, realWidth, offsetX, offsetY } = getRealWidthHeight(customWidth, offset)
|
|
637
|
-
const values = displayedData.map((entry: unknown) => {
|
|
638
|
-
const val = getValueByDataKey(entry, dataKey, 0)
|
|
639
|
-
return typeof val === "number" ? val : 0
|
|
640
|
-
})
|
|
641
|
-
const maxValue = Math.max.apply(null, values)
|
|
642
|
-
const len = displayedData.length
|
|
643
|
-
const rowHeight = realHeight / len
|
|
644
|
-
const parentViewBox = {
|
|
645
|
-
height: offset.height,
|
|
646
|
-
width: offset.width,
|
|
647
|
-
x: offset.left,
|
|
648
|
-
y: offset.top,
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
let trapezoids: ReadonlyArray<FunnelTrapezoidItem> = displayedData.map(
|
|
652
|
-
(entry: unknown, i: number): FunnelTrapezoidItem => {
|
|
653
|
-
const rawVal = getValueByDataKey(entry, dataKey, 0) as number | ReadonlyArray<number>
|
|
654
|
-
const name: string = String(getValueByDataKey(entry, nameKey, i))
|
|
655
|
-
let val = rawVal
|
|
656
|
-
let nextVal: number | ReadonlyArray<number> | undefined
|
|
657
|
-
|
|
658
|
-
if (i !== len - 1) {
|
|
659
|
-
const nextDataValue = getValueByDataKey(displayedData[i + 1], dataKey, 0)
|
|
660
|
-
if (typeof nextDataValue === "number") {
|
|
661
|
-
nextVal = nextDataValue
|
|
662
|
-
} else if (Array.isArray(nextDataValue)) {
|
|
663
|
-
const [first, second] = nextDataValue
|
|
664
|
-
if (typeof first === "number") {
|
|
665
|
-
val = first
|
|
666
|
-
}
|
|
667
|
-
if (typeof second === "number") {
|
|
668
|
-
nextVal = second
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
} else if (Array.isArray(rawVal) && rawVal.length === 2) {
|
|
672
|
-
const [first, second] = rawVal
|
|
673
|
-
if (typeof first === "number") {
|
|
674
|
-
val = first
|
|
675
|
-
}
|
|
676
|
-
if (typeof second === "number") {
|
|
677
|
-
nextVal = second
|
|
678
|
-
}
|
|
679
|
-
} else if (lastShapeType === "rectangle") {
|
|
680
|
-
nextVal = val
|
|
681
|
-
} else {
|
|
682
|
-
nextVal = 0
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
/* val and nextVal may be arrays for ranged values; numeric coercion handles the math */
|
|
686
|
-
/* maxValue 0 (all values zero) would divide by zero: collapse to zero width (#7184) */
|
|
687
|
-
const x = maxValue === 0 ? offsetX : ((maxValue - (val as number)) * realWidth) / (2 * maxValue) + offsetX
|
|
688
|
-
const y = rowHeight * i + offsetY
|
|
689
|
-
const upperWidth = maxValue === 0 ? 0 : ((val as number) / maxValue) * realWidth
|
|
690
|
-
const lowerWidth = maxValue === 0 ? 0 : ((nextVal as number) / maxValue) * realWidth
|
|
691
|
-
|
|
692
|
-
const tooltipPayload: TooltipPayload = [
|
|
693
|
-
{ dataKey, graphicalItemId, name, payload: entry, type: tooltipType, value: val },
|
|
694
|
-
]
|
|
695
|
-
const tooltipPosition: Coordinate = {
|
|
696
|
-
x: x + upperWidth / 2,
|
|
697
|
-
y: y + rowHeight / 2,
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
const trapezoidViewBox: TrapezoidViewBox = {
|
|
701
|
-
height: rowHeight,
|
|
702
|
-
lowerWidth,
|
|
703
|
-
upperWidth,
|
|
704
|
-
width: Math.max(upperWidth, lowerWidth),
|
|
705
|
-
x,
|
|
706
|
-
y,
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
return {
|
|
710
|
-
...trapezoidViewBox,
|
|
711
|
-
name,
|
|
712
|
-
val: val as number | ReadonlyArray<number>,
|
|
713
|
-
tooltipPayload,
|
|
714
|
-
tooltipPosition,
|
|
715
|
-
...(entry != null && typeof entry === "object"
|
|
716
|
-
? omit(entry as Record<string, unknown>, ["width"])
|
|
717
|
-
: {}),
|
|
718
|
-
payload: entry,
|
|
719
|
-
parentViewBox,
|
|
720
|
-
labelViewBox: trapezoidViewBox,
|
|
721
|
-
}
|
|
722
|
-
},
|
|
723
|
-
)
|
|
724
|
-
|
|
725
|
-
if (reversed) {
|
|
726
|
-
trapezoids = trapezoids.map(
|
|
727
|
-
(entry: FunnelTrapezoidItem, index: number): FunnelTrapezoidItem => {
|
|
728
|
-
const reversedViewBox: TrapezoidViewBox = {
|
|
729
|
-
height: rowHeight,
|
|
730
|
-
lowerWidth: entry.upperWidth,
|
|
731
|
-
upperWidth: entry.lowerWidth,
|
|
732
|
-
width: Math.max(entry.lowerWidth, entry.upperWidth),
|
|
733
|
-
x: entry.x - (entry.lowerWidth - entry.upperWidth) / 2,
|
|
734
|
-
y: entry.y - index * rowHeight + (len - 1 - index) * rowHeight,
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
return {
|
|
738
|
-
...entry,
|
|
739
|
-
...reversedViewBox,
|
|
740
|
-
labelViewBox: reversedViewBox,
|
|
741
|
-
tooltipPosition: {
|
|
742
|
-
...entry.tooltipPosition,
|
|
743
|
-
y: entry.y - index * rowHeight + (len - 1 - index) * rowHeight + rowHeight / 2,
|
|
744
|
-
},
|
|
745
|
-
}
|
|
746
|
-
},
|
|
747
|
-
)
|
|
748
|
-
}
|
|
749
|
-
|
|
750
|
-
return trapezoids
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
/**
|
|
754
|
-
* @consumes CartesianViewBoxContext
|
|
755
|
-
* @provides LabelListContext
|
|
756
|
-
* @provides CellReader
|
|
757
|
-
*/
|
|
758
|
-
function FunnelFn(outsideProps: Props): JSX.Element {
|
|
759
|
-
/* GOTCHA-013: split children before resolveDefaultProps. The destructure spread
|
|
760
|
-
reads the `children` getter on the props proxy, eagerly evaluating user JSX
|
|
761
|
-
(Cell, etc.) before RegisterGraphicalItemId installs its Provider.
|
|
762
|
-
Memoize once — the `get children()` getter on user JSX re-creates components on
|
|
763
|
-
every read. */
|
|
764
|
-
const [childrenProps, restProps] = splitProps(outsideProps, ["children"])
|
|
765
|
-
const [idProps, props] = splitProps(resolveDefaultProps(restProps, defaultFunnelProps), ["id"])
|
|
766
|
-
return (
|
|
767
|
-
<RegisterGraphicalItemId id={idProps.id} type="funnel">
|
|
768
|
-
{(id) => (
|
|
769
|
-
<LabelListContextBridge>
|
|
770
|
-
{(() => {
|
|
771
|
-
/* <Cell/> children register here; upstream reads them with findAllByType. */
|
|
772
|
-
const cellsRegistry = createCellsRegistry()
|
|
773
|
-
return (
|
|
774
|
-
<CellsContextProvider value={cellsRegistry}>
|
|
775
|
-
{(() => {
|
|
776
|
-
/* Memoize children inside Provider scope (GOTCHA-013). */
|
|
777
|
-
const memoizedChildren = createMemo(() => childrenProps.children)
|
|
778
|
-
return (
|
|
779
|
-
<FunnelImpl {...props} id={id} cellsRegistry={cellsRegistry}>
|
|
780
|
-
{memoizedChildren()}
|
|
781
|
-
</FunnelImpl>
|
|
782
|
-
)
|
|
783
|
-
})()}
|
|
784
|
-
</CellsContextProvider>
|
|
785
|
-
)
|
|
786
|
-
})()}
|
|
787
|
-
</LabelListContextBridge>
|
|
788
|
-
)}
|
|
789
|
-
</RegisterGraphicalItemId>
|
|
790
|
-
)
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
/**
|
|
794
|
-
* Typed entry point: the generics constrain props at the call site, like upstream.
|
|
795
|
-
*/
|
|
796
|
-
/* eslint-disable-next-line typescript-eslint/no-explicit-any -- upstream contract: untyped usage accepts any data */
|
|
797
|
-
export const Funnel = FunnelFn as {
|
|
798
|
-
<DataPointType = any, DataValueType = any>(props: Props<DataPointType, DataValueType>): JSX.Element
|
|
799
|
-
/* eslint-disable-next-line typescript-eslint/no-explicit-any -- upstream fallback overload for mismatched data/dataKey */
|
|
800
|
-
(props: Props<any, any>): JSX.Element
|
|
801
|
-
displayName?: string
|
|
802
|
-
}
|
|
803
|
-
Funnel.displayName = "Funnel"
|