JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<div id="tree-container">

</div>
<button id="zoomIn">
Zoom In
</button>
<button id="zoomOut">
Zoom Out
</button>

CSS

#tree-container{width:300px;height:300px}
rect.selection {
    stroke          : gray;
    stroke-dasharray: 4px;
    stroke-opacity  : 0.5;
    fill            : transparent;
}
g.ci-node-element circle.outer {
    display         : none;
    stroke-dasharray: 4px;
    stroke-opacity  : 1;
    stroke-width : 1.5px;
    fill            : transparent;
}

g.ci-node-element.selectedNode circle.outer {
    display         : inline;
    stroke:gray;
}

JavaScript

var tree = d3.layout.tree().size([200,200]);
markerWidth =6;
markerHeight = 6;
cRadius =16;


svg = d3.select("#tree-container").append("svg")
            .attr("width", 500)
            .attr("height", 500)
            .attr("class", "overlay main-tree-svg-box");
    
svg.on( "mousedown", function() {
        	if( !d3.event.ctrlKey) {
                d3.selectAll(			  'g.selectedNode').classed("selectedNode", false);
            }
          var p = d3.mouse( this);
            svg.append( "rect")
            .attr({
                rx      : 6,
                ry      : 6,
                class   : "selection",
                x       : p[0],
                y       : p[1],
                width   : 0,
                height  : 0
            })
            .attr('stroke','gray')
            .attr('stroke-dasharray','4px')
            .attr('stroke-opacity','0.5')
            .attr('fill','transparent')
        })
        .on( "mousemove", function() {
        	   var s = svg.select( "rect.selection");

            if( !s.empty()) {
                var p = d3.mouse( this),
                    d = {
                        x       : parseInt( s.attr( "x"), 10),
                        y       : parseInt( s.attr( "y"), 10),
                        width   : parseInt( s.attr( "width"), 10),
                        height  : parseInt( s.attr( "height"), 10)
                    },
                    move = {
                        x : p[0] - d.x,
                        y : p[1] - d.y
                    }
                ;

                if( move.x < 1 || (move.x*2<d.width)) {
                    d.x = p[0];
                    d.width -= move.x;
                } else {
                    d.width = move.x;       
                }

                if( move.y < 1 || (move.y*2<d.height)) {
                    d.y = p[1];
                    d.height -= move.y;
                } else {
                    d.height = move.y;       
                }
              ...