2015-05-05 3 views
11

Я использую jointjs для создания диаграмм, которые будут доступны для редактирования. Пользователь может перетащить их и переместить каждую ячейку. Однако, когда ячейка перетаскивается к краю, она переполняется и обрезается. Я хочу, чтобы это не происходило, вместо того, чтобы клетка останавливалась, прежде чем она попала на край бумаги, и ей не разрешили пересечь край, таким образом, всегда оставаясь полностью в бумаге. Поведение можно увидеть в очень собственных демо jointjs' здесь:Как я могу удерживать клетки сустава от переполнения бумаги?

http://www.jointjs.com/tutorial/ports

Попробуйте перетащить ячейку к краю, и вы увидите, что он в конце концов становится скрыт, как она пересекает край бумажного элемента.

Во-вторых, я использую плагин для направленного макет графа, здесь:

http://jointjs.com/rappid/docs/layout/directedGraph

Как вы можете видеть, положение дерева автоматически перемещается в левой верхней части бумажного элемента всякий раз, когда ваш клик раскладка. Как изменить эти позиции по умолчанию? Единственными параметрами, которые я вижу для предоставленной функции, являются пространство между рангами и пространством между узлами, без начального положения. Скажем, я хотел, чтобы дерево появилось в середине бумаги, щелкнув «макет», где мне нужно было внести изменения? Заранее благодарю за любую помощь.

ответ

5

Я думаю, что мой предыдущий ответ по-прежнему возможен, но так я реализовал его в своем проекте. Он имеет преимущество перед другим ответом в том, что он не требует от вас использования пользовательского elementView и кажется более простым (для меня).

(Рабочая jsfiddle: http://jsfiddle.net/pL68gs2m/2/)

На paper, обрабатывать cell:pointermove событие. В обработчике событий создайте ограничивающий прямоугольник cellView, на котором было инициировано событие, и используйте его для ограничения движения.

var graph = new joint.dia.Graph; 

var width = 400; 
var height = 400; 
var gridSize = 1; 

var paper = new joint.dia.Paper({ 
    el: $('#paper'), 
    width: width, 
    height: height, 
    model: graph, 
    gridSize: gridSize 
}); 

paper.on('cell:pointermove', function (cellView, evt, x, y) { 

    var bbox = cellView.getBBox(); 
    var constrained = false; 

    var constrainedX = x; 

    if (bbox.x <= 0) { constrainedX = x + gridSize; constrained = true } 
    if (bbox.x + bbox.width >= width) { constrainedX = x - gridSize; constrained = true } 

    var constrainedY = y; 

    if (bbox.y <= 0) { constrainedY = y + gridSize; constrained = true } 
    if (bbox.y + bbox.height >= height) { constrainedY = y - gridSize; constrained = true } 

    //if you fire the event all the time you get a stack overflow 
    if (constrained) { cellView.pointermove(evt, constrainedX, constrainedY) } 
}); 
+0

Отлично! Спасибо за обновленный ответ! – dalvacoder

+0

Если это работает, вы могли бы оставить неприемлемый ответ? Я думаю, было бы лучше, если бы люди, посетившие этот вопрос в будущем, увидели второй ответ первым :) –

2

Редактировать: Я думаю, что этот подход по-прежнему возможен, но теперь я думаю, что мой другой ответ проще/лучше.

В JointJS документы обеспечивают образец, где движение формы является contrained лежать на эллипсе:

http://www.jointjs.com/tutorial/constraint-move-to-circle

Он работает по

  1. Определяя новый взгляд для вашего элемента , удлинение joint.dia.ElementView
  2. Превышение pointerdown и pointermove событий в представлении для реализации ограничения внутр. Это делается путем вычисления нового положения, на основе положения мыши и ограничения, а затем передать это базовый ElementView обработчик события
  3. Принуждение paper использовать ваш пользовательский вид ЭЛЕМЕНТ

Этот подход может быть легко адаптируется для предотвращения вытягивания фигуры с края бумаги. На шаге 2 вместо вычисления пересечения с эллипсом, как в учебнике, вы должны использовать Math.min() или Math.max() для расчета новой позиции.

+0

спасибо, кажется, что это путь, хотя до сих пор не уверены в том, как вычислить его, но плохо держать баловаться с ней. – dalvacoder

+0

hmm. У меня есть элемент на моем отставании, чтобы сделать это. это было довольно низко, но я посмотрю, смогу ли я его подтолкнуть, а затем опубликую решение здесь: o) –

+0

Удивительный! Благодаря! – dalvacoder

5

I. Чтобы предотвратить элементы от переполненности бумагу можно использовать restrictTranslate бумаги вариант (JointJS v0.9.7 +).

paper.options.restrictTranslate = function(cellView) { 
    // move element inside the bounding box of the paper element only 
    return cellView.paper.getArea(); 
} 

http://jointjs.com/api#joint.dia.Paper:options

II. Используйте marginX и marginY Параметры макета DirectedGraph для перемещения левого верхнего угла результирующего графика, то есть добавьте маржу слева и сверху.

http://jointjs.com/rappid/docs/layout/directedGraph#configuration

3

В дополнение к ответу Романа, restrictTranslate также может быть настроен как true ограничить перемещение элементов на границе области бумаги.

Пример:

var paper = new joint.dia.Paper({ 
    el: $('#paper'), 
    width: 600, 
    height: 400, 
    model: graph, 
    restrictTranslate: true 
})