Is it not possible to change node labels in D3.js after clicking on a node?

After being inspired by this link, I successfully created a basic network visualization app using D3.js.

The app reads node names from a textarea on an HTML page and then constructs a network where all nodes are interconnected.

All the relevant code can be found at the end of this post.

However, my current challenge lies in setting labels for each node. Upon loading the D3jNetVis.html file in a web browser, I encounter the following error:

Uncaught TypeError: D3jNetVis.js:64
undefined is not a function

This error occurs when trying to set labels with the following piece of code:

dataSet.nodes.append("text")
    .attr("x", 12)
    .attr("dy", ".35em")
    .text(function(d) { return d.name; });

The suggestion to implement node labels came from a thread on Stack Overflow.

I'm seeking assistance to understand why this error is happening and how it can be resolved.

Google hinted that the issue could be related to the order in which JS files are imported in the HTML page. Despite experimenting with different combinations, I haven't been able to fix it.

Regards,
Erno Lindfors

D3jNetVis.html:

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8 />
        <title>Network Visualization Example - d3js</title>
        <link rel="stylesheet" type="text/css" href="D3jNetVis.css">
    </head>
    <body>
        <table>
            <tr><td><div id="svgContent"></div></td></tr>
            <tr><th align="left">Give node ids</th></tr>
            <tr><td><textarea id="nodeIds" cols=5 rows=20></textarea></td></tr>
            <tr><td><button type="button" onclick="constNet()">Construct Network</button></td></tr>
        </table>
        <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
        <script src="D3jNetVis.js" charset="utf-8"></script>
    </body>
</html>

D3jNetVis.js:

function constNet() {
    var textArea = document.getElementById("nodeIds");
    var nodeIdsArray = document.getElementById("nodeIds").value.split("\n");
    var w = 500,
    h = 500;
    var svg = d3.select("#svgContent")
        .append("svg")
        .attr("width", w)
        .attr("height", h)
        .attr('preserveAspectRatio', 'xMinYMin slice') 
        .append('g');

    var nodesArray = [];
    for (var i = 0; i < nodeIdsArray.length; i++) {
        var nodeId = nodeIdsArray[i];
        var newNode = {name: "Node" + nodeId, id:nodeId, fixed:false};
        nodesArray[nodesArray.length] = newNode;
    }
    var edgesArray = [];
    for (var i = 0; i < nodeIdsArray.length-1; i++) {
        var sNodeId = nodeIdsArray[i];
        for (var j = i+1; j < nodeIdsArray.length; j++) {
            var tNodeId = nodeIdsArray[j];
            edgesArray[edgesArray.length] = {source:sNodeId-1, target:tNodeId-1}; 
        }
    }
    var dataSet = {
        nodes: nodesArray,
        edges: edgesArray
    };
    var force = self.force = d3.layout.force()
        .nodes(dataSet.nodes)
        .links(dataSet.edges)
        .gravity(0.05)
        .distance(100)
        .charge(-100)
        .size([w,h])
        .start();

    var link = svg.selectAll(".link")
        .data(dataSet.edges)
        .enter().append("line")
        .attr("class", "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; });

    var node_drag = d3.behavior.drag()
        .on("dragstart", dragstart)
        .on("drag", dragmove)
        .on("dragend", dragend);

    var node = svg.selectAll("circle")
        .data(dataSet.nodes)
        .enter().append("circle")
        .attr("class", "node")
        .attr("r", 4.5)
        .call(node_drag);

    /*
    The "Uncaught TypeError" happens in the next line.
     */
    dataSet.nodes.append("text")
        .attr("x", 12)
        .attr("dy", ".35em")
        .text(function(d) { return d.name; });


    function dragstart(d, i) {
        force.stop(); 
    }

    function dragmove(d, i) {
        d.px += d3.event.dx;
        d.py += d3.event.dy;
        d.x += d3.event.dx;
        d.y += d3.event.dy; 
        tick(); 
    }

    function dragend(d, i) {
        d.fixed = true; 
        tick();
        force.resume();
    }  
    force.on("tick", tick);

    function tick() {
        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; });

        node.attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; });
    }
}

D3jNetVis.css:

line{
    stroke: #cccccc;
    stroke-width: 1;
}
circle{
  fill: blue;
}

Answer №1

To add HTML elements to a specific section of the DOM, simply append them to the selection of HTML elements.

If dataSet.nodes does not represent a selection of HTML elements, an error message will be displayed.

Try using this syntax instead: node.append("text").....

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What are the steps to transform an object containing arrays into strings and then embed them into my HTML code?

Here is the code I need to add to my errors array and send the values to my HTML client-side template: { "email": [ "user with this email already exists." ] } I am looking for something like this: "user with t ...

Retrieve information using Observables just once in Angular 2

