Create a new chart using completely unique information

I am currently working on implementing the example found at http://bl.ocks.org/mbostock/1093130. The goal is to have the "update" function redraw the graph with a completely different dataset each time a button on the DOM is pressed. I have made some modifications to the example in order to achieve this. Let's say I want to randomly populate the graph with JSON datasets whose names are stored in an array:

var array = ["graph.json","graph2.json"];    
function reload() {
    var rnd = Math.floor(Math.random()*2);
    d3.json(array[rnd], function(error, json) {
        if (error) throw error;

        root = json;
        update();
    });    
}

However, whenever the graph is redrawn, there seems to be a bug where nodes from the previous dataset still appear. I have tried various methods to remove elements from the container before calling update(), but none of them seem to work. After researching, I came across the data() function that uses a join approach to update the graph with changes in the data. Although this approach is useful for dynamic updates, it does not suit my needs. I then tried using datum() instead of data() as it was suggested for non-dynamic layouts, and removed the enter() and exit() calls accordingly. While the code compiles without errors, nothing is rendered on the screen. Here is the updated update() function:

function update() {
  var nodes = flatten(root),
      links = d3.layout.tree().links(nodes);

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

  // Update links.
  link = link.datum(links, function(d) { return d.target.id; });

  link.insert("line", ".node")
    .attr("class", "link");

  // Update nodes.
  node = node.datum(nodes, function(d) { return d.id; });

  var nodeEnter = node.append("g")
    .attr("class", "node")
    .on("click", click)
    .call(force.drag);

  nodeEnter.append("circle")
    .attr("r", function(d) { return Math.sqrt(d.size) / 10 || 4.5; });

  nodeEnter.append("text")
    .attr("dy", ".35em")
    .text(function(d) { return d.name; });

  node.select("circle")
    .style("fill", color);
}

Any help or guidance on this issue would be greatly appreciated.

https://i.stack.imgur.com/wzhv5.png

In the image above, you can see that the displayed data does not match the dataset. It should show names like "Mike", "Mike Jr.", "Paul"... and when collapsing nodes by clicking the root node, some of the data gets corrected, but not the data on the root node itself.

Here is the correct data that should be displayed:

//Second graph
{
 "name": "Mike",
 "children": [
  {
   "name": "Mike Jr.",
   "children": [
    {
     "name": "Paul",
     "children": [      
      {"name": "Peter", "size": 743}
     ]
    }
   ]
  }
 ]
}

Answer №1

It seems like you might need a refresher on the fundamental concepts of D3, specifically the enter, update, exit pattern. If you're interested, here is an informative article by Mike Bostock discussing this topic. Below is an image from the article:

https://i.stack.imgur.com/25xUD.png

The key principle is that when making changes to your data, you must rejoin the data:

var circles = d3.selectAll("circle").data(nodes, function(d) { return d.id; });

Afterwards, you can utilize specific functions to determine what has been modified. D3 automates the process of tracking data and HTML elements to identify necessary updates. This allows you to perform actions such as:

circles.enter().append("circle"); // Adding circles for new entries
circles.exit().remove();            // Removing outdated circles from the DOM

Once you invoke enter(), the data items are moved to the update section - where existing data points with representations in the DOM reside. Subsequently, you can apply:

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

Furthermore, it's crucial to pass the key function into .datum() or .data(). Your current implementation appears to include this, so make sure to retain it for effective data management.

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

Value of type 'string' cannot be assigned to type '{ model: { nodes: []; links: []; }; }'

I am a beginner in TypeScript and I have added types to my project. However, I am encountering an error with one of the types related to the graph: Type 'string' is not assignable to type '{ model: { nodes: []; links: []; }; }'.ts(2322) ...

Dealing with currency symbols in Datatables and linking external sources

I'm having trouble linking an external link to the "customer_id" field. The link should look like this: /edit-customer.php?customer_id=$customer_id (which is a link to the original customer id). I am creating a detailed page with most of the informati ...

Issues encountered while trying to integrate chessboard.js into a Vue application

I am facing an issue while trying to incorporate chessboard.js into my jetstream-vue application. Following the creation of the project, I executed the command npm install @chrisoakman/chessboardjs which successfully downloaded the package into my node_mod ...

