Getting started with vx.

Evan Conrad
May 19, 2017 · 7 min read
Image for post
Image for post
Line plot created with vx.

is a collection of low-level react components for d3. Do you like React? Do you like d3? Wana combine them in a way that’s easy to use and makes sense? You want .

As of this writing, is in a super-beta and probably should not be used in production.

This guide assumes you:

  • Have knowledge of React.
  • May or may not have knowledge of d3.

Packages

tries hard to be tiny and compact. You should only import the packages you need. So, instead of doing something like this:

import vx from 'vx'; // BAD! 

You should import each package individually:

import { Bar } from '@vx/shape'; // GOOD! 

You can see a list of all packages here.

At the moment, documentation for each package lives in the package folder’s file. For example, if you want to see what the package does, you would go to the folder here. Eventually, the docs will exist on the vx website.

Below is a short description of the a few of the packages we’ll be using in alphabetic order.

Axis Package

import { AxisLeft, AxisBottom } from '@vx/axis';
Image for post
Image for post
Axis Example

A typical graph axis with ticks that can help you label your graphs. Docs Here.

Gradient Package

import { GradientOrangeRed } from '@vx/gradient';
Image for post
Image for post
Gradient Example

A gradient is a definition of a attribute that you can use in your shapes. We’ll talk more about this in a bit. Docs Here.

Group Package

import { Group } from '@vx/group';

A group is just a container for other objects. It’s really just a wrapper around the svg element. Docs Here.

Mock Data Package

import { browserUsage, genDateValue } from '@vx/mock-data';

The Mock Data package is a collection of data sets that you can use to test out your graphs. Docs Here.

Scale Package

import { scaleLinear } from '@vx/scale';

The Scale package is a wrapper around the original d3 scaling functions that let you scale your data to the size of your graph. For example, if your values are between 100,000 and 200,000 your graph doesn’t need to be 200,000 pixels high. Docs Here.

Shape Package

import { Bar } from '@vx/shape';
Image for post
Image for post
Shape Example

The Shape package contains the majority of the “shapes” you see in the graphs. Bars, Lines, and Areas are all in here.

Building Your First Graph

We’ll start by using some data from like so:

import { appleStock } from '@vx/mock-data';// ...const data = appleStock;

If we that data, we’ll see that it’s an array of JSON objects with timestamps and dollar values for apple stock.

We’ll also give our graph a width and a height.

const width = 750;
const height = 400;

We should also define some bounds and margins for our graph.

const margin = {
top: 60,
bottom: 60,
left: 80,
right: 80,
};
const xMax = width - margin.left - margin.right;
const yMax = height - margin.top - margin.bottom;

Defining What “X,Y” Means

If you’ve made graphs before in matlab or pyplot, you may have noticed that you needed to pass in an array of and . You also may have passed in an array of tuples.

D3 and vx take a functional approach. We create two functions, and to define what we mean when we say “x” and “y”. With Javascript’s arrow syntax, this can cleanly be done with our data like so:

const x = d => new Date(d.date); // d.date is unix timestamps
const y = d => d.close;

We convert the unix timestamp to date objects. See this SO question for more.

If we were to take one element of our data and put it through these functions we might get something like this:

console.log(x(data[0])); // Fri Aug 21 1970 12:23:21 GMT-0600 (MDT)
console.log(y(data[0])); // 72.2

Then, if we wanted all the y values, we could run a map function on the data like so:

data.map(y); // Gives an array of all the y values

D3 calls this pattern “accessors.”

Scaling Our Data

Since we have timestamps, we’ll use the package’s function for our x values and a for the y values.

import { scaleTime, scaleLinear } from '@vx/scale';
import { extent } from 'd3-array';
// ...const xScale = scaleTime({
range: [0, xMax],
domain: extent(data, x)
});

For the parameters, we’re going to put in a which is the values that we want to scale down our x’s to. In this case, we want the info to go from the left to right of our graph, so to .

In the domain, we’re going to make use of a function (docs here). will take an array and one of our or functions (d3 calls them accessors) and returns the min and max values.

We can then create a y value scale like so:

import {extent, max} from 'd3-array';// ...const yScale = scaleLinear({
range: [yMax, 0],
domain: [0, max(data, y)],
});

Here we’re adding another d3 function that will get us the largest y value in the data.

Creating Our First Element

expects your elements to be rendered inside of an element, so we’ll start by creating one.

const chart = ( <svg width={width} height={height}> </svg> );

Then, we’ll create an element (Docs Here) inside a element.

import { AreaClosed } from '@vx/shape';const chart = (
<svg width={width} height={height}>
<Group top={margin.top} left={margin.left}>
<AreaClosed
data={data}
xScale={xScale}
yScale={yScale}
x={x}
y={y}
fill={"red"}
/>
</Group>
</svg>
)

If we render this chart, we’ll see something like this:

Image for post
Image for post
Example First Chart

Giving Context to the Data

Now we can add some axes to label our information. We’ll add an import statement at the top like:

import { AxisLeft, AxisBottom } from ‘@vx/axis’;

To add a bottom axis, we’ll add an (Docs Here) to our chart like so:

<AxisBottom
scale={xScale}
top={yMax}
label={'Years'}
stroke={'#1b1a1e'}
tickTextFill={'#1b1a1e'}
/>

Then, we can add an with:

<AxisLeft
scale={yScale}
top={0}
left={0}
label={'Close Price ($)'}
stroke={'#1b1a1e'}
tickTextFill={'#1b1a1e'}
/>

All together we have:

<svg width={width} height={height}>
<Group top={margin.top} left={margin.left}>
<AxisLeft
scale={yScale}
top={0}
left={0}
label={'Close Price ($)'}
stroke={'#1b1a1e'}
tickTextFill={'#1b1a1e'}
/>
<AxisBottom
scale={xScale}
top={yMax}
label={'Years'}
stroke={'#1b1a1e'}
tickTextFill={'#1b1a1e'}
/>
<AreaClosed
data={data}
xScale={xScale}
yScale={yScale}
x={x}
y={y}
fill={"red"}
/>
</Group>
</svg>

Which will create a graph that looks like this:

Image for post
Image for post
Graph with Axes

Making It Pretty

It’s functional, but it’s not super appealing. Let’s use some of vx’s gradient features to make this graph a little nicer.

To use a gradient, we first need to define it. We’ll do that by added a component (Docs Here).

import { LinearGradient } from '@vx/gradient';

VX comes with a whole bunch of pre-made gradients that you can use, but let’s create our own for now.

I bookmarked webgradients awhile ago, so I’m gonna take one off there. We’ll take two color values and pop them into an element like this:

<LinearGradient
from='#fbc2eb'
to='#a6c1ee'
id='gradient'
/>

Then, we’ll change the of our to be and remove that line on top like so:

<AreaClosed
data={data}
xScale={xScale}
yScale={yScale}
x={x}
y={y}
fill={"url(#gradient)"}
stroke={""}
/>

Now we’ll have a graph that looks like this:

Image for post
Image for post
Gradient Graph

Full Source

You can find the full source code for the graph we just made here.

Image for post
Image for post

Where to Go From Here

Want to do more with ? Check out some of the other packages!

  • Play with icons with the package!
  • Explore Brush & Zoom features with the package!
  • Use Text and Labels with the package!
  • Paint with Patterns in the package!

Check out the new gallery to get a better sense of how to use .

Want to help get to a production stage? Checkout the V1 project on Github and submit a PR!

vx code

react + d3 = vx | visualization components

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store