You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于networkD3包forceNetwork实现悬停显示自身及邻接节点名称

解决networkD3 forceNetwork邻接节点高亮问题

Got it, I see exactly what you're dealing with here. The built-in opacityNoHover parameter in forceNetwork is too blunt—it makes every node except the one you're hovering over transparent, which isn't what you want when you need to highlight a node and its direct neighbors.

The fix here is to use custom JavaScript (via D3.js, which networkD3 is built on) to override the default hover behavior. We'll listen for mouseover/mouseout events on nodes, then manually toggle visibility for only the relevant nodes (and links, if you want) instead of using the one-size-fits-all opacityNoHover.

Here's a complete, working example:

library(networkD3)
library(htmlwidgets)

# Load example data
data(MisLinks)
data(MisNodes)

# Create the base force network (don't use opacityNoHover here)
base_network <- forceNetwork(
  Links = MisLinks,
  Nodes = MisNodes,
  Source = "source",
  Target = "target",
  Value = "value",
  NodeID = "name",
  Group = "group",
  opacity = 1,
  fontSize = 15,
  opacityNoHover = 1  # Keep all nodes visible by default
)

# Add custom JS to handle neighbor highlighting
enhanced_network <- onRender(
  base_network,
  'function(el, x) {
    // Grab all node and link elements from the rendered chart
    const nodes = d3.select(el).selectAll(".node");
    const links = d3.select(el).selectAll(".link");
    
    // Store original opacity values so we can reset later
    nodes.each(d => d.originalOpacity = 1);
    links.each(d => d.originalOpacity = 1);
    
    // Handle mouseover event
    nodes.on("mouseover", (event, d) => {
      // Create a set to hold IDs of the hovered node and its direct neighbors
      const connectedIds = new Set([d.id]);
      
      // Iterate through all links to find neighbors
      x.links.forEach(link => {
        if (link.source === d.id) connectedIds.add(link.target);
        if (link.target === d.id) connectedIds.add(link.source);
      });
      
      // Show only connected nodes, hide others
      nodes.style("opacity", nodeD => connectedIds.has(nodeD.id) ? 1 : 0);
      
      // Optional: Show only links connected to the hovered node/neighbors
      links.style("opacity", linkD => {
        return connectedIds.has(linkD.source) && connectedIds.has(linkD.target) ? 1 : 0;
      });
    });
    
    // Handle mouseout event to reset everything
    nodes.on("mouseout", () => {
      nodes.style("opacity", d => d.originalOpacity);
      links.style("opacity", d => d.originalOpacity);
    });
  }'
)

# Display the enhanced network
enhanced_network

Key details about this solution:

  • We use htmlwidgets::onRender() to inject custom D3.js code after the network renders—this lets us override the default hover behavior.
  • On mouseover, we build a set of IDs including the hovered node and all its direct neighbors by checking the link data.
  • We then set opacity to 1 for nodes in that set, and 0 for everyone else. The optional link handling ensures only relevant connections stay visible too.
  • When you move your mouse away, everything resets to its original state.

Quick tweaks you can make:

  • If you don't want to hide links, just remove the links.style(...) block in the mouseover function.
  • Instead of setting non-connected nodes to 0 (completely hidden), use a small value like 0.1 to keep a faint outline of the full network.

内容的提问来源于stack exchange,提问作者Fred

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:44:56