Creating a React Graph Component using D3.js
Today, we’ll create a graph component that uses React and D3.js. Usually, when someone speaks about a graph in D3.js, they mean a representation of entities as circles and relationships between them – "edges" or "links" connecting them. For many cases, this representation is more than enough. However, recently, I’ve met the necessity to render a React component instead of just a simple circle. This would give us great freedom in ways to display the information in the node, because the main pain point in SVG is the inability to comfortably deal with text, flexbox, etc.
Getting Started
First, we need to set up a Vite+React+Typescript project using bun as the package manager:
bun create vite
We also need to add some packages to render the graph:
bun add d3-force d3-selection
Additionally, we need type definitions for the d3 packages, which come separately:
bun add -D @types/d3-force @types/d3-selection
Defining the Data Type
Now, we need to define the type of data. We’ll use the d3-force package’s generics for type safety.
// Graph.tsx
import { SimulationLinkDatum, SimulationNodeDatum } from 'd3-force';
interface GraphNode extends SimulationNodeDatum {
id: string;
name: string;
url: string;
}
interface GraphLink extends SimulationLinkDatum<GraphNode> {
strength: number;
}
Extending the d3-force Generics
We’ll extend our interfaces from the generics from d3-force:
// Graph.tsx
import { SimulationLinkDatum, SimulationNodeDatum } from 'd3-force';
interface GraphNode extends SimulationNodeDatum {
id: string;
name: string;
url: string;
}
interface GraphLink extends SimulationLinkDatum<GraphNode> {
strength: number;
}
Creating the Node Component
We’ll create a Node component that will render a div with a class name "bg-blue-300 rounded-full border border-blue-800 px-5 py-1" and an h2 with the node’s name and an a tag with the node’s URL.
// Node.tsx
import { GraphNode } from '../Graph';
export function Node({ node }: { node: GraphNode }) {
return (
<div className="bg-blue-300 rounded-full border border-blue-800 px-5 py-1">
<h2>{node.name}</h2>
<a
className="inline-block text-sm underline"
href={node.url}
>
{node.url}
</a>
</div>
);
}
Conclusion
In this article, we’ve created a React graph component using D3.js. We’ve defined the type of data and extended the d3-force generics for type safety. We’ve also created a Node component that renders a div with a class name "bg-blue-300 rounded-full border border-blue-800 px-5 py-1" and an h2 with the node’s name and an a tag with the node’s URL.
FAQs
Q: What is the purpose of using d3-force in this example?
A: The purpose of using d3-force is to create a graph component that uses React and D3.js. It allows us to create a graph with nodes and edges.
Q: What is the difference between d3-force and d3-selection?
A: d3-force is used for creating a graph with nodes and edges, while d3-selection is used for selecting elements in an SVG.
Q: Can I use d3-force without d3-selection?
A: No, you can’t use d3-force without d3-selection. d3-force relies on d3-selection for selecting elements in an SVG.

