Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate over already created nodes in D3js

I am using a force-directed graph and am adding newly created nodes to the graph. This works perfectly fine.

My node has a property called "state" that keeps changing. The problem I'm facing is that, in my code, the condition to check the "state" is only checked when a new node comes in. When theres an update, my JSON is updated with the state but the execution doesn't reach the code for checking the state.

Find my code below:

function buildGraph() {
                // Update link data
                link = link.data(links);

                // Create new links
                link.enter().append("g")
                .attr("class", "link")
                .each(function (d) {
                    d3.select(this)
                    .append("line")
                    .attr("stroke", "#000")
                    .attr("stroke-width", 2)
                    .attr("opacity", 0.3);
                });

                // Delete removed links
                link.exit().remove();

                // Update node data
                node = node.data(nodes);

                // Create new nodes
                node.enter().append("g")
                .attr("class", "node")
                .each(function (d) {
                    if (d.state == "0") {                      // doesn't come here after an update
                        var imgId = d.name;
                        d3.select(this).append("svg:image")
                        .attr("class", "spinner")
                        .attr("id", imgId)
                        .attr("xlink:href", "Images/icons/ajax-loader.gif")
                        .attr("x", "+16px")
                        .attr("y", "-16px")
                        .attr("width", "20px")
                        .attr("height", "20px");
                    } else if (d.state == "1") {
                        var imgId = "#" + d.name;
                        d3.select(imgId).remove();
                    } else if (d.state == "3" || d.state == "4") {
                        //d3.select(this)
                        //    .style("opacity", 0.4);

                        d3.select(this)
                        .style("filter", function (d, i) {
                            if (i % 2 == 0) {
                                return ("filter", "url(#desaturate)");
                            } else {
                                return "";
                            }
                        });
                    }

                    d3.select(this).append("text")
                    .attr("dy", ".50em")
                    .attr("text-anchor", "end")
                    .attr("font-size", "15px")
                    .attr("fill", "black")
                    .text(function (d) { return d.name; });

                    d3.select(this).call(force.drag);
                })
                //.call(force.drag)
                .on('mouseover', tip.show)
                .on('mouseout', tip.hide);

                // Delete removed nodes
                node.exit().remove();

                //debugger;
                force.start();
            }

I understand that right now, its iterating over new nodes only. Can someone please tell me how to iterate over the existing nodes too?

Thanks in advance.

like image 203
Natasha Avatar asked Dec 10 '14 15:12

Natasha


People also ask

How do I access the current event in D3 event?

Any event that is registered by selection.on will be accessible inside the event handler with the static field d3.event. d3.event always points to the current event being invoked, so it is useful inside event functions to access various fields or methods on the event (such as event.timeStamp or event. preventDefault () ).

Can I add tooltips to a visualization in D3 JS?

In this tutorial, we’ll explore one such limitation of d3.js by adding tooltips to a visualization, which is not an inherent capability of the library. Instead, we’ll explore two examples, one using the browser’s built-in title tag and the other using a custom div attached to mouse events.

How to add an event to every node in a selection?

Luckily D3.js allows us to add an event to every node in a selection at once with selection. on (typenames [,listener [,options]]). We use selection.on in a similar way as addEventListener.

How to display part of a D3 visualization when mousing over it?

Easily the most basic method for displaying data that is part of a d3.js visualization when mousing over part of the graphic is to use the title tag.


Video Answer


1 Answers

You can simply select your nodes and manipulate them in the part of your code where the state update happens.

function updateState() {
  ... // processing the update
  d3.selectAll('g.node')  //here's how you get all the nodes
    .each(function(d) {
      // your update code here as it was in your example
      d3.select(this) // Transform to d3 Object
      ... 
    });
}

If the update happens very frequently, it might be worth storing the selection in a variable and saving the time it takes to search through the DOM.

like image 152
Andrew Avatar answered Oct 23 '22 17:10

Andrew