Adición los nodos/enlaces a mi gráfico de fuerza D3 fueron muy confusos hasta que entendí mejor cómo estaba agregando el conjunto inicial de nodos.
Suponiendo una <g>
es lo que desea utilizar para sus nodos:
// Select the element where you'd like to create the force layout
var el = d3.select("#svg");
// This should not select anything
el.selectAll("g")
// Because it's being compared to the data in force.nodes()
.data(force.nodes())
// Calling `.enter()` below returns the difference in nodes between
// the current selection and force.nodes(). At this point, there are
// no nodes in the selection, so `.enter()` should return
// all of the nodes in force.nodes()
.enter()
// Create the nodes
.append("g")
.attr("id", d.name)
.classed("manipulateYourNewNode", true);
Ahora vamos a hacer que la función que va a añadir un nodo a la disposición una vez que el gráfico se ha inicializado!
newNodeData
es un objeto con los datos que desea utilizar para su nuevo nodo. connectToMe
es una cadena que contiene la identificación única de un nodo al que le gustaría conectar su nuevo nodo.
function createNode (newNodeData, connectToMe) {
force.nodes().push(newNodeData);
el.selectAll("g")
.data(force.nodes(), function(datum, index) { return index })
la función dada como el segundo argumento opcional en .data()
se ejecuta una vez para cada nodo en la selección y otra vez para cada nodo en force.nodes()
, igualando a ellos basado en el valor devuelto. Si no se proporciona ninguna función, se invoca una función de retorno, que devuelve el index
(como se indicó anteriormente).
Sin embargo, es muy probable que haya una disputa entre el índice de su nueva selección (creo que la orden es aleatoria) y la orden en force.nodes()
. En cambio, lo más probable es que necesite la función para devolver una propiedad que sea única para cada nodo.
Esta vez, .enter()
solo devolverá el nodo que está tratando de agregar como newData
porque no encontró ninguna clave para él con el segundo argumento de .data()
.
.enter()
.insert("g", "#svg")
.attr("id", d.name)
.classed("manipulatYourNewNode", true);
createLink(connectToMe, newNodeData.name);
force.start();
}
La función createLink (definida a continuación) crea un enlace entre su nuevo nodo y su nodo de elección.
Además, the d3js API states that force.start() should be called after updating the layout.
Nota: Calling force.stop()
en el comienzo de mi función fue una gran ayuda para mí cuando yo estaba tratando de encontrar la manera de añadir nodos y enlaces a mi primera gráfica.
function createLink (from, to) {
var source = d3.select("g#" + from).datum(),
target = d3.select("g#" + to).datum(),
newLink = {
source: source,
target: target,
value: 1
};
force.links().push(newLink);
El código siguiente funciona bajo los supuestos de que:
#links
es el elemento contenedor que contiene todos los elementos de enlace
Sus enlaces se representan como <line>
elementos:
d3.select("#links")
.selectAll("line")
.data(force.links())
.enter()
.append("line");
gracias pero yo esperaba que alguien pueda describir el proceso también – BlitzCrank
La parte importante es guardar el valor devuelto por el método .data en var (por ejemplo, x) y llamar a x.exit(). remove() al final del método. –