library force examples ejemplos directed d3js d3.js force-layout

d3.js - force - d3js charts examples



¿Cómo elimino todos los elementos secundarios de un nodo y luego los vuelvo a aplicar con diferente color y tamaño? (5)

Mi primer consejo es que deberías leer la API de d3.js sobre las selecciones: https://github.com/mbostock/d3/wiki/Selections

Debes entender cómo funciona el comando enter() ( API ). El hecho de que debes usarlo para manejar nuevos nodos tiene un significado que te ayudará.

Aquí está el proceso básico cuando tratas con selection.data() :

  • primero quiere "adjuntar" algunos datos a la selección. Así que tienes:

    var nodes = visualRoot.selectAll(".node") .data(graphData.nodes)

  • Luego puede modificar todos los nodos cada vez que se modifiquen los datos (esto hará exactamente lo que quiera). Si, por ejemplo, cambia el radio de los nodos antiguos que están en el nuevo conjunto de datos que cargó

    nodes.attr("r", function(d){return d.radius})

  • Luego, debe manejar nodos nuevos, para esto debe seleccionar los nuevos nodos, esto es para lo que selection.enter() está hecho:

    var nodesEnter = nodes.enter() .attr("fill", "red") .attr("r", function(d){return d.radius})

  • Por último, ciertamente desea eliminar los nodos que ya no desea, para ello, debe seleccionarlos, para esto está selection.exit() .

    var nodesRemove = nodes.exit().remove()

Un buen ejemplo de todo el proceso también se puede encontrar en la API wiki: https://github.com/mbostock/d3/wiki/Selections#wiki-exit

Así que tengo el siguiente código de gráfico de diseño de fuerza para establecer nodos, enlaces y otros elementos:

var setLinks = function () { link = visualRoot.selectAll("line.link") .data(graphData.links) .enter().append("svg:line") .attr("class", "link") .style("stroke-width", function (d) { return nodeStrokeColorDefault; }) .style("stroke", function (d) { return fill(d); }) .attr("x1", function (d) { return d.source.x; }) .attr("y1", function (d) { return d.source.y; }) .attr("x2", function (d) { return d.target.x; }) .attr("y2", function (d) { return d.target.y; }); graphData.links.forEach(function (d) { linkedByIndex[d.source.index + "," + d.target.index] = 1; }); }; var setNodes = function () { node = visualRoot.selectAll(".node") .data(graphData.nodes) .enter().append("g") .attr("id", function (d) { return d.id; }) .attr("title", function (d) { return d.name; }) .attr("class", "node") .on("click", function (d, i) { loadAdditionalData(d.userID, this); }) .call(force.drag) .on("mouseover", fadeNode(.1)).on("mouseout", fadeNode(1)); }; //append the visual element to the node var appendVisualElementsToNodes = function () { node.append("circle") .attr("id", function (d) { return "circleid_" + d.id; }) .attr("class", "circle") .attr("cx", function (d) { return 0; }) .attr("cy", function (d) { return 0; }) .attr("r", function (d) { return getNodeSize(d); }) .style("fill", function (d) { return getNodeColor(d); }) .style("stroke", function (d) { return nodeStrokeColorDefault; }) .style("stroke-width", function (d) { return nodeStrokeWidthDefault; }); //context menu: d3.selectAll(".circle").on("contextmenu", function (data, index) { d3.select(''#my_custom_menu'') .style(''position'', ''absolute'') .style(''left'', d3.event.dx + "px") .style(''top'', d3.event.dy + "px") .style(''display'', ''block''); d3.event.preventDefault(); }); //d3.select("svg").node().oncontextmenu = function(){return false;}; node.append("image") .attr("class", "image") .attr("xlink:href", function (d) { return d.profile_image_url; })//"Images/twitterimage_2.png" .attr("x", -12) .attr("y", -12) .attr("width", 24) .attr("height", 24); node.append("svg:title") .text(function (d) { return d.name + "/n" + d.description; }); };

Ahora, las dependencias de colores y tamaños cambiaron y necesito volver a dibujar los círculos del gráfico (+ todos los elementos anexos) con diferentes colores y radios. Teniendo problemas con eso

Puedo hacer esto:

visualRoot.selectAll(".circle").remove();

pero tengo todas las imágenes que ''.circles'' a ''.circles'' todavía allí.

De cualquier forma, cualquier ayuda será apreciada, avíseme si la explicación no es lo suficientemente clara, intentaré solucionarla.

PS ¿cuál es la diferencia entre graphData.nodes y d3.selectAll(''.nodes'') ?


Para eliminar todo el elemento de un nodo:

var siblings = element.parentNode.childNodes; for (var i = 0; i < siblings.length; i++) { for (var j = 0; j < siblings.length; j++) { siblings[i].parentElement.removeChild(siblings[j]); } }`


Si desea eliminar el elemento en sí, simplemente use element.remove() , como lo hizo. En caso de que solo desee eliminar el contenido del elemento, pero mantenga el elemento tal como está, puede usar f.ex.

visualRoot.selectAll(".circle").html(null); visualRoot.selectAll(".image").html(null);

en lugar de .html("") (No estaba seguro de qué elementos de los hijos quieres eliminar). Esto mantiene el elemento en sí, pero limpia todo el contenido incluido . Es la forma oficial de hacerlo , por lo que debe funcionar en todos los navegadores.

PD: querías cambiar el tamaño de los círculos. Has probado

d3.selectAll(".circle").attr("r", newValue);


Su respuesta funcionará, pero para la posteridad, estos métodos son más genéricos.

Eliminar todos los niños de HTML:

d3.select("div.parent").html("");

Eliminar todos los hijos de SVG / HTML:

d3.select("g.parent").selectAll("*").remove();

La llamada .html("") funciona con mi SVG, pero podría ser un efecto secundario de usar innerSVG .


de esta manera, lo he resuelto muy fácilmente,

visualRoot.selectAll(".circle").remove(); visualRoot.selectAll(".image").remove();

y luego simplemente volví a agregar elementos visuales que se procesaron de manera diferente porque el código para calcular el radio y el color había cambiado las propiedades. Gracias.