One of my Angular 2 components relies on a service that fetches customer data from a Web API and returns an Observable: getCustomers() { return this.http .get(this.baseURI + this.url) .map((r: Response) => { let a = r.jso ...

Tips for displaying real-time error notifications from server-side validation using AJAX

Seeking a way to display inline error messages from my Symfony2 Backend without refreshing the page. I considered replacing the current form in the HTML with the validated form containing the error messages returned by the backend through AJAX. However, ...

What's the source of this undefined error and is there a way to eliminate it from the code?

After successfully filtering and reducing the data, I encountered an issue with undefined. I am trying to figure out what is causing this and how I can either remove it or make it visible on the screen without being invisible. You can also check the codes ...

How to automatically close a JavaScript popup once a form is submitted and refresh the parent page

I am facing an issue with a popup on my website. I have a separate page called math.ejs that pops up when a button is pressed on the index.ejs page. However, after clicking the submit Ok button in the math.ejs popup, I want it to close and display the calc ...

As I attempt to connect with the bitcoin average server, I encounter a 403 status code error in the communication

const express = require("express"); const bodyParser = require("body-parser"); const request = require("request"); const app = express(); app.use(bodyParser.urlencoded({extended: true})); app.get("/", function(req, res){ res.sendFile(__dirname + "/inde ...

How can I pass arguments from a Python command line program (compiled to an EXE) to a JavaScript file?

As I work on developing a node program, I've come across certain abilities that Python possesses which JavaScript lacks, such as utilizing Python-specific modules. To bridge this gap, I made the decision to compile Python files into EXE and then invok ...

Connecting a JavaScript script from my HTML file to Django's static files - here's how

I recently started a Django project with frontend code that wasn't initially written for Django. I am having trouble connecting this script: <script> document.body.appendChild(document.createElement('script')). src='js/ma ...

Obtaining Data from an Array with Reactive Forms in Angular 4

Just starting out with Angular 4 and trying to figure out how to populate input fields with information based on the selection made in a dropdown. <select formControlName="selectCar" class="form-field"> <option value="">Choose a car&l ...

Struggling with implementing a personalized zoom feature in React-Leaflet?

Looking to create a custom Zoom button using react-leaflet Below is the code I have been working on: import React from 'react'; import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; import { Map, TileLayer } from 're ...

Node.js server continues running after attempting to stop with ctrl + C following starting the server using the command "npm start"

Whenever I initiate my server by typing node app.js in the command line on Git Bash, I can stop it simply by using ctrl + C. In my package.json file, I have configured a start script that allows me to use the command npm start to kickstart the server: "s ...

Easily collect form information from an HTML <form> element

I've been struggling to figure out how to retrieve data from an HTML form and display it in the console. What step am I overlooking? Here is the HTML code I'm working with: <!DOCTYPE html> <html> <head> <title>U ...

The navigation toggler seems to be malfunctioning in the browser, but it is functioning properly on Code

I'm having an issue with my navigation bar toggler. The code works fine in Codeply, but not in the browser. The hamburger button appears on mobile, but the lists are not showing up. Here is the code snippet I'm using: <html> <head> ...

Incorporating an HTTP header into d3.json using queue.js

I know that I can include a header in a D3 JSON request by using the following code: d3.json("http://localhost:8080/data") .header("Application-ID", "1") However, I'm uncertain about how to add this header when utilizing queue's defer method. ...

Guide to extracting a specific segment from req.body in Node.js

I've been attempting to access a specific nested property of req.body, but the output always turns out to be undefined. Here is the code snippet: let dataReceived = JSON.stringify(req.body); console.log(dataReceived); let refCode = ...

Unused Vue Chart JS options are neglected

I'm encountering an issue with Vue Chart JS v3.5.1 in my Nuxt JS/Vue project where when trying to pass options as a prop, the chart defaults back to its default settings and does not reflect the changes I made. My project includes multiple files: pl ...

Discover the simple steps to include row numbers or serial numbers in an angular2 datagrid

Currently, I am utilizing angular2 -datatable. Unfortunately, I am facing an issue where the correct row numbers are not being displayed in their corresponding rows. Whenever a user moves to the next page using the paginator, the datatable starts countin ...

The code inside the if statement is somehow executing even when the if statement is not true

Similar Question: Issue with jQuery function running at inappropriate times I've spent several hours trying to figure out why my function isn't working properly. I have a function inside an if ($window.width() < 1000) statement, but it se ...

I'm having trouble grasping the concept of serving gzip-compressed JavaScript and CSS files

Why is it important to serve compressed JavaScript and CSS files? I understand that it reduces file size, but does the browser/webserver have to decompress them to read them? It's been mentioned that the webserver handles the compression. Does this me ...

Changing the color variable of an object using an onClick function in JavaScript

I'm currently working on a simple game where users can draw using the keys W, A, S, and D. If you want to take a look at the progress I've made so far, here is a JSFiddle link. There's a collision function in the code that I no longer need, ...