Is it possible to create a graph using only links from a JSON file when using D3.js?

I am looking to extract node information from links data stored in a JSON file. My ultimate goal is to visualize this data by creating a graph with connections and edges.

Here is a snippet from my sample JSON file:

{
    "links": [
        { "source":0, "target":1, "value":20, "orientation":"down" },
        { "source":1, "target":2, "value":1, "orientation":"left" },
        { "source":2, "target":3, "value":1, "orientation":"right" }
    ]
}

This is the JavaScript function I have implemented:

$(function() {

    var width = 500,
        height = 300;

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

    var force = d3.layout.force()
        .gravity(.05)
        .distance(100)
        .charge(-100)
        .size([width, height]);

    d3.json("test_1.json", function(error, json) {
        if (error) throw error;

        var count = 0;
        var nodes = [];


        json.links.forEach(function(e) { 
            count++;
            nodes.push({name: "test_"+e.source, orientation: e.orientation});
        });
        console.log("Count is : "+count);  

        force
            .nodes(json.nodes)
            .links(json.links)
            .start();

        var link = svg.selectAll(".link")
            .data(json.links)
            .enter().append("line")
            .attr("class", "link");

        var node = svg.selectAll(".node")
           .data(json.nodes)
           .attr("class", "node")
           .call(force.drag);

        node.append("circle")
           .attr("class", "node")
           .attr("r", 5);

        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("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
        });
    });
});

Unfortunately, I am encountering issues with extracting the list from the function due to an error related to the forEach method of JSON data structure.

If anyone could provide guidance or assistance, it would be greatly appreciated.

UPDATE: The complete code has been added for reference.

Error: Cannot read property 'weight' of undefined.

To resolve this issue, I included additional nodes in my JSON as D3.js always requires a node element in the dataset.

Answer №1

When assigning a newly created nodes array to the variable nodes, make sure to pass it to your force layout instead of using links.nodes.

force
    .nodes(nodes)
    .links(json.links)
    .start();

Alternatively, you can simply add it to the links object.


json.links.forEach(function(entry) { 
    counter++;
    nodes.push({label: "sample_"+entry.source, value: entry.value});
});

links.nodes = nodes;
...

Answer №2

After some trial and error, I was able to come up with a solution:

Here is a snippet of my JSON file:

[
    {"source":"entry","target":"chocolate","value":20,"orientation":"down","x": 200, "y": 150},
    {"source":"chocolate","target":"bread","value":1,"orientation":"left","x": 140, "y": 300},
     {"source":"bread","target":"soap","value":1,"orientation":"right","x": 400, "y": 190}
    ]

This is the JavaScript code that helped me visualize the data:

var width = 960,
    height = 500;
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);
var force = d3.layout.force()
    .size([width, height])
    .linkDistance(20)
    .charge(-500);

d3.json("name.json", function(error, links) {
  if (error) throw error;
  var nodesByName = {};
  // Create nodes for each unique source and target.
  links.forEach(function(link) {
    link.source = nodeByName(link.source);
    link.target = nodeByName(link.target);
  });
  // Extract the array of nodes from the map by name.
  var nodes = d3.values(nodesByName);
  // Create the link lines.
  var link = svg.selectAll(".link")
      .data(links)
    .enter().append("line")
      .attr("class", "link");
  // Create the node circles.

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

  // Start the force layout.
  force
      .nodes(nodes)
      .links(links)
      .on("tick", tick)
      .start();

  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; });
  }
  function nodeByName(name) {
    return nodesByName[name] || (nodesByName[name] = {name: name});
  }
});
});

The script successfully visualizes the provided data in a graphical layout.

Thank you!

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

Is there a way to broadcast a message to all the Discord servers where my bot is currently active using v14 of discord.js?

Can someone assist me in creating code that allows me to send a message to all servers at my discretion? I have not found any resources on this topic for discord.py or the newer versions of discord.js ...

Is it possible to create a dynamic header or image that expands and zooms

Have you noticed the iOS-style header images in some apps where you pull to zoom and it feels like an elastic image? I want to replicate this effect using jquery, possibly with some CSS as well. This effect has been achieved using angularjs, but since I& ...

If an Angular reactive form component has a particular value

I am working with a group of radio buttons. When a user chooses the option "yes," I would like to display an additional input box on the form. Link to Code Example HTML.component <div formGroupName="radioButtonsGroup" class="form-group col-6 pl-0 pt- ...

