Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multiple line charts with different tooltips combined in one chart #385

Open
ammann29 opened this issue Oct 4, 2024 · 1 comment
Open

Comments

@ammann29
Copy link

ammann29 commented Oct 4, 2024

Question

Is it possible to have multiple line charts with different x and y values combined in one chart?
I am using scatter on each line and on pressing scatter want to display data under the chart.

Right now, scatter is being displayed on data points but I am only able to use touch points on the first line chart only.
I am only getting touch point data from first line. On pressing scatter on other lines i am getting NaN.
Also, in "value" variable no matter i click on which line i am always getting ''isFirstPressActive'' as true.

"victory-native": "^41.0.1"
"react-native": "^0.71.7"
"@shopify/react-native-skia": "^1.4.2"
"react-native-reanimated": "^3.15.4"
"react-native-gesture-handler": "^2.20.0"

Screen.Recording.2024-10-04.at.12.59.10.PM.mov
const initChartPressState = {x: 0, y: {pump1: 0, pump2: 0}} as const;
const Tab = () => {
  const theme = useAppTheme();
  const styles = generateStyles(theme);
  const font = useFont(inter, 12);
  // const {state, isActive} = useChartPressState({
  //   x: 0,
  //   y: {pump1: 0, pump2: 0},
  // });
  const {state: firstTouch, isActive: isFirstPressActive} =
    useChartPressState(initChartPressState);

  const {state: secondTouch, isActive: isSecondPressActive} =
    useChartPressState(initChartPressState);


  const value = useDerivedValue(() => {
    if (isFirstPressActive) {
      console.log('first press');
      return firstTouch.y.pump1.value.value.toString();
    }
    if (isSecondPressActive) {
      console.log('second press');
      return secondTouch.y.pump2.value.value.toString();
    }
    return '';
  });

  const ToolTip = ({x, y}) => {
    return <Circle cx={x} cy={y} r={8} color="black" />;
  };

  return (
    <ScrollView style={[{width: width}]}>
      <View style={{height: 380, width: 380, paddingTop: 20}}>
        <CartesianChart
          data={DATA}
          domain={{x: [0, 2000]}}
          chartPressState={[firstTouch, secondTouch]}
          xKey="x"
          yKeys={['pump1', 'pump2', 'pump3', 'pump4']}
          axisOptions={{font}}>
          {({points}) => (
            <>
              <Line
                connectMissingData={true}
                points={points.pump1}
                yKeys={['pump1']}
                color="red"
                strokeWidth={3}
              />
              {isFirstPressActive && 
                <View>
                  <ToolTip
                    x={firstTouch.x.position}
                    y={firstTouch.y.pump1.position}
                  />
                  <Text
                    x={firstTouch.x.position}
                    y={firstTouch.y.pump1.position}
                    text={firstTouch.y.pump1.value.value}
                    font={font}
                  />
                </View>
              }
              <Scatter
                points={points.pump1}
                yKeys={['pump1']}
                shape="circle"
                radius={5}
                style="fill"
                color="red"
              />
              <Line
                connectMissingData={true}
                points={points.pump2}
                yKeys={['pump2']}
                color="blue"
                strokeWidth={3}
              />
              {isSecondPressActive &&
                <View>
                  <ToolTip
                    x={secondTouch.x.position}
                    y={secondTouch.y.pump2.position}
                  />
                  <Text
                    x={secondTouch.x.position}
                    y={secondTouch.y.pump2.position}
                    text={secondTouch.y.pump2.value.value}
                    font={font}
                  />
                </View>
              }
              <Scatter
                points={points.pump2}
                yKeys={['pump2']}
                shape="circle"
                radius={5}
                style="fill"
                color="blue"
              />
              <Line
                connectMissingData={true}
                points={points.pump3}
                yKeys={['pump3']}
                color="green"
                strokeWidth={3}
              />
              <Scatter
                points={points.pump3}
                yKeys={['pump3']}
                shape="circle"
                radius={5}
                style="fill"
                color="green"
              />
              <Line
                connectMissingData={true}
                points={points.pump4}
                yKeys={['pump4']}
                color="orange"
                strokeWidth={3}
              />
              <Scatter
                points={points.pump4}
                yKeys={['pump4']}
                shape="circle"
                radius={5}
                style="fill"
                color="orange"
              />
            </>
          )}
        </CartesianChart>
        <AnimatedText
          text={value}
          style={{fontSize: 24, color: 'black', alignSelf: 'center'}}
        />
      </View>
    </ScrollView>
  );
};

export default Tab;

const DATA = [
  {x: 0, pump1: 110, pump2: 110, pump3: 110, pump4: 110},
  {x: 100, pump1: 110, pump2: null, pump3: null, pump4: null},
  {x: 200, pump1: 106, pump2: 110, pump3: null, pump4: null},
  {x: 300, pump1: 100, pump2: null, pump3: 110, pump4: null},
  {x: 400, pump1: 85, pump2: 106, pump3: null, pump4: 110},
  {x: 500, pump1: 60, pump2: null, pump3: null, pump4: null},
  {x: 600, pump1: null, pump2: 100, pump3: 106, pump4: null},
  {x: 800, pump1: null, pump2: 85, pump3: null, pump4: 106},
  {x: 900, pump1: null, pump2: null, pump3: 100, pump4: null},
  {x: 1000, pump1: null, pump2: 60, pump3: null, pump4: null},
  {x: 1200, pump1: null, pump2: null, pump3: 85, pump4: 100},
  {x: 1500, pump1: null, pump2: null, pump3: 60, pump4: null},
  {x: 1600, pump1: null, pump2: null, pump3: null, pump4: 85},
  {x: 2000, pump1: null, pump2: null, pump3: null, pump4: 60},
];

@ammann29 ammann29 changed the title multiple line charts with different tooltips in one chart multiple line charts with different tooltips combined in one chart Oct 4, 2024
@zibs
Copy link
Contributor

zibs commented Oct 7, 2024

Hey there, this is a bit tricky, but you'll want to open up the debugger and look at your values more closely and work from there.

I was able to get it to return and display the active y value using this:

const yValueDisplay = useDerivedValue(() => {
    const active = Object.entries(firstTouch.y).find(([key, v]) => {
      return !isNaN(v.value.value);
    });
    return active![1].value.value.toString();
  });

because not all the pumps have a value for where you are touching, so that is why it's NaN, and in your code you were always reaching for pump1s data primarily... It's pretty sensitive touch area, but try this out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants