2012-05-08 17 views
7

Tengo nodos en un diseño dirigido por fuerza D3 que están configurados en. fijo = verdadero. Si configuro los valores .x o .y, los nodos no se moverán a su nueva posición.Mover nodos fijos en D3

Aquí es mi función:

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; 
      } 
     } 
    } 
} 

ACTUALIZACIÓN 1:

Aquí es la función de trabajo basado en los consejos de 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(); 
} 

Respuesta

12

El diseño de la fuerza dirigida se desacopla de la representación real. Normalmente tiene un controlador de ticks, que actualiza los atributos de sus elementos SVG para cada "tic" del algoritmo de diseño (lo bueno del desacoplamiento es que lo renderiza en un <canvas> en su lugar, u otra cosa).

Para responder a su pregunta, simplemente necesita llamar a este controlador directamente para actualizar los atributos de sus elementos SVG. Por ejemplo, el código podría tener este aspecto:

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; }); 
} 

por lo que podría llamar simplemente tick() en cualquier momento y actualizar las posiciones de los elementos.

Puede que tengas la tentación de llamar al force.tick(), pero está destinado a ser utilizado como una alternativa síncrona al force.start(): puedes llamarlo repetidamente y cada llamada ejecuta un paso del algoritmo de diseño. Sin embargo, existe una variable interna alpha utilizada para controlar el recocido simulado utilizado internamente, y una vez que el diseño se "enfrió", esta variable será 0 y las llamadas posteriores a force.tick() no tendrán efecto. (Es cierto que podría ser bueno si force.tick() siempre activa un evento de marcación independientemente de la refrigeración, pero ese no es el comportamiento actual).

Como se señaló correctamente en los comentarios, si establece manualmente d.x y d.y, también debe establecer d.px y d.py con los mismos valores si desea que el nodo permanezca en una posición determinada.

+0

Gracias, ahora lo entiendo. Acabo de probar el comportamiento y quería señalar algo que puede despistar a las personas que provienen de los ejemplos predeterminados: necesita cambiar los valores px/py, así como los valores x/y si el nodo se ha movido. Publicaré la función actualizada arriba. – Elijah

Cuestiones relacionadas