Canvas Tree

by rajeshpillai

HTML

<canvas id="canvas" width="1000" height="1000"></canvas>

<table>
    <tr>
        <td colspan="3"><span class="element">1</span>
        <span class="element">2</span></td>
        
    </tr>
   
    <tr>
        <td><span class="element">1.2.1</span></td>
        <td><span class="element">1.2.2</span></td>
        <td><span class="element">1.2.3</span></td>
    </tr>
    
</table>

CSS

canvas
{
    background-color: #FFFFFF;
    position: absolute;
    z-index: -10;
    /* control height and width in code to prevent stretching */
}

table {
    padding:0;
    text-align: center;
    border: 0px solid lightblue;
    margin: 0 auto;
    position: relative;
}

td {
    padding:40px;
    text-align: center;
    border: 0px solid lightblue;
}

span.element {
    position: relative;
    display: inline-block;
    width: 150px;
    height: 50px;
    border: 1px solid lightgreen;
    border-radius: 14px;
}

.anchor.connected {
   z-index: 1000;
   display: inline-block;
   width:5px;
   height:5px;
   border: 1px solid green;
   border-radius: 50%;
   background-color: rgb(100,255,100);
}


td span {
   padding: 10px;
}

JavaScript

$(function () {
   
    var bag = new Bag();
    var mainNode = new Node(50,50);
    
    bag.addNode(mainNode);
    
    bag.render();
   
});

function Bag() {
    this.nodes = [];
    this.canvas = $('#canvas');
    this.ctx = this.canvas[0].getContext('2d');
          
}

Bag.prototype.render = function () {
    for(var node in this.nodes) {
        node.draw();
    }
};

Bag.prototype.addNode = function (node) {
    this.nodes.push(node);
};

function Node (x,y) {
    this.x = x;
    this.y = y;
    this.bgcolor = "red";
}

Node.prototype.draw = function (ctx) {
    ctx.strokeRect(this.x,this.y, 50,50);
};

$(function () {
    
    var $elements = $(".element");
    
    
    var $first = $elements.first();
    
    var sPos = $first.offset();
    console.log(sPos);
    var $anchor = $("<span class='anchor' id='n0' />");
    $first.append($anchor);
    
    $anchor.css({
        position: "absolute",
        top: sPos.top +10,
        left: $first.width() + 10
    });
    
    addAnchors();
    
    connectBenzier($("#n0"), $("#id2"));
    connectBenzier($("#n0"), $("#id3"));
    connectBenzier($("#n0"), $("#id4"));
    
   
});

function connectBenzier(sourceElement, targetElement) {
    
     // mark the source and target as connected
     sourceElement.addClass("connected");
     targetElement.addClass("connected");
     //draw from/to the centre, not the top left
            //don't use .position()
            //that will be relative to the parent div and not the page
            var sourceX = sourceElement.offset().left + sourceElement.width() / 2;
            sourceX = sourceElement.offset().left + sourceElement.width()/2 + 10;
            
            var sourceY = sourceElement.offset().top + sourceElement.height() / 2;
            sourceY = sourceElement.offset().top + sourceElement.height() /2 + 10;

            var targetX = targetElement.offset().left + sourceElement.width() / 2;
            targetX = targetElement.offset().left +...