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 />);