0

I have created a dynamically built force graph in D3. When I click on one of the links I want to only show that and all the connected links/nodes.

This Plunkr is a simplified version of what I have: http://plnkr.co/edit/TiKKmvydqXNipe103juL?p=preview (EDIT: I have updated this and is now a complete solution).

As you can see there are 3 separate 'groups' of connected nodes, in my real data set there are several hundred nodes and I want to be able to isolate an individual 'group' and only show that when the link which is part of that group is clicked on (it can't be the node that is clicked on as this shows a pop-up with more info).

I have been able to colour/hide connected links by pre-processing my data and using a rather complicated and long winded algorithm to determine whether the links are in the same connected group.

I have also been able to change the node that is clicked on or all the nodes/links by changing the dragstart function, this feels like I am getting close, but I don't think it recognises any link relationships.

function dragstarted(d) {
  if (!d3.event.active) simulation.alphaTarget(0.3).restart();
    // Changes all nodes/links
    d3.select("circle").classed("others",true).style("display","none"); 
    // Trying different ways to hide only 'other' nodes
    d3.selectAll("circle").classed("others",true).style("display","none"); 
    d3.selectAll("line").classed("others",true).style("display","none");

    d.fx = d.x;
    d.fy = d.y;
}

(I am aware of this question/answer how to highlight(change color) of all connected(neighbours) nodes and links in a d3 force directed graph but I don't think it really helps).

Any help would be appreciated.

AEngineer
  • 152
  • 3
  • 12
  • This is the answer I used for a similar function: https://stackoverflow.com/questions/8739072/highlight-selected-node-its-links-and-its-children-in-a-d3-force-directed-grap – Oliver Houston Jun 05 '17 at 11:11
  • Thanks I found that just after I had posted this. I may be able to make it fit. – AEngineer Jun 05 '17 at 11:30
  • I have updated my Plunker with an implementation of the method highlighted in that post and it kinda works, but doesn't seem to get the links correct. I don't really understand it - I have updated the data to make 2 of the groups identical and clicking on link MN works, but clicking on link HI doesn't. Which is confusing as they are in the same place in relation to the rest of their attached nodes. – AEngineer Jun 05 '17 at 14:00
  • OK, I see your problem, when you click on the links it seems to highlight an arbitrary selection of the links in one of your networks. Rather than the whole network... Is that correct? I think you may need a slightly more complicated function, possibly sorting your links... – Oliver Houston Jun 05 '17 at 14:12
  • Thanks for the prompt response. Yes I am seeing the same behaviour. I'll see if I can come up with something better - I actually already have an algorithm as mentioned in the original post, it just seems way too complex. I'm guessing that there is no way of linking the connected elements any other way - something under the covers must know the connections so they all stay connected when dragged? (or are they separate elements with the same physics applied which makes it look like they're connected?) – AEngineer Jun 05 '17 at 14:27

1 Answers1

1

OK, this might be beyond me, but I think you somehow need to group your links into the same sorts of groups as your nodes. If you could somehow add the "group" attribute of the source node to the link, then when you click on the link something like this might work:

d3.selectAll("line")function fade(){if 
(group = "selected", "opacity" = 1)
else
("opacity" = 0)
};

alternatively, if you can sort the links into groups before the data is loaded (in your PHP etc. script), then you could append 3 (or n) groups of lines with separate classes.

Sorry, JS isn't my strongsuit, hopefully someone more experienced will sort that out for us...

Oliver Houston
  • 313
  • 1
  • 9
  • This is exactly what I did in the end. My data is from an external source and is pre-processed into the required JSON object using D3. I am adding a group attribute to the line, circle and text nodes. What I am essentially doing is, getting the source/dest strings for the links, iterating through them and adding them to an existing group or creating a new group if either end of the link doesn't exist in an existing group. The resulting JSON has a group number for each link and node. Here is an updated plunker http://plnkr.co/edit/TiKKmvydqXNipe103juL?p=preview – AEngineer Jun 06 '17 at 08:36