2015-05-05 12 views
11

Sto usando jointjs per creare diagrammi che possono essere modificati dall'utente. L'utente può trascinarli e riposizionare ogni cella. Tuttavia, quando una cella viene trascinata fino al bordo, questa viene espulsa e viene tagliata. Voglio evitare che ciò accada, invece che la cella si fermi prima che arrivi al bordo del foglio e non sia permesso di attraversare il bordo, rimanendo così sempre completamente all'interno del foglio. Il comportamento può essere visto in molto proprio demo jointjs' qui:Come posso evitare che le celle jointjs trabocchino la carta?

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

provare a trascinare la cella a bordo e vedrete che alla fine viene nascosto mentre attraversa il bordo del elemento in carta.

In secondo luogo, sto usando il plugin per il layout grafo orientato, trovato qui:

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

Come si può vedere, la posizione albero si sposta automaticamente in alto a sinistra del elemento di carta ogni volta che il clic disposizione. Come posso modificare queste posizioni predefinite? Le uniche opzioni che vedo per la funzione fornita sono lo spazio tra i ranghi e lo spazio tra i nodi, nessuna posizione iniziale. Diciamo che volevo che l'albero appaia nel mezzo del foglio quando si fa clic su 'layout', dove dovrei apportare modifiche? Grazie in anticipo per qualsiasi aiuto.

risposta

5

Penso che la mia risposta precedente sia ancora fattibile, ma è così che l'ho implementata nel mio progetto. Ha un vantaggio rispetto all'altra risposta in quanto non richiede l'uso di una personalizzata elementView e sembra più semplice (per me).

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

Sul paper, gestire l'evento cell:pointermove. Nel gestore dell'evento, elaborare il riquadro di delimitazione dello cellView su cui è stato attivato l'evento e utilizzarlo per limitare il movimento.

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

Perfetto! Grazie per la risposta aggiornata! – dalvacoder

+0

Se funziona, potresti annullare la risposta myprevious? Penso che sarebbe meglio se le persone che visitassero questa domanda in futuro vedessero prima la seconda risposta :) –

2

Edit: Penso che questo approccio sia ancora fattibile, ma ora penso che l'altra risposta sia più semplice/migliore.

I JointJS documenti forniscono un campione in cui il movimento di una forma è contrained a mentire sul un'ellisse:

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

Agisce

  1. Definizione di una nuova visione per il vostro elemento , che si estende joint.dia.ElementView
  2. Over the pointerdown e pointermove evento nella vista per implementare il vincolo Int. Questo viene fatto calcolando una nuova posizione, in base alla posizione del mouse e il vincolo, e poi passare questo alla base ElementView gestore di eventi
  3. Forzare il paper di utilizzare la vostra abitudine vista elemento

Questo approccio può essere facilmente adattato per evitare che una forma venga trascinata fuori dal bordo del foglio. Nel passaggio 2, invece di calcolare l'intersezione con l'ellisse come nell'esercitazione, utilizzare Math.min() o Math.max() per calcolare una nuova posizione.

+0

grazie, sembra come questo è la strada da percorrere, anche se ancora sicuri di come calcolarlo ma mal tenere pasticciano con esso. – dalvacoder

+0

hmm. Ho un articolo sul mio backlog per fare questo. era abbastanza basso, ma vedrò se riesco a spingerlo su e quindi postare la soluzione qui; o) –

+0

Fantastico! Grazie! – dalvacoder

5

I. Per evitare che gli elementi da traboccante la carta si potrebbe utilizzare restrictTranslate carta opzionale (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. Usa marginX e marginY Opzioni di layout DirectedGraph per spostare l'angolo in alto a sinistra del grafico risultante, ad esempio aggiungi margine a sinistra e in alto.

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

3

In aggiunta alla risposta di Romano, restrictTranslate può anche essere configurato come true per limitare il movimento degli elementi al confine della zona di carta.

Esempio:

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