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

sticky Y axis when scrolling horizontally #271

Closed
maciejbaczynski opened this issue May 14, 2024 · 16 comments
Closed

sticky Y axis when scrolling horizontally #271

maciejbaczynski opened this issue May 14, 2024 · 16 comments
Labels
enhancement New feature or request

Comments

@maciejbaczynski
Copy link

maciejbaczynski commented May 14, 2024

Is there a way to achieve sticky Y axis when scrolling horizontally? Something like VictoryZoomContainer in old version. Right now Im using ScrollView outside CartesianChart but it would be great to use it inside, only over lines so Y axis legend is always visible.
scroll.webm

@zibs
Copy link
Contributor

zibs commented May 14, 2024

Hey, sorry we haven't implemented panning/scrolling yet.

@zibs zibs added the enhancement New feature or request label May 14, 2024
@devevecare
Copy link

+1

@manyaagarwal
Copy link

Hey @zibs

Do you have any tips on go about creating a custom implementation for panning or if me or someone on my team can contribute to the process of implementing it (if this is on the eventual roadmap for xl)?

@carbonrobot
Copy link
Contributor

@manyaagarwal Brush and Zoom containers are on the roadmap, but we do not have resources assigned to work on it currently.

@ducpt-bili
Copy link

yeah, the chart on the mobile is really need this feature (cause the size of device is too small, user need to scroll), this is only reason right now stoping me from using Victory native chart. I hope this feature will be on in the nearest future. Thank for your great lib. @carbonrobot

@cr0nil
Copy link

cr0nil commented Oct 24, 2024

+1

@keithluchtel
Copy link
Member

This alone doesn't quite get the required functionality, but here's a pan/zoom PR I've been working on: #413 , I'll see if I can build upon this to implement the Brush Container from original Victory.

@Jothebug
Copy link

Is there a way to achieve sticky Y axis when scrolling horizontally? Something like VictoryZoomContainer in old version. Right now Im using ScrollView outside CartesianChart but it would be great to use it inside, only over lines so Y axis legend is always visible. scroll.webm

Hi maciejbaczynski,

How can you implement the horizontal scrolling like GIF above?. Because I stuck with the issue for weeks, I'm so glad if you share the idea about the horizontal scroll to me. Thank you so much in advance.

@keithluchtel
Copy link
Member

The PR for panning/zoom was merged today. I think it can be extended to allow for the horizontal axis scrolling only relatively easily.

@maciejbaczynski
Copy link
Author

maciejbaczynski commented Nov 21, 2024

@Jothebug

 <ScrollView horizontal ref={scrollViewRef}>
      <View style={styles.container}>
        <View style={styles.labelContainer}>
          <Text style={{ color: GLOBAL_STYLES.colors.chartLabel }}>{unitLabel}</Text>
        </View>
        <CartesianChart
          chartPressState={state}
          data={data}
          xKey="x"
          yKeys={['y1', 'y2']}
          domain={{ y: [lowestValueWithOffset, highestValueWithOffset] }}
          padding={{ bottom: axisMargin }}
          axisOptions={{
            font,
            axisSide: {
              x: 'bottom',
              y: 'right',
            },
            tickCount: {
              x: 6,
              y: 5,
            },
            lineColor: {
              grid: {
                x: 'transparent',
                y: GLOBAL_STYLES.colors.chartScaleLine,
              },
              frame: 'transparent',
            },
            labelColor: GLOBAL_STYLES.colors.chartLabel,
            labelOffset: {
              x: axisMargin,
              y: axisMargin,
            },
            labelPosition: {
              y: 'outset',
              x: 'outset',
            },
            formatXLabel: value => value || '',
          }}>
          {({ points }) => {
            return (
              <>
                {line1Visible && (
                  <Line
                    points={points.y1}
                    color={line1Color}
                    strokeWidth={3}
                    animate={animation}
                  />
                )}
                {line2Visible && (
                  <Line
                    points={points.y2}
                    color={line2Color}
                    strokeWidth={3}
                    animate={animation}
                  />
                )}
                {isActive ? (
                  <RoundedRect
                    x={state.x.position}
                    y={0}
                    width={1}
                    height={300}
                    r={0}
                    color={GLOBAL_STYLES.colors.chartLabel}
                  />
                ) : null}
              </>
            );
          }}
        </CartesianChart>
      </View>
    </ScrollView>

@keithluchtel
Copy link
Member

Released in 41.13.0

@alvintwking
Copy link

image

how do I clip the chart so that I do not out-zoomed or out-panned the chart

@keithluchtel
Copy link
Member

@alvintwking there currently isn't a configuration to limit the min/max scale values. I can look into added that if you want to create a new issue.

In the meantime, you can reference some of the example app code that resets the zoom value automatically. You can modify it so that it will reset if the user goes outside your desired range:

  const { state } = useChartTransformState();

  const k = useSharedValue(1);
  const tx = useSharedValue(0);
  const ty = useSharedValue(0);

  useAnimatedReaction(
    () => {
      return state.panActive.value || state.zoomActive.value;
    },
    (cv, pv) => {
      if (!cv && pv) {
        const vals = getTransformComponents(state.matrix.value);
        k.value = vals.scaleX;
        tx.value = vals.translateX;
        ty.value = vals.translateY;

        k.value = withTiming(1);
        tx.value = withTiming(0);
        ty.value = withTiming(0);
      }
    },
  );

  useAnimatedReaction(
    () => {
      return { k: k.value, tx: tx.value, ty: ty.value };
    },
    ({ k, tx, ty }) => {
      const m = setTranslate(state.matrix.value, tx, ty);
      state.matrix.value = setScale(m, k);
    },
  );
Screen.Recording.2024-12-31.at.9.43.10.AM.mov

@alvintwking
Copy link

@keithluchtel , thanks will try it out

@alvintwking
Copy link

@keithluchtel happy new year, will you be able to share the complete code of the example.

@keithluchtel
Copy link
Member

@keithluchtel happy new year, will you be able to share the complete code of the example.

https://github.com/FormidableLabs/victory-native-xl/blob/main/example/app/pan-zoom.tsx

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

No branches or pull requests

10 participants