Handling OnClick events in D3 with Websocket Integration

My goal is to implement a Websocket in JavaScript that transmits a variable obtained when clicking on a node in a D3 chart. While I have made progress using static data, I'm struggling with initiating the code upon node click to retrieve the "user information". At this point, what I need help with most is extracting the variable from the OnClick event on the D3 node and passing it as a parameter via Websocket for data retrieval to display.

Websocket:

var jsonObject = "";
var username = "test_123";

function init() {
  testWebSocket();
}

function testWebSocket() {
  websocket = new WebSocket(wsUri);
  websocket.onopen = function(evt) {
    onOpen(evt)
  };
  websocket.onclose = function(evt) {
    onClose(evt)
  };
  websocket.onmessage = function(evt) {
    onMessage(evt)
    testObject();
  };
  websocket.onerror = function(evt) {
    onError(evt)
  };
}

function onOpen(evt) {
  console.log("CONNECTED");
  doSend('{"request":"getTweetRelationshipGraphForUser", "screen_name" : }');
}

function onClose(evt) {
  console.log("DISCONNECTED");
}

function onMessage(evt) {
  console.log("Message: " + evt.data);
  jsonObject = evt.data;
  console.log("json object: "+jsonObject);
  return jsonObject;
  //  websocket.close();
}

function onError(evt) {
  console.log("Error:" + evt.data);
}

function doSend(message) {
  console.log("SENT: " + message);
  websocket.send(message);
}

function testObject(){
  document.getElementById("test").innerHTML = jsonObject;
  console.log(jsonObject);
}

window.addEventListener("load", init, false);

D3 Javascript

function start() {
  var w = 1200,
    h = 600,
    radius = 10,
    node,
    link,
    root;

  var count = 0;

  var force = d3.layout.force()
    .on("tick", tick)
    .charge(function (d) {
      return -500;
    })
    .linkDistance(function (d) {
      return d.target._children ? 100 : 50;
    })
    .size([w, h - 160]);

  var svg = d3.select("body").append("svg")
    .attr("width", w)
    .attr("height", h);

  svg.append("rect")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("fill", "#000");

  root = JSON.parse(jsonObject);
  console.log("root" + root);
  root.fixed = true;
  root.x = w / 2;
  root.y = h / 2 - 80;
  update();

  function update() {
    var nodes = root.nodes,
      links = root.links;

    // Restart the force layout.
    force
      .nodes(nodes)
      .links(links)
      .start();

    // Update the links…
    link = svg.selectAll(".link")
      .data(links);

    // Enter any new links.
    link.enter().insert("svg:line", ".node")
      .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;
      });

    // Exit any old links.
    link.exit().remove();

    // Update the nodes…
    node = svg.selectAll("circle.node")
      .data(nodes, function (d) {
        return d.name;
      })
      .style("fill", color);

    node.transition()
      .attr("r", radius);

    // Enter any new nodes.
    node.enter().append("svg:circle")
      .attr("xlink:href", function (d) {
        return d.image;
      })
      .attr("class", "node")
      .attr("cx", function (d) {
        return d.x;
      })
      .attr("cy", function (d) {
        return d.y;
      })
      .attr("r", radius)
      .attr("r", function (d) {
        return d.size * 2;
      })
      .style("fill", color)
      .on("click", click)
      .call(force.drag);
    node.append("title")
      .text(function (d) {
        return d.name;
      });

    // Exit any old nodes.
    node.exit().remove();

    title = svg.selectAll("text.title")
      .data(nodes);

    // Enter any new titles.
    title.enter()
      .append("text")
      .attr("class", "title");
    //.text(function(d) { return d.name; });

    // Exit any old titles.
    title.exit().remove();
  }

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

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

  // Color leaf nodes orange, and packages white or blue.
  function color(d) {
    if (d._children) {
      return "#95a5a6";
    } else {
      switch (d.group) {
        case 'r': //adverb
          return "#e74c3c";
          break;
        case 'n': //noun
          return "#3498db";
          break;
        case 'v': //verb
          return "#2ecc71";
          break;
        case 's': //adjective
          return "#e78229";
          break;
        default:
          return "rgb(0, 238, 238)";
      }
    }
  }

  // Toggle children on click.
  function click(d) {
    document.getElementById("image").src = d.image;
    document.getElementById("username").innerHTML = "Username:" + d.name;
    document.getElementById("id").innerHTML = "ID:" + d.id;
    document.getElementById("friends").innerHTML = d.friend;
    document.getElementById("nodeTitle").innerHTML = "";
    document.getElementById("size").innerHTML = d.size;
    //document.getElementById("id").innerHTML = "Friend Count:" + d.name;
    //if (d._children)
    //grabImage();
    //document.getElementById("image").innerHTML = (d.image);

    /*if (d.children) { 
     d._children = d.children;
     d.children = null;
     } else {
     d.children = d._children;
     d._children = null;
     }
     update();*/
  }

  function mouseover() {
    d3.select(this).select("circle").transition()
      .duration(750)
      .attr("r", 16);
  }


  function mouseout() {
    d3.select(this).select("circle").transition()
      .duration(750)
      .attr("r", 8);
  }

  // Returns a list of all nodes under the root.
  function flatten(root) {
    var nodes = [], i = 0;

    function recurse(node) {
      if (node.children) node.size = node.children.reduce(function (p, v) {
        return p + recurse(v);
      }, 0);
      if (!node.id) node.id = ++i;
      nodes.push(node);
      return node.size;
    }

    root.size = recurse(root);
    return nodes;
  }
}