The use of set.has in filtering does not produce the desired outcome

I am attempting to use Set.has to filter an array in the following way: const input = [ { nick: 'Some name', x: 19, y: 24, grp: 4, id: '19340' }, { nick: 'Some name', x: 20, y: 27, grp: 11, id: '19343' }, { ...

IE Script loading

There is a script that I have, it appends in the document like so: window.d = document s = d.createElement('script') s.setAttribute('type','text/javascript') s.setAttribute('src',options.url) d.getElementById ...

Ensuring the validity of input tags

I encountered an issue with an input tag that has a specific logic: https://codepen.io/ion-ciorba/pen/MWVWpmR In this case, I have a minimum value retrieved from the database (400), and while the logic is sound, the user experience with the component lea ...

Revamping an npm package on GitHub

Currently, I am managing a project that has gained popularity among users and has received contributions from multiple individuals. The next step I want to take is to convert the entire library into TypeScript, but I am unsure of the best approach to ach ...

Does creating a form render the "action" attribute insignificant in an AJAX environment?

When submitting forms exclusively through AJAX, is there any advantage to setting the action attribute at all? I have yet to come across any AJAX-form guides suggesting that it can be left out, but I fail to see the purpose of including it, so I wanted t ...

Adding and removing controls on Google Maps in real-time

Recently, I encountered an issue with my custom search bar overlapping some controls on my map. Despite adjusting the z-index of these controls, they continued to stay on top. To work around this problem, I thought about hiding the controls during the sear ...

Is there a messaging app that provides real-time updates for when messages are posted?

I am in the process of developing a messaging application. User1 sends out a message, and I want to display how long ago this message was posted to other users - for example, "Posted 9 min. ago", similar to what we see on sites like SO or Facebook. To ach ...

Utilizing jQuery to select an attribute containing a special character

There is a special div with a unique data-id: <div data-id=""> </div> I tried to target this div using jQuery, but it didn't work as expected: jQuery("[data-id='']").text('hello'); Can anyone help me on how to ...

Retrieve the string saved in a ViewBag when the ajax call is successful

I am new to ASP.NET MVC and have been struggling to find a solution to this problem. Despite searching on various platforms, including Stack Overflow, I have not been able to resolve it. Here are some links to solutions that did not work for me: Possible ...

Using ng-transclude directive allows for encapsulating HTML content within an ng-transclude element

My directive includes an ng-repeat in the template and also has an ng-transclude option after the repeater to allow users to input their own content. The issue arises when the custom content is surrounded by an ng-transclude element upon rendering, which i ...

Struggling to loop through a child in Firebase real-time database?

I'm struggling to retrieve a nested child from my database with the following structure https://i.stack.imgur.com/ZDs38.png I am attempting to get the URI from the Gallery object. When I log in, I can see this in the console https://i.stack.imgur.c ...

Why won't the div move when I click it?

Could you please explain why my JavaScript code isn't functioning as expected? The intended behavior is for the 'mark' div to move to the current mouse coordinates upon clicking within the map. ...

What is the best way to apply a specific style based on the book ID or card ID when a click event occurs on a specific card in vue.js

My latest project involves creating a page that displays a variety of books, with the data being fetched from a backend API and presented as cards. Each book card features two button sections: the first section includes "ADD TO BAG" and "WISHLIST" buttons ...

Typescript inheritance results in an undefined value being returned

I am trying to understand the code below, as I am confused about its functionality. In languages like C# or Java, using the base or super keyword usually returns values, whereas in TypeScript, I am receiving "undefined". However, when I switch from using " ...

Unleashing the power of conditional exports in package.json

Within my package.json, I define an exports section: "exports": { "import": "./dist/a.es.js", "require": "./dist/b.umd.js" }, However, during development, I wish to use different pa ...

JSP checkbox functionality

I have been attempting to solve this issue since last night, but I am struggling and need some help. There are two pages, named name.jsp and roll.jsp. In name.jsp, there are two input text boxes and one checkbox. After entering data in the text boxes and ...

Cannot save PDF files to a server using jsPDF

I'm new to this community and still learning javascript & php. I am having trouble saving my PDFs with jsPDF to the local storage on the server (automatically generated). It used to work in the past, but now when I add Canvas (javascript) to my HTML, ...