Pan and Zoom
Use VictoryZoomContainer
to add panning and zooming behavior to any Victory components that work with an x-y coordinate system.
See the full API here.
Basic
In the example below, an initial domain is set with the zoomDomain
prop. This prop may also be used to trigger pan and zoom behavior from other components.
function App() { return ( <VictoryChart theme={VictoryTheme.clean} domain={{ y: [0, 100] }} containerComponent={ <VictoryZoomContainer zoomDomain={{ x: [5, 35], y: [0, 100], }} /> } > <VictoryScatter data={getScatterData()} style={{ data: { opacity: ({ datum }) => datum.y % 5 === 0 ? 1 : 0.7, fill: ({ datum }) => datum.y % 5 === 0 ? "lightblue" : "lightgreen", }, }} /> </VictoryChart> ); } function getScatterData() { return _.range(50).map((index) => { return { x: _.random(1, 50), y: _.random(10, 90), size: _.random(8) + 3, }; }); } render(<App />);
Limits
The allowZoom
and allowPan
props may be used to restrict zooming and panning behavior. In the example below, zooming is disabled, but panning is allowed.
function App() { return ( <VictoryChart theme={VictoryTheme.clean} domain={{ y: [0, 100] }} containerComponent={ <VictoryZoomContainer allowZoom={false} allowPan={true} zoomDomain={{ x: [5, 35], y: [0, 100], }} /> } > <VictoryScatter data={getScatterData()} style={{ data: { opacity: ({ datum }) => datum.y % 5 === 0 ? 1 : 0.7, fill: ({ datum }) => datum.y % 5 === 0 ? "lightblue" : "lightgreen", }, }} /> </VictoryChart> ); } function getScatterData() { return _.range(50).map((index) => { return { x: _.random(1, 50), y: _.random(10, 90), size: _.random(8) + 3, }; }); } render(<App />);
Combined with Brushing
In the next example, VictoryZoomContainer
and VictoryBrushContainer
are used to create a zoomable chart with a mini-map brush control.
Here, the onZoomDomainChange
prop on VictoryZoomContainer
alters the brushDomain
prop on VictoryBrushContainer
tying highlighted brush region of the mini-map to the zoom level of the chart.
The onBrushDomainChange
prop on VictoryBrushContainer
alters the zoomDomain
prop on VictoryZoomContainer
so that the zoomed level of the chart matches the highlighted region of the mini-map.
For more information on brushing, see the Data Selection guide.
function App() { const [state, setState] = React.useState({}); function handleZoom(domain) { setState({ selectedDomain: domain, }); } function handleBrush(domain) { setState({ zoomDomain: domain }); } return ( <div> <VictoryChart width={550} height={300} scale={{ x: "time" }} theme={VictoryTheme.clean} containerComponent={ <VictoryZoomContainer responsive={false} zoomDimension="x" zoomDomain={ state.zoomDomain } onZoomDomainChange={ handleZoom } /> } > <VictoryLine data={[ { x: new Date(1982, 1, 1), y: 125, }, { x: new Date(1987, 1, 1), y: 257, }, { x: new Date(1993, 1, 1), y: 345, }, { x: new Date(1997, 1, 1), y: 515, }, { x: new Date(2001, 1, 1), y: 132, }, { x: new Date(2005, 1, 1), y: 305, }, { x: new Date(2011, 1, 1), y: 270, }, { x: new Date(2015, 1, 1), y: 470, }, ]} /> </VictoryChart> <VictoryChart width={550} height={90} scale={{ x: "time" }} theme={VictoryTheme.clean} padding={{ top: 0, left: 50, right: 50, bottom: 30, }} containerComponent={ <VictoryBrushContainer responsive={false} brushDimension="x" brushDomain={ state.selectedDomain } onBrushDomainChange={ handleBrush } /> } > <VictoryAxis tickValues={[ new Date(1985, 1, 1), new Date(1990, 1, 1), new Date(1995, 1, 1), new Date(2000, 1, 1), new Date(2005, 1, 1), new Date(2010, 1, 1), new Date(2015, 1, 1), ]} tickFormat={(x) => new Date(x).getFullYear() } /> <VictoryLine data={[ { x: new Date(1982, 1, 1), y: 125, }, { x: new Date(1987, 1, 1), y: 257, }, { x: new Date(1993, 1, 1), y: 345, }, { x: new Date(1997, 1, 1), y: 515, }, { x: new Date(2001, 1, 1), y: 132, }, { x: new Date(2005, 1, 1), y: 305, }, { x: new Date(2011, 1, 1), y: 270, }, { x: new Date(2015, 1, 1), y: 470, }, ]} /> </VictoryChart> </div> ); } render(<App />);