Building a line chart using Visx
I’ve always been a staunch supporter of using d3 for visualization projects because it’s probably the most flexible tool. This flexibility comes at the cost of a steep learning curve, but in my view, the cost of using d3 is worth it.
Why use d3 despite the learning curve?
Most designers I have worked with tend to have design and UX requirements that are more complex than what standard plug-and-play charting solutions can provide. With plug-and-play tools, oftentimes we have to say no to several of the design team’s requests and as a developer, I try to avoid that whenever I can. While it is technically possible to customize a plug-and-play tool to fit complex design requirements, it requires writing a lot of custom d3 anyway (assuming the library is built on top of d3), so there is no escaping the learning curve in order to accommodate more complex designs. I still think d3 is the best tool for the most complex visualizations but for simpler ones like the example I will show below, a tool like Visx will allow you to deliver faster while still meeting design requirements.
Visx
Visx is a simple enough tool to use while also being a low-level tool like d3. It allows you to have granular control over any aspect of the chart but does not require as steep of a learning curve as d3.
Let’s look at an example by building a chart together. By the end of this post, we want to have a chart that looks like this:
Here’s a copy-paste of the line chart example from the visx docs.
Note that there is no y-axis. Let’s add one. We’ll also add more data to fill out the chart.
To add a y-axis, you can simply add this line:
<AnimatedAxis orientation="left" />
Currently, the x-axis scale is set toband
. I want the x-axis to accept date objects so that it will dynamically update the axis labels based on any date range I provide to the chart. It’s as simple as passing xScale={{ type: ‘time'}}
to the XYChart
component. We’ll also need to update our xAccessor
to convert our date strings to Date
objects.
const accessors = {
xAccessor: (d) => new Date(`${d.x}T00:00:00`),
yAccessor: (d) => d.value,
};
We call new Date
without a timezone by adding T00:00:00
to our date string so that we’ll get a date based on the browser’s timezone. Otherwise, you might end up getting a different date — which in my case is always the day before since I’m in EST. Here’s an example of that:
new Date("2021-01-01")
Thu Dec 31 2020 19:00:00 GMT-0500 (Eastern Standard Time)
The remainder of the code is styling and tooltip related and here is our final result after applying the changes.
I’m glad that I found a tool that can be relatively quick to use while also providing the flexibility that I need to deliver on our design team’s requests. We’ll likely be using Visx for many of our future projects.
We’re hiring!