2015-05-05 17 views
11

Używam jointjs do tworzenia diagramów, które będą edytowalne przez użytkownika. Użytkownik może przeciągnąć je i przenieść każdą komórkę. Jednakże, gdy komórka jest przeciągnięta do krawędzi, przepełnia się i zostaje odcięta. Chcę temu zapobiec, zamiast tego komórka musi przestać, zanim dotrze do krawędzi papieru i nie będzie mogła przekroczyć krawędzi, przez co zawsze pozostanie całkowicie w papierze. Zachowanie można zaobserwować w bardzo własnych dema tutaj jointjs':W jaki sposób mogę zapobiec przepełnieniu papieru jointjs?

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

Spróbuj przeciągnąć komórkę do krawędzi, a zobaczysz, że w końcu zostanie ukryty, ponieważ przecina krawędź elementu papieru.

drugie, używam plugin dla skierowanego układ wykresu znaleźć tutaj:

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

Jak widać, pozycja drzewa automatycznie przesuwa się w lewym górnym rogu elementu papieru ilekroć click układ. Jak mogę zmienić te domyślne pozycje? Jedyne opcje, jakie widzę dla podanej funkcji to spacja między stopniami i przestrzeń między węzłami, brak pozycji początkowej. Powiedzmy, że chciałbym, aby drzewo pojawiło się w środku papieru po kliknięciu "layout", gdzie musiałbym dokonać zmian? Z góry dziękuję za pomoc.

Odpowiedz

5

Myślę, że moja poprzednia odpowiedź jest nadal możliwa, ale tak ją wdrożyłem w moim projekcie. Ma przewagę nad drugą odpowiedzią, ponieważ nie wymaga użycia niestandardowego elementView i wydaje się prostsze (dla mnie).

(robocza jsfiddle: http://jsfiddle.net/pL68gs2m/2/)

Na paper, obsłużyć zdarzenia cell:pointermove. W procedurze obsługi zdarzenia opracuj obwiednię obiektu cellView, w której wywołano zdarzenie, i użyj go, aby ograniczyć ruch.

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

Idealnie! Dzięki za zaktualizowaną odpowiedź! – dalvacoder

+0

Jeśli to zadziała, czy możesz nie zaakceptować odpowiedzi? Myślę, że byłoby lepiej, gdyby ludzie odwiedzający to pytanie w przyszłości zobaczyli drugą odpowiedź po raz pierwszy :) –

2

Edycja: Myślę, że to podejście jest nadal możliwe, ale teraz myślę, że moja druga odpowiedź jest prostsza/lepsza.

W JointJS docs dostarcza próbkę gdzie ruch kształcie jest contrained leżeć na elipsie:

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

Działa poprzez

  1. Definiowanie nowego widoku dla elementu , przedłużając joint.dia.ElementView
  2. Zastanawiając się nad zdarzeniem pointerdown i pointermove w celu wprowadzenia warunku int. Odbywa się to poprzez obliczenie nowej pozycji, na podstawie położenia myszy i ograniczenia, a następnie przechodząc tym do obsługi zdarzeń baza ElementView
  3. Zmuszanie paper użyć niestandardowego elementu Zobacz

Takie podejście może być łatwo dostosowany, aby zapobiec przeciągnięciu kształtu poza krawędź papieru. W kroku 2 zamiast obliczania przecięcia z elipsą, jak w samouczku, do obliczenia nowej pozycji można użyć wartości Math.min() lub Math.max().

+0

dzięki, wydaje się, że jest to droga, chociaż nadal nie ma pewności, jak go obliczyć, ale źle przechowywać aprowizacji z nim. – dalvacoder

+0

hmm. Mam do tego zaległości, aby to zrobić. było dość nisko, ale zobaczę, czy mogę go podnieść, a następnie opublikować rozwiązanie tutaj; o) –

+0

Awesome! Dzięki! – dalvacoder

5

I. Aby zapobiec przepełnieniu elementy papier można użyć restrictTranslate opcję papieru (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. Użyj opcji układu DirectedGraph, aby przesunąć lewy górny róg wynikowego wykresu, np. Dodaj margines w lewo i górę.

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

3

Jako dodatek do odpowiedzi Romana, restrictTranslate może być również skonfigurowane jako true aby ograniczyć ruch elementów do granicy obszaru papieru.

Przykład:

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