If you work with graphs, it’s useful to have a fast way to interactively visualize a set of connected nodes. This post explains the D3 code required to go from a text file describing a set of edges to an
interactive graph visualization.
If you just want the code check out this gist.
Below is an
interactive example of the final product. Click and drag nodes around in the graph. Edit the
textarea then click the graph to see your changes in realtime.
setup process for D3.js is straightforward. We just include the library in a script tag. A second script tag at the end of the body element is where we will write our code. The code below should be saved in a file called
As shown above in the interactive example, our graph is defined by a
list of edges. If you’re following along, create a file called
graph.json in the same directory as
index.html and add the following content:
We use a
list of edges to describe our graph. The set of
unique strings we find while parsing the edges becomes our
set of vertices.
D3 can load a
JSON file and fire a callback with the
parsed result, so that’s what we’ll use to get the graph data. There’s just a bit of
boiler plate first to create an SVG context on which to render our graphics.
index.html file to include the following code in the
Note, D3 won’t be able to load the file in certain browsers if you try to serve it over
file://. The easiest way fix this is to run a local server with NodeJS. With NPM installed, run the following command to globally install the http-server node package:
npm install http-server -g
After a successful install, run the following command in the local directory to host the current directory as a static server.
localhost:8080 to see our running app, which is currently just a white screen!
We now see the following message printed to the browser’s console, which displays the JSON object from
Now we have
data and an
SVG context, so we’re ready to start writing D3 code to render our graph.
The section is split into two:
Format the Data and
Render the Graph. In both these subsections, there’s a fair bit of code to walk through. Each code block will display line numbers
relative to the
index.html file, which means, if you’re following along, its best if your
index.html file is an exact match to what’s shown below:
line 5 we added a link to
style.css. Create a file called
style.css in the same directory as
index.html and add the following lines:
The CSS above will ensure our rendered graph looks nice once we display it.
Looking back at our
graph.json file, we
only specified the
edges of our graph. Specifying only the edges makes it easy to modify the text representation of our graph, but it means we’ll have to do a bit of extra work in code to extract information about the vertices, but it’s code, so
hopefully we’ll only have to write it
once. Place the following code inside the callback from D3’s
The code above creates a data structure called
graph to hold information about our nodes and edges. We iterate over the
data object in order to format our edges. We find all the unique vertex names from our data and assign
random coordinates to each vertex. None of that code uses D3, but it’s time to start in the next section.
The code in this section should be placed inside D3’s json callback after the code from the previous section.
D3 might look a bit strange the first few times you see it, but here’s whats happening in the next code block;
svg.selectAll(".edge") selects all elements with class
edge even if none exist yet. We then give D3 an array representing our data
.data(graph.edges). Finally, we call
.enter() and describe how to build an
edge out of an element from our data array. A
line is an SVG element with two pairs of coordinates representing end points.
Each node is a
circle and a
text element. We wrap the circle and text inside a group which SVG calles a
Here we describe that each
g tag node group will contain a
circle with a given radius
r and coordinates. We assigned random values to the coordinates earlier.
text element is added to each node which will show the nodes name.
Refreshing the app now will show our graph with vertices at random locations and the nodes will not be draggable. In the next section, we add one more code block to add draggability.
To make nodes draggable, add the following function definition inside D3’s json callback after the code from the previous section.
line 74 - this line
.call(d3.drag().on("drag", dragged)); - to connect the
dragged function with each node.
That’s everything. We now have a
draggable network graph we can easily modify by adding/removing edges from the
graph.json file, and, hopefully, we learnt something about D3 along the way. Get the full code in one file here.