首页 > 解决方案 > 不确定如何在本机反应中配置此工具提示功能

问题描述

小吃我已经在 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",
  },
}); 

标签: javascriptreact-native

解决方案


我根据选定的图表点索引添加了一个名为 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',
  },
});

推荐阅读