@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,46 @@
|
|
|
1
|
+
/* eslint-disable import/no-cycle */
|
|
2
|
+
import type { JSX } from '@solidjs/web';
|
|
3
|
+
import { arrayTooltipSearcher } from "../state/optionsSlice"
|
|
4
|
+
import type { PolarChartProps, TooltipEventType } from "../util/types"
|
|
5
|
+
import { defaultPolarChartProps, PolarChart } from "./PolarChart"
|
|
6
|
+
|
|
7
|
+
import { mergeProps } from '../util/solid-1-compat';
|
|
8
|
+
const allowedTooltipTypes: ReadonlyArray<TooltipEventType> = ["axis", "item"]
|
|
9
|
+
|
|
10
|
+
export const defaultRadialBarChartProps = {
|
|
11
|
+
...defaultPolarChartProps,
|
|
12
|
+
endAngle: 360,
|
|
13
|
+
layout: "radial",
|
|
14
|
+
startAngle: 0,
|
|
15
|
+
} as const satisfies Partial<PolarChartProps<never>>
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @consumes ResponsiveContainerContext
|
|
19
|
+
* @provides PolarViewBoxContext
|
|
20
|
+
* @provides PolarChartContext
|
|
21
|
+
*/
|
|
22
|
+
export function RadialBarChart<DataPointType = unknown>(
|
|
23
|
+
props: PolarChartProps<DataPointType> & { ref?: SVGSVGElement | ((el: SVGSVGElement) => void) },
|
|
24
|
+
): JSX.Element {
|
|
25
|
+
/* mergeProps preserves the props proxy — see PieChart for the rationale. */
|
|
26
|
+
const propsWithDefaults = mergeProps(defaultRadialBarChartProps, props) as PolarChartProps<
|
|
27
|
+
DataPointType
|
|
28
|
+
> & {
|
|
29
|
+
cx: NonNullable<PolarChartProps["cx"]>
|
|
30
|
+
cy: NonNullable<PolarChartProps["cy"]>
|
|
31
|
+
startAngle: NonNullable<PolarChartProps["startAngle"]>
|
|
32
|
+
endAngle: NonNullable<PolarChartProps["endAngle"]>
|
|
33
|
+
innerRadius: NonNullable<PolarChartProps["innerRadius"]>
|
|
34
|
+
outerRadius: NonNullable<PolarChartProps["outerRadius"]>
|
|
35
|
+
}
|
|
36
|
+
return (
|
|
37
|
+
<PolarChart
|
|
38
|
+
chartName="RadialBarChart"
|
|
39
|
+
defaultTooltipEventType="axis"
|
|
40
|
+
validateTooltipEventTypes={allowedTooltipTypes}
|
|
41
|
+
tooltipPayloadSearcher={arrayTooltipSearcher}
|
|
42
|
+
categoricalChartProps={propsWithDefaults}
|
|
43
|
+
ref={props.ref}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
/* eslint-disable import/no-cycle */
|
|
2
|
+
import type { JSX } from '@solidjs/web';
|
|
3
|
+
import { createSignal, onCleanup, untrack } from 'solid-js';
|
|
4
|
+
import { clsx } from "clsx"
|
|
5
|
+
import { useChartStore } from "../state/RechartsStoreContext"
|
|
6
|
+
import { useOptionalChartState } from "../state/useChartState"
|
|
7
|
+
import { useSynchronisedEventsFromOtherCharts } from "../synchronisation/useChartSynchronisation"
|
|
8
|
+
import { useReportScale } from "../util/useReportScale"
|
|
9
|
+
import type { ExternalMouseEvents } from "./types"
|
|
10
|
+
import { TooltipPortalContext } from "../context/tooltipPortalContext"
|
|
11
|
+
import { LegendPortalContext } from "../context/legendPortalContext"
|
|
12
|
+
import { ReportChartSize } from "../context/chartLayoutContext"
|
|
13
|
+
import { useResponsiveContainerContext } from "../component/ResponsiveContainer"
|
|
14
|
+
import type { HTMLMousePointer, Percent } from "../util/types"
|
|
15
|
+
|
|
16
|
+
export type RechartsWrapperProps = ExternalMouseEvents & {
|
|
17
|
+
children: JSX.Element
|
|
18
|
+
width: number | Percent | undefined
|
|
19
|
+
height: number | Percent | undefined
|
|
20
|
+
/**
|
|
21
|
+
* If true, then it will listen to container size changes and adapt the SVG chart accordingly.
|
|
22
|
+
* If false, then it renders the chart at the specified width and height and will stay that way
|
|
23
|
+
* even if the container size changes.
|
|
24
|
+
*/
|
|
25
|
+
responsive: boolean
|
|
26
|
+
class?: string
|
|
27
|
+
style?: JSX.CSSProperties
|
|
28
|
+
ref?: HTMLDivElement | ((el: HTMLDivElement) => void)
|
|
29
|
+
/**
|
|
30
|
+
* Treemap is special snowflake that handles its own mouse events so
|
|
31
|
+
* here is a flag to disable the dispatching of mouse events from RechartsWrapper.
|
|
32
|
+
* If false, then this disables mouse click and touch event dispatching.
|
|
33
|
+
* Mouse move events are still dispatched because they are needed for tooltip synchronization.
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
dispatchTouchEvents?: boolean
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function EventSynchronizer(): null {
|
|
40
|
+
useSynchronisedEventsFromOtherCharts()
|
|
41
|
+
return null
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/* Solid does not auto-append `px` to numeric inline style values like React does
|
|
45
|
+
for length properties — `height: 200` lands on the DOM as a unitless string and
|
|
46
|
+
browsers ignore it. Mirror React's behavior on length-typed keys. */
|
|
47
|
+
const PX_KEYS = new Set([
|
|
48
|
+
"width",
|
|
49
|
+
"height",
|
|
50
|
+
"minWidth",
|
|
51
|
+
"minHeight",
|
|
52
|
+
"maxWidth",
|
|
53
|
+
"maxHeight",
|
|
54
|
+
"top",
|
|
55
|
+
"left",
|
|
56
|
+
"right",
|
|
57
|
+
"bottom",
|
|
58
|
+
])
|
|
59
|
+
function pxifyStyle(style: JSX.CSSProperties | undefined): JSX.CSSProperties | undefined {
|
|
60
|
+
if (style == null) return style
|
|
61
|
+
let mutated = false
|
|
62
|
+
const out: Record<string, string | number> = {}
|
|
63
|
+
for (const k of Object.keys(style)) {
|
|
64
|
+
const v = (style as Record<string, string | number | undefined>)[k]
|
|
65
|
+
if (v == null) continue
|
|
66
|
+
if (PX_KEYS.has(k) && typeof v === "number") {
|
|
67
|
+
out[k] = `${v}px`
|
|
68
|
+
mutated = true
|
|
69
|
+
} else {
|
|
70
|
+
out[k] = v
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return mutated ? (out as JSX.CSSProperties) : style
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function getNumberOrZero(value: number | string | undefined): number {
|
|
77
|
+
if (typeof value === "number") {
|
|
78
|
+
return value
|
|
79
|
+
}
|
|
80
|
+
if (typeof value === "string") {
|
|
81
|
+
const parsed = parseFloat(value)
|
|
82
|
+
if (!Number.isNaN(parsed)) {
|
|
83
|
+
return parsed
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return 0
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
type WrapperDivProps = {
|
|
90
|
+
width: number | string | undefined
|
|
91
|
+
height: number | string | undefined
|
|
92
|
+
class?: string
|
|
93
|
+
style?: JSX.CSSProperties
|
|
94
|
+
ref?: HTMLDivElement | ((el: HTMLDivElement) => void)
|
|
95
|
+
onClick?: (e: MouseEvent) => void
|
|
96
|
+
onContextMenu?: (e: MouseEvent) => void
|
|
97
|
+
onDblClick?: (e: MouseEvent) => void
|
|
98
|
+
/* `onFocus`/`onBlur` (focus/blur events) do NOT bubble in the DOM. The
|
|
99
|
+
* focusable target is the inner `<svg tabindex=0>`, not this wrapper div —
|
|
100
|
+
* so a focus event on the svg never reaches a div-level `onfocus` listener.
|
|
101
|
+
* Solid binds events 1:1 with the DOM (no React-style synthetic delegation),
|
|
102
|
+
* so we listen to `focusin`/`focusout` instead — those bubble. */
|
|
103
|
+
onFocusIn?: () => void
|
|
104
|
+
onFocusOut?: () => void
|
|
105
|
+
onKeyDown?: (e: KeyboardEvent) => void
|
|
106
|
+
onMouseDown?: (e: MouseEvent) => void
|
|
107
|
+
onMouseEnter?: (e: MouseEvent) => void
|
|
108
|
+
onMouseLeave?: (e: MouseEvent) => void
|
|
109
|
+
onMouseMove?: (e: MouseEvent) => void
|
|
110
|
+
/* React's onMouseEnter/Leave were synthetic and fired on mouseover/mouseout too.
|
|
111
|
+
Solid binds native events 1:1 — mouseenter doesn't fire on fireEvent.mouseOver.
|
|
112
|
+
Bind both pairs so test helpers that fire mouseOver/mouseOut still trigger
|
|
113
|
+
the same dispatch path users get from real-browser pointer entry. */
|
|
114
|
+
onMouseOver?: (e: MouseEvent) => void
|
|
115
|
+
onMouseOut?: (e: MouseEvent) => void
|
|
116
|
+
onMouseUp?: (e: MouseEvent) => void
|
|
117
|
+
onTouchEnd?: (e: TouchEvent) => void
|
|
118
|
+
onTouchMove?: (e: TouchEvent) => void
|
|
119
|
+
onTouchStart?: (e: TouchEvent) => void
|
|
120
|
+
children?: JSX.Element
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function ResponsiveDiv(props: WrapperDivProps) {
|
|
124
|
+
let observerRef: ResizeObserver | null = null
|
|
125
|
+
|
|
126
|
+
/* eslint-disable solid/reactivity -- props.style.height/width seed signal once at setup; innerRef is a callback ref (not a signal), used correctly with ref={innerRef} */
|
|
127
|
+
const [sizes, setSizes] = createSignal<{
|
|
128
|
+
containerWidth: number
|
|
129
|
+
containerHeight: number
|
|
130
|
+
}>(
|
|
131
|
+
untrack(() => ({
|
|
132
|
+
containerHeight: getNumberOrZero(props.style?.height),
|
|
133
|
+
containerWidth: getNumberOrZero(props.style?.width),
|
|
134
|
+
})),
|
|
135
|
+
)
|
|
136
|
+
/* eslint-enable solid/reactivity */
|
|
137
|
+
|
|
138
|
+
function setContainerSize(newWidth: number, newHeight: number) {
|
|
139
|
+
const roundedWidth = Math.round(newWidth)
|
|
140
|
+
const roundedHeight = Math.round(newHeight)
|
|
141
|
+
const prev = untrack(sizes)
|
|
142
|
+
if (prev.containerWidth === roundedWidth && prev.containerHeight === roundedHeight) {
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
setSizes({ containerHeight: roundedHeight, containerWidth: roundedWidth })
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* eslint-disable-next-line solid/reactivity -- innerRef is a callback ref assigned via ref={innerRef}; linter false-positive on function-as-ref */
|
|
149
|
+
function innerRef(node: HTMLDivElement) {
|
|
150
|
+
if (typeof props.ref === "function") {
|
|
151
|
+
props.ref(node)
|
|
152
|
+
}
|
|
153
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
154
|
+
const { width: containerWidth, height: containerHeight } = node.getBoundingClientRect()
|
|
155
|
+
setContainerSize(containerWidth, containerHeight)
|
|
156
|
+
const callback = (entries: ResizeObserverEntry[]) => {
|
|
157
|
+
const entry = entries[0]
|
|
158
|
+
if (entry == null) {
|
|
159
|
+
return
|
|
160
|
+
}
|
|
161
|
+
const { width, height } = entry.contentRect
|
|
162
|
+
setContainerSize(width, height)
|
|
163
|
+
}
|
|
164
|
+
const observer = new ResizeObserver(callback)
|
|
165
|
+
observer.observe(node)
|
|
166
|
+
observerRef = observer
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
onCleanup(() => {
|
|
171
|
+
if (observerRef != null) {
|
|
172
|
+
observerRef.disconnect()
|
|
173
|
+
}
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
/* eslint-disable solid/reactivity -- innerRef is a callback ref; ref={fn} is the correct Solid pattern */
|
|
177
|
+
return (
|
|
178
|
+
<>
|
|
179
|
+
<ReportChartSize width={sizes().containerWidth} height={sizes().containerHeight} />
|
|
180
|
+
<div
|
|
181
|
+
ref={innerRef}
|
|
182
|
+
class={props.class}
|
|
183
|
+
style={pxifyStyle(props.style)}
|
|
184
|
+
onClick={(e) => props.onClick?.(e)}
|
|
185
|
+
onContextMenu={(e) => props.onContextMenu?.(e)}
|
|
186
|
+
onDblClick={(e) => props.onDblClick?.(e)}
|
|
187
|
+
onFocusIn={() => props.onFocusIn?.()}
|
|
188
|
+
onFocusOut={() => props.onFocusOut?.()}
|
|
189
|
+
onKeyDown={(e) => props.onKeyDown?.(e)}
|
|
190
|
+
onMouseDown={(e) => props.onMouseDown?.(e)}
|
|
191
|
+
onMouseEnter={(e) => props.onMouseEnter?.(e)}
|
|
192
|
+
onMouseLeave={(e) => props.onMouseLeave?.(e)}
|
|
193
|
+
onMouseMove={(e) => props.onMouseMove?.(e)}
|
|
194
|
+
onMouseOver={(e) => props.onMouseOver?.(e)}
|
|
195
|
+
onMouseOut={(e) => props.onMouseOut?.(e)}
|
|
196
|
+
onMouseUp={(e) => props.onMouseUp?.(e)}
|
|
197
|
+
onTouchEnd={(e) => props.onTouchEnd?.(e)}
|
|
198
|
+
onTouchMove={(e) => props.onTouchMove?.(e)}
|
|
199
|
+
onTouchStart={(e) => props.onTouchStart?.(e)}
|
|
200
|
+
>
|
|
201
|
+
{props.children}
|
|
202
|
+
</div>
|
|
203
|
+
</>
|
|
204
|
+
)
|
|
205
|
+
/* eslint-enable solid/reactivity */
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function ReadSizeOnceDiv(props: WrapperDivProps) {
|
|
209
|
+
/* eslint-disable solid/reactivity -- props.height/width seed signal once at setup; innerRef is a callback ref */
|
|
210
|
+
const [sizes, setSizes] = createSignal<{
|
|
211
|
+
containerWidth: number
|
|
212
|
+
containerHeight: number
|
|
213
|
+
}>(
|
|
214
|
+
untrack(() => ({
|
|
215
|
+
containerHeight: getNumberOrZero(props.height),
|
|
216
|
+
containerWidth: getNumberOrZero(props.width),
|
|
217
|
+
})),
|
|
218
|
+
)
|
|
219
|
+
/* eslint-enable solid/reactivity */
|
|
220
|
+
|
|
221
|
+
function setContainerSize(newWidth: number, newHeight: number) {
|
|
222
|
+
const roundedWidth = Math.round(newWidth)
|
|
223
|
+
const roundedHeight = Math.round(newHeight)
|
|
224
|
+
const prev = untrack(sizes)
|
|
225
|
+
if (prev.containerWidth === roundedWidth && prev.containerHeight === roundedHeight) {
|
|
226
|
+
return
|
|
227
|
+
}
|
|
228
|
+
setSizes({ containerHeight: roundedHeight, containerWidth: roundedWidth })
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* eslint-disable-next-line solid/reactivity -- callback ref assigned via ref={innerRef}; linter false-positive on function-as-ref */
|
|
232
|
+
function innerRef(node: HTMLDivElement) {
|
|
233
|
+
if (typeof props.ref === "function") {
|
|
234
|
+
props.ref(node)
|
|
235
|
+
}
|
|
236
|
+
const { width: containerWidth, height: containerHeight } = node.getBoundingClientRect()
|
|
237
|
+
setContainerSize(containerWidth, containerHeight)
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* eslint-disable solid/reactivity -- innerRef is a callback ref; ref={fn} is the correct Solid pattern */
|
|
241
|
+
return (
|
|
242
|
+
<>
|
|
243
|
+
<ReportChartSize width={sizes().containerWidth} height={sizes().containerHeight} />
|
|
244
|
+
<div
|
|
245
|
+
ref={innerRef}
|
|
246
|
+
class={props.class}
|
|
247
|
+
style={pxifyStyle(props.style)}
|
|
248
|
+
onClick={(e) => props.onClick?.(e)}
|
|
249
|
+
onContextMenu={(e) => props.onContextMenu?.(e)}
|
|
250
|
+
onDblClick={(e) => props.onDblClick?.(e)}
|
|
251
|
+
onFocusIn={() => props.onFocusIn?.()}
|
|
252
|
+
onFocusOut={() => props.onFocusOut?.()}
|
|
253
|
+
onKeyDown={(e) => props.onKeyDown?.(e)}
|
|
254
|
+
onMouseDown={(e) => props.onMouseDown?.(e)}
|
|
255
|
+
onMouseEnter={(e) => props.onMouseEnter?.(e)}
|
|
256
|
+
onMouseLeave={(e) => props.onMouseLeave?.(e)}
|
|
257
|
+
onMouseMove={(e) => props.onMouseMove?.(e)}
|
|
258
|
+
onMouseOver={(e) => props.onMouseOver?.(e)}
|
|
259
|
+
onMouseOut={(e) => props.onMouseOut?.(e)}
|
|
260
|
+
onMouseUp={(e) => props.onMouseUp?.(e)}
|
|
261
|
+
onTouchEnd={(e) => props.onTouchEnd?.(e)}
|
|
262
|
+
onTouchMove={(e) => props.onTouchMove?.(e)}
|
|
263
|
+
onTouchStart={(e) => props.onTouchStart?.(e)}
|
|
264
|
+
>
|
|
265
|
+
{props.children}
|
|
266
|
+
</div>
|
|
267
|
+
</>
|
|
268
|
+
)
|
|
269
|
+
/* eslint-enable solid/reactivity */
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function StaticDiv(props: WrapperDivProps & { width: number; height: number }) {
|
|
273
|
+
return (
|
|
274
|
+
<>
|
|
275
|
+
<ReportChartSize width={props.width} height={props.height} />
|
|
276
|
+
<div
|
|
277
|
+
ref={props.ref}
|
|
278
|
+
class={props.class}
|
|
279
|
+
style={pxifyStyle(props.style)}
|
|
280
|
+
onClick={(e) => props.onClick?.(e)}
|
|
281
|
+
onContextMenu={(e) => props.onContextMenu?.(e)}
|
|
282
|
+
onDblClick={(e) => props.onDblClick?.(e)}
|
|
283
|
+
onFocusIn={() => props.onFocusIn?.()}
|
|
284
|
+
onFocusOut={() => props.onFocusOut?.()}
|
|
285
|
+
onKeyDown={(e) => props.onKeyDown?.(e)}
|
|
286
|
+
onMouseDown={(e) => props.onMouseDown?.(e)}
|
|
287
|
+
onMouseEnter={(e) => props.onMouseEnter?.(e)}
|
|
288
|
+
onMouseLeave={(e) => props.onMouseLeave?.(e)}
|
|
289
|
+
onMouseMove={(e) => props.onMouseMove?.(e)}
|
|
290
|
+
onMouseOver={(e) => props.onMouseOver?.(e)}
|
|
291
|
+
onMouseOut={(e) => props.onMouseOut?.(e)}
|
|
292
|
+
onMouseUp={(e) => props.onMouseUp?.(e)}
|
|
293
|
+
onTouchEnd={(e) => props.onTouchEnd?.(e)}
|
|
294
|
+
onTouchMove={(e) => props.onTouchMove?.(e)}
|
|
295
|
+
onTouchStart={(e) => props.onTouchStart?.(e)}
|
|
296
|
+
>
|
|
297
|
+
{props.children}
|
|
298
|
+
</div>
|
|
299
|
+
</>
|
|
300
|
+
)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/* eslint-disable solid/reactivity -- props.width/height type checks are structural guards at component setup; NonResponsiveDiv branches once at mount */
|
|
304
|
+
function NonResponsiveDiv(props: WrapperDivProps) {
|
|
305
|
+
const width = untrack(() => props.width)
|
|
306
|
+
const height = untrack(() => props.height)
|
|
307
|
+
/* When width or height are percentages or CSS short names, read size from DOM once */
|
|
308
|
+
if (typeof width === "string" || typeof height === "string") {
|
|
309
|
+
return <ReadSizeOnceDiv {...props} />
|
|
310
|
+
}
|
|
311
|
+
/* When both are numbers, use them directly */
|
|
312
|
+
if (typeof width === "number" && typeof height === "number") {
|
|
313
|
+
return <StaticDiv {...props} width={props.width as number} height={props.height as number} />
|
|
314
|
+
}
|
|
315
|
+
/* eslint-enable solid/reactivity */
|
|
316
|
+
/* When width/height are undefined, render wrapper div without reporting size */
|
|
317
|
+
return (
|
|
318
|
+
<>
|
|
319
|
+
<ReportChartSize
|
|
320
|
+
width={props.width as number | undefined}
|
|
321
|
+
height={props.height as number | undefined}
|
|
322
|
+
/>
|
|
323
|
+
<div
|
|
324
|
+
ref={props.ref}
|
|
325
|
+
class={props.class}
|
|
326
|
+
style={pxifyStyle(props.style)}
|
|
327
|
+
onClick={(e) => props.onClick?.(e)}
|
|
328
|
+
onContextMenu={(e) => props.onContextMenu?.(e)}
|
|
329
|
+
onDblClick={(e) => props.onDblClick?.(e)}
|
|
330
|
+
onFocusIn={() => props.onFocusIn?.()}
|
|
331
|
+
onFocusOut={() => props.onFocusOut?.()}
|
|
332
|
+
onKeyDown={(e) => props.onKeyDown?.(e)}
|
|
333
|
+
onMouseDown={(e) => props.onMouseDown?.(e)}
|
|
334
|
+
onMouseEnter={(e) => props.onMouseEnter?.(e)}
|
|
335
|
+
onMouseLeave={(e) => props.onMouseLeave?.(e)}
|
|
336
|
+
onMouseMove={(e) => props.onMouseMove?.(e)}
|
|
337
|
+
onMouseOver={(e) => props.onMouseOver?.(e)}
|
|
338
|
+
onMouseOut={(e) => props.onMouseOut?.(e)}
|
|
339
|
+
onMouseUp={(e) => props.onMouseUp?.(e)}
|
|
340
|
+
onTouchEnd={(e) => props.onTouchEnd?.(e)}
|
|
341
|
+
onTouchMove={(e) => props.onTouchMove?.(e)}
|
|
342
|
+
onTouchStart={(e) => props.onTouchStart?.(e)}
|
|
343
|
+
>
|
|
344
|
+
{props.children}
|
|
345
|
+
</div>
|
|
346
|
+
</>
|
|
347
|
+
)
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function getWrapperDivComponent(responsive: boolean) {
|
|
351
|
+
return responsive ? ResponsiveDiv : NonResponsiveDiv
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
export function RechartsWrapper(props: RechartsWrapperProps) {
|
|
355
|
+
let _containerRef: HTMLDivElement | null = null
|
|
356
|
+
const ctx = useChartStore()
|
|
357
|
+
const newCtx = useOptionalChartState()
|
|
358
|
+
const [tooltipPortal, setTooltipPortal] = createSignal<HTMLElement | null>(null)
|
|
359
|
+
const [legendPortal, setLegendPortal] = createSignal<HTMLElement | null>(null)
|
|
360
|
+
|
|
361
|
+
const setScaleRef = useReportScale()
|
|
362
|
+
|
|
363
|
+
const responsiveContainerCalculations = useResponsiveContainerContext()
|
|
364
|
+
const width = () =>
|
|
365
|
+
responsiveContainerCalculations.width > 0 ? responsiveContainerCalculations.width : props.width
|
|
366
|
+
const height = () =>
|
|
367
|
+
responsiveContainerCalculations.height > 0
|
|
368
|
+
? responsiveContainerCalculations.height
|
|
369
|
+
: props.height
|
|
370
|
+
|
|
371
|
+
function innerRef(node: HTMLDivElement) {
|
|
372
|
+
setScaleRef(node)
|
|
373
|
+
if (typeof props.ref === "function") {
|
|
374
|
+
props.ref(node)
|
|
375
|
+
}
|
|
376
|
+
setTooltipPortal(node)
|
|
377
|
+
setLegendPortal(node)
|
|
378
|
+
_containerRef = node
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function toHTMLMousePointer(e: MouseEvent): HTMLMousePointer {
|
|
382
|
+
return {
|
|
383
|
+
clientX: e.clientX,
|
|
384
|
+
clientY: e.clientY,
|
|
385
|
+
currentTarget: e.currentTarget as HTMLElement,
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/* GOTCHA-016-C: dedupe across native mouseenter + mouseover bindings.
|
|
390
|
+
Solid binds 1:1; both fire on real entry. Shared flag prevents double-dispatch. */
|
|
391
|
+
/* null until the first enter/leave: a leave with no prior enter still dispatches, like React. */
|
|
392
|
+
let pointerInside: boolean | null = null
|
|
393
|
+
|
|
394
|
+
function myOnClick(e: MouseEvent) {
|
|
395
|
+
ctx?.events.handleMouseClick(toHTMLMousePointer(e))
|
|
396
|
+
ctx?.events.handleExternalEvent(e, props.onClick)
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function myOnMouseEnter(e: MouseEvent) {
|
|
400
|
+
ctx?.events.handleMouseMove(toHTMLMousePointer(e))
|
|
401
|
+
if (pointerInside !== true) {
|
|
402
|
+
pointerInside = true
|
|
403
|
+
ctx?.events.handleExternalEvent(e, props.onMouseEnter)
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function myOnMouseLeave(e: MouseEvent) {
|
|
408
|
+
{
|
|
409
|
+
newCtx?.setState("tooltip", "axisInteraction", "hover", "active", false)
|
|
410
|
+
newCtx?.setState("tooltip", "itemInteraction", "hover", "active", false)
|
|
411
|
+
}
|
|
412
|
+
if (pointerInside !== false) {
|
|
413
|
+
pointerInside = false
|
|
414
|
+
ctx?.events.handleExternalEvent(e, props.onMouseLeave)
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/* React's onMouseEnter wrapped both mouseenter + mouseover under one synthetic
|
|
419
|
+
event. Solid wires native events 1:1, so test helpers calling fireEvent.mouseOver
|
|
420
|
+
bypass mouseenter and the tooltip never activates. Bind mouseover to the same
|
|
421
|
+
dispatch path; handleMouseMove is idempotent on identical pointer state. */
|
|
422
|
+
function myOnMouseOver(e: MouseEvent) {
|
|
423
|
+
ctx?.events.handleMouseMove(toHTMLMousePointer(e))
|
|
424
|
+
/* Mirror native mouseenter -> user onMouseEnter handler dispatch.
|
|
425
|
+
Dedupe so binding both mouseenter+mouseover doesn't double-fire. */
|
|
426
|
+
if (pointerInside !== true) {
|
|
427
|
+
pointerInside = true
|
|
428
|
+
ctx?.events.handleExternalEvent(e, props.onMouseEnter)
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/* Symmetric pair for mouseLeave. mouseout bubbles from descendants too —
|
|
433
|
+
only dispatch when the pointer actually leaves the wrapper container,
|
|
434
|
+
matching mouseleave semantics. */
|
|
435
|
+
function myOnMouseOut(e: MouseEvent) {
|
|
436
|
+
const wrapper = e.currentTarget as HTMLElement
|
|
437
|
+
const next = e.relatedTarget as Node | null
|
|
438
|
+
if (next != null && wrapper.contains(next)) {
|
|
439
|
+
return
|
|
440
|
+
}
|
|
441
|
+
{
|
|
442
|
+
newCtx?.setState("tooltip", "axisInteraction", "hover", "active", false)
|
|
443
|
+
newCtx?.setState("tooltip", "itemInteraction", "hover", "active", false)
|
|
444
|
+
}
|
|
445
|
+
if (pointerInside !== false) {
|
|
446
|
+
pointerInside = false
|
|
447
|
+
ctx?.events.handleExternalEvent(e, props.onMouseLeave)
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function myOnMouseMove(e: MouseEvent) {
|
|
452
|
+
ctx?.events.handleMouseMove(toHTMLMousePointer(e))
|
|
453
|
+
ctx?.events.handleExternalEvent(e, props.onMouseMove)
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
function onFocusIn() {
|
|
457
|
+
ctx?.events.handleFocus()
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
function onFocusOut() {
|
|
461
|
+
ctx?.events.handleBlur()
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
function onKeyDown(e: KeyboardEvent) {
|
|
465
|
+
ctx?.events.handleKeyDown(e.key)
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
function myOnContextMenu(e: MouseEvent) {
|
|
469
|
+
ctx?.events.handleExternalEvent(e, props.onContextMenu)
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
function myOnDoubleClick(e: MouseEvent) {
|
|
473
|
+
ctx?.events.handleExternalEvent(e, props.onDoubleClick)
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function myOnMouseDown(e: MouseEvent) {
|
|
477
|
+
ctx?.events.handleExternalEvent(e, props.onMouseDown)
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
function myOnMouseUp(e: MouseEvent) {
|
|
481
|
+
ctx?.events.handleExternalEvent(e, props.onMouseUp)
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function myOnTouchStart(e: TouchEvent) {
|
|
485
|
+
ctx?.events.handleExternalEvent(e, props.onTouchStart)
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/*
|
|
489
|
+
* onTouchMove is special because it behaves different from mouse events.
|
|
490
|
+
* Mouse events have 'enter' + 'leave' combo that notify us when the mouse is over
|
|
491
|
+
* a certain element. Touch events don't have that; touch only gives us
|
|
492
|
+
* start (finger down), end (finger up) and move (finger moving).
|
|
493
|
+
* So we need to figure out which element the user is touching
|
|
494
|
+
* ourselves. Fortunately, there's a convenient method for that:
|
|
495
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Document/elementFromPoint
|
|
496
|
+
*/
|
|
497
|
+
function myOnTouchMove(e: TouchEvent) {
|
|
498
|
+
const dispatchTouchEvents = props.dispatchTouchEvents ?? true
|
|
499
|
+
if (dispatchTouchEvents) {
|
|
500
|
+
ctx?.events.handleTouchMove(e)
|
|
501
|
+
}
|
|
502
|
+
ctx?.events.handleExternalEvent(e, props.onTouchMove)
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function myOnTouchEnd(e: TouchEvent) {
|
|
506
|
+
ctx?.events.handleExternalEvent(e, props.onTouchEnd)
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/* eslint-disable-next-line solid/reactivity -- props.responsive determines wrapper component once at mount; stable structural check */
|
|
510
|
+
const WrapperDiv = getWrapperDivComponent(untrack(() => props.responsive))
|
|
511
|
+
|
|
512
|
+
return (
|
|
513
|
+
<TooltipPortalContext value={tooltipPortal}>
|
|
514
|
+
<LegendPortalContext value={legendPortal}>
|
|
515
|
+
<WrapperDiv
|
|
516
|
+
width={width() ?? props.style?.width}
|
|
517
|
+
height={height() ?? props.style?.height}
|
|
518
|
+
class={clsx("recharts-wrapper", props.class)}
|
|
519
|
+
style={{
|
|
520
|
+
cursor: "default",
|
|
521
|
+
height:
|
|
522
|
+
typeof height() === "number" ? `${height()}px` : (height() as string | undefined),
|
|
523
|
+
position: "relative",
|
|
524
|
+
width: typeof width() === "number" ? `${width()}px` : (width() as string | undefined),
|
|
525
|
+
...props.style,
|
|
526
|
+
}}
|
|
527
|
+
onClick={myOnClick}
|
|
528
|
+
onContextMenu={myOnContextMenu}
|
|
529
|
+
onDblClick={myOnDoubleClick}
|
|
530
|
+
onFocusIn={onFocusIn}
|
|
531
|
+
onFocusOut={onFocusOut}
|
|
532
|
+
onKeyDown={onKeyDown}
|
|
533
|
+
onMouseDown={myOnMouseDown}
|
|
534
|
+
onMouseEnter={myOnMouseEnter}
|
|
535
|
+
onMouseLeave={myOnMouseLeave}
|
|
536
|
+
onMouseMove={myOnMouseMove}
|
|
537
|
+
onMouseOver={myOnMouseOver}
|
|
538
|
+
onMouseOut={myOnMouseOut}
|
|
539
|
+
onMouseUp={myOnMouseUp}
|
|
540
|
+
onTouchEnd={myOnTouchEnd}
|
|
541
|
+
onTouchMove={myOnTouchMove}
|
|
542
|
+
onTouchStart={myOnTouchStart}
|
|
543
|
+
ref={innerRef}
|
|
544
|
+
>
|
|
545
|
+
<EventSynchronizer />
|
|
546
|
+
{props.children}
|
|
547
|
+
</WrapperDiv>
|
|
548
|
+
</LegendPortalContext>
|
|
549
|
+
</TooltipPortalContext>
|
|
550
|
+
)
|
|
551
|
+
}
|