UNPKG

react-native-wagmi-charts

Version:

A sweet candlestick chart for React Native

191 lines (183 loc) 5.86 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true, }); exports.CursorContext = void 0; exports.LineChartCursor = LineChartCursor; var _react = _interopRequireWildcard(require('react')); var _reactNativeReanimated = _interopRequireWildcard( require('react-native-reanimated') ); var _reactNativeGestureHandler = require('react-native-gesture-handler'); var _Chart = require('./Chart'); var _reactNative = require('react-native'); var _d3Array = require('d3-array'); var _d3Scale = require('d3-scale'); var _useLineChart = require('./useLineChart'); function _interopRequireWildcard(e, t) { if ('function' == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || ('object' != typeof e && 'function' != typeof e)) return f; if ((o = t ? n : r)) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) 'default' !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : (f[t] = e[t])); return f; })(e, t); } const CursorContext = (exports.CursorContext = /*#__PURE__*/ _react.default.createContext({ type: '', })); LineChartCursor.displayName = 'LineChartCursor'; function LineChartCursor({ children, snapToPoint, type, at, shouldCancelWhenOutside = false, minDurationMs = 0, onActivated, onEnded, }) { const { pathWidth: width, parsedPath } = _react.default.useContext( _Chart.LineChartDimensionsContext ); const { currentX, currentIndex, isActive, data, xDomain } = (0, _useLineChart.useLineChart)(); const xValues = _react.default.useMemo( () => (data ?? []).map(({ timestamp }, i) => (xDomain ? timestamp : i)), [data, xDomain] ); // Same scale as in /src/charts/line/utils/getPath.ts const scaleX = _react.default.useMemo(() => { const domainArray = xDomain ?? [0, xValues.length]; return (0, _d3Scale.scaleLinear)().domain(domainArray).range([0, width]); }, [width, xDomain, xValues.length]); const linearScalePositionAndIndex = ({ xPosition }) => { if (!parsedPath) { return; } // Calculate a scaled timestamp for the current touch position const xRelative = scaleX.invert(xPosition); const closestIndex = (0, _d3Array.bisectCenter)(xValues, xRelative); const pathDataDelta = Math.abs(parsedPath.curves.length - xValues.length); // sometimes there is a difference between data length and number of path curves. const closestPathCurve = Math.max( Math.min(closestIndex, parsedPath.curves.length + 1) - pathDataDelta, 0 ); const curveSegment = closestIndex > 0 && parsedPath.curves[closestPathCurve] ? parsedPath.curves[closestPathCurve] : null; const newXPosition = (curveSegment ? curveSegment.to : parsedPath.move).x; // Update values currentIndex.value = closestIndex; currentX.value = newXPosition; }; (0, _react.useEffect)(() => { if (at !== undefined) { const xPosition = scaleX(at); (0, _reactNativeReanimated.runOnJS)(linearScalePositionAndIndex)({ xPosition, }); isActive.value = true; } }, [at, scaleX]); const updatePosition = (xPosition) => { 'worklet'; if (parsedPath) { // on Web, we could drag the cursor to be negative, breaking it // so we clamp the index at 0 to fix it // https://github.com/coinjar/react-native-wagmi-charts/issues/24 const minIndex = 0; const boundedIndex = Math.max( minIndex, Math.round(xPosition / width / (1 / (data ? data.length - 1 : 1))) ); if (snapToPoint) { // We have to run this on the JS thread unfortunately as the scaleLinear functions won't work on UI thread (0, _reactNativeReanimated.runOnJS)(linearScalePositionAndIndex)({ xPosition, }); } else if (!snapToPoint) { currentX.value = xPosition; currentIndex.value = boundedIndex; } } }; const longPressGesture = _reactNativeGestureHandler.Gesture.LongPress() .minDuration(minDurationMs ?? 0) .maxDistance(999999) .shouldCancelWhenOutside(shouldCancelWhenOutside) .onStart((event) => { 'worklet'; if (parsedPath) { const xPosition = Math.max(0, event.x <= width ? event.x : width); isActive.value = true; updatePosition(xPosition); if (onActivated) { (0, _reactNativeReanimated.runOnJS)(onActivated)(); } } }) .onTouchesMove((event) => { 'worklet'; if ( parsedPath && isActive.value && event.allTouches.length > 0 && event.allTouches[0] ) { const touchX = event.allTouches[0].x; const xPosition = Math.max(0, touchX <= width ? touchX : width); updatePosition(xPosition); } }) .onEnd(() => { 'worklet'; isActive.value = false; currentIndex.value = -1; if (onEnded) { (0, _reactNativeReanimated.runOnJS)(onEnded)(); } }); return /*#__PURE__*/ _react.default.createElement( CursorContext.Provider, { value: { type, }, }, /*#__PURE__*/ _react.default.createElement( _reactNativeGestureHandler.GestureDetector, { gesture: longPressGesture, }, /*#__PURE__*/ _react.default.createElement( _reactNativeReanimated.default.View, { style: _reactNative.StyleSheet.absoluteFill, }, children ) ) ); } //# sourceMappingURL=Cursor.js.map