【发布时间】:2020-08-03 12:05:53
【问题描述】:
我也在尝试在this tutorial 和this one 之后创建自定义折线图。一切正常,但是当我在图表上拖动手指时,我想显示当前位置的值(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>
)
}
这是上面代码的结果:
【问题讨论】:
-
我看不到
scaleQuantile的任何用法(likeconst scaleLabel = scaleQuantile()...);该示例使用它来制作像const label = scaleLabel(scaleY.invert(y));这样的实际文本。另外,你为什么要做scaleY.invert(cursorX.__getValue())而不是scaleY.invert(cursorX)?如果您可以使用此示例创建 Expo Snack,那将非常有帮助。 -
你能不能做一个expo demo之类的,这样人们可以更好地帮助你
-
@ChristosLytras 起初我使用的是
scaleQuantile,但它对我不起作用,所以我决定尝试其他方法。我正在使用cursorX.__getValue(),因为sub()返回一个复活的对象。对不起,也许我应该在帖子中添加。 -
@ChristosLytras 我创建了一个工作零食:snack.expo.io/@corasan/intrigued-truffle
-
@ShubhamKhatri snack.expo.io/@corasan/intrigued-truffle
标签: javascript reactjs react-native d3.js svg