Connecting nodes to edges based on their unique ids in the d3.js graph library

I am encountering an issue with this code while trying to integrate it with a new JSON object called 'new_json'. Specifically, I need the links in this code to be created based on the nodes' IDs. Can anyone provide assistance with this?

 var new_json = {{"nodes": [{ "id": 124587, "name": "paper1", "citation": 5, "group": 1 },
{ "id": 178456, "name": "paper2", "citation": 8, "group": 2 }],
"links": [{ "source": 124587, "target": 178456, "name": "A-B-1", "value": 8 }]};

function load_graph(text) {
            var color = d3.scale.category20();           
            var data1 = {
                "nodes": [
                    { "id": 0, "name": "paper1", "citation": 5, "group": 1 },
                    { "id": 1, "name": "paper2", "citation": 8, "group": 2 },
                    { "id": 2, "name": "paper3", "citation": 12, "group": 3 },
                    { "id": 3, "name": "paper4", "citation": 25, "group": 4 },
                    { "id": 4, "name": "paper5", "citation": 15, "group": 5 },
                    { "id": 5, "name": "paper6", "citation": 5, "group": 1 },
                    { "id": 6, "name": "paper7", "citation": 8, "group": 2 },
                    { "id": 7, "name": "paper8", "citation": 12, "group": 3 },
                    { "id": 8, "name": "paper9", "citation": 25, "group": 4 },
                    { "id": 9, "name": "paper10", "citation": 15, "group": 5 }
                ],
                "links": [
                    { "source": 0, "target": 1, "name": "A-B-1", "value": 8 },
                    ...
                    ... (more data values)
                ]
            };

            // more JavaScript code ...

        }

</script>

Answer №1

Force layout primarily operates based on indexes rather than IDs or names. Therefore, you need to specify that you want to establish a connection via ID in your scenario:

var edges = [];
data.links.forEach(function(e) {
    var sourceNode = data.nodes.filter(function(n) {
        return n.id === e.source;
    })[0],
        targetNode = data.nodes.filter(function(n) {
            return n.id === e.target;
        })[0];

    edges.push({
        source: sourceNode,
        target: targetNode
    });
});

The provided code identifies which node matches the same ID as the link's source and pushes it into the source of the edges array. The same process is repeated for the target node. Subsequently, use this edges array to construct the graph:

Force :

force
      .nodes(data.nodes)
      .links(edges)

Regarding the links :

var link = svg.selectAll(".link")
          .data(edges)

A demo implementation with your new_json can be found here: https://jsfiddle.net/thatOneGuy/60oLwg8t/1/

Alternatively:

 
  var data = 
      {
        "nodes": [{
          "id": 124587,
          "name": "paper1",
          "citation": 5,
          "group": 1
        }, {
          "id": 178456,
          "name": "paper2",
          "citation": 8,
          "group": 2
        }],
        "links": [{
          "source": 124587,
          "target": 178456,
          "name": "A-B-1",
          "value": 8
        }]
      };

console.log(data.nodes)
console.log(data.links)
      var width = 960,
        height = 500;

      var color = d3.scale.category20();

      var force = d3.layout.force()
        .charge(-120)
        .linkDistance(30)
        .size([width, height]);

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

      var edges = [];
data.links.forEach(function(e) {
    var sourceNode = data.nodes.filter(function(n) {
        return n.id === e.source;
    })[0],
        targetNode = data.nodes.filter(function(n) {
            return n.id === e.target;
        })[0];

    edges.push({
        source: sourceNode,
        target: targetNode,
        value: e.Value
    });
});


        force
          .nodes(data.nodes)
          .links(edges)
          .start();
        var link = svg.selectAll(".link")
          .data(edges)
          .enter().append("line")
          .attr("class", "link")
          .style("stroke-width", 2);

        var node = svg.selectAll(".node")
          .data(data.nodes)
          .enter().append("circle")
          .attr("class", "node")
          .attr("r", 5)
          .style("fill", 'red')
          .call(force.drag);

        node.append("title")
          .text(function(d) {
            return d.name;
          });

        force.on("tick", function() {
          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;
            });
        }); 
.node {
  stroke: #fff;
  stroke-width: 1.5px;
}

.link {
  stroke: #999;
  stroke-opacity: .6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

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

Tips for including a decimal point in an angular reactive form control when the initial value is 1 or higher

I am trying to input a decimal number with 1 and one zero like 1.0 <input type="number" formControlName="global_velocity_weight" /> this.form = this.fb.group({ global_velocity_weight: new FormControl(1.0, { validators: [Valida ...

The background failed to display (potentially due to a hovering function)

I encountered an issue with a div that has a background image. Upon loading the page, the background image fails to display initially. However, when I hover over the div and then move my mouse elsewhere (due to a specific function described below), the bac ...

The appearance of all input forms in MaterializeCSS when used in an electron environment appears to

After following the instructions here on how to get started with Materialize CSS, I am having issues with my input form appearing strange: https://i.sstatic.net/lveS2.png The contents of my current index.html file are as follows: <!DOCTYPE html> &l ...

The transfer of JSON information from View to Controller yields no value

My goal is to create functionality where users can add and delete JQuery tabs with specific model data, and then save this data to a database. I'm attempting to use an ajax call to send JSON data to the controller, but I am encountering an issue where ...

Using SVG Mask to enhance shape Fill

I am having trouble achieving the desired effect of darkening the fill of objects based on a specified gradient. Instead, when the mask is applied over the fill, it actually lightens it. I suspect that this issue arises from the color blending method being ...

Unlocking the Power of Select Options in Vue.js

I am currently learning how to use Vue.js. Below is an example of the Javascript code I have written: new Vue({ el: '#app', data: { classes: [] }, created: function () { var vm = this // Fetch API ...

Provide the identification number of a specific row within the modal

I am trying to pass the id of a specific row into a modal popup Link code: <a href="#myModal" class="btn btn-default btn-small" id="custId" data-toggle="modal" data-id="<? echo $row['id']; ?>">Resume</a> Modal code: <div ...

What is the best way to send a request using an API key through a form submission method?

I encountered an issue while attempting to retrieve the json response through a form using the post method; I kept receiving a forbidden 403 error. window.onload = function() { document.getElementById("Save").onclick = function fun() { var x = docum ...

Step-by-step guide on setting up a click counter that securely stores data in a text file, even after the

Can anyone help me make this link actually function as intended? Right now it only runs the JavaScript code, but I would like it to run the code and redirect to a webpage. Additionally, I need the data to be saved to a text file. Please provide assistanc ...

Unexpected bug encountered while implementing redux

I received a warning from eslint while working with create-react-app. ./src/components/auth.js Line 24: Unexpected labeled statement no-labels Line 24: 'authenticated:' is defined but never used ...

Adding a fresh element to an array in Angular 4 using an observable

I am currently working on a page that showcases a list of locations, with the ability to click on each location and display the corresponding assets. Here is how I have structured the template: <li *ngFor="let location of locations" (click)="se ...

Error: Unable to authenticate due to timeout on outgoing request to Azure AD after 3500ms

Identifying the Problem I have implemented SSO Azure AD authentication in my application. It functions correctly when running locally at localhost:3000. However, upon deployment to a K8s cluster within the internal network of a private company, I encounte ...

Error: Identical div IDs detected

<div id="tagTree1" class="span-6 border" style='width:280px;height:400px;overflow:auto;float:left;margin:10px; '> <a class="tabheader" style="font-size:large">Data Type</a><br /> <div class="pane">Refine sea ...

What is the best way to efficiently query a substantial dataset using Node.js in an asynchronous fashion?

I need to extract data from a mysql database by fetching 10 rows at a time until I reach 400k rows. To achieve this asynchronously, I am using recursion as shown in the code below: var migrate = function(offset, size) { Mysql.query(query, [offset, size] ...

Troubleshooting: The issue of receiving a 403 error when trying to access

I'm currently using Codeigniter 3 and have encountered an issue with a script. When the code is in my HTML file, everything works perfectly fine. However, if I move the code to an external file, I receive a 403 error. The location of my JavaScript fi ...

Using Typescript to iterate through an array of objects and modifying their keys using the forEach method

I have an object called 'task' in my code: const task = ref<Task>({ name: '', description: '', type: undefined, level: 'tactic', participants: undefined, stages: undefined, }); export interface Tas ...

Tips for maintaining the original value of a state variable on a child page in ReactJS. Keeping the initial value passed as props from the parent page

Whenever the 'isChildOpen' flag in the parent is true, my child page opens. The goal now is to ensure that the state variable filtered2 in the child component remains constant. While both filtered and filtered2 should initially receive the same v ...

Setting up an OnMouseOver event for each URL on a webpage

Is there a way to add an OnMouseOver event for all anchor tags on a page, without replacing any existing event handlers that are already in place? I'm looking for guidance on how to achieve this using JavaScript or JQuery. Any suggestions would be gr ...

Modify the event from creating a table on click to loading it on the page onload

Hey there, friends! I've been brainstorming and came up with an idea, but now I'm stuck trying to switch the code to onload(). I've tried numerous approaches, but none seem to be working for me. Below is the code I've been working wit ...

Executing a function on page load instead of waiting for user clicks

I've been researching a problem with onclick triggers that are actually triggered during page/window load, but I haven't been able to find a solution yet. What I need is the ID of the latest clicked button, so I tried this: var lastButtonId = ...