Interactive visualizations with React + D3. Feeling Lucky — Part #2

Grace Elina
Artris Code
Published in
5 min readFeb 18, 2018

This is part two of a series of articles on Feeling Lucky. A simple visualization app that uses React + D3 to help students find a place close to school and cheap to rent! If you’re new to this series, we recommend you begin with part one. Fork the repo to start experimenting.

Feeling lucky Demo

To make it as easy as possible for the user to select the BEST place to rent, we drew a scatterplot with the travel time on the x-axis and the price on the y-axis. This way a user can find the cheapest and closest place by selecting the points closest to the origin. We’ll be focusing on two key aspects of the scatterplot we drew.

  1. The Color Scale needs to change linearly in both the x and y direction. Here we will be doing a teeny bit of math to figure it out.
  2. The Force Simulation allows nodes in the plot to repel each other so that they do not overlap. The user can then click on a node to select a house and be directed to its website.

Color Scale

We selected two colors for the range and used a domain to help color the nodes according to the data.

Note: If you are confused about domain and range D3 Scott’s tutorial will help you understand in no time!

For the range we experimented with two colors until we were happy with the way the nodes looked. We added a domain that allowed points to be colored according to both distance and price. In other words, think of a scenario where the minimum price of a house is $0 and the maximum is $100. The minimum distance to a house is 0 minutes and the maximum is 100 minutes. A $10 change in price should change the color of a node by the same amount as a 10 minute change in distance.

To do this we calculate the ratio of the current value over the maxium value in the data for both distance and price. We then add them together. This is then passed into the color scale function which maps it to a color in the range.

The domain in the color scale starts from the minimum value that can occur to the maximum value in the data. This is shown in the createColorScalefunction.

And voila as you can see in the picture below the colors of the points change linearly both in the y and x direction!

Scatter Plot

Force Simulation

A problem we faced when we first made the scatter plot was that the nodes would overlap. To overcome this issue, we added a force field. The D3 force field that really matters here is charge. A negative charge makes nodes repel each other -exactly what we need.

The forceSimulation function takes in a set of data points and simulates a force field. At each tick the data gets updated until the simulation ends. In React we update the state of the component each time a tick happens so that the nodes are redrawn with the updated data. The issue here is that we want static nodes. We do not want nodes moving around in our scatter plot! To solve this, we found a clever hack that speeds up these ticks so that the simulation ends before the nodes are drawn unto the screen.

Handling the updating of states in a React component is tricky. First we set the state equal to the data passed in through the props. We then call the createRepulsionForce function in componentDidMount. Afterwards we draw the plot.

Here we have managed to make nodes not overlap each other. But what happens if the props change? For example, we want to apply filters and adjust the data drawn on the scatter plot. ComponentDidMount does not get called again and so the new data points will not have been updated by the force simulator. We need to update the state with the new props and call the createRepulsionForce function again with this new data. We do this in componentWillRecieveProps. Be careful here. Setting the state is asynchronous so we need to add the createRepulsionForce as a callback. This guarantees we are running the simulation with the updated data.

We now have successfully managed to make the nodes not overlap too much in the graph by creating a force simulator.

Further reading on D3

We used some great tutorials to help us along the way of making this scatter plot.

  • Nadia demos on how to add some extra features such as a tooltips
  • Jack explains how to implement force fields in a React component
  • This beautiful visualization acts as a source of inspiration

What do you want to see?

If you would like to see any features implemented on this app or you want us to clarify anything we would appreciate your feedback! Comment down below!

--

--