I would like to highlight the links and nodes to the parent node in a graph when the child node is hovered. I took inspiration from The New York Times 'Paths to the white house':
I have seen the answer to this question with this Fiddle using:
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter()
.append("g")
.attr("class", function(d) { return "node " + d.name + " " + d.location; })
.call(force.drag)
.on("mouseover", function(d) {
// if(isConnected(d, o)) {
d3.select(this).select("circle").style("stroke-width", 6);
var nodeNeighbors = graph.links.filter(function(link) {
return link.source.index === d.index || link.target.index === d.index;
})
.map(function(link) {
return link.source.index === d.index ? link.target.index : link.source.index;
});
svg.selectAll('circle').style('stroke', 'gray');
svg.selectAll('circle').filter(function(node) {
return nodeNeighbors.indexOf(node.index) > -1;
})
// }
.on("mouseover", function(d) {
// I would like to insert an if statement to do all of
// these things to the connected nodes
// if(isConnected(d, o)) {
d3.select(this).select("circle").style("stroke-width", 6);
d3.select(this).select("circle").style("stroke", "orange");
// }
})
.on("mouseout", function(d) {
// if(isConnected(d, o)) {
d3.select(this).select("circle").style("stroke-width", 1.5);
d3.select(this).select("circle").style("stroke", "gray");
// }
});
Though they're using source and target, I wonder if it's also possible, and how it would be done, with a network diagram (force-directed graph) using parent and children?
I've done something similar by adapting the functions found in this example. The trick is to build selections that work on only the links you'd like to highlight. Here's a snippet of my code:
function linkMouseover(d){
chart.selectAll(".node").classed("active", function(p) { return d3.select(this).classed("active") || p === d.source || p === d.target; });
}
// Highlight the node and connected links on mouseover.
function nodeMouseover(d) {
chart.selectAll(".link").classed("active", function(p) { return d3.select(this).classed("active") || p.source === d || p.target === d; });
chart.selectAll(".link.active").each(function(d){linkMouseover(d)})
d3.select(this).classed("active", true);
}
This force-directed example uses the terminology source and target—I don't imagine there's much distinction between source-target and parent-child. You should be able to make it work by editing the above, such that the .each()
and .classed()
callbacks operate only on the highlighted node, its (multiple generations of) children, and links between them.