有人知道如何在 Victory Native XL 中支持多行吗?
我认为问题是 useChartPressState 仅支持单行,但尚未找到在多行时包含 y 位置的方法。
这里是示例,类似于教程,希望绘制多条线,我希望每行显示一个工具提示。
尝试了很多事情,但下一次尝试将是用从chartKeys生成的键替换highTmp,也许这就是技巧,胜利XL会自动映射它们?但这是一项工作,所以我只是想知道是否有人实现了这一点,或者知道实现它的“正确方法”是什么。
感谢您的阅读
import * as React from "react";
import { View } from "react-native";
import { CartesianChart, Line, useChartPressState } from "victory-native";
import { Circle, useFont } from "@shopify/react-native-skia";
import type { SharedValue } from "react-native-reanimated";
import inter from "../../assets/inter-medium.ttf"; // Wherever your font actually lives
function VictoryLineChart({ chartData, chartSettings, selectedTimeRangeOption }) {
const font = useFont(inter, 12);
const { state, isActive } = useChartPressState({ x: 0, y: { highTmp: 0 } });
...
return (
<View style={{ height: 300 }}>
<CartesianChart
data={DATA}
xKey="day"
yKeys={["highTmp"]}
axisOptions={{
font,
}}
chartPressState={state}
>
{
({ points }: { points: any }) => {
return (
<>
{
chartKeys && chartKeys?.map((key, index) => {
const settings = chartSettings?.settings?.points[index];
return (
<>
<Line points={ points[key] } color={ settings?.color } strokeWidth={ 1 } key={ index } antiAlias={ true } />
{
isActive && <ToolTip
x={ state.x.position }
y={ state?.y[key]?.position || 0 }
color={ settings?.color || '#000' }
/>
}
</>
);
})
}
</>
);
}
}
</CartesianChart>
</View>
);
}
function ToolTip({ x, y, color }: { x: number; y: number, color: string })
{
const font = useFont(inter, 12);
return (
<>
<Circle cx={x} cy={y} r={8} color={color} />
<SkiaText x={x} y={y} text={parseFloat(y).toFixed(2).toString()} font={font} />
</>
);
}
这是多按键支持的示例代码
import * as React from "react";
import { StyleSheet, View, SafeAreaView, Linking } from "react-native";
import { CartesianChart, Line, useChartPressState } from "victory-native";
import { Circle, useFont } from "@shopify/react-native-skia";
import type { SharedValue } from "react-native-reanimated";
import { Button } from "example/components/Button";
import { appColors } from "../consts/colors";
import inter from "../../assets/inter-medium.ttf";
import { urlForRoute } from "../consts/routes";
const initChartPressState = { x: 0, y: { highTmp: 0 } } as const;
export default function GettingStartedScreen(props: { segment: string }) {
const font = useFont(inter, 12);
const { state: firstPress, isActive: isFirstPressActive } =
useChartPressState(initChartPressState);
const { state: secondPress, isActive: isSecondPressActive } =
useChartPressState(initChartPressState);
const url = urlForRoute(props.segment);
const handleDocsButtonPress = React.useCallback(async () => {
url && (await Linking.canOpenURL(url)) && Linking.openURL(url);
}, [url]);
return (
<SafeAreaView style={styles.safeView}>
<View style={{ margin: 20 }}>
<Button onPress={handleDocsButtonPress} title="Read Docs" />
</View>
<View style={{ flex: 1, maxHeight: 400, padding: 32 }}>
<CartesianChart
data={DATA}
xKey="day"
yKeys={["highTmp"]}
axisOptions={{
font,
}}
chartPressState={[firstPress, secondPress]}
>
{({ points }) => (
<>
<Line points={points.highTmp} color="red" strokeWidth={3} />
{isFirstPressActive && (
<ToolTip
x={firstPress.x.position}
y={firstPress.y.highTmp.position}
/>
)}
{isSecondPressActive && (
<ToolTip
x={secondPress.x.position}
y={secondPress.y.highTmp.position}
/>
)}
</>
)}
</CartesianChart>
</View>
</SafeAreaView>
);
}
function ToolTip({ x, y }: { x: SharedValue<number>; y: SharedValue<number> }) {
return <Circle cx={x} cy={y} r={8} color="black" />;
}
const DATA = Array.from({ length: 31 }, (_, i) => ({
day: i,
highTmp: 40 + 30 * Math.random(),
}));
const styles = StyleSheet.create({
safeView: {
flex: 1,
backgroundColor: appColors.viewBackground.light,
$dark: {
backgroundColor: appColors.viewBackground.dark,
},
},
});