javascript - 不确定如何在本机反应中配置此工具提示功能
问题描述
小吃我已经在 rn 中渲染了一个图表以及工具提示。单击图表中的每个单独的点会呈现其自己的单独工具提示组件。目前,按照我写下来的方式,单击点 1,所有相应的工具提示都会同时下拉。例如,如果我单击点 1,所有相应的工具提示组件下拉列表-
如果我单击点 1,我只希望第一个工具提示组件下拉。有没有办法做到这一点?
import * as React from "react";
import { Text, View, StyleSheet } from "react-native";
import { useState, useEffect, useCallback, useRef } from "react";
import {
BarChart,
Grid,
PieChart,
XAxis,
YAxis,
LineChart,
AreaChart,
ProgressCircle,
} from "react-native-svg-charts";
// You can import from local files
import AssetExample from "./components/AssetExample";
import { Text as TextSvg, Svg, Circle, G, Line, Rect } from "react-native-svg";
// or any pure javascript modules available in npm
import * as shape from "d3-shape";
export default function App() {
const [tooltipPosx, setTooltipPosx] = useState(false);
const initialData = [95, 50, 40, 95];
const [isAreasVisible, setIsAreasVisible] = useState(true);
const [datas, setDatas] = useState(initialData);
const verticalContentInset = { top: 10, bottom: 10 };
const axesSvg = { fontSize: 10, fill: "grey" };
const xAxisLabels = ["09-10-2020", "10-10-2020", "11-10-2020", "12-10-2020"];
const CUT_OFF = 1;
const ChartPoints = ({ x, y, color, data }) => {
return datas.map((value, index) => (
<Circle
key={index}
cx={x(index)}
cy={y(value)}
r={5}
stroke={color}
fill="white"
onPress={() => {
setTooltipPosx(!tooltipPosx);
console.log(x(index));
console.log(y(value));
console.log(index);
}}
/>
));
};
const Tooltips = ({ x, y, data }) => {
return datas.map((value, index) => (
<Svg>
<Rect
x={x(index)}
y={value < CUT_OFF ? y(value) - 10 : y(value) + 15}
width="25"
height="20"
fill="black"
/>
<TextSvg
key={index}
x={x(index) + 12}
y={value < CUT_OFF ? y(value) - 10 + 20 : y(value) + 15 + 12}
fontSize={8}
fontWeight="bold"
fill={value >= CUT_OFF ? "pink" : "white"}
alignmentBaseline={"middle"}
textAnchor={"middle"}
>
{`${datas[index]}`}
</TextSvg>
</Svg>
));
};
return (
<View style={[styles.chartView]}>
<View style={styles.header}>
<View style={styles.title}>
<Text>Area Chart</Text>
</View>
<View style={styles.icons}>
<View style={styles.infoIcon}></View>
</View>
</View>
{isAreasVisible && (
<View>
<View
style={{
height: 250,
padding: 20,
width: "90%",
flexDirection: "row",
marginTop: "-9%",
}}
>
<YAxis
data={datas}
style={{ marginTop: 15 }}
contentInset={verticalContentInset}
svg={axesSvg}
/>
<View style={{ flex: 1, marginLeft: 10 }}>
<AreaChart
style={{ height: 200, marginTop: 15 }}
data={datas}
contentInset={{ top: 20, bottom: 22, left: 8, right: 7 }}
curve={shape.curveNatural}
svg={{ fill: "#ffdab9" }}
>
<Grid />
<ChartPoints color="#98FFFE" />
{tooltipPosx && <Tooltips />}
</AreaChart>
<XAxis
data={datas}
formatLabel={(value, index) => xAxisLabels[index]}
contentInset={{ left: 20, right: 20 }}
svg={{ fontSize: 8, fill: "#555555" }}
/>
</View>
</View>
</View>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
backgroundColor: "#ecf0f1",
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: "bold",
textAlign: "center",
},
});
解决方案
我根据选定的图表点索引添加了一个名为 activeToolTip 的变量,只有当数据数组索引与 activeToolTip 值匹配时,Tooltips 函数才会生成一个组件。还添加了一个 toggleToolTip 函数来更改 activeTooltip,如果按下相同的图表点,则隐藏所有这些,或者如果单击不同的图表点,则更新 activeTooltip。 示例图像
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { useState, useEffect, useCallback, useRef } from 'react';
import {
BarChart,
Grid,
PieChart,
XAxis,
YAxis,
LineChart,
AreaChart,
ProgressCircle,
} from 'react-native-svg-charts';
// You can import from local files
import AssetExample from './components/AssetExample';
import { Text as TextSvg, Svg, Circle, G, Line, Rect } from 'react-native-svg';
// or any pure javascript modules available in npm
import * as shape from 'd3-shape';
export default function App() {
const [tooltipPosx, setTooltipPosx] = useState(false);
const [activeToolTip, setActiveToolTip] = useState(null);
const initialData = [95, 50, 40, 95];
const [isAreasVisible, setIsAreasVisible] = useState(true);
const [datas, setDatas] = useState(initialData);
const verticalContentInset = { top: 10, bottom: 10 };
const axesSvg = { fontSize: 10, fill: 'grey' };
const xAxisLabels = ['09-10-2020', '10-10-2020', '11-10-2020', '12-10-2020'];
const CUT_OFF = 1;
const toggleToolTip = (index) => {
if (!tooltipPosx) {
setActiveToolTip(index);
setTooltipPosx(true);
} else if (tooltipPosx) {
setActiveToolTip(index);
}
if (activeToolTip == index) {
setTooltipPosx(false);
}
};
const ChartPoints = ({ x, y, color, data }) => {
return datas.map((value, index) => (
<Circle
key={index}
cx={x(index)}
cy={y(value)}
r={5}
stroke={color}
fill="white"
onPress={() => {
toggleToolTip(index);
console.log(x(index));
console.log(y(value));
console.log(index);
}}
/>
));
};
const Tooltips = ({ x, y, data }) => {
return datas.map((value, index) => {
if (activeToolTip === index) {
return (
<Svg>
<Rect
x={x(index)}
y={value < CUT_OFF ? y(value) - 10 : y(value) + 15}
width="25"
height="20"
fill="black"
/>
<TextSvg
key={index}
x={x(index) + 12}
y={value < CUT_OFF ? y(value) - 10 + 20 : y(value) + 15 + 12}
fontSize={8}
fontWeight="bold"
fill={value >= CUT_OFF ? 'pink' : 'white'}
alignmentBaseline={'middle'}
textAnchor={'middle'}>
{`${datas[index]}`}
</TextSvg>
</Svg>
);
} else {
return null;
}
});
};
return (
<View style={styles.container}>
<View style={styles.header}>
<View style={styles.title}>
<Text>Area Chart</Text>
</View>
<View style={styles.icons}>
<View style={styles.infoIcon}></View>
</View>
</View>
{isAreasVisible && (
<View>
<View
style={{
height: 250,
padding: 20,
width: '90%',
flexDirection: 'row',
marginTop: '-9%',
}}>
<YAxis
data={datas}
style={{ marginTop: 15 }}
contentInset={verticalContentInset}
svg={axesSvg}
/>
<View style={{ flex: 1, marginLeft: 10 }}>
<AreaChart
style={{ height: 200, marginTop: 15 }}
data={datas}
contentInset={{ top: 20, bottom: 22, left: 8, right: 7 }}
curve={shape.curveNatural}
svg={{ fill: '#ffdab9' }}>
<Grid />
<ChartPoints color="#98FFFE" />
{tooltipPosx && <Tooltips />}
</AreaChart>
<XAxis
data={datas}
formatLabel={(value, index) => xAxisLabels[index]}
contentInset={{ left: 20, right: 20 }}
svg={{ fontSize: 8, fill: '#555555' }}
/>
</View>
</View>
</View>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
},
});
推荐阅读
- android - 使用 requestPinAppWidget 在屏幕上添加小部件时如何添加额外的预览?
- jenkins - CI 开发的最佳实践是什么?
- excel - 运行时导出 SAP 数据不会打开工作簿
- c# - 如何在 EpPlus 中为动态工作表设置动态打印区域?
- excel - 使用 Excel 用户表单进行搜索和更新
- c# - WPF GridViewColumnHeader.Click - 获取 ItemsSource
- java - 错误 13 Webhook 调用失败错误 500:内部服务器错误
- kubernetes - Kubernetes python客户端:身份验证问题
- python - python / matplotlib中是否有任何内置函数用于标记一条线所触及的网格?
- python - Numpy,如何将列表分成多个块