JSFiddle - React, Tailwind, and code Playground

HTML

<script src="http://d3js.org/d3.v3.min.js"></script>
<body>
    <div id="tree-container"></div>
</body>

CSS

.node {
    cursor: pointer;
}
.overlay {
    background-color:#EEE;
}
.node circle {
    fill: #fff;
    stroke: steelblue;
    stroke-width: 1.5px;
}
.node text {
    font-size:10px;
    font-family:sans-serif;
}
.link {
    fill: none;
    stroke: #ccc;
    stroke-width: 1.5px;
}
.templink {
    fill: none;
    stroke: red;
    stroke-width: 3px;
}
.ghostCircle.show {
    display:block;
}
.ghostCircle, .activeDrag .ghostCircle {
    display: none;
}

JavaScript

function makeTree(links) {
    var nodesByName = {};

    links.forEach(function (link) {
        var parent = link.source = nodeByName(link.source),
            child = link.target = nodeByName(link.target);
        if (parent.children) parent.children.push(child);
        else parent.children = [child];
    });

    return links;

    function nodeByName(name) {
        return nodesByName[name] || (nodesByName[name] = {
            name: name
        });
    }
}

function dndTree(treeData) {
    // Calculate total nodes, max label length
    var totalNodes = 0;
    var maxLabelLength = 0;
    // variables for drag/drop
    var selectedNode = null;
    var draggingNode = null;
    // panning variables
    var panSpeed = 200;
    var panBoundary = 20; // Within 20px from edges will pan when dragging.
    // Misc. variables
    var i = 0;
    var duration = 750;
    var root;

    // size of the diagram
    var viewerWidth = $(document).width();
    var viewerHeight = $(document).height();

    var tree = d3.layout.tree()
        .size([viewerHeight, viewerWidth]);

    // define a d3 diagonal projection for use by the node paths later on.
    var diagonal = d3.svg.diagonal()
        .projection(function (d) {
        return [d.y, d.x];
    });

    // A recursive helper function for performing some setup by walking through all nodes

    function visit(parent, visitFn, childrenFn) {
        if (!parent) return;

        visitFn(parent);

        var children = childrenFn(parent);
        if (children) {
            var count = children.length;
            for (var i = 0; i < count; i++) {
                visit(children[i], visitFn, childrenFn);
            }
        }
    }

    // Call visit function to establish maxLabelLength
    visit(treeData, function (d) {
        totalNodes++;
        maxLabelLength = Math.max(d.name.length, maxLabelLength);

    }, function (d) {
        return d.children && d.children.length > 0 ? d.children : null;
    });

    // sort...