JSFiddle - React, Tailwind, and code Playground

by Ameet Rana

HTML

<script src="http://code.jquery.com/jquery-2.0.3.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
<div class="container">
    <div class="todoList">
        <div >
            <ul>
                <li class="dragElement" id="1">1</li>
                <li class="dragElement" id="2">2</li>
                <li class="dragElement" id="3">3</li>
                <li class="dragElement" id="4">4</li>
                <li class="dragElement" id="5">5</li>
                <li class="dragElement" id="6">6</li>
                <li class="dragElement" id="7">7</li>
            </ul>
        </div>
    </div>
    <div class="nodePaneContainer">
        <div id="nodePane">

        </div>
    </div>
    <div class="clear"></div>
</div>

CSS

.container {
    height: 95%;
    margin: auto;
    min-width: 900px;
    padding: 10px;
    position: absolute;
    width: 97%;
}
.todoList {
    border: 1px solid;
    float: left;
    height: 100%;
    width: 300px;
}
.list {
    /*overflow: auto;*/
    height: 100%;
    position: relative;
}
.nodePaneContainer {
    border: 1px solid;
    overflow: hidden;
    height: 100%;
    margin-left: 320px;
    width: -webkit-calc(93% - 255px);
    width: -moz-calc(93% - 255px);
    width: calc(93% - 255px);
}
.clear {
    clear: both;
}
.dragElement {
    padding: 10px;
}
.drangNode {
    overflow: visible;
    width: 90px;
    height: 90px;
}
g.node circle {
    stroke:gray;
    cursor:pointer;
}
g.node circle.inner {
    fill : white;
}
g.node.hover circle.inner {
    fill : aliceblue;
}
g.node circle.outer {
    stroke-width : 0px;
    stroke-dasharray: 4px;
    stroke-opacity : 0.5;
    fill : transparent;
}
g.node.selected circle.outer {
    stroke-width : 1px;
}
g.node text {
    font : 12px sans-serif;
    font-weight : bold;
    pointer-events : none;
}
path.transition, path.dragline {
    fill : none;
    stroke : #000;
    stroke-width: 1px;
    cursor : default;
    marker-end : url(#end-arrow);
}
path.dragline {
    pointer-events: none;
}
path.dragline.hidden {
    stroke-width: 0;
}
/* disable text selection */
svg *::selection {
    background : transparent;
}
svg *::-moz-selection {
    background:transparent;
}
svg *::-webkit-selection {
    background:transparent;
}

JavaScript

$(document).ready(function () {
    var nodes = [{x:50, y: 50,label:'test',
                  transitions: []}];
    var selected = {};
    var radius = 40;

    $( window ).resize(function() {
           restart();
    });

    $('.dragElement').draggable({
        cursorAt: {
            top: 40,
            left: 40
        },
        cursor: 'move',
        helper: function (event) {
            var elem = this.id;
            selected.id = this.id
            var dragSVG = '<svg xmlns="http://www.w3.org/2000/svg" class="drangNode">' +
                '<g class="node" transform="translate(44,44)">' +
                '<circle r="44" class="outer"/>' +
                '<circle r="40" class="inner"/>' +
                '<text text-anchor="middle" y="4">' + this.id + '</text>' +
                '</g>' +
                '</svg>';
            return dragSVG;
        }
    });

    $(".nodePaneContainer").droppable({
        // tolerance can be set to 'fit', 'intersect', 'pointer', or 'touch'
        tolerance: 'intersect',

        over: function (event, ui) {
            var posX = event.originalEvent.clientX - $(this).offset().left;
            var posY = event.originalEvent.clientY - $(this).offset().top;
            console.log(posX, posY);
        },

        out: function (event, ui) {
            console.log("out");
        },

        drop: function (event, ui) {
            var posX = event.originalEvent.clientX - $(this).offset().left;
            var posY = event.originalEvent.clientY - $(this).offset().top;
            nodes.push({
                x: posX,
                y: posY,
                label: selected.id,
                transitions: []
            });
            restart();
        }
    });


    var svg = d3.select('#nodePane')
        .append("svg")
        .attr("width", function () {
            return $(".nodePaneContainer").width();
        })
        .attr("height", function () {
            return $(".nodePaneContainer").height();
 ...