do {
  var intervalID = window.setTimeout(start, 1000)
} while (jsonObject != "") {

}

Answer №1

After reviewing your needs, I have made some adjustments to the code provided. Currently, my focus is on implementing websockets for retrieving financial data and using d3.js for visualization. To achieve this, you need to establish an initialization point for the websocket connection and a rendering initiation point for the d3 code. These should be in a closed loop so that when a user clicks on a node, information is sent to the websocket, and upon receiving data from the websocket, the chart will be updated.

`    var jsonObject = "";
        var username = "test_123";

        function init() {
          testWebSocket();
        }

        function testWebSocket() {
          websocket = new WebSocket(wsUri);
          websocket.onopen = function(evt) {
            onOpen(evt)
          };
          websocket.onclose = function(evt) {
            onClose(evt)
          };
          websocket.onmessage = function(evt) {
            onMessage(evt)
            testObject();
          };
          websocket.onerror = function(evt) {
            onError(evt)
          };
        }

        function onOpen(evt) {
          console.log("CONNECTED");
          doSend('{"request":"getTweetRelationshipGraphForUser", "screen_name" : }');
        }

        function onClose(evt) {
          console.log("DISCONNECTED");
        }

        function onMessage(evt) {
          console.log("Message: " + evt.data);
          jsonObject = evt.data;

    //initiate the d3 rendering with new JSON
    start(jsonObject);


          console.log("json object: "+jsonObject);
          return jsonObject;
           }

        function onError(evt) {
          console.log("Error:" + evt.data);
        }

        function doSend(message) {

          websocket.send(message);
        }

      function initiateForInput(userName){
       //updating userinfo to JSON and send the wrapper to doSend
      var userInfoJson='{"request":"getTweetRelationshipGraphForUser", "screen_name" :'+userName+' }';
       doSend(userInfoJson);
    }


        function testObject(){
          document.getElementById("test").innerHTML = jsonObject;
          console.log(jsonObject);
        }

        window.addEventListener("load", init, false);

d3 file:-

    function start(newJsonObject) {
  var w = 1200,
    h = 600,
    radius = 10,
    node,
    link,
    root;

  var count = 0;

  var force = d3.layout.force()
    .on("tick", tick)
    .charge(function (d) {
      return -500;
    })
    .linkDistance(function (d) {
      return d.target._children ? 100 : 50;
    })
    .size([w, h - 160]);

  var svg = d3.select("body").append("svg")
    .attr("width", w)
    .attr("height", h);

  svg.append("rect")
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("fill", "#000");

  root = JSON.parse(newJsonObject);
  console.log("root" + root);
  root.fixed = true;
  root.x = w / 2;
  root.y = h / 2 - 80;
  update();

  function update() {
    var nodes = root.nodes,
      links = root.links;

    // Restart the force layout.
    force
      .nodes(nodes)
      .links(links)
      .start();

    // Update the links…
    link = svg.selectAll(".link")
      .data(links);

    // Enter any new links.
    link.enter().insert("svg:line", ".node")
      .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;
      });

    // Exit any old links.
    link.exit().remove();

    // Update the nodes...
    node = svg.selectAll("circle.node")
      .data(nodes, function (d) {
        return d.name;
      })
      .style("fill", color);

    node.transition()
      .attr("r", radius);

    // Enter any new nodes.
    node.enter().append("svg:circle")
      .attr("xlink:href", function (d) {
        return d.image;
      })
      .attr("class", "node")
      .attr("cx", function (d) {
        return d.x;
      })
      .attr("cy", function (d) {
        return d.y;
      })
      .attr("r", radius)
      .attr("r", function (d) {
        return d.size * 2;
      })
      .style("fill", color)
      .on("click", click)
      .call(force.drag);
    node.append("title")
      .text(function (d) {
        return d.name;
      });

    // Exit any old nodes.
    node.exit().remove();

    title = svg.selectAll("text.title")
      .data(nodes);

    // Enter any new titles.
    title.enter()
      .append("text")
      .attr("class", "title");
    //.text(function(d) { return d.name; });

    // Exit any old titles.
    title.exit().remove();
  }

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

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

  // Color leaf nodes orange, and packages white or blue.
  function color(d) {
    if (d._children) {
      return "#95a5a6";
    } else {
      switch (d.group) {
        case 'r': //adverb
          return "#e74c3c";
          break;
        case 'n': //noun
          return "#3498db";
          break;
        case 'v': //verb
          return "#2ecc71";
          break;
        case 's': //adjective
          return "#e78229";
          break;
        default:
          return "rgb(0, 238, 238)";
      }
    }
  }

  // Toggle children on click.
  function click(d) {
    document.getElementById("image").src = d.image;
    document.getElementById("username").innerHTML = "Username:" + d.name;
    document.getElementById("id").innerHTML = "ID:" + d.id;
    document.getElementById("friends").innerHTML = d.friend;
    document.getElementById("nodeTitle").innerHTML = "";
    document.getElementById("size").innerHTML = d.size;



    //command to websockets

    initiateForInput(d.name);






    //document.getElementById("id").innerHTML = "Friend Count:" + d.name;
    //if (d._children)
    //grabImage();
    //document.getElementById("image").innerHTML = (d.image);

    /*if (d.children) { 
     d._children = d.children;
     d.children = null;
     } else {
     d.children = d._children;
     d._children = null;
     }
     update();*/
  }

  function mouseover() {
    d3.select(this).select("circle").transition()
      .duration(750)
      .attr("r", 16);
  }


  function mouseout() {
    d3.select(this).select("circle").transition()
      .duration(750)
      .attr("r", 8);
  }

  // Returns a list of all nodes under the root.
  function flatten(root) {
    var nodes = [], i = 0;

    function recurse(node) {
      if (node.children) node.size = node.children.reduce(function (p, v) {
        return p + recurse(v);
      }, 0);
      if (!node.id) node.id = ++i;
      nodes.push(node);
      return node.size;
    }

    root.size = recurse(root);
    return nodes;
  }
}

do {
  var intervalID = window.setTimeout(start, 1000)
} while (jsonObject != "") {

}

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

How can I dynamically retrieve the width of an image in React as the screen size changes?

I have successfully implemented an image hover effect on my website. When I hover over a certain text, an image appears. The image is responsive, but I am facing an issue where I want the width of the text to be equal to the width of the image. When I resi ...

What is the best way to send props to a styled component without needing to convert them to transient props beforehand

Recently, I designed a custom Text component that accepts several props. These props are then forwarded to the styled component where specific styles are applied. However, I am facing an issue where I do not want these props to be passed down to the DOM, b ...

Iframe navigation tracking technology

Let's say I have an iframe element in my HTML document. <html> <body> This is my webpage <button> Button </button> <iframe src="www.example.com"></iframe> </body> </html> If a user clicks on links wi ...

Setting a JavaScript variable to null

Using Jquery, I have a variable that is assigned a value on button click. After the code executes successfully, I need to reset the variable to null. $("#btnAdd").click(function () { var myDataVariable= {}; myDataVariable.dataOne="SomeDa ...

Transforming CSV data into JSON format by converting each column into a separate array

I have a set of csv data examples that are structured like the following: id,hex1,hex2,hex3,hex4,hex5 388,#442c1c,#927450,#664c31,#22110c, 387,#6a442f,#826349,,, 1733,#4d432e,#75623f,,, 1728,#393e46,#5f4433,#ad7a52,#362c28,#a76042 I am interested in tran ...

React JS progress circle bar is a simple and effective way to visualize

Currently, I am in the process of developing a progress circle bar that will function as a timer alongside sliders. Each slide is intended to have its own corresponding progress bar. While I have managed to create the bars individually, I am facing challe ...

Leveraging the combination of <Form>, jQuery, Sequelize, and SQL for authentication and navigation tasks

My objective is to extract the values from the IDs #username-l and #pwd-l in an HTML form upon the user clicking the submit button. I aim to compare these values with those stored in a SQL database, and if they match exactly, redirect the user to a specifi ...

Refresh Angular component upon navigation

I have set up routes for my module: const routes: Routes = [ { path: ":level1/:level2/:level3", component: CategoriesComponent }, { path: ":level1/:level2", component: CategoriesComponent}, { path: ":level1", component: ...

Repeated attempts to initiate ajax script failing to function

I am completely new to the world of Ajax, having just started learning about it a few days ago. Despite my lack of experience, I need to incorporate it into a form that I am creating for my employer. Unfortunately, I have been facing difficulties in getti ...

The return value from vue-query is ObjectRefImpl, not the actual data

Greetings to the Vue.js community! As a newcomer to Vue.js, I am seeking guidance on fetching data using vue-query, Vue.js 3, and the composition API. The data returned to me is ObjectRefImpl, but when I try to print the values, I encounter the error: "Pro ...

ASP.NET - The Power of a Long Press

I am currently working on implementing a Long Press event in JavaScript on an ASPX page. Due to my limited experience with JavaScript, I am facing a few challenges. I found a similar question that was previously asked here. When running the code, I encoun ...

Javascript - Converting a function to run asynchronously

Just starting to work with Node.js for the first time and feeling a bit puzzled by asynchronous functions. I'm getting better at identifying when async is causing issues, but still unsure how to fix them. Here's the code snippet in question: fu ...

How can you integrate Dygraph into your React project alongside redux?

Lately, I've been facing some challenges while trying to integrate Dygraph into React (utilizing Redux). The Dygraph wrapper packages available on NPM don't seem to cooperate. Furthermore, the conventional method of using: <div id="graph"> ...

Importing modules using relative paths results in failure due to module not being found, whereas employing absolute paths

I have been encountering this problem for a considerable amount of time and have made multiple attempts to resolve it. I am currently working on the development of my discord.js bot and recently switched from TS back to JS due to certain complications I fa ...

Discovering the center of an element and implementing a left float

I'm looking for a way to dynamically position the element #ucp_arrow in the middle of a div using float: left. Here is an illustration: https://i.stack.imgur.com/nzvgb.png Currently, I have hard-coded it like this: JAVASCRIPT: $("#a_account").cli ...

Steps for resolving the "endless redirection loop" issue in Sharepoint

I am currently learning Javascript and working on setting up a multi-language Sharepoint site. I am trying to implement a code into each page that checks the user's email and the language in the URL (Portuguese or Spanish) and then redirects according ...

I'm curious if there is an eslint rule specifically designed to identify and flag any unnecessary spaces between a block comment and the function or

Can anyone help me find a solution to prevent the following issue: /** * This is a comment */ function foo() { ... } I need it to be corrected and formatted like this: /** * This is a comment */ function foo() { ... } ...

AngularJS ng-onclick method sending value to Thymeleaf

I am facing an issue with the integration of Thymeleaf and AngularJS. Below is the Thymleaf page I have: <div ng-controller="ctrlsubcomment" > <div class="media" th:fragment="comments" th:each="newsComment : ${comments}"> <img ...

When using AngularJS filter, the comparator will evaluate to true and display the ng-repeat list even when the input

Recently, I stumbled upon this interesting example fiddle showcasing the use of a comparator parameter to filter exact matches: http://jsfiddle.net/api/post/library/pure/ The priority is supposed to be a number between 1-100, but due to inputting it as t ...

AngularJS checkbox ng-repeat directive not displaying controller data

I am facing an issue with rendering checkbox data from the Controller file in my HTML. Here is the code snippet: HTML: <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script& ...