Search code examples
javascriptreactjsreact-nativevictory-charts

How to create a progress bar with current state tooltip


I'm trying to archive some progress line look like this

enter image description here

It will have a start point and a end point, along with a current point, the current point will be display base on value, mean, if it was 155 will be at first of red line, if 180 for example, will be near the edge on the right of red line, or if it was 85, it will be in the very first of green line, so the hard part is how to make the tooltip display base on number on the line

My idea is using a chart library, in this case is victory chart and display tooltip base on that, but it seen harder than i think and the chart is more advanced than this

So which is the best way or is there any library to create this line with current state tooltip like this? Thank you so much


Solution

  • Working example: https://snack.expo.dev/@msbot01/tenacious-watermelon

    code:

    import React,{useState, useEffect, useRef} from 'react';
    import { Text, View, StyleSheet,Dimensions,Image,Picker  } from 'react-native';
    import Constants from 'expo-constants';
    
    // You can import from local files
    import AssetExample from './components/AssetExample';
    
    // or any pure javascript modules available in npm
    import { Card } from 'react-native-paper';
    
    export default function App() {
    const windowWidth = Dimensions.get('window').width-100;
    const windowHeight = Dimensions.get('window').height;
    
    const [position, setPosition] = useState(0);
    const [points, setPoints] = useState(0);
    
    useEffect(()=>{
        // checkCameraPermission();
        setPointerPostion()
    
      })
    
      const setPointerPostion=()=>{
        var eachPoint = windowWidth/200;
        console.log(eachPoint)
        setPosition(eachPoint*points)
      }
    
      return (
        <View style={{justifyContent:'center',flex:1, padding:50}}>
          <View style={{height:100, width:windowWidth, justifyContent:'center'}}>
            <View style={{flexDirection:'row', alignItems:'center', width:'100%'}}>
              <View style={{height:3, width:windowWidth/3, backgroundColor:'green'}}></View>
              <View style={{height:3, width:windowWidth/3, backgroundColor:'yellow'}}></View>
              <View style={{height:3, width:windowWidth/3, backgroundColor:'blue'}}></View>
            </View>
    
            <View style={{height:50,width:50, position:'absolute', top:0, left:position-20}}>
              <Image
                  style={{height:50, width:50}}
                  source={require('./chat.png')}
                />
                <Text style={{position:'absolute',top:10, bottom:0, left:0, textAlign:'center', height:30, width:50, fontWeight:'bold'}}>{points}</Text>
            </View>
          </View>
    
          <View style={{}}>
          <Picker
            selectedValue={points}
            style={{ height: 50, width: 150 }}
            onValueChange={(itemValue, itemIndex) => setPoints(Number(itemValue,[setPointerPostion()]))}
          >
            <Picker.Item label="10" value="10" />
            <Picker.Item label="20" value="20" />
            <Picker.Item label="30" value="3" />
            <Picker.Item label="40" value="40" />
            <Picker.Item label="80" value="80" />
            <Picker.Item label="100" value="100" />
            <Picker.Item label="150" value="150" />
            <Picker.Item label="200" value="200" />
          </Picker>
        </View>
    
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        paddingTop: Constants.statusBarHeight,
        backgroundColor: '#ecf0f1',
        padding: 8,
      }
    });