Exclude the HTML attribute prior to displaying

Is there a way to prevent the src attribute from being used for each img tag until after a certain action is completed? I am trying to modify how images are fetched. Here's what I tried: $('img').each(function() { var elem = $(this); ...

The tooltip chart is not displaying all of its data

I create a dynamic tooltip with a custom chart inside of it. tooltip: { borderRadius: 15, borderWidth: 0, shadow: false, enabled: true, backgroundColor: 'none', useHTML: true, shared: true, formatter: function() { ...

Troubleshooting Images in a React Application Integrated with WordPress API

I am struggling to understand why this GET request is consistently returning a 404 error. I have thoroughly tested the URL using Postman and everything seems to be in working order for the title and excerpt, but the images are causing some issues. Does a ...

Encountering a problem during the installation process of cldr

GET `https://github.com/unicode-cldr/cldr-units-modern/archive/36.0.0.zip` Uh oh! There was an error while making the request. The error mentioned above occurs when attempting to: npm i cldr-data We have been using an Angular project for quite some time ...

Extract JSON components from MQTT Socket in Flask

Currently utilizing MQTT-Flask to send a payload over MQTT and sockets to my Flask webserver. The integration has been successful, but now I am looking to convert the payload into JSON format to include more data, allowing me to use the variables across di ...

Sharing authentication sessions between Node.js and Redis

Utilizing both PHP and Node.js, I discovered a method for authenticating users. The first step was changing my PHP session save path to Redis. Below is the code snippet for inserting a session: session_name("userID"); session_start(); $_SESSION["usern ...

Verify the form's accuracy prior to transmitting the information through AJAX to the designated resources on Liferay version 7.3.5

Currently, I am in the process of creating a form within Liferay 7.3.5 with a specific goal in mind. This form is designed to validate input data before it is sent via AJAX to designated resources. Despite having functioning code, I am facing an issue whe ...

Creating an application that retrieves JSON data from the tmdb.org API

I'm in the process of developing an app where I aim to have a grid of popular movie posters displayed upon launching. These movie posters are obtained from TheMovieDataBase API and then loaded using Picasso. To implement the GridView, I'm utilizi ...

Repeated actions using jQuery

Being new to jQuery, I am currently exploring ways to repeat functions without the need to continuously write them over and over again. In the code snippet below, you can see that when a button is clicked, it changes to 'I was clicked' in an h1 t ...

Attempting to showcase PHP print statement within HTML using JSON

I want to showcase two PHP echo messages from a different PHP file on my HTML body page. I aim for the echo message to appear when I click the submit button, without being redirected to the PHP page. To achieve this, I need to establish a connection betwe ...

JavaScript: function that operates asynchronously

I am new to JavaScript and encountered some issues with async functions. I have a function that fetches data from MongoDB by creating a promise, but it returns a collection with an empty object. async function getRating(item, applicant) { let arr = await ...

The Google reCaptcha fails to load if Bootstrap is used to call the remote modal

On my initial page, I have defined the following: <span class="btn btn-default"> <a data-toggle="modal" id="fillTheFormHiddenInput" data-target="#login-modal" href="login-i">sign in</a> </span> And at the end of the first ...

Tips for verifying if a JSON element is a JSON primitive

Currently, I am in the process of transitioning code from Gson to Jackson. One of the tasks at hand involves verifying if the type of the current element is primitive. In Gson, I could perform this check like so: JsonElement element = entry.getValue(); i ...

Executing a JavaScript command within an R package had become a common practice among

I am looking to create identicons using the Jdenticon library within an R package. I want a function that takes certain arguments stored in R variables, such as the output file name, and returns a filename corresponding to the generated Jdenticon (in eithe ...

Menu options

I am currently working on developing a mouseover navigation website. Initially, my design included main buttons for "Our Team", Locations, and Patient Resources. Here is the basic structure I had before attempting to switch to a mouseover approach... &l ...

How can PHP handle JSON data that arrives in an incomplete format?

I have created a basic website application that interacts with an API to gather backlink data for any website entered by the user. The API sends data in JSON format, consisting of strings and numbers. After parsing the response, I filter out the desired da ...

How come my uvmapped texture is flipping vertically when using iewebgl + threejs?

Currently in the process of developing a 3D viewer for game pads with the aim of customizing the pad using various colors and materials. Initially, I created a simple ".bin .js" loader with sample materials using Threejs r62 to create a visualizer prototy ...