Skip to main content

Pan/Zoom

The CartesianChart and PolarChart components have opt-in support for "pan/zoom" gestures simply by using the useChartTransformState hook.

useChartTransformState​

The useChartTransformState hook provides the necessary state management for pan and zoom gestures. It accepts an optional configuration object and returns an object with a state property.

Configuration​

The hook accepts a configuration object with the following options:

type ChartTransformStateConfig = {
scaleX?: number; // Initial X-axis scale
scaleY?: number; // Initial Y-axis scale
};

Return Value​

The hook returns an object with a state property that contains:

{
state: {
panActive: SharedValue<boolean>; // Whether a pan gesture is currently active
zoomActive: SharedValue<boolean>; // Whether a zoom gesture is currently active
origin: SharedValue<{ x: number; y: number }>; // The origin point for transformations
matrix: SharedValue<Matrix4>; // The current transformation matrix
offset: SharedValue<Matrix4>; // The offset transformation matrix
};
}

Basic Usage​

To enable pan and zoom gestures on a chart, pass the transform state to the chart's transformState prop:

import { CartesianChart, useChartTransformState } from "victory-native";

function MyChart() {
const {state: transformState} = useChartTransformState({
scaleX: 1.5, // Initial X-axis scale
scaleY: 1.0, // Initial Y-axis scale
});

return (
<CartesianChart
transformState={transformState}
// ... other props
>
{/* chart content */}
</CartesianChart>
)
}

If no configuration is provided, the chart will initialize with a scale of 1.0 for both axes.

Transform Gesture Configuration​

You can customize the pan gesture behavior using the transformConfig prop:

<CartesianChart
transformState={state}
transformConfig={{
pan: {
activateAfterLongPress: 100, // Delay in ms before pan gesture activates
},
}}
>
{/* chart content */}
</CartesianChart>

When a chart is inside a vertical ScrollView, dimensions: "x" only controls how the chart moves after pan activation. Use pan activation/failure offsets to let vertical scroll gestures pass through while still allowing horizontal chart panning:

<CartesianChart
transformState={state}
transformConfig={{
pan: {
dimensions: "x",
activeOffsetX: [-20, 20],
failOffsetY: [-12, 12],
},
pinch: { enabled: false },
}}
>
{/* chart content */}
</CartesianChart>

Utility Functions​

Several utility functions are available to help work with chart transformations:

getTransformComponents​

Extracts the scale and translation components from a transformation matrix:

const { scaleX, scaleY, translateX, translateY } = getTransformComponents(matrix);

setScale​

Updates the scale components of a transformation matrix:

// Set uniform scale
const newMatrix = setScale(matrix, 2.0); // scales both X and Y by 2.0

// Set different X and Y scales
const newMatrix = setScale(matrix, 2.0, 1.5); // scaleX = 2.0, scaleY = 1.5

setTranslate​

Updates the translation components of a transformation matrix:

const newMatrix = setTranslate(matrix, 100, 50); // moves 100 units in X, 50 in Y

These utility functions are particularly useful when you need to programmatically modify chart transformations or read the current transformation state.

Reading the current transform in chart children​

useCartesianTransformContext exposes the current Cartesian transform values to components rendered inside a CartesianChart. This is useful for opt-in drawing behavior that should compensate for zoom, such as keeping a stroke width visually stable while the chart content scales.

import { Line, useCartesianTransformContext } from "victory-native";

function TransformAwareLine({ points }) {
const { kx } = useCartesianTransformContext();
const strokeScale = Math.max(Math.abs(kx), 0.001);

return (
<Line
points={points}
color="blue"
strokeWidth={Math.max(1, 3 / strokeScale)}
/>
);
}

The hook returns { k, kx, ky, tx, ty }, where kx and ky are the current x/y scale factors and tx / ty are the current translation values. It must be used from chart children or renderOutside content rendered inside a CartesianChart.