Visx is a library that lets us add graphics to our React app easily.
In this article, we’ll look at how to use it to add grouped bar charts into our React app.
Install Required Packages
We have to install a few modules to create the grouped bar chart.
To get started, we run:
npm i @visx/axis @visx/group @visx/mock-data @visx/responsive @visx/scale @visx/shape
to install the packages.
Create the Chart
We can create the chart by adding the items provided by the modules.
We use the data from the @visx/mock-data
module.
To create the chart, we write:
import React from "react";
import { Group } from "@visx/group";
import { BarGroup } from "@visx/shape";
import { AxisBottom } from "@visx/axis";
import cityTemperature from "@visx/mock-data/lib/mocks/cityTemperature";
import { scaleBand, scaleLinear, scaleOrdinal } from "@visx/scale";
import { timeParse, timeFormat } from "d3-time-format";
const blue = "#aeeef8";
export const green = "#e5fd3d";
const purple = "#9caff6";
export const background = "#612efb";
const data = cityTemperature.slice(0, 8);
const keys = Object.keys(data[0]).filter((d) => d !== "date");
const defaultMargin = { top: 40, right: 0, bottom: 40, left: 0 };
const parseDate = timeParse("%Y-%m-%d");
const format = timeFormat("%b %d");
const formatDate = (date) => format(parseDate(date));
const getDate = (d) => d.date;
const dateScale = scaleBand({
domain: data.map(getDate),
padding: 0.2
});
const cityScale = scaleBand({
domain: keys,
padding: 0.1
});
const tempScale = scaleLinear({
domain: [
0,
Math.max(...data.map((d) => Math.max(...keys.map((key) => Number(d[key])))))
]
});
const colorScale = scaleOrdinal({
domain: keys,
range: [blue, green, purple]
});
function Example({ width, height, events = false, margin = defaultMargin }) {
const xMax = width - margin.left - margin.right;
const yMax = height - margin.top - margin.bottom;
dateScale.rangeRound([0, xMax]);
cityScale.rangeRound([0, dateScale.bandwidth()]);
tempScale.range([yMax, 0]);
return width < 10 ? null : (
<svg width={width} height={height}>
<rect
x={0}
y={0}
width={width}
height={height}
fill={background}
rx={14}
/>
<Group top={margin.top} left={margin.left}>
<BarGroup
data={data}
keys={keys}
height={yMax}
x0={getDate}
x0Scale={dateScale}
x1Scale={cityScale}
yScale={tempScale}
color={colorScale}
>
{(barGroups) =>
barGroups.map((barGroup) => (
<Group
key={`bar-group-${barGroup.index}-${barGroup.x0}`}
left={barGroup.x0}
>
{barGroup.bars.map((bar) => (
<rect
key={`bar-group-bar-${barGroup.index}-${bar.index}-${bar.value}-${bar.key}`}
x={bar.x}
y={bar.y}
width={bar.width}
height={bar.height}
fill={bar.color}
rx={4}
onClick={() => {
if (!events) return;
const { key, value } = bar;
alert(JSON.stringify({ key, value }));
}}
/>
))}
</Group>
))
}
</BarGroup>
</Group>
<AxisBottom
top={yMax + margin.top}
tickFormat={formatDate}
scale={dateScale}
stroke={green}
tickStroke={green}
hideAxisLine
tickLabelProps={() => ({
fill: green,
fontSize: 11,
textAnchor: "middle"
})}
/>
</svg>
);
}
export default function App() {
return (
<div className="App">
<Example width="500" height="300" />
</div>
);
}
We set the color of the bars with the blue
, green
, and purple
variables.
background
is the background color.
The data
variable has the mock data values we want to get and display in the bars.
keys
have the x-axis values.
defaultMargin
has the margin styles.
We create the parseDate
and format
functions from D3’s time parsing and formatting functions.
Then we create the day and city scales with the dateScale
and cityScale
variables.
The cityScale
values are the bars.
tempScale
are the bar heights.
colorScale
have the color of the bars.
The Example
component has the bar chart. We put everything together in there.
The xMax
and yMax
values are the max x and y-axis values respectively.
We use it to set the max values of the dateScale
and tempScale
.
In the return
statement, we put everything in the svg
element.
Group
has the chart components.
We map the barGroups
into rect
elements to display the bars.
We set the width
and height
prop to set their width and height.
The x-axis is rendered by the AxisBottom
component.
We set the top
prop to set the location of the axis.
tickFormat
has the ticks.
tickLabelProps
have the label styles.
Conclusion
We can add grouped bar charts easily into our React app with the Visx library.