简体   繁体   English

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

[英]jsPlumb/JQuery How to position arbitrary number of nodes?

I'm trying to implement Perimeter Anchors, and I finally got to the point where i have all nodes inside their shapes, connected as they should, and not overlapping, but I can't find how to disperse them more nicely on the page. 我正在尝试实现外围锚,最终到了要点,我将其形状内的所有节点都按需连接,并且没有重叠,但是我找不到如何在页面上更好地分散它们的方法。

I have 2 groups of nodes, each node in group 1 is connected to all related nodes in group 2. All the nodes appear one after another, with connections overlapping each other. 我有2组节点,组1中的每个节点都连接到组2中的所有相关节点。所有节点一个接一个地出现,连接彼此重叠。 I'm trying to follow the demo on github , and I see that each node has additional style attribute that positions it somewhere on the page, I can't find how, where or what adds this attribute. 我正在尝试按照github上演示进行操作 ,并且看到每个节点都具有其他样式属性,该属性将其放置在页面上的某个位置,我找不到如何,在何处或什么添加此属性。

How can I disperse the nodes in a nice way, so that they don't overlap each other? 我怎样才能很好地分散节点,使它们彼此不重叠?

This library might help: https://github.com/lndb/jsPlumb_Liviz.js 该库可能会有所帮助: https : //github.com/lndb/jsPlumb_Liviz.js

A combination of the jsPlumb library that connects elements with the Liviz.js for the positioning of these elements. jsPlumb库的组合,该库将元素与Liviz.js连接以定位这些元素。

In other words: using jsPlumb for the UI (connecting divs), and Liviz.js for the positioning of these elements (divs). 换句话说:对于用户界面(连接div)使用jsPlumb,对于这些元素(div)的定位使用Liviz.js。

I've never used this library before, but by looking into the API docs. 我以前从未使用过此库,而是通过研究API文档来使用。

Try setting the anchorCount to a smaller value, the default is 60 . 尝试将anchorCount设置为较小的值,默认值为60

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

This way the anchors will be more spread out in the shape. 这样,锚将在形状中更分散。

You could also check out the StateMachine Connector , which seems to have a proximity option and a curviness , probably both can help you avoid collisions. 您还可以查看StateMachine Connector ,它似乎具有一个proximity选项和一个curviness ,可能两者都可以帮助您避免碰撞。

I hope I understood your question 我希望我能理解你的问题

Ok, after long hours of banging my head on the wall, i finally got it. 好的,经过长时间的敲打,我终于明白了。 It's not perfect, and not wonderful, but essentially it does what i wanted it to, which is: place arbitrary number of nodes, wo them overlapping each other. 它不是完美的,也不是很棒的,但是从本质上来说,它可以实现我想要的功能,即:放置任意数量的节点,让它们彼此重叠。

First of all, jsPlumb doesn't position the nodes, it leaves it to you, it just connects them. 首先,jsPlumb不会放置节点,而是将其留给您,而只是将它们连接起来。 So, before running jsPlumb.connect(), I had to disperse the nodes using js and css. 因此,在运行jsPlumb.connect()之前,我不得不使用js和css分散节点。

Here is the code: 这是代码:

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: 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]);
        }
    }
}

What it's doing is: 它正在做什么:

  1. get all nodes i'm going to work with. 获取我要使用的所有节点。
  2. place first node, save it in set array. 放置第一个节点,将其保存在set数组中。
  3. place next node, add it to set and check that it doesn't overlap with other nodes in set array, if it does, keep it moving. 放置下一个节点,将其添加到set并检查它是否与set数组中的其他节点不重叠,如果存在,请使其继续移动。

When all nodes dispersed, I run jsPlumb.connect(), and voila, they are all connected. 当所有节点分散时,我运行jsPlumb.connect()和voila,它们都已连接。 I'm not blown with efficiency here, it takes time until it's done. 我对效率并不感到惊讶,要花些时间才能完成。 If anyone has any suggestions how to improve it I would love to hear it. 如果有人对如何改进它有任何建议,我很想听听。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM