2013-07-29 6 views
12

In questo esempio: http://bl.ocks.org/mbostock/1747543:evitare la collisione tra i nodi e spigoli in D3 disposizione vigore

enter image description here

... Mike ci mostra come evitare collisioni tra i nodi in modo che non ci sono due nodi si sovrappongono l'un l'altro.

Mi chiedo se sia possibile evitare la collisione tra i nodi e i bordi in modo che nessun nodo 'clip' o si sovrapponga a un bordo a meno che non sia collegato da quel bordo.

Il seguente esempio mostra utilizzando D3 forza-diretti che nodo L sovrappone al bordo di attacco e IA, e allo stesso modo, il nodo M sovrappone al bordo di attacco e LD. Come possiamo prevenire questi casi?

enter image description here

+2

Questo non è possibile con l'implementazione del layout di forza in D3. Dovresti implementarlo tu stesso. Nota che questo è in realtà un problema molto difficile (dal punto di vista computazionale), quindi anche se avevi un'implementazione probabilmente non vorresti eseguirla nel browser. –

+0

@LarsKotthoff, stai dicendo, in generale, che nessun algoritmo di layout grafico noto (incluso quello implementato per D3) può risolvere questo problema in modo efficiente? – skyork

+0

Dipende dalla tua definizione di efficienza. Trovare una soluzione (statica) a questo suona almeno NP-difficile per me. Ciò non significa che possa essere risolto rapidamente in tutti i casi specifici, ma in generale è difficile (e per i grafici di grandi dimensioni probabilmente non è possibile farlo rapidamente). Per poi cambiare quella soluzione iniziale in modo tale che i nodi si spostassero leggermente (come farebbe la simulazione) sarebbe molto facile in quanto è sufficiente eseguire solo riparazioni locali. –

risposta

6

Se il grafico non ha troppi nodi, si può fingere. Basta inserire uno o più nodi per ciascun collegamento e impostare la loro posizione lungo il collegamento nel gestore tick. Scopri http://bl.ocks.org/couchand/7190660 per un esempio, ma le modifiche alla quantità versione di Mike Bostock a fondamentalmente solo:

var linkNodes = []; 

graph.links.forEach(function(link) { 
    linkNodes.push({ 
    source: graph.nodes[link.source], 
    target: graph.nodes[link.target] 
    }); 
}); 

e

// force.on('tick', function() { 
linkNodes.forEach(function(node) { 
    node.x = (node.source.x + node.target.x) * 0.5; 
    node.y = (node.source.y + node.target.y) * 0.5; 
}); 

Questo introdurrà un piuttosto grave sovraccarico di prestazioni se si dispone di molti nodi e spigoli , ma se il tuo grafico non diventa molto più grande del tuo esempio, difficilmente si noterà.

Si potrebbe anche voler armeggiare con la forza relativa dei nodi reali rispetto ai nodi di collegamento.

Fai un ulteriore passo avanti e ottieni i bei collegamenti curvi di http://bl.ocks.org/mbostock/4600693.

Problemi correlati