2012-11-21 21 views
11

Penso che molti di voi, che hanno lavorato con D3.js, abbiano già sperimentato la stessa cosa: la vostra rete o gli elementi mobili che avete preso continuano a volare fuori dall'elemento svg se vengono spinti a difficile. Se la mia rete è troppo grande, i nodi esterni scompaiono, sono una sorta di "caduta del bordo del mondo".Bounding box in D3.js

Sono abbastanza shure c'è un modo per rendere il confine del svg un solido 'muro', in modo da elementi non possono lasciare e volare attraverso lo spazio invisibile :)

Che cosa hai fatto con questo problema? come l'hai risolto?

Grazie in anticipo, David

risposta

13

Alla fine, se trovate i siti giusti sul web è abbastanza facile. http://bl.ocks.org/1129492 fa esattamente quello che volevo - gli oggetti non possono scivolare fuori dallo svg. Quindi ha appena aggiunto alcuni vincoli durante l'aggiornamento delle posizioni dei nodi. mia funzione 'tick' finito come

node.attr("cx", function(d) { return d.x = Math.max(15, Math.min(width - 15, d.x)); }) 
    .attr("cy", function(d) { return d.y = Math.max(15, Math.min(height - 15, d.y)); }); 

link.attr("x1", function(d) { return d.source.x; }) 
    .attr("y1", function(d) { return d.source.y; }) 
    .attr("x2", function(d) { return d.target.x; }) 
    .attr("y2", function(d) { return d.target.y; }); 

node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 

Questo è chiamato ogni volta che qualcosa di importante potrebbe accadere, il "battito" -thing è qualcosa di costruito da qualche parte nel profondo d3.js, quindi non chiedete a me di questo. :)

Le prime due righe e l'ultima nel codice specificato verificano che le coordinate non escano dalla scatola.

Spero che questo possa aiutare qualcuno là fuori per fare il lavoro più velocemente di quanto ho fatto io;)

avere un buon tempo, Dave

+0

Grazie @David .. risposta davvero utile. lo stavo cercando da molti giorni. – Jaydipsinh

0

Il modo generale per risolvere grafico visualizzazione scappando da te è quello di ottenere il rettangolo di selezione, quindi creare una trasformazione sul SVG che mappa il rettangolo di selezione sulla finestra esattamente (tenendo il rapporto di aspetto bloccato a un valore vagamente ragionevole).

Se l'utente esegue lo zoom, si dimentica di questo processo.

Il risultato sarà che se "roba" vola via, in effetti lo vedrai ingrandito. E l'utente può zoomare a loro piacimento.

La chiave per ottenere questo funziona bene è scrivere un grafico di stato. Quando qualcosa fa scattare un ricalcolo, vai nella modalità "aggiusta la scatola di delimitazione", e quando i grafici smettono di spostarsi, passa alla modalità "controlli utente zoom". Ottenere questo per funzionare bene significa ottenere le transizioni tra gli stati giusto (fornire sempre un override per gli utenti avanzati).

+0

Grazie per l'assisstance! Ora ho trovato esattamente quello che volevo e funziona senza zoom. Ho pensato che fosse molto più difficile, ma si è rivelato molto facile controllare i cambiamenti nelle coordinate per non uscire dalla scatola;) – David

2

Per rendere i confini un "muro" solido in un grafico orientato alla forza, è necessario implementare un rilevamento di collisione personalizzato per i bordi del riquadro di delimitazione. Here's an example of a custom collision detection.

L'approccio di christopher funzionerà bene per grafici di dimensioni ridotte, ma per i grafici molto più grandi di quelli visualizzati verranno ridimensionati a dimensioni non sufficientemente ridotte. L'approccio che ho qui sopra fallirà anche su grafici di grandi dimensioni in finestre di piccole dimensioni poiché le collisioni non potranno essere risolte a un certo punto.

Per grafici veramente grandi, vorrei invece raccomandare semplicemente all'utente di eseguire una panoramica e una riduzione. This SO post gives some tips about zooming. Dovrai anche creare un rect che sia la dimensione del tuo grafico come target per ricevere gli eventi del mouse. È possibile ridimensionarlo dinamicamente in base alle dimensioni, ad esempio, di un grafico di force force, nel gestore di eventi tick.

Spero che siano utili indicazioni.

+0

il "tick" era una cosa da menzionare qui, come puoi vedere ho risolto il problema nella funzione tick, ma senza alcun zoom :) – David