Home > Software design >  how to add text inside a rectangular nodes for a network graph in D3.js?
how to add text inside a rectangular nodes for a network graph in D3.js?

Time:12-02

I am not able to display text within rectangular nodes in a D3.js network graph.

I have first created groups for each array element, and appended the rectangular node, but nothing gets displayed in vain. Can anyone review my code and suggest any changes so that the code will work?

I am asking this question as I have already implemented most of the answers posted in Stackoverflow earlier, but the nodes are not at all being displayed.

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 aelement is used ot 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>

Input json file:

{
    "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} 
    ]
}

The result is appearing to be just the links without the nodes:

enter image description here

CodePudding user response:

I think you may be accidentally appending g elements, then changing them to rect then appending text. I'm not certain this will fix everything, but here you want 'append' and not 'join':

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