Creating a Force Graph using React, D3, and PixiJS



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 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” 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:

import