The Victory lets us add charts and data visualization into our React app.
In this article, we’ll look at how to add charts into our React app with Victory.
Transitions
We can set the transition effects for animations with the VictoryBar
component.
For instance, we can write:
import React, { useEffect, useState } from "react";
import { VictoryBar, VictoryChart } from "victory";
const random = (min, max) => Math.floor(min + Math.random() * max);
const getData = () => {
const bars = random(6, 10);
return Array(bars)
.fill()
.map((_, index) => {
return {
x: index + 1,
y: random(2, 100)
};
});
};
export default function App() {
const [data, setData] = useState([]);
useEffect(() => {
const timer = setInterval(() => {
setData(getData());
}, 3000);
return () => clearInterval(timer);
}, []);
return (
<VictoryChart domainPadding={{ x: 20 }} animate={{ duration: 500 }}>
<VictoryBar
data={data}
style={{
data: { fill: "tomato", width: 12 }
}}
animate={{
onExit: {
duration: 500,
before: () => ({
_y: 0,
fill: "orange",
label: "BYE"
})
}
}}
/>
</VictoryChart>
);
}
We generate random data for our graph and update it with the new data every 3 seconds.
We set the animate
prop on the VictoryBar
component to add transition effects for the bars.
onExit.duration
has the duration of the leave animation.
We change the color of the bars with fill
property.
And the label
is displayed when the bars leave the screen.
Brush and Zoom
We can add brush and zoom into our charts with the VictoryChart
‘s containerComponent
prop.
For instance, we can write:
import React from "react";
import { VictoryChart, VictoryScatter, VictoryZoomContainer } from "victory";
const random = (min, max) => Math.floor(min + Math.random() * max);
const getData = () => {
return Array(50)
.fill()
.map((index) => {
return {
x: random(1, 50),
y: random(10, 90),
size: random(8) + 3
};
});
};
export default function App() {
return (
<VictoryChart
domain={{ y: [0, 100] }}
containerComponent={
<VictoryZoomContainer zoomDomain={{ x: [5, 35], y: [0, 100] }} />
}
>
<VictoryScatter
data={getData()}
style={{
data: {
opacity: ({ datum }) => (datum.y % 5 === 0 ? 1 : 0.7),
fill: ({ datum }) => (datum.y % 5 === 0 ? "tomato" : "black")
}
}}
/>
</VictoryChart>
);
}
We set containerComponent
to the VictoryZoomContainer
component.
The zoomDomain
prop lets us set the zoom level range for the x and y axes with the x
and y
properties.
We can also create a separate chart for the brush:
import React, { useState } from "react";
import {
VictoryAxis,
VictoryBrushContainer,
VictoryChart,
VictoryLine,
VictoryZoomContainer
} from "victory";
export default function App() {
const [selectedDomain, setSelectedDomain] = useState();
const [zoomDomain, setZoomDomain] = useState();
const handleZoom = (domain) => {
setSelectedDomain(domain);
};
const handleBrush = (domain) => {
setZoomDomain(domain);
};
return (
<>
<VictoryChart
width={550}
height={300}
scale={{ x: "time" }}
containerComponent={
<VictoryZoomContainer
responsive={false}
zoomDimension="x"
zoomDomain={zoomDomain}
onZoomDomainChange={handleZoom}
/>
}
>
<VictoryLine
style={{
data: { stroke: "tomato" }
}}
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" }}
padding={{ top: 0, left: 50, right: 50, bottom: 30 }}
containerComponent={
<VictoryBrushContainer
responsive={false}
brushDimension="x"
brushDomain={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
style={{
data: { stroke: "tomato" }
}}
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>
</>
);
}
We do this by setting the zoomDomain
and the selectedDomain
by dragging on the bottom graph.
In the bottom VictoryChart
, we have the containerComponent
set to the VictoryBrushContainer
.
brushDomain
is set to the selectedDomain
,
And the onBrushDomainChange
is set to the handleBrush
function to change selectedDomain
.
The location will be reflected in the top chart.
We have similar code to set the zoomDomain
in the top chart.
The zoom is reflected in the bottom chart.
Conclusion
We can add transitions, brush, and zoom into charts in our React app with Victory.