react-native-wagmi-charts
Version:
A sweet candlestick chart for React Native
289 lines (277 loc) • 8.22 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', {
value: true,
});
exports.LineChartTooltip = LineChartTooltip;
var _react = _interopRequireWildcard(require('react'));
var _reactNativeReanimated = _interopRequireWildcard(
require('react-native-reanimated')
);
var _reactNative = require('react-native');
var _PriceText = require('./PriceText');
var _Cursor = require('./Cursor');
var _Chart = require('./Chart');
var _getXPositionForCurve = require('./utils/getXPositionForCurve');
var _reactNativeRedash = require('react-native-redash');
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);
}
function _extends() {
return (
(_extends = Object.assign
? Object.assign.bind()
: function (n) {
for (var e = 1; e < arguments.length; e++) {
var t = arguments[e];
for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
}
return n;
}),
_extends.apply(null, arguments)
);
}
LineChartTooltip.displayName = 'LineChartTooltip';
function LineChartTooltip({
children,
format,
xGutter = 8,
yGutter = 8,
cursorGutter = 48,
position = 'top',
withHorizontalFloating = false,
textProps,
textStyle,
at,
...props
}) {
const { width, height, parsedPath } = _react.default.useContext(
_Chart.LineChartDimensionsContext
);
const { type } = _react.default.useContext(_Cursor.CursorContext);
const { currentX, currentY, isActive } = (0, _useLineChart.useLineChart)();
const elementWidth = (0, _reactNativeReanimated.useSharedValue)(0);
const elementHeight = (0, _reactNativeReanimated.useSharedValue)(0);
const handleLayout = _react.default.useCallback(
(event) => {
elementWidth.value = event.nativeEvent.layout.width;
elementHeight.value = event.nativeEvent.layout.height;
},
[elementHeight, elementWidth]
);
// When the user set a `at` index, get the index's y & x positions
const atXPosition = (0, _react.useMemo)(
() =>
at !== null && at !== undefined
? (0, _getXPositionForCurve.getXPositionForCurve)(parsedPath, at)
: undefined,
[at, parsedPath]
);
const atYPosition = (0, _reactNativeReanimated.useDerivedValue)(() => {
return atXPosition == null
? undefined
: (0, _reactNativeRedash.getYForX)(parsedPath, atXPosition) ?? 0;
}, [atXPosition]);
const getInitialTranslateXOffset = _react.default.useCallback(
(elementWidth) => {
'worklet';
if (position === 'right') return elementWidth + cursorGutter;
if (position === 'left') return -cursorGutter;
return elementWidth / 2;
},
[cursorGutter, position]
);
/**
* Helper function to calculate the X translation offset based on position
* and boundary constraints
*/
const calculateXTranslateOffset = _react.default.useCallback(
(params) => {
'worklet';
const {
position,
x,
elementWidth,
width,
xGutter,
cursorGutter,
withHorizontalFloating,
} = params;
let translateXOffset = getInitialTranslateXOffset(elementWidth);
const elementFullWidth = elementWidth + xGutter + cursorGutter;
if (position === 'right') {
if (x < elementFullWidth) {
translateXOffset = withHorizontalFloating
? -cursorGutter
: translateXOffset - elementFullWidth + x;
}
} else if (position === 'left') {
if (x > width - elementFullWidth) {
translateXOffset = withHorizontalFloating
? elementWidth + cursorGutter
: translateXOffset + (x - (width - elementFullWidth));
}
} else {
// Center position
if (x < elementWidth / 2 + xGutter) {
translateXOffset -= elementWidth / 2 + xGutter - x;
}
if (x > width - elementWidth / 2 - xGutter) {
translateXOffset += x - (width - elementWidth / 2 - xGutter);
}
}
return translateXOffset;
},
[getInitialTranslateXOffset]
);
/**
* Helper function to calculate the Y translation offset based on position and
* boundary constraints
*/
const calculateYTranslateOffset = _react.default.useCallback((params) => {
'worklet';
const { position, y, elementHeight, height, yGutter, cursorGutter } =
params;
let translateYOffset = 0;
if (position === 'top') {
translateYOffset = elementHeight / 2 + cursorGutter;
if (y - translateYOffset < yGutter) {
translateYOffset = y - yGutter;
}
} else if (position === 'bottom') {
translateYOffset = -(elementHeight / 2) - cursorGutter / 2;
if (y - translateYOffset + elementHeight > height - yGutter) {
translateYOffset = y - (height - yGutter) + elementHeight;
}
} else if (position === 'right' || position === 'left') {
translateYOffset = elementHeight / 2;
}
return translateYOffset;
}, []);
const animatedCursorStyle = (0,
_reactNativeReanimated.useAnimatedStyle)(() => {
// the tooltip is considered static when the user specified an `at` prop
const isStatic = atYPosition.value != null;
// Calculate X position:
const x = atXPosition ?? currentX.value;
const translateXOffset = calculateXTranslateOffset({
position,
x,
elementWidth: elementWidth.value,
width,
xGutter,
cursorGutter,
withHorizontalFloating,
});
const translateX = x - translateXOffset;
// Calculate Y position:
const y = atYPosition.value ?? currentY.value;
const translateYOffset = calculateYTranslateOffset({
position,
y,
elementHeight: elementHeight.value,
height,
yGutter,
cursorGutter,
});
// Determine final translateY value
let translateY;
if (type === 'crosshair' || isStatic) {
translateY = y - translateYOffset;
} else {
translateY =
position === 'top' ? yGutter : height - elementHeight.value - yGutter;
}
// Calculate opacity
let opacity = isActive.value ? 1 : 0;
if (isStatic) {
// Only show static when there is no active cursor
opacity = (0, _reactNativeReanimated.withTiming)(isActive.value ? 0 : 1);
}
return {
transform: [
{
translateX,
},
{
translateY,
},
],
opacity: opacity,
};
}, [
atXPosition,
atYPosition.value,
calculateXTranslateOffset,
calculateYTranslateOffset,
currentX.value,
currentY.value,
cursorGutter,
elementHeight.value,
elementWidth.value,
height,
isActive.value,
position,
type,
width,
withHorizontalFloating,
xGutter,
yGutter,
]);
return /*#__PURE__*/ _react.default.createElement(
_reactNativeReanimated.default.View,
_extends(
{
onLayout: handleLayout,
},
props,
{
style: [styles.tooltip, animatedCursorStyle, props.style],
}
),
children ||
/*#__PURE__*/ _react.default.createElement(
_PriceText.LineChartPriceText,
_extends(
{
format: format,
index: at,
style: [textStyle],
},
textProps
)
)
);
}
const styles = _reactNative.StyleSheet.create({
tooltip: {
position: 'absolute',
padding: 4,
alignSelf: 'flex-start',
},
});
//# sourceMappingURL=Tooltip.js.map