我正在尝试创建一个自定义折线图 this tutorial和 this one以及。一切正常,但当我在图表上拖动手指时,我想显示当前位置的值(value)(iOS 上的股票应用程序或 Robinhood 应用程序)。起初,它显示一个值,但它是静态的并且不会更新。
LineChart.js
const d3 = {
scale,
shape,
}
const height = 300
const { width } = Dimensions.get('window')
const verticalPadding = 30
export default function LineChart({ data = exampleData }) {
const minX = minBy(data, el => moment(el.label, 'LT'))
const maxX = maxBy(data, el => moment(el.label, 'LT'))
const minY = minBy(data, el => el.value)
const maxY = maxBy(data, el => el.value)
const scaleX = scaleTime()
.domain([moment(minX.label, 'LT'), moment(maxX.label, 'LT')])
.range([0, width])
const scaleY = scaleLinear()
.domain([minY.value, maxY.value])
.range([height - verticalPadding, verticalPadding])
const line = d3.shape
.line()
.x(d => scaleX(moment(d.label, 'LT')))
.y(d => scaleY(d.value))
.curve(d3.shape.curveBasis)(data)
return (
<View style={styles.container}>
<Svg {...{ width, height }}>
<Path d={line} fill="transparent" stroke={GREEN} strokeWidth="2" />
</Svg>
<View style={{ ...StyleSheet.absoluteFill, width }}>
<Cursor d={line} scaleY={scaleY} scaleX={scaleX} data={data} />
</View>
</View>
)
}
Cursor.js
const { Value } = Animated
const { width } = Dimensions.get('window')
export default ({ d, scaleY, scaleX, data }) => {
const translationX = new Value(0)
const path = parsePath(d)
const length = interpolate(translationX, {
inputRange: [0, width],
outputRange: [0, path.totalLength],
})
const { x, y } = getPointAtLength(path, length)
const translateX = x
const cursorX = sub(x, 4)
const cursorY = sub(y, 4)
const text = scaleY.invert(cursorX.__getValue())
const onGestureEvent = event([
{
nativeEvent: {
x: translationX,
},
},
])
return (
<PanGestureHandler onGestureEvent={onGestureEvent}>
<Animated.View>
<Animated.View style={{ transform: [{ translateX }], ...styles.label }}>
<Animated.Text style={{ color: 'white' }}>{text}</Animated.Text>
</Animated.View>
<Animated.View style={[styles.line, { transform: [{ translateX }] }]} />
<Animated.View
style={[
styles.cursor,
{ transform: [{ translateX: cursorX, translateY: cursorY }] },
]}
/>
</Animated.View>
</PanGestureHandler>
)
}
这是上面代码的结果:
最佳答案
您已使用React Native Reanimated call
获得 translationX
的回调值更改,然后在其中您可以更新文本,它必须使用 setNativeProps
自<Text>
以来组件没有 text
原生 Prop ,你必须使用 <TextInput>
就像 revolut-chart
中那样示例:
光标组件代码
// Changed imports
import React, { useEffect, useRef } from 'react';
import { Dimensions, TextInput } from 'react-native';
import Animated, { event, interpolate, sub, useCode, call } from 'react-native-reanimated';
...
export default function Cursor({ d, scaleY, scaleX, data }) {
// Create a ref for the TextInput component
const textRef = useRef();
const translationX = new Value(0)
const path = parsePath(d)
const length = interpolate(translationX, {
inputRange: [0, width],
outputRange: [0, path.totalLength],
})
const { x, y } = getPointAtLength(path, length)
const translateX = x
const cursorX = sub(x, 4)
const cursorY = sub(y, 4)
// const text = scaleY.invert(cursorX.__getValue())
const onGestureEvent = event([
{
nativeEvent: {
x: translationX,
},
},
]);
// Update text value using xValue = 0 when the component is mounted
useEffect(() => {
updateText(0);
}, []);
// Create reanimated code to get a translationX change callback
useCode(() => {
return call([translationX], (value) => {
// On translationX value change update the text using the value
updateText(value);
})
}, [translationX]);
// Function to update the text based on current translationX value
function updateText(xValue) {
const { x, y } = getPointAtLength(path, xValue);
const cursorX = sub(x, 4)
const updated = scaleY.invert(cursorX.__getValue());
// Use setNativeProps to update the TextInput component text prop
textRef.current.setNativeProps({ text: `${updated.toFixed(5)}` })
}
return (
<PanGestureHandler onGestureEvent={onGestureEvent}>
<Animated.View>
<Animated.View style={{ transform: [{ translateX }], ...styles.label }}>
<TextInput ref={textRef} style={{ color: 'white' }}/>
</Animated.View>
<Animated.View style={[styles.line, { transform: [{ translateX }] }]} />
<Animated.View
style={[
styles.cursor,
{ transform: [{ translateX: cursorX, translateY: cursorY }] },
]}
/>
</Animated.View>
</PanGestureHandler>
)
}
屏幕截图示例
您可以在这里查看更新的世博小吃:https://snack.expo.io/@clytras/intrigued-truffle
关于javascript - D3 + React Native - X 位置更改时数据点值不更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61331754/