UNPKG

victory-native

Version:

A charting library for React Native with a focus on performance and customization.

593 lines (592 loc) 29.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CartesianChart = void 0; const React = __importStar(require("react")); const react_native_skia_1 = require("@shopify/react-native-skia"); const react_native_reanimated_1 = require("react-native-reanimated"); const its_fine_1 = require("its-fine"); const react_native_gesture_handler_1 = require("react-native-gesture-handler"); const react_fast_compare_1 = __importDefault(require("react-fast-compare")); const transformInputData_1 = require("./utils/transformInputData"); const transformHorizontalInputData_1 = require("./utils/transformHorizontalInputData"); const valueFromSidedNumber_1 = require("../utils/valueFromSidedNumber"); const asNumber_1 = require("../utils/asNumber"); const useFunctionRef_1 = require("../hooks/useFunctionRef"); const CartesianChartContext_1 = require("./contexts/CartesianChartContext"); const XAxis_1 = require("./components/XAxis"); const YAxis_1 = require("./components/YAxis"); const CategoryYAxis_1 = require("./components/CategoryYAxis"); const Frame_1 = require("./components/Frame"); const useBuildChartAxis_1 = require("./hooks/useBuildChartAxis"); const transformGestures_1 = require("./utils/transformGestures"); const CartesianTransformContext_1 = require("./contexts/CartesianTransformContext"); const tickHelpers_1 = require("../utils/tickHelpers"); const GestureHandler_1 = require("../shared/GestureHandler"); const ChartWrapper_1 = require("../shared/ChartWrapper"); const useChartCanvasSize_1 = require("../shared/useChartCanvasSize"); const boundsToClip_1 = require("../utils/boundsToClip"); const normalizeYAxisTicks_1 = require("../utils/normalizeYAxisTicks"); const applyChartPressPanConfig_1 = require("./utils/applyChartPressPanConfig"); const createFallbackChartState_1 = require("./utils/createFallbackChartState"); const getCartesianTouchCoordinates_1 = require("./utils/getCartesianTouchCoordinates"); const resetChartPressState_1 = require("./utils/resetChartPressState"); const getClosestDatumIndex_1 = require("./utils/getClosestDatumIndex"); const getStackedBarTouchSegmentIndex_1 = require("./utils/getStackedBarTouchSegmentIndex"); const chartPressBootstrap_1 = require("./utils/chartPressBootstrap"); const createSafeZoomTransform_1 = require("./utils/createSafeZoomTransform"); const getCartesianChartBounds_1 = require("./utils/getCartesianChartBounds"); function CartesianChart(_a) { var { transformState, children, ref } = _a, rest = __rest(_a, ["transformState", "children", "ref"]); return (<its_fine_1.FiberProvider> <CartesianTransformContext_1.CartesianTransformProvider transformState={transformState}> <CartesianChartContent {...Object.assign(Object.assign({}, rest), { transformState })} ref={ref}> {children} </CartesianChartContent> </CartesianTransformContext_1.CartesianTransformProvider> </its_fine_1.FiberProvider>); } exports.CartesianChart = CartesianChart; function CartesianCanvas(_a) { var { children } = _a, props = __rest(_a, ["children"]); const Bridge = (0, its_fine_1.useContextBridge)(); return (<ChartWrapper_1.ChartWrapper {...props} chartContent={children} wrapCanvasContent={(content) => <Bridge>{content}</Bridge>}/>); } function CartesianChartContent({ data, xKey, yKeys, orientation = "vertical", padding, domainPadding, children, renderOutside = () => null, axisOptions, domain, chartPressState, chartPressConfig, gestureHandlerConfig, onChartBoundsChange, onScaleChange, gestureLongPressDelay = 100, xAxis, yAxis, frame, transformState, transformConfig, customGestures, actionsRef, viewport, ref, explicitSize, headless, }) { var _a, _b, _c, _d, _e; const { size, hasMeasuredLayoutSize, onLayout, isHeadless } = (0, useChartCanvasSize_1.useChartCanvasSize)({ explicitSize, headless }); const chartBoundsRef = React.useRef(undefined); const xScaleRef = React.useRef(undefined); const yScaleRef = React.useRef(undefined); const canvasRef = React.useRef(null); const chartPressStateRef = React.useRef(chartPressState); chartPressStateRef.current = chartPressState; const yKeysKey = yKeys.join("\u0000"); const normalizedAxisProps = (0, useBuildChartAxis_1.useBuildChartAxis)({ xAxis: xAxis, yAxis: yAxis, frame, yKeys, axisOptions: axisOptions, }); const axisScales = axisOptions === null || axisOptions === void 0 ? void 0 : axisOptions.axisScales; // create a d3-zoom transform object based on the current transform state. This // is used for rescaling the X and Y axes. const transform = (0, CartesianTransformContext_1.useCartesianTransformContext)(); const zoomX = React.useMemo(() => (0, createSafeZoomTransform_1.createSafeZoomTransform)(transform.k, transform.tx, transform.ty), [transform.k, transform.tx, transform.ty]); const zoomY = React.useMemo(() => (0, createSafeZoomTransform_1.createSafeZoomTransform)(transform.ky, transform.tx, transform.ty), [transform.ky, transform.tx, transform.ty]); const tData = (0, react_native_reanimated_1.useSharedValue)({ ix: [], ox: [], y: yKeys.reduce((acc, key) => { acc[key] = { i: [], o: [] }; return acc; }, {}), }); const { yAxes, xScale, chartBounds, isNumericalData, xTicksNormalized, _tData, } = React.useMemo(() => { if (!data.length) { return (0, createFallbackChartState_1.createFallbackChartState)(yKeys); } const transformArgs = { data, xKey, yKeys, outputWindow: { xMin: (0, valueFromSidedNumber_1.valueFromSidedNumber)(padding, "left"), xMax: size.width - (0, valueFromSidedNumber_1.valueFromSidedNumber)(padding, "right"), yMin: (0, valueFromSidedNumber_1.valueFromSidedNumber)(padding, "top"), yMax: size.height - (0, valueFromSidedNumber_1.valueFromSidedNumber)(padding, "bottom"), }, domain, domainPadding, viewport, labelRotate: normalizedAxisProps.xAxis.labelRotate, axisScales, }; const transformed = orientation === "horizontal" ? (0, transformHorizontalInputData_1.transformHorizontalInputData)(Object.assign(Object.assign({}, transformArgs), { xAxis: normalizedAxisProps.xAxis, yAxes: normalizedAxisProps.yAxes })) : (0, transformInputData_1.transformInputData)(Object.assign(Object.assign({}, transformArgs), { xAxis: normalizedAxisProps.xAxis, yAxes: normalizedAxisProps.yAxes })); const { xScale, yAxes, isNumericalData, xTicksNormalized } = transformed, _tData = __rest(transformed, ["xScale", "yAxes", "isNumericalData", "xTicksNormalized"]); const primaryYAxis = yAxes[0]; const primaryYScale = primaryYAxis.yScale; const chartBounds = (0, getCartesianChartBounds_1.getCartesianChartBounds)({ xScale, yScale: primaryYScale, viewport, domainPadding, orientation, }); return { xTicksNormalized, yAxes, xScale, chartBounds, isNumericalData, _tData, }; }, [ data, xKey, yKeys, padding, size.width, size.height, domain, domainPadding, normalizedAxisProps, axisScales, viewport, orientation, ]); React.useEffect(() => { tData.value = _tData; }, [_tData, tData]); const primaryYAxis = yAxes[0]; const primaryYScale = primaryYAxis.yScale; // stacked bar values const chartHeight = chartBounds.bottom; const yScaleTop = primaryYAxis.yScale.domain().at(0); const yScaleBottom = primaryYAxis.yScale.domain().at(-1); const chartWidth = chartBounds.right - chartBounds.left; const xScaleLeft = xScale.invert(chartBounds.left); const xScaleRight = xScale.invert(chartBounds.right); // end stacked bar values /** * Pan gesture handling */ const lastIdx = (0, react_native_reanimated_1.useSharedValue)(null); /** * Take a "press value" and an x-value and update the shared values accordingly. */ const handleTouch = React.useCallback((v, x, y) => { "worklet"; const idx = (0, getClosestDatumIndex_1.getClosestDatumIndex)({ orientation, categoryPositions: tData.value.ox, touchX: x, touchY: y, }); if (typeof idx !== "number") return; const isInYs = (yk) => yKeys.includes(yk); // begin stacked bar handling: // store the heights of each bar segment const barHeights = []; for (const yk in v.y) { if (isInYs(yk)) { const height = (0, asNumber_1.asNumber)(tData.value.y[yk].i[idx]); barHeights.push(height); } } if (orientation === "horizontal") { const chartXPressed = x - chartBounds.left; const xDomainValue = chartWidth > 0 && xScaleLeft !== undefined && xScaleRight !== undefined ? (chartXPressed / chartWidth) * (xScaleRight - xScaleLeft) + xScaleLeft : NaN; v.yIndex.value = (0, getStackedBarTouchSegmentIndex_1.getStackedBarTouchSegmentIndex)({ values: barHeights, touchValue: xDomainValue, }); } else { const chartYPressed = chartHeight - y; // Invert y-coordinate, since RNGH gives us the absolute Y, and we want to know where in the chart they clicked // Calculate the actual yValue of the touch within the domain of the yScale const yDomainValue = (chartYPressed / chartHeight) * (yScaleTop - yScaleBottom); // track the cumulative height and the y-index of the touched segment let cumulativeHeight = 0; let yIndex = -1; // loop through the bar heights to find which bar was touched for (let i = 0; i < barHeights.length; i++) { // Accumulate the height as we go along cumulativeHeight += barHeights[i]; // Check if the y-value touched falls within the current segment if (yDomainValue <= cumulativeHeight) { // If it does, set yIndex to the current segment index and break yIndex = i; break; } } // Update the yIndex value in the state or context v.yIndex.value = yIndex; } // end stacked bar handling if (v) { try { v.matchedIndex.value = idx; v.x.value.value = tData.value.ix[idx]; v.x.position.value = (0, asNumber_1.asNumber)(tData.value.ox[idx]); for (const yk in v.y) { if (isInYs(yk)) { v.y[yk].value.value = (0, asNumber_1.asNumber)(tData.value.y[yk].i[idx]); v.y[yk].position.value = (0, asNumber_1.asNumber)(tData.value.y[yk].o[idx]); } } } catch (err) { // no-op } } lastIdx.value = idx; }, [ chartBounds.left, chartHeight, chartWidth, lastIdx, orientation, tData, xScaleLeft, xScaleRight, yKeys, yScaleBottom, yScaleTop, ]); React.useImperativeHandle(ref, () => ({ canvas: canvasRef.current, actions: { handleTouch, }, }), // eslint-disable-next-line react-hooks/exhaustive-deps [canvasRef]); const handleTouchRef = (0, useFunctionRef_1.useFunctionRef)(handleTouch); const mutableActionsRef = actionsRef && "current" in actionsRef ? actionsRef : undefined; const sharedActionsRef = actionsRef && "value" in actionsRef ? actionsRef : undefined; React.useImperativeHandle(mutableActionsRef, () => ({ handleTouch: (value, x, y) => { var _a; (_a = handleTouchRef.current) === null || _a === void 0 ? void 0 : _a.call(handleTouchRef, value, x, y); }, }), [handleTouchRef]); React.useEffect(() => { if (!sharedActionsRef) return; sharedActionsRef.value = { handleTouch, }; return () => { sharedActionsRef.value = null; }; }, [handleTouch, sharedActionsRef]); /** * Touch gesture is a modified Pan gesture handler that allows for multiple presses: * - Using Pan Gesture handler effectively _just_ for the .activateAfterLongPress functionality. * - Tracking the finger is handled with .onTouchesMove instead of .onUpdate, because * .onTouchesMove gives us access to each individual finger. * - The activation gets a bit complicated because we want to wait til "start" state before updating Press Value * which gives time for the gesture to get cancelled before we start updating the shared values. * Therefore we use gestureState.bootstrap to store some "bootstrap" information if gesture isn't active when finger goes down. */ // touch ID -> value index mapping to keep track of which finger updates which value const touchMap = (0, react_native_reanimated_1.useSharedValue)({}); const activePressSharedValues = Array.isArray(chartPressState) ? chartPressState : [chartPressState]; const gestureState = (0, react_native_reanimated_1.useSharedValue)({ isGestureActive: false, bootstrap: [], }); React.useEffect(() => { const vals = chartPressStateRef.current; const states = Array.isArray(vals) ? vals : [vals]; for (const state of states) { if (state) (0, resetChartPressState_1.resetChartPressState)(state); } touchMap.value = {}; gestureState.value = { isGestureActive: false, bootstrap: [], }; lastIdx.value = null; }, [data, gestureState, lastIdx, touchMap, xKey, yKeysKey]); const panGesture = react_native_gesture_handler_1.Gesture.Pan() /** * When a finger goes down, either update the state or store in the bootstrap array. */ .onTouchesDown((e) => { const vals = activePressSharedValues || []; if (!vals.length || e.numberOfTouches === 0) return; for (let i = 0; i < Math.min(e.allTouches.length, vals.length); i++) { const touch = e.allTouches[i]; const v = vals[i]; if (!v || !touch) continue; if (gestureState.value.isGestureActive) { // Update the mapping if (typeof touchMap.value[touch.id] !== "number") touchMap.value[touch.id] = i; v.isActive.value = true; const touchPoint = (0, getCartesianTouchCoordinates_1.getCartesianTouchCoordinates)({ touch, transform: transformState === null || transformState === void 0 ? void 0 : transformState.matrix.value, }); handleTouch(v, touchPoint.x, touchPoint.y); } else { gestureState.value.bootstrap.push({ pressIndex: i, state: v, touch, }); } } }) /** * On start, check if we have any bootstrapped updates we need to apply. */ .onStart(() => { gestureState.value.isGestureActive = true; const bootstrap = gestureState.value.bootstrap.slice(0); gestureState.value.bootstrap = []; for (let i = 0; i < bootstrap.length; i++) { const { pressIndex, state: v, touch } = bootstrap[i]; // Update the mapping if (typeof touchMap.value[touch.id] !== "number") touchMap.value[touch.id] = pressIndex; v.isActive.value = true; const touchPoint = (0, getCartesianTouchCoordinates_1.getCartesianTouchCoordinates)({ touch, transform: transformState === null || transformState === void 0 ? void 0 : transformState.matrix.value, }); handleTouch(v, touchPoint.x, touchPoint.y); } }) /** * Clear gesture state on gesture end. */ .onFinalize(() => { const vals = activePressSharedValues || []; for (const val of vals) { if (val) { val.isActive.value = false; } } touchMap.value = {}; gestureState.value = { isGestureActive: false, bootstrap: [], }; }) /** * As fingers move, update the shared values accordingly. */ .onTouchesMove((e) => { const vals = activePressSharedValues || []; if (!vals.length || e.numberOfTouches === 0) return; for (let i = 0; i < Math.min(e.allTouches.length, vals.length); i++) { const touch = e.allTouches[i]; const touchId = touch === null || touch === void 0 ? void 0 : touch.id; const idx = typeof touchId === "number" && touchMap.value[touchId]; const v = typeof idx === "number" && (vals === null || vals === void 0 ? void 0 : vals[idx]); if (!v || !touch) continue; if (!v.isActive.value) v.isActive.value = true; const touchPoint = (0, getCartesianTouchCoordinates_1.getCartesianTouchCoordinates)({ touch, transform: transformState === null || transformState === void 0 ? void 0 : transformState.matrix.value, }); handleTouch(v, touchPoint.x, touchPoint.y); } }) /** * On each finger up, start to update values and "free up" the touch map. */ .onTouchesUp((e) => { gestureState.value.bootstrap = (0, chartPressBootstrap_1.pruneChartPressBootstrap)({ bootstrap: gestureState.value.bootstrap, changedTouches: e.changedTouches, numberOfTouches: e.numberOfTouches, }); for (const touch of e.changedTouches) { const vals = activePressSharedValues || []; // Set active state to false const touchId = touch === null || touch === void 0 ? void 0 : touch.id; const idx = typeof touchId === "number" && touchMap.value[touchId]; const val = typeof idx === "number" && vals[idx]; if (val) { val.isActive.value = false; } // Free up touch map for this touch touchMap.value[touch.id] = undefined; } }) /** * Once the gesture ends, ensure all active values are falsified. */ .onEnd(() => { const vals = activePressSharedValues || []; // Set active state to false for all vals for (const val of vals) { if (val) { val.isActive.value = false; } } }); (0, applyChartPressPanConfig_1.applyChartPressPanConfig)({ panGesture, panConfig: chartPressConfig === null || chartPressConfig === void 0 ? void 0 : chartPressConfig.pan, gestureLongPressDelay, }); const points = React.useMemo(() => { const cache = {}; return new Proxy({}, { get(_, property) { const key = property; if (!yKeys.includes(key)) return undefined; if (cache[key]) return cache[key]; cache[key] = _tData.ix.map((x, i) => ({ x: orientation === "horizontal" ? (0, asNumber_1.asNumber)(_tData.y[key].o[i]) : (0, asNumber_1.asNumber)(_tData.ox[i]), xValue: x, y: orientation === "horizontal" ? (0, asNumber_1.asNumber)(_tData.ox[i]) : _tData.y[key].o[i], yValue: _tData.y[key].i[i], })); return cache[key]; }, }); }, [_tData, orientation, yKeys]); // On bounds change, emit const onChartBoundsRef = (0, useFunctionRef_1.useFunctionRef)(onChartBoundsChange); React.useEffect(() => { var _a; if (!(0, react_fast_compare_1.default)(chartBounds, chartBoundsRef.current)) { chartBoundsRef.current = chartBounds; (_a = onChartBoundsRef.current) === null || _a === void 0 ? void 0 : _a.call(onChartBoundsRef, chartBounds); } }, [chartBounds, onChartBoundsRef]); const onScaleRef = (0, useFunctionRef_1.useFunctionRef)(onScaleChange); React.useEffect(() => { var _a, _b, _c, _d, _e; const rescaledX = zoomX.rescaleX(xScale); const rescaledY = zoomY.rescaleY(primaryYScale); if (!(0, react_fast_compare_1.default)((_a = xScaleRef.current) === null || _a === void 0 ? void 0 : _a.domain(), rescaledX.domain()) || !(0, react_fast_compare_1.default)((_b = yScaleRef.current) === null || _b === void 0 ? void 0 : _b.domain(), rescaledY.domain()) || !(0, react_fast_compare_1.default)((_c = xScaleRef.current) === null || _c === void 0 ? void 0 : _c.range(), rescaledX.range()) || !(0, react_fast_compare_1.default)((_d = yScaleRef.current) === null || _d === void 0 ? void 0 : _d.range(), rescaledY.range())) { xScaleRef.current = xScale; yScaleRef.current = primaryYScale; (_e = onScaleRef.current) === null || _e === void 0 ? void 0 : _e.call(onScaleRef, rescaledX, rescaledY); } }, [onScaleChange, onScaleRef, xScale, zoomX, zoomY, primaryYScale]); const renderArg = { xScale, xTicks: xTicksNormalized, yScale: primaryYScale, yTicks: primaryYAxis.yTicksNormalized, chartBounds, canvasSize: size, points, }; const clipRect = (0, boundsToClip_1.boundsToClip)(chartBounds); const YAxisComponents = hasMeasuredLayoutSize && (axisOptions || yAxes) ? (_a = normalizedAxisProps.yAxes) === null || _a === void 0 ? void 0 : _a.map((axis, index) => { const yAxis = yAxes[index]; if (!yAxis) return null; if (orientation === "horizontal") { return (<CategoryYAxis_1.CategoryYAxis key={index} {...axis} formatYLabel={axis.formatYLabel} labelRenderer={axis.labelRenderer} xScale={zoomX.rescaleX(xScale)} yScale={zoomY.rescaleY(yAxis.yScale)} yTicksNormalized={yAxis.yTicksNormalized} ix={_tData.ix} chartBounds={chartBounds}/>); } const primaryAxisProps = normalizedAxisProps.yAxes[0]; const primaryRescaled = zoomY.rescaleY(primaryYScale); const rescaled = zoomY.rescaleY(yAxis.yScale); const rescaledTicks = axis.tickValues ? (0, tickHelpers_1.downsampleTicks)(axis.tickValues, axis.tickCount) : axis.enableRescaling ? rescaled.ticks(axis.tickCount) : yAxis.yScale.ticks(axis.tickCount); const primaryTicksRescaled = primaryAxisProps.tickValues ? (0, tickHelpers_1.downsampleTicks)(primaryAxisProps.tickValues, primaryAxisProps.tickCount) : primaryAxisProps.enableRescaling ? primaryRescaled.ticks(primaryAxisProps.tickCount) : primaryYScale.ticks(primaryAxisProps.tickCount); return (<YAxis_1.YAxis key={index} {...axis} xScale={zoomX.rescaleX(xScale)} yScale={rescaled} yTicksNormalized={index > 0 && !axis.tickValues ? (0, normalizeYAxisTicks_1.normalizeYAxisTicks)(primaryTicksRescaled, primaryRescaled, rescaled) : rescaledTicks} chartBounds={chartBounds} orientation={orientation}/>); }) : null; const XAxisComponents = hasMeasuredLayoutSize && (axisOptions || xAxis) ? (<XAxis_1.XAxis {...normalizedAxisProps.xAxis} xScale={xScale} yScale={zoomY.rescaleY(primaryYScale)} ix={_tData.ix} isNumericalData={orientation === "horizontal" ? true : isNumericalData} chartBounds={chartBounds} orientation={orientation} zoom={zoomX}/>) : null; const FrameComponent = hasMeasuredLayoutSize && (axisOptions || frame) ? (<Frame_1.Frame {...normalizedAxisProps.frame} xScale={xScale} yScale={primaryYScale}/>) : null; const chartContent = (<> {YAxisComponents} {XAxisComponents} {FrameComponent} <react_native_skia_1.Group clip={clipRect}> <react_native_skia_1.Group matrix={transformState === null || transformState === void 0 ? void 0 : transformState.matrix}> {hasMeasuredLayoutSize && children(renderArg)} </react_native_skia_1.Group> </react_native_skia_1.Group> {hasMeasuredLayoutSize && (renderOutside === null || renderOutside === void 0 ? void 0 : renderOutside(renderArg))} </>); let gestureOverlay; if (!isHeadless) { let composed = customGestures !== null && customGestures !== void 0 ? customGestures : react_native_gesture_handler_1.Gesture.Race(); if (transformState) { let gestures = react_native_gesture_handler_1.Gesture.Simultaneous(); if ((_c = (_b = transformConfig === null || transformConfig === void 0 ? void 0 : transformConfig.pinch) === null || _b === void 0 ? void 0 : _b.enabled) !== null && _c !== void 0 ? _c : true) { gestures = react_native_gesture_handler_1.Gesture.Simultaneous(gestures, (0, transformGestures_1.pinchTransformGesture)(transformState, transformConfig === null || transformConfig === void 0 ? void 0 : transformConfig.pinch)); } if ((_e = (_d = transformConfig === null || transformConfig === void 0 ? void 0 : transformConfig.pan) === null || _d === void 0 ? void 0 : _d.enabled) !== null && _e !== void 0 ? _e : true) { gestures = react_native_gesture_handler_1.Gesture.Simultaneous(gestures, (0, transformGestures_1.panTransformGesture)(transformState, transformConfig === null || transformConfig === void 0 ? void 0 : transformConfig.pan)); } composed = react_native_gesture_handler_1.Gesture.Race(composed, react_native_gesture_handler_1.Gesture.Simultaneous(gestures)); } if (chartPressState) { composed = react_native_gesture_handler_1.Gesture.Race(composed, panGesture); } gestureOverlay = (<GestureHandler_1.GestureHandler config={gestureHandlerConfig} gesture={composed}/>); } return (<CartesianTransformContext_1.CartesianTransformValueProvider value={transform}> <CartesianChartContext_1.CartesianChartProvider yScale={primaryYScale} xScale={xScale} orientation={orientation}> <CartesianCanvas isHeadless={isHeadless} explicitSize={explicitSize} onLayout={onLayout} hasMeasuredLayoutSize={hasMeasuredLayoutSize} canvasSize={size} canvasRef={canvasRef} gestureOverlay={gestureOverlay}> {chartContent} </CartesianCanvas> </CartesianChartContext_1.CartesianChartProvider> </CartesianTransformContext_1.CartesianTransformValueProvider>); }