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.