Creating network diagrams with D3.js

D3.js is a JavaScript library for manipulating documents based on data. It can be used for all sorts of visualizations including network diagrams. In this article we will create a network diagram with nodes and directed links between them, visualized by circles and lines with arrowheads. We start with the file index.html that holds the HTML and basic SVG structure:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8">
        <title>Cloud</title>
        <script type="text/javascript" src="d3.v2.js"></script>
    </head>
    <body>
        <svg id="cloud" width="800" height="600">
            <defs>
                <marker id="arrow" viewbox="0 -5 10 10" refX="18" refY="0"
                        markerWidth="6" markerHeight="6" orient="auto">
                    <path d="M0,-5L10,0L0,5Z">
                </marker>
           </defs>
        </svg>
        <link href="cloud.css" rel="stylesheet" type="text/css" />
        <script src="cloud.js" type="text/javascript"></script>
    </body>
</html>

The file cloud.js contains the Javascript code to generate the SVG code according to some JSON content:

var width = 1200;
var height = 800;

var color = d3.scale.category10();

var force = d3.layout.force()
    .charge(-180)
    .linkDistance(70)
    .size([width, height]);

var svg = d3.select("#cloud");

d3.json("cloud.json", function(json) {
    force
        .nodes(json.nodes)
        .links(json.links)
        .start();

    var links = svg.append("g").selectAll("line.link")
        .data(force.links())
        .enter().append("line")
        .attr("class", "link")
        .attr("marker-end", "url(#arrow)");

    var nodes = svg.selectAll("circle.node")
        .data(force.nodes())
        .enter().append("circle")
        .attr("class", "node")
        .attr("r", 8)
        .style("fill", function(d) { return color(d.group); })
        .call(force.drag);

    nodes.append("title")
        .text(function(d) { return d.name; });

    force.on("tick", function() {
        links.attr("x1", function(d) { return d.source.x; })
            .attr("y1", function(d) { return d.source.y; })
            .attr("x2", function(d) { return d.target.x; })
            .attr("y2", function(d) { return d.target.y; });

        nodes.attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; });
    });
});

The file cloud.json contains the JSON that the Javascript uses to create SVG:

{
    "nodes":
        [
            {"name":"Client 1",       "group":1},
            {"name":"Loadbalancer 1", "group":2},
            {"name":"Webserver 1",    "group":3},
            {"name":"Webserver 2",    "group":3}
        ],
    "links":
        [
            {"source":0, "target":1, "value":1},
            {"source":1, "target":2, "value":1},
            {"source":1, "target":3, "value":1}
        ]
}

The final file cloud.css contains the CSS to make things more pretty:

circle.node {
    stroke: #fff;
    stroke-width: 3px;
}

line.link {
    stroke-width: 2px;
    stroke: #999;
    stroke-opacity: 0.6;
}

marker#arrow {
    stroke: #999;
    fill: #999;
}

9 thoughts on “Creating network diagrams with D3.js

  1. Permalink  ⋅ Reply

    João

    April 19, 2013 at 9:24am

    Hi,

    Awesome tutorial.. What if i want to add the name of the node to appear inside the node itself????

    Thanks for the tutorial,
    João

  2. Permalink  ⋅ Reply

    Jacob Briggs

    March 16, 2015 at 4:45pm

    Joao, here you go:

    cloud.js

    var width = 1200;
    var height = 800;

    var color = d3.scale.category10();

    var force = d3.layout.force()
    .charge(-180)
    .linkDistance(70)
    .size([width, height]);

    var svg = d3.select("#cloud");

    d3.json("cloud.json", function(json) {
    force
    .nodes(json.nodes)
    .links(json.links)
    .start();

    var links = svg.append("g").selectAll("line.link")
    .data(force.links())
    .enter().append("line")
    .attr("class", "link")
    .attr("marker-end", "url(#arrow)");

    var nodes = svg.append("g").selectAll("circle.node")
    .data(force.nodes())
    .enter().append("circle")
    .attr("class", "node")
    .attr("r", 8)
    .style("fill", function(d) { return color(d.group); })
    .call(force.drag);

    var texts = svg.append("g").selectAll("circle.node")
    .data(force.nodes())
    .enter().append("text")
    .attr("class", "label")
    .text(function(d) { return d.name; })
    .call(force.drag);

    force.on("tick", function() {
    links.attr("x1", function(d) { return d.source.x; })
    .attr("y1", function(d) { return d.source.y; })
    .attr("x2", function(d) { return d.target.x; })
    .attr("y2", function(d) { return d.target.y; });

    nodes.attr("cx", function(d) { return d.x; })
    .attr("cy", function(d) { return d.y; });

    texts.attr("x", function(d) { return d.x; })
    .attr("y", function(d) { return d.y; });
    });
    });

    cloud.css

    circle.node {
    stroke: #fff;
    stroke-width: 3px;
    }

    line.link {
    stroke-width: 2px;
    stroke: #999;
    stroke-opacity: 0.6;
    }

    text.label {
    font: 10px sans-serif;
    pointer-events: none;
    text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
    }

    marker#arrow {
    stroke: #999;
    fill: #999;
    }

    • Permalink  ⋅ Reply

      Rakesh Ranjan

      August 20, 2015 at 12:49pm

      How to make marker for arrow in script tag so that i can change its color(fill) dynamically

    • Permalink  ⋅ Reply

      Rithvika

      August 5, 2016 at 9:15am

      How to give images from json data?

  3. Permalink  ⋅ Reply

    Knut

    April 1, 2015 at 12:51pm

    Thanks a ton for this template!
    I struggled for quite some time with the dragging behavior of the labels… :-/ But now it’s up and running.

    Groetjes,
    Knut

  4. Permalink  ⋅ Reply

    Poyal Biswas

    April 14, 2015 at 3:14pm

    I am trying to develop a similar kind of project in eclipse. I just wanted to know the directory structure, as in where should the css files be located and where will my json data be kept?

  5. Permalink  ⋅ Reply

    Suyash

    June 26, 2015 at 7:35am

    hello
    i want to display connection among nodes like a central node is connected to subnodes …i want to display it with sequence diagram..
    can u please provide me one template to implement it

Leave a Reply

Your email will not be published. Name and Email fields are required.