Creating a Force Graph using React, D3 and PixiJS
Tags: pixijs, webdev, d3js, react
Published: 2021-03-07 09:07:39

---
title: Creating a Force Graph using React, D3 and PixiJS
published: true
date: 2021-03-07 08:42:28 UTC
tags: pixijs,webdevelopment,d3js,react
canonical_url: https://medium.com/@gilfink/creating-a-force-graph-using-react-d3-and-pixijs-95616051aba
---

A few months ago I published a post about how to [create a force graph using React and D3](https://dev.to/gilfink/creating-a-force-graph-using-react-and-d3-jpg-temp-slug-2341904). But what if the force graph data source is enormous? Would you still use D3 or are there any other solutions out there?  
In this post I’ll explain how you can combine both D3 and PixiJS to create almost the same force graph but in a different way which will enable you to support bigger data sources.

In the app we created we faced a very painful performance problem. While D3 helped us to create the relevant force graph we needed to show on screen, the data source we were using became very large. When using D3, the graph representation underneath is created using SVG and that means that when the data source becomes larger the amount of SVG elements increase. The more SVG elements you have on screen the less performant the app becomes.

So, how can we solve the problem? What if we could transfer D3 SVG representation into canvas representation. Would that help?   
In our app it helped.

#### Enter PixiJS

PixiJS is a flexible 2D WebGL renderer library which is working on top of HTML5 canvas element.

_Note - I won’t get into PixiJS fundamentals in this post and I encourage you to go to it’s_ [_website_](https://www.pixijs.com/) _for further reading._

In a whole what I did was to use the D3 force graph simulation on one hand to keep the force graph simulation and I let PixiJS handle all the rendering on top of the canvas element.

#### Creating the Example App

I’m going to refactor a little bit the app I created in the “[Creating a Force Graph using React and D3](https://dev.to/gilfink/creating-a-force-graph-using-react-and-d3-jpg-temp-slug-2341904)” post. That means that if you haven’t read it go ahead and do that before you continue reading this post.

First you will need to install PixiJS library. In command line run the following code to install both PixiJS and PixiJS Viewport, which will help us to support things like zoom in and out:

```
npm i pixi.js pixi-viewport
```

After the libraries are installed we are ready to proceed.

I’ll use the same **ForceGraph** component container I created in the previous post, but this time I’ll use the **runForceGraphPixi** function instead of **runForceGraph**. **runForceGraphPixi** will be responsible to create and run the new force graph.

#### Building the Force Graph Generator

The force graph generator will be a function that will be responsible to generate the graph. Here is the declaration of the function which gets the containing div, the data for links and nodes and a function to generate a node tooltip:

{% gist https://gist.github.com/gilf/364694a40ad59d0c01bb5bbd96d88ace.js %}

You can see that I import both D3 and PixiJS and I use the same signature that I used in **runForceGraph** from the previous post. Now let’s implement the function.

The first lines of code will be to copy the data and to get the container’s **width** and  **height** :

{% gist https://gist.github.com/gilf/78def566e83583af8c4bf3faf4dcd814 %}

I also add a variable I’ll use later to control the nodes drag and drop and clean the container from it’s previously generated HTML content.

Then, let’s add a few helper functions:

{% gist https://gist.github.com/gilf/9911f78a060a2c1a536fa4fadec626b9 %}

The helper functions will help us to add the tooltip, to support the coloring of the nodes and also to create the drag and drop functionality.

Now we add the code that will create the nodes and their links and will simulate the force graph:

{% gist https://gist.github.com/gilf/62ac60780af76de02c6949c8aa1cec54 %}

Pay attention that I add both a **Pixi.Applicaiton** and also **d3.forceSimulation**. The PixiJS application will be responsible for the graph rendering according to the force simulation that D3 exposes.

When the graph is ready we will add a few event handlers to handle what is going to happen when the tick is happening :

{% gist https://gist.github.com/gilf/f500e5e76ce050f0052baff43342b946 %}

In the tick event we clean all the links and then redraw them on the canvas again.

Last but not least, we will return the destroy function that the graph container is going to use when it’s going to unmount the graph:

{% gist https://gist.github.com/gilf/4cdd3e56c972752ae643ba883235767a %}

The whole function source code:

{% gist https://gist.github.com/gilf/c8923b9543194137a3d4ef136cca0d52 %}

Now that everything is set in place you can run the app and look at your fancy force graph.

![](https://cdn-images-1.medium.com/max/1024/1*pKQw_62EAYzW2HuFio5ijw.png)<figcaption>The Generated Force Graph</figcaption>

### Summary

In the post, I showed you how to create a force graph component using **React, D3** and **PixiJS** libraries. You can find the graph code [here](https://onedrive.live.com/?authkey=%21AL75phd8K0DQDgs&id=CC807E0FCC4169F4%2137455&cid=CC807E0FCC4169F4).