-3

I have built a Gantt chart layout out and I need to be able to draw the connecting lines between the tasks. The tasks are just divs with a background color and height, width etc.. I will add attributes to the div's to specify which task is related to which.

How would I go about automatically drawing lines between the related tasks based on the offset of the task div's?

Is there some kind of library I could use for this or will I have to program it all manually if so where do I begin.

Bucket
  • 7,415
  • 9
  • 35
  • 45
user794846
  • 1,881
  • 5
  • 29
  • 72
  • 1
    "Drawing lines" requires a canvas and maybe 3js or something similar. A little research would tell you that. – Fallenreaper Mar 31 '14 at 15:32
  • hmm not really the lines could be div's. – user794846 Mar 31 '14 at 15:48
  • It wouldnt look that good to compute data, then transform abs positioned divs to the corresponding angles. I feel it is a rather nieve, computationally annoying approach. – Fallenreaper Mar 31 '14 at 15:49
  • You would most likely want to take a look at: http://stackoverflow.com/questions/6278152/drawing-a-line-between-two-draggable-divs but modify it as needed. – Fallenreaper Mar 31 '14 at 15:51
  • thanks that was a good link, a bit more than I need tho. Its lines similar to the arrow links in this I am trying to achieve http://gantt.twproject.com/distrib/gantt.html. Infact I am looking at his code right now to see how its done. – user794846 Mar 31 '14 at 15:56
  • as you can tell: http://stackoverflow.com/questions/19382872/how-to-connect-html-divs-with-lines points to the same place. You might want to look into it a bit more. :) Im sure you can define it to how you were wanting it to. – Fallenreaper Mar 31 '14 at 15:58
  • I'd suggest using `svg` for drawing charts – T J Mar 31 '14 at 16:27
  • In the end I just adapted code from the other gantt chart I linked. – user794846 Apr 01 '14 at 14:23
  • Possible duplicate of [Drawing a line between two divs](https://stackoverflow.com/questions/6278152/drawing-a-line-between-two-divs) – balupton Nov 05 '18 at 21:04

1 Answers1

0

In the end I adpated the code from here gantt.twproject.com/distrib/gantt.html to work with my own Gantt chart. The following sections is what I used. And this can be changed to work with any html based gantt chart I should think.

 /*********************************** Draw Link Elements **************************************/

var peduncolusSize = 5;
var lineSize = 0;


function drawlink (from, to, type) {

var rectFrom = buildRect(from);
var rectTo = buildRect(to);

// Dispatch to the correct renderer
if (type == 'start-to-start') {
    $("#gantt").append(
        drawStartToStart(rectFrom, rectTo, peduncolusSize)
    );
} else {
    $("#gantt").append(
        drawStartToEnd(rectFrom, rectTo, peduncolusSize)
    );
}

}

/**
* A representation of a Horizontal line
*/
HLine = function(width, top, left) {
var hl = $("<div>").addClass("taskDepLine");

hl.css({
    height: lineSize,
    left: left,
    width: width,
    top: top - lineSize / 2 -2 //added - 1
 });
  return hl;
 };

/**
* A representation of a Vertical line
*/

VLine = function(height, top, left) {
var vl = $("<div>").addClass("taskDepLine");

vl.css({
    height: height -2,//added -2
    left:left - lineSize / 2,
    width: lineSize,
    top: top
});
return vl;
 };

/**
* Given an item, extract its rendered position
* width and height into a structure.
*/
function buildRect(item) {
  var rect = item.position();
    rect.width = item.width();
  rect.height = item.height();

  return rect;
  }

 /**
   * The default rendering method, which paints a start to end dependency.
 *
 * @see buildRect
 */
 function drawStartToEnd(rectFrom, rectTo, peduncolusSize) {
 var left, top;
 var gheight = $('.main_table').innerHeight();
 var gleft = -5;

 var ndo = $("<div style='position: relative;'> </div>").css({
    "bottom":gheight,
    "left":-5
  });

var currentX = rectFrom.left + rectFrom.width;
var currentY = rectFrom.height / 2 + rectFrom.top;

var useThreeLine = (currentX + 2 * peduncolusSize) < rectTo.left;

if (!useThreeLine) {
    // L1
    if (peduncolusSize > 0) {
        var l1 = new HLine(peduncolusSize, currentY, currentX);
        currentX = currentX + peduncolusSize;
        ndo.append(l1);
    }

    // L2
    var l2_4size = ((rectTo.top + rectTo.height / 2) - (rectFrom.top + rectFrom.height / 2)) / 2;
    var l2;
    if (l2_4size < 0) {
        l2 = new VLine(-l2_4size, currentY + l2_4size, currentX);
    } else {
        l2 = new VLine(l2_4size, currentY, currentX);
    }
    currentY = currentY + l2_4size;

    ndo.append(l2);

    // L3
    var l3size = rectFrom.left + rectFrom.width + peduncolusSize - (rectTo.left - peduncolusSize);
    currentX = currentX - l3size;
    var l3 = new HLine(l3size, currentY, currentX);
    ndo.append(l3);

    // L4
    var l4;
    if (l2_4size < 0) {
        l4 = new VLine(-l2_4size, currentY + l2_4size, currentX);
    } else {
        l4 = new VLine(l2_4size, currentY, currentX);
    }
    ndo.append(l4);

    currentY = currentY + l2_4size;

    // L5
    if (peduncolusSize > 0) {
        var l5 = new HLine(peduncolusSize, currentY, currentX);
        currentX = currentX + peduncolusSize;
        ndo.append(l5);

    }
} else {
    //L1
    var l1_3Size = (rectTo.left - currentX) / 2;
    var l1 = new HLine(l1_3Size, currentY, currentX);
    currentX = currentX + l1_3Size;
    ndo.append(l1);

    //L2
    var l2Size = ((rectTo.top + rectTo.height / 2) - (rectFrom.top + rectFrom.height / 2));
    var l2;
    if (l2Size < 0) {
        l2 = new VLine(-l2Size, currentY + l2Size, currentX);
    } else {
        l2 = new VLine(l2Size, currentY, currentX);
    }
    ndo.append(l2);

    currentY = currentY + l2Size;

    //L3
    var l3 = new HLine(l1_3Size, currentY, currentX);
    currentX = currentX + l1_3Size;
    ndo.append(l3);
}

//arrow
var arr = $("<img src='custom/modules/Project/linkArrow.png'>").css({
    position: 'absolute',
    top: rectTo.top + rectTo.height / 2 - 6,//added -6
    left: rectTo.left - 5
});

ndo.append(arr);

return ndo;
 }

  /**
   * A rendering method which paints a start to start dependency.
   *
   * @see buildRect
   */
   function drawStartToStart(rectFrom, rectTo, peduncolusSize) {
      var left, top;
      var gheight = $('.main_table').innerHeight();
       var ndo = $("<div style='position: relative;'> </div>").css({
       "bottom":gheight,
      "left":-5
   });

var currentX = rectFrom.left;
var currentY = rectFrom.height / 2 + rectFrom.top;

var useThreeLine = (currentX + 2 * peduncolusSize) < rectTo.left;

if (!useThreeLine) {
    // L1
    if (peduncolusSize > 0) {
        var l1 = new HLine(peduncolusSize, currentY, currentX - peduncolusSize);
        currentX = currentX - peduncolusSize;
        ndo.append(l1);
    }

    // L2
    var l2_4size = ((rectTo.top + rectTo.height / 2) - (rectFrom.top + rectFrom.height / 2)) / 2;
    var l2;
    if (l2_4size < 0) {
        l2 = new VLine(-l2_4size, currentY + l2_4size, currentX);
    } else {
        l2 = new VLine(l2_4size, currentY, currentX);
    }
    currentY = currentY + l2_4size;

    ndo.append(l2);

    // L3
    var l3size = (rectFrom.left - peduncolusSize) - (rectTo.left - peduncolusSize);
    currentX = currentX - l3size;
    var l3 = new HLine(l3size, currentY, currentX);
    ndo.append(l3);

    // L4
    var l4;
    if (l2_4size < 0) {
        l4 = new VLine(-l2_4size, currentY + l2_4size, currentX);
    } else {
        l4 = new VLine(l2_4size, currentY, currentX);
    }
    ndo.append(l4);

    currentY = currentY + l2_4size;

    // L5
    if (peduncolusSize > 0) {
        var l5 = new HLine(peduncolusSize, currentY, currentX);
        currentX = currentX + peduncolusSize;
        ndo.append(l5);
    }
} else {
    //L1

    var l1 = new HLine(peduncolusSize, currentY, currentX - peduncolusSize);
    currentX = currentX - peduncolusSize;
    ndo.append(l1);

    //L2
    var l2Size = ((rectTo.top + rectTo.height / 2) - (rectFrom.top + rectFrom.height / 2));
    var l2;
    if (l2Size < 0) {
        l2 = new VLine(-l2Size, currentY + l2Size, currentX);
    } else {
        l2 = new VLine(l2Size, currentY, currentX);
    }
    ndo.append(l2);

    currentY = currentY + l2Size;

    //L3

    var l3 = new HLine((rectTo.left - rectFrom.left ), currentY, currentX);
    currentX = currentX + peduncolusSize + (rectTo.left - rectFrom.left);
    ndo.append(l3);
}

//arrow
var arr = $("<img src='custom/modules/Project/linkArrow.png'>").css({
    position: 'absolute',
    top: rectTo.top + rectTo.height / 2 - 6,//changed to -6
    left: rectTo.left - 5
});

ndo.append(arr);

return ndo;

}

user794846
  • 1,881
  • 5
  • 29
  • 72