I’m working on a project where I’m visualizing a network graph using the networkD3 package in R. The network consists of nodes and edges, represented by two data frames: node_df and edge_df, respectively. The node_df data frame contains information about the nodes, including their IDs, labels, groups, and colors. The edge_df data frame contains information about the edges, including the source and target nodes, as well as edge labels.
I’ve tried various approaches to visualize the network graph and add interactivity to it, adding tooltips to nodes and edges. However, I haven’t been successful on adding the tooltips on the arrows when hovering the mouse.
Here’s a summary of the code I’ve tried so far:
Data
> head(edge_df, 10)
id from to rel label penwidth color fontname fontsize weight constraint
1 1 2 16 <NA> 183 5.000000 dodgerblue4 Arial 10 1 TRUE
2 2 3 6 <NA> 1 1.021858 dodgerblue4 Arial 10 1 TRUE
3 3 3 11 <NA> 10 1.218579 dodgerblue4 Arial 10 1 TRUE
4 4 3 17 <NA> 5 1.109290 dodgerblue4 Arial 10 1 TRUE
5 5 3 19 <NA> 2 1.043716 dodgerblue4 Arial 10 1 TRUE
6 6 4 4 <NA> 2 1.043716 dodgerblue4 Arial 10 1 TRUE
7 7 4 21 <NA> 1 1.021858 dodgerblue4 Arial 10 1 TRUE
8 8 5 17 <NA> 17 1.371585 dodgerblue4 Arial 10 1 TRUE
9 9 6 6 <NA> 1 1.021858 dodgerblue4 Arial 10 1 TRUE
10 10 6 10 <NA> 5 1.109290 dodgerblue4 Arial 10 1 TRUE
> head(node_df, 10)
id type label shape color_level style fontcolor color tooltip
1 1 <NA> End circle Inf rounded,filled brown4 brown4 ARTIFICIAL_ENDn183
2 2 <NA> Start circle Inf rounded,filled chartreuse4 chartreuse4 ARTIFICIAL_STARTn183
3 3 <NA> Analyze Donen18 rectangle 0.08333333 rounded,filled black grey Analyze Donen18
4 4 <NA> Approvedn3 rectangle 0.01388889 rounded,filled black grey Approvedn3
5 5 <NA> Back from Developmentn17 rectangle 0.07870370 rounded,filled black grey Back from Developmentn17
6 6 <NA> Backlogn9 rectangle 0.04166667 rounded,filled black grey Backlogn9
7 7 <NA> Cancelledn1 rectangle 0.00462963 rounded,filled black grey Cancelledn1
8 8 <NA> Closedn138 rectangle 0.63888889 rounded,filled white grey Closedn138
9 9 <NA> Dispatchedn166 rectangle 0.76851852 rounded,filled white grey Dispatchedn166
10 10 <NA> Donen216 rectangle 1.00000000 rounded,filled white grey Donen216
penwidth fixedsize fontname fontsize fillcolor Group
1 1.5 FALSE Arial 10 white End
2 1.5 FALSE Arial 10 white Start
3 1.5 FALSE Arial 10 #ECE7F2 Analyze Donen18
4 1.5 FALSE Arial 10 #FFF7FB Approvedn3
5 1.5 FALSE Arial 10 #ECE7F2 Back from Developmentn17
6 1.5 FALSE Arial 10 #FFF7FB Backlogn9
7 1.5 FALSE Arial 10 #FFF7FB Cancelledn1
8 1.5 FALSE Arial 10 #74A9CF Closedn138
9 1.5 FALSE Arial 10 #3690C0 Dispatchedn166
10 1.5 FALSE Arial 10 #034E7B Donen216
Code
# Add a dummy "Group" column to nodes dataframe
node_df$Group <- node_df$label
#
edges_net <- edge_df[, c("from", "to", "label")]
colnames(edges_net) <- c("from", "to", "title")
nodes_net <- node_df[, c("id", "label", "Group", "fillcolor")]
colnames(nodes_net) <- c("id", "node_label", "Group", "nodes_color")
# Subtract 1 from the "from" and "to" columns to zero-index them
edges_net$from <- edges_net$from - 1
edges_net$to <- edges_net$to - 1
# set node size
nodes_net$NodeSize <- 20
# JS
clickJS <- "
d3.selectAll('.xtooltip').remove();
d3.select('body').append('div')
.attr('class', 'xtooltip')
.style('position', 'absolute')
.style('border', '1px solid #999')
.style('border-radius', '3px')
.style('padding', '5px')
.style('opacity', '0.85')
.style('background-color', '#fff')
.style('box-shadow', '2px 2px 6px #888888')
.html('name: ' + d.name + '<br>' + 'group: ' + d.group)
.style('left', (d3.event.pageX) + 'px')
.style('top', (d3.event.pageY - 28) + 'px');
"
# plot network
my_network<- networkD3::forceNetwork(
Links = edges_net,
Nodes = nodes_net,
Source = "from",
Target = "to",
Value = "title",
NodeID = "node_label",
Group = "Group",
colourScale = networkD3::JS("d3.scaleOrdinal(d3.schemeCategory20);"),
linkDistance = 300,
linkWidth = networkD3::JS("function(d) { return Math.sqrt(d.value);}"),
radiusCalculation = networkD3::JS(" Math.sqrt(d.nodesize)+6"),
Nodesize = "NodeSize",
charge = - 30,,
linkColour = "black",
opacity = 0.8,
zoom = T,
legend = T,
arrows = T,
bounded = T,
opacityNoHover = 1.5,
fontSize = 12,
clickAction = clickJS
#
)
# Increase the size of nodes
my_network$x$width <- '1200px'
my_network$x$height <- '800px'
# Get the target variable in fn$x$links (an integer id) to show up as a tooltip when user hovers over a link (i.e. edge) in the graph
fnrender <- htmlwidgets::onRender(
my_network,
'
function(el, x) {
d3.selectAll(".link").append("svg:title")
.text(function(d) { return d.source.name + " -> " + d.target.name; })
}
'
)
# display the result
fnrender
Produced graph

The objective of my project is to create an interactive network visualization where users can hover on nodes to view additional information and hover over edges to see edge labels.