es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo agregar texto dentro de nodos rectangulares para un gráfico de red en D3.js?

No puedo mostrar texto dentro de nodos rectangulares en un gráfico de red de D3.js.

Primero he creado grupos para cada elemento del array, y he agregado el nodo rectangular, pero nada se muestra en vano. ¿Alguien puede revisar mi código y sugerir algún cambio para que funcione?

Hago esta pregunta porque ya he implementado la mayoría de las respuestas publicadas en Stackoverflow antes, pero los nodos no se muestran en absoluto.

Network.html:

<!DOCTYPE html>

<meta charset="utf-8">
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v6.js"></script>

<body>
    <!-- Create a div where the graph will take place -->
    <div id="my_dataviz"></div>
    <script>

                                                     // set the dimensions and margins of the graph
    const margin = {top: 20, right: 20, bottom: 40, left: 100},
      width = 2000 - margin.left - margin.right,
      height = 1000 - margin.top - margin.bottom;

                                                    // append the svg object to the body of the page
    const svg = d3.select("#my_dataviz")
    .append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
                                                            //The SVG g element is used to group SVG shapes together. Once grouped you can transform the whole group as if it was a single shape.
    .append("g")                                         //This mainly appends a 'g' element to the SVG.
      .attr("transform",
            `translate(${margin.left}, ${margin.top})`);    //this is used to move it to the top left position.

    d3.json("sample_input.json").then( function( data) {

                              // Initialize the links
        const link = svg      // we have appended the LINE for each LINK in the data. 
            .append("g")
            .selectAll("line")
            .data(data.links)
            .enter()
            .append("line")
            .style("stroke", "#000000");

        const simulation = d3.forceSimulation(data.nodes)
            .force("link", d3.forceLink()                               
                .id(function(d) { return d.id; })                     
                .links(data.links)                                    
            )
            .force("charge", d3.forceManyBody().strength(-25000))         
            .force("center", d3.forceCenter(width/2, height/3))     
            .on("tick", ticked); 

        var textNodes= svg.append("g") // this is for the second <g> 
                        .selectAll("g")
                        .data(data.nodes)
                        .enter().append("g");

        var rects= textNodes.join("rect").attr("width",300)
                                .attr("height",90)
                                .style("fill", "#69b3a2")
                                .attr("stroke","black");

        var texts= textNodes.append("text")
            .text(function(d){
            d.label;
            });

        function ticked() {
                textNodes.attr("transform",function (d) {return "translate("+d.x+", "+d.y+")";});


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

});
</script>
</body>

Archivo de entrada json:

{
“nodes”: [
{“id”: 0, “label”:”Donald Trump”},
{“id”: 1, “label”: “https://www.politifact.com”},
{“id”: 2, “label”: “https://www.washingtonpost.com”},
{“id”: 3, “label”: “https://www.thedailybeast.com”},
{“id”: 4, “label”: “https://www.daytondailynews.com”},
{“id”: 5, “label”: “https://centurylink.net”},
{“id”:6, “label”: “https://www.businessinsider.com”},
{“id”:7, “label”: “https://thehill.com”},
{“id”:8, “label”: “https://www.texasstandard.org”}
],
“links”: [
{“source”: 1, “target”: 0},
{“source”: 2, “target”: 0},
{“source”: 3, “target”: 1},
{“source”: 4, “target”: 0},
{“source”: 5, “target”: 0}
]
}

El resultado aparece como solo los enlaces sin los nodos:

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema reside en el código que añade los nodos rectangulares y el texto dentro de ellos. Actualmente, el código solo está añadiendo los elementos rectángulo pero sin dar ninguna posición o texto que se muestre en ellos.

    Así es como puede modificar el código para agregar texto dentro de nodos rectangulares:

    // Añadir los elementos de texto y rectángulo dentro de cada grupo
    var textNodes = svg.append("g")
        .selectAll("g")
        .data(data.nodes)
        .enter()
        .append("g");
    
    var rects = textNodes.append("rect")
        .attr("width", 300)
        .attr("height", 90)
        .style("fill", "#69b3a2")
        .attr("stroke", "black");
    
    var texts = textNodes.append("text")
        .text(function(d) { return d.label; })
        .attr("x", 150) // Colocar el texto en el centro del elemento rectángulo
        .attr("y", 45)
        .style("font-size", "16px")
        .style("text-anchor", "middle"); // Alinear el texto en el centro del elemento rectángulo
    
    

    Este código creará un grupo para cada nodo, añadirá un elemento rectángulo con los atributos especificados y luego añadirá un elemento de texto con la etiqueta de cada nodo centrada dentro del rectángulo. Asegúrese de ajustar las posiciones x e y según el diseño deseado.

    Además, tenga en cuenta que está utilizando el método .join() en la variable textNodes. Esto no es necesario ya que ya ha creado los grupos con el método .append(). Puede eliminar el método .join() para simplificar el código.

Comments are closed.