2012-05-08 16 views
7

Ho nodi in un layout D3 diretto a forza impostato su. corretto = true. Se imposto i valori .x o .y, i nodi stessi non si spostano nella loro nuova posizione.Spostamento di nodi fissi in D3

Ecco la mia funzione:

function fixNode(idArray, locationX, locationY) { 
    for (x = 0; x < idArray.length; x++) { 
     for (y = 0; y < nodes.length; y++) { 
      if (nodes[y].id == idArray[x]) { 
       nodes[y].fixed = true; 
       nodes[y].x = 50; 
       nodes[y].y = 50; 
       break; 
      } 
     } 
    } 
} 

UPDATE 1:

Ecco la funzione di lavoro sulla base del parere di Jason:

function fixNode(idArray, locationX, locationY) { 
    for (x = 0; x < idArray.length; x++) { 
     for (y = 0; y < nodes.length; y++) { 
      if (nodes[y].id == idArray[x]) { 
       nodes[y].fixed = true; 
       nodes[y].x = 50; 
       nodes[y].y = 50; 
       nodes[y].px = 50; 
       nodes[y].py = 50; 
       break; 
      } 
     } 
    } 
    tick(); 
} 

risposta

12

Il layout forza-diretto è disaccoppiato dal rendering reale. Normalmente hai un tick ticker che aggiorna gli attributi dei tuoi elementi SVG per ogni "tick" dell'algoritmo di layout (la cosa bella del disaccoppiamento è il rendering a un <canvas>, o qualcos'altro).

Quindi per rispondere alla tua domanda, devi semplicemente chiamare questo gestore direttamente per aggiornare gli attributi dei tuoi elementi SVG. Ad esempio, il codice potrebbe essere simile a questo:

var node = …; // append circle elements 

var force = d3.layout.force() 
    .nodes(…) 
    .links(…) 
    .on("tick", tick) 
    .start(); 

function tick() { 
    // Update positions of circle elements. 
    node.attr("cx", function(d) { return d.x; }) 
     .attr("cy", function(d) { return d.y; }); 
} 

così si potrebbe semplicemente chiamare tick() in qualsiasi punto e aggiornare le posizioni degli elementi.

Si potrebbe essere tentati di chiamare force.tick(), ma questo è pensato per essere utilizzato come alternativa sincrona a force.start(): è possibile chiamarlo ripetutamente e ogni chiamata esegue un passo dell'algoritmo di layout. Tuttavia, esiste una variabile interna alpha utilizzata per controllare la ricottura simulata utilizzata internamente e una volta che il layout si è "raffreddato", questa variabile sarà 0 e ulteriori chiamate a force.tick() non avranno alcun effetto. (Certo, potrebbe essere bello se force.tick() emettesse sempre un evento tick indipendentemente dal raffreddamento, ma questo non è il comportamento corrente).

come avrete notato correttamente nei commenti, se si imposta manualmente d.x e d.y, si dovrebbe anche impostare d.px e d.py con gli stessi valori, se si desidera il nodo di rimanere in una certa posizione.

+0

Grazie, ora ho capito. Ho appena testato il comportamento e ho voluto indicare qualcosa che potrebbe scoraggiare persone che provengono dagli esempi predefiniti: è necessario modificare i valori px/py e i valori x/y se il nodo è stato spostato. Pubblicherò la funzione aggiornata sopra. – Elijah

Problemi correlati