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 area difference charts into our React app.
Install Required Libraries
We’ve to install multiple modules provided by the Visx library to create the Area Difference Chart.
To do this, we run:
npm i @visx/axis @visx/curve @visx/grid @visx/group @visx/mock-data @visx/responsive @visx/scale @visx/shape @visx/threshold
Create the Chart
Once we installed all the required libraries, we add the chart by writing:
import React from "react";
import { Group } from "@visx/group";
import { curveBasis } from "@visx/curve";
import { LinePath } from "@visx/shape";
import { Threshold } from "@visx/threshold";
import { scaleTime, scaleLinear } from "@visx/scale";
import { AxisLeft, AxisBottom } from "@visx/axis";
import { GridRows, GridColumns } from "@visx/grid";
import cityTemperature from "@visx/mock-data/lib/mocks/cityTemperature";
export const background = "#f3f3f3";
const date = (d) => new Date(d.date).valueOf();
const ny = (d) => Number(d["New York"]);
const sf = (d) => Number(d["San Francisco"]);
const timeScale = scaleTime({
domain: [
Math.min(...cityTemperature.map(date)),
Math.max(...cityTemperature.map(date))
]
});
const temperatureScale = scaleLinear({
domain: [
Math.min(...cityTemperature.map((d) => Math.min(ny(d), sf(d)))),
Math.max(...cityTemperature.map((d) => Math.max(ny(d), sf(d))))
],
nice: true
});
const defaultMargin = { top: 40, right: 30, bottom: 50, left: 40 };
function Theshold({ width, height, margin = defaultMargin }) {
if (width < 10) return null;
const xMax = width - margin.left - margin.right;
const yMax = height - margin.top - margin.bottom;
timeScale.range([0, xMax]);
temperatureScale.range([yMax, 0]);
return (
<div>
<svg width={width} height={height}>
<rect
x={0}
y={0}
width={width}
height={height}
fill={background}
rx={14}
/>
<Group left={margin.left} top={margin.top}>
<GridRows
scale={temperatureScale}
width={xMax}
height={yMax}
stroke="#e0e0e0"
/>
<GridColumns
scale={timeScale}
width={xMax}
height={yMax}
stroke="#e0e0e0"
/>
<line x1={xMax} x2={xMax} y1={0} y2={yMax} stroke="#e0e0e0" />
<AxisBottom
top={yMax}
scale={timeScale}
numTicks={width > 520 ? 10 : 5}
/>
<AxisLeft scale={temperatureScale} />
<text x="-70" y="15" transform="rotate(-90)" fontSize={10}>
Temperature (°F)
</text>
<Threshold
id={`${Math.random()}`}
data={cityTemperature}
x={(d) => timeScale(date(d)) ?? 0}
y0={(d) => temperatureScale(ny(d)) ?? 0}
y1={(d) => temperatureScale(sf(d)) ?? 0}
clipAboveTo={0}
clipBelowTo={yMax}
curve={curveBasis}
belowAreaProps={{
fill: "violet",
fillOpacity: 0.4
}}
aboveAreaProps={{
fill: "green",
fillOpacity: 0.4
}}
/>
<LinePath
data={cityTemperature}
curve={curveBasis}
x={(d) => timeScale(date(d)) ?? 0}
y={(d) => temperatureScale(sf(d)) ?? 0}
stroke="#222"
strokeWidth={1.5}
strokeOpacity={0.8}
strokeDasharray="1,2"
/>
<LinePath
data={cityTemperature}
curve={curveBasis}
x={(d) => timeScale(date(d)) ?? 0}
y={(d) => temperatureScale(ny(d)) ?? 0}
stroke="#222"
strokeWidth={1.5}
/>
</Group>
</svg>
</div>
);
}
export default function App() {
return (
<div className="App">
<Theshold width="500" height="300" />
</div>
);
}
We use the mock data provided by the Visx library to create the chart.
We create the timeScale
scale for the x-axis.
And we create the temperatureScale
for the y-axis.
We call scaleTime
and scaleLinear
respectively to scale the data to display the chart.
Next, we set the margins with the defaultMargin
object.
Then we create the Threshold
component which has the area difference chart.
In it, we computed the xMax
and yMax
values to create the max value for the x and y axes respectively.
Then we call the range
method to create the time and temperature scales for the chart.
Next, we add the svg
element to add the container for the chart.
rect
has the rectangle that surrounds the chart.
Group
has items we need to form the chart.
GridRows
has the grid rows.
We set the scale
prop to the temperatureScale
to display the temperatures.
Likewise, we do the same for the GridColumns
component but scale
is set to timeScale
.
line
has the perimeter lines for the chart.
AxisBottom
has the x-axis.
AxisLeft
is the y-axis.
We add the Threshold
component to bad the fill between the lines.
And we add the lines with the LinePath
component.
We set the data by setting the data
prop.
The x
and y
props return the x and y values.
Finally, in App
, we render the Threshold
component we created and set the width
and height
to display the chart.
Conclusion
We can create area difference charts easily in our React app with the Visx library.