jsPlumb / JQuery如何定位任意数量的节点?

时间:2013-01-29 18:05:59

标签: javascript jquery jsplumb

我正在尝试实施Perimeter Anchors,我终于达到了这样的程度,即我的所有节点都在它们的形状内,按照它们应该连接,而不是重叠,但我找不到如何更好地驱散它们这页纸。

我有2组节点,组1中的每个节点都连接到组2中的所有相关节点。所有节点一个接一个地出现,连接彼此重叠。我正在尝试关注demo on github,我发现每个节点都有额外的样式属性,将其定位在页面的某个位置,我无法找到添加此属性的方式,位置或内容。

如何以一种很好的方式分散节点,使它们不会相互重叠?

3 个答案:

答案 0 :(得分:1)

此库可能有所帮助:https://github.com/lndb/jsPlumb_Liviz.js

  

将元素与Liviz.js连接起来的jsPlumb库的组合,用于定位这些元素。

     

换句话说:使用jsPlumb作为UI(连接div),使用Liviz.js来定位这些元素(div)。

答案 1 :(得分:0)

我之前从未使用过这个库,但是通过查看API文档。

尝试将anchorCount设置为较小的值,默认值为60

[ "Perimeter", {
      shape:$(shapes[i]).attr("data-shape"),
      rotation:$(shapes[i]).attr("data-rotation"),
      anchorCount: 30 }]

这样锚的形状会更加展开。

您还可以查看StateMachine Connector,它似乎有proximity选项和curviness,可能两者都可以帮助您避免碰撞。

我希望我理解你的问题

答案 2 :(得分:0)

好吧,经过长时间的敲打我的头,我终于得到了它。它并不完美,并不精彩,但基本上它可以实现我想要的,即:放置任意数量的节点,w。它们相互重叠。

首先,jsPlumb不会定位节点,它会将它留给您,它只是连接它们。所以,在运行jsPlumb.connect()之前,我不得不使用js和css来分散节点。

以下是代码:

CSS:

.group1, .group2 {
    z-index:6;
    opacity:0.7;
    filter:alpha(opacity=70);
    position:absolute;
    cursor:pointer;
    text-align:center;
    color:#333;
}

[data-shape=ellipse] {
    width:210px;
    height:70px;
    left:250px;
    top:300px;
    line-height: 70px;
    background-image:url(../img/ellipse.png);
}

[data-shape=circle] {
    width:70px;
    height:70px;
    left:100px;
    top:60px;
    line-height: 60px;
    background-image:url(../img/circle.png);
}

#chart {
    width:80%;
    height:50em;
    margin-left:3em;
    margin-top:3em;
    position:relative;
}

JS:

function random_width() {
    return Math.floor(Math.random() * (900 - 200) + 200);
}

function random_height() {
    return Math.floor(Math.random() * (700 - 200) + 200);
}

function overlap (el1, el2) {
    var x1 = $(el1).offset().left;
    var x2 = x1 + $(el1).width();
    var y1 = $(el1).offset().top;
    var y2 = y1 + $(el1).height();

    var x3 = $(el2).offset().left;
    var x4 = $(el2).width() + x3;
    var y3 = $(el2).offset().top;
    var y4 = $(el2).height() + y3;

    if (x3 > x3 || x4 < x1) { return false; } //overlap not possible
    if (y3 > y2 || y4 < y1) { return false; } //overlap not possible

    if (x3 > x1 && x3 < x2) { return true; }
    if (x4 > x1 && x4 < x2) { return true; }

    if (y3 > y1 && y3 < y2) { return true; }
    if (y4 > y1 && y4 < y2) { return true; }
}

function change_position(el) {
    $(el).css({'left': random_width(), 'top': random_height()});
}

function have_overlap(els) {
    for (var k = 0; k < els.length; k++) {
        for (var t = 0; t < els.length; t++){
            if (k !== t && overlap(els[k], els[t])){
                return true;
            }
        }
    }

    return false;
}

function disperse() {
    var group1 = $('.group1');
    var group2 = $('group2');
    var divs = $.merge(group1, group2);
    var set = [];

    console.log('dispersing');
    for (var i = 0; i < divs.length; i++) {
        set.push(divs[i]);
        change_position(divs[i]);
        while (have_overlap(set)) {
            change_position(divs[i]);
        }
    }
}

它正在做的是:

  1. 获取我将要使用的所有节点。
  2. 放置第一个节点,将其保存在set数组中。
  3. 放置下一个节点,将其添加到set并检查它是否与set数组中的其他节点重叠,如果有,请继续移动。
  4. 当所有节点分散后,我运行jsPlumb.connect(),瞧,它们都是连接的。 我在这里没有效率,它需要时间才能完成。如果有人有任何建议如何改进它,我很乐意听到它。