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;
}
Creating network diagrams with D3.js
Tagged on:     

10 thoughts on “Creating network diagrams with D3.js

  • 2013-04-19 at 09:24
    Permalink

    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

    Reply
  • 2015-03-16 at 16:45
    Permalink

    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;
    }

    Reply
    • 2015-08-20 at 12:49
      Permalink

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

      Reply
    • 2016-08-05 at 09:15
      Permalink

      How to give images from json data?

      Reply
  • 2015-04-01 at 12:51
    Permalink

    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

    Reply
  • 2015-04-14 at 15:14
    Permalink

    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?

    Reply
  • 2015-06-26 at 07:35
    Permalink

    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

    Reply
  • 2019-03-28 at 15:07
    Permalink

    Hi, how can i create such a project using a spreadsheet data to create the nodes, links and arrow direction dynamically. Would love the help as its all meant to be packaged as an app.

    The generated network diagram can be interacted with to show the shortest links to things, a change in direction of arrow affects the spreadsheet data automatically

    Reply

Leave a Reply to Kailas Cancel reply

Your email address will not be published. Required fields are marked *