jsPlumb/JQuery Как позиционировать произвольное количество узлов?
Я пытаюсь реализовать привязки по периметру, и, наконец, я дошел до того, что у меня есть все узлы внутри их фигур, соединенные так, как они должны, и не перекрывающиеся, но я не могу найти, как лучше распределить их по странице.
У меня есть 2 группы узлов, каждый узел в группе 1 связан со всеми связанными узлами в группе 2. Все узлы появляются один за другим, причем соединения перекрывают друг друга. Я пытаюсь следовать демонстрации на github, и я вижу, что у каждого узла есть дополнительный атрибут стиля, который размещает его где-то на странице, я не могу найти, как, где или что добавляет этот атрибут.
Как я могу хорошо распределить узлы, чтобы они не перекрывали друг друга?
3 ответа
Эта библиотека может помочь: https://github.com/lndb/jsPlumb_Liviz.js
Комбинация библиотеки jsPlumb, которая связывает элементы с Liviz.js для позиционирования этих элементов.
Другими словами: использование jsPlumb для пользовательского интерфейса (подключение divs) и Liviz.js для позиционирования этих элементов (div).
Хорошо, после долгих часов стуча головой о стену, я наконец-то понял. Он не идеален и не чудесен, но, по сути, он делает то, что хотел, а именно: размещает произвольное количество узлов, когда они перекрывают друг друга.
Прежде всего, 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]);
}
}
}
Что он делает:
- получить все узлы, с которыми я собираюсь работать.
- поместите первый узел, сохраните его в
set
массив. - разместить следующий узел, добавить его в
set
и убедитесь, что он не перекрывается с другими узлами вset
массив, если он это делает, продолжайте двигаться.
Когда все узлы разошлись, я запускаю jsPlumb.connect() и вуаля, они все связаны. Я не поражен эффективностью здесь, это занимает время, пока это не сделано. Если у кого-то есть предложения, как его улучшить, я бы с удовольствием его услышал.
Я никогда раньше не использовал эту библиотеку, но изучил документы API.
Попробуйте установить anchorCount
на меньшее значение, по умолчанию 60
,
[ "Perimeter", {
shape:$(shapes[i]).attr("data-shape"),
rotation:$(shapes[i]).attr("data-rotation"),
anchorCount: 30 }]
Таким образом якоря будут более разложены по форме.
Вы также можете проверить StateMachine Connector, который, кажется, имеет proximity
вариант и curviness
, вероятно, оба могут помочь вам избежать столкновений.
Надеюсь я понял твой вопрос