Creación de un elemento de "compuesto" es tan simple como anexar uno o más hijos a otro elemento. En su ejemplo, desea vincular sus datos a una selección de elementos <a>
, y otorgar a cada <a>
un único hijo <circle>
.
En primer lugar, debe seleccionar "a.node"
en lugar de "circle.node"
. Esto se debe a que sus hipervínculos serán los elementos principales. Si no hay un elemento primario obvio, y solo desea agregar elementos múltiples para cada dato, use <g>
, elemento de grupo de SVG.
Luego, desea agregar un elemento <a>
a cada nodo en la selección entrante. Esto crea tus hipervínculos. Después de configurar los atributos de cada hipervínculo, desea darle un hijo <circle>
. Simple: solo llame al .append("circle")
.
var node = vis.selectAll("a.node")
.data(nodes);
// The entering selection: create the new <a> elements here.
// These elements are automatically part of the update selection in "node".
var nodeEnter = node.enter().append("a")
.attr("class", "node")
.attr("xlink:href", "http://whatever.com")
.call(force.drag);
// Appends a new <circle> element to each element in nodeEnter.
nodeEnter.append("circle")
.attr("r", 5)
.style("fill", function(d) { return fill(d.group); })
node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
D3 Recuerde que opera principalmente en selecciones de nodos. Por lo tanto, al llamar al .append()
en la selección entrante , significa que cada nodo en la selección obtiene un nuevo hijo. ¡Poderoso!
Una cosa más: SVG tiene its own <a>
element, que es a lo que me refería anteriormente. ¡Esto es diferente del HTML! Normalmente, solo utiliza elementos SVG con SVG y HTML con HTML.
Gracias a @mbostock por sugerir que aclare la nomenclatura variable.
Aunque entiendo por qué esto funciona para la creación, ¿no se rompe en la actualización? Como append() fusiona las selecciones de entrada y actualización, ¿no agrega un nuevo círculo a los nodos antiguos cada vez que se llama a la actualización? –
He actualizado el ejemplo para hacerlo más claro. selection.append no * fusiona * ninguna selección, pero selection.enter(). append agrega automáticamente los elementos a la selección de actualización. Mi ejemplo original tenía vis.selectAll (...) .data (...) .enter(). Append (...). Esto solo agrega elementos a la selección de entrada, por lo que no hay problema; el punto clave es que la selección de entrada inicialmente solo contiene marcadores de posición para * nuevos * elementos que aún no existen. –