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.
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 () ).
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With