JSFiddle - React, Tailwind, and code Playground

by Cyril Cherian

HTML

<button id="addButton">Add Person</button>

CSS

.link {
    stroke: #ccc;
}
.node text {
    pointer-events: none;
}

JavaScript

var scope = {};

scope.nodes = [];
scope.links = [];

var width = 960,
    height = 500;

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

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

function renderGraph(resume) {
    force.nodes(scope.nodes)
        .links(scope.links)
        .start();

    var link = svg.selectAll(".link")
        .data(scope.links)
    link.enter().append("line")
        .attr("class", "link");

    var node = svg.selectAll(".node")
        .data(scope.nodes);
    var nodeg = node.enter().append("g")
        .attr("class", "node")
        .call(force.drag);

    nodeg.append("image")
        .attr("xlink:href", function (d) {
        return d.avatar || 'https://github.com/favicon.ico'
    })
        .attr("x", -56)
        .attr("y", -8)
        .attr("width", 64)
        .attr("height", 64);

    nodeg.append("text")
        .attr("dx", 12)
        .attr("dy", ".35em")
        .text(function (d) {
        return d._id === scope.user.profile._id ? 'You' : d.firstName + ' ' + d.lastName
    });
    force.on("tick", function () {
        link.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;
        });

        node.attr("transform", function (d) {
            return "translate(" + d.x + "," + d.y + ")";
        });
    });

}

scope.user = {
    profile: {
        _id: 1,
        firstName: 'Bob',
        lastName: 'Smith'
    }
};
scope.nodes.push(scope.user.profile);

renderGraph();

var b = document.getElementById("addButton");
b.onclick = addPerson;

function addPerson() {
    scope.nodes.push({
        _id: 2,
        firstName: 'Jane',
        lastName: 'Smith'
    });
   ...