Нарисуйте линию между элементами автоматически, используя jquery или javascript

Я построил макет диаграммы Ганта, и мне нужно уметь рисовать соединительные линии между задачами. Задачи - это просто div с цветом фона и высотой, шириной и т. Д. Я добавлю атрибуты в div, чтобы указать, какая задача связана с какой.

Как бы я начал автоматически рисовать линии между связанными задачами на основе смещения элементов задач?

Есть ли какая-то библиотека, которую я мог бы использовать для этого, или мне придется программировать все вручную, если да, то с чего мне начать?

1 ответ

В конце я добавил код gantt.twproject.com/distrib/gantt.html для работы с моей собственной диаграммой Ганта. Следующие разделы - это то, что я использовал. И это может быть изменено для работы с любой диаграммой Ганта на основе HTML, я должен думать.

 /*********************************** 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;

}

Другие вопросы по тегам