Note that there are some explanatory texts on larger screens.

plurals
  1. POModifying node and edge properties in d3.js
    text
    copied!<p>I am using d3.js to lay out a node and link graph using force layout. Nodes are represented by circles; links by lines. Under certain circumstances, I would like to change the visual characteristics (e.g., color, size, opacity, etc.) of a line or a node to denote some state change on the graph. I have been able to do that by redrawing the graph, but that jiggles all the nodes, resulting in confusing rather than clarity. </p> <p>Code to create the graph:</p> <pre><code>force = d3.layout.force() .charge(-120) .gravity(0.2) .linkDistance(30) .size([width-pad, height-pad]); nodeSet = svg.selectAll(".qNode"); // BIND NODE DATA nodeSet = nodeSet.data(chartData.nodes); // CREATE NODES nodeSet.enter().append("circle") .attr("class", "qNode") .attr("r", function(d) { return d.size();}) .style('stroke-opacity', function(d) { return d.opacity(); }) .style('stroke', function(d) { return d.color(); }) .style("fill", function(d) { return color(1); }); //similarly for links. force.nodes(chartData.nodes).links(chartData.links).start(); </code></pre> <p>To update the graph, I use this fragment:</p> <pre><code> // SELECT NODES nodeSet = svg.selectAll('.qNode'); // JOIN NODES nodeSet = nodeSet.data(force.nodes()); // UPDATE NODES nodeSet.attr("class", "qNode") .attr("r", function(d) { return d.size();}) .style("fill", function(d) { return color(1); }) .style('stroke', function(d) { return d.color(); }) .style('stroke-opacity', function(d) { return d.opacity(); }) .style('opacity', 1) .call(force.drag); // CREATE NODES nodeSet.enter().append("circle") .attr("class", "qNode") .attr("r", function(d) { return d.size();}) .style("fill", function(d) { return color(1); }) .call(force.drag); // DELETE NODES nodeSet.exit().remove(); // START SHOW force.start(); </code></pre> <p>When this runs, the entire graph jiggles a bit before then new stroke attributes are applied.</p> <p>So I have two questions: Assuming a state change in the data object will return different values for <code>d.size()</code>, <code>d.color()</code>, etc.,</p> <ol> <li>How do I modify the visual appearance of the graph without jiggling any nodes?</li> <li>If I do want to jiggle the nodes, can I determine which set of nodes to jiggle? (So that I can signal to the user which linkor node had their visual appearance change.)</li> </ol> <p><strong>EDITED</strong></p> <p>I've given up on jiggling the nodes for the time being, but the following code (based on suggestions by <a href="https://stackoverflow.com/users/2079141/defenestrated">@defenestrated</a>), seems to do the trick to update the properties of some nodes and edges in the graph:</p> <pre><code>var allLinks = ... // my links from a d3 selectAll var allNodes = ... // my nodes from a d3 selectAll force = ... // my d3 force layout function updateGraph(graph, nodeSubset, linkSubset) { for (var i=0; i&lt;allLlinks.length; i++) allLinks[i].selected = false; for (var i=0; i&lt;allNodes.length; i++) allNodes[i].selected = false; for (var i=0; i&lt;linkSubset.length; i++) linkSubset[i].selected = true; for (var i=0; i&lt;nodeSubset.length; i++) nodeSubset[i].selected = true; // these functions modify the selected nodes and links linkSubset.call(setLinkAttributes); nodeSubset.call(setNodeAttributes); if (force.alpha() == 0) { force.start(); force.stop(); } } function setLinkAttributes(links) { link.style(...); } function setNodeAttributes(nodes) { nodes.style(...); } </code></pre> <p>I don't need to call <code>start</code>/<code>stop</code> or <code>resume</code> if the graph is still moving (if <code>alpha() &gt; 0</code>) after applying attributes because the subsequent ticks pick up the new attributes. If the graph has settled, calling start refreshes it without moving the nodes.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload