You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

力导向图鼠标悬停时修改选中节点及所有相连节点颜色的技术问询

解决D3.js力导向图节点悬停高亮自身与邻接节点的问题

看起来你已经找对了核心思路,但现有代码里有几个小问题需要修正,还有逻辑上可以优化的地方,咱们一步步来捋清楚:

1. 先修正代码里的语法错误

你写的isConnected函数里有个明显的笔误:o.index === d,index 这里的逗号应该是点,要改成d.index——这是最基础的语法问题,先把它改掉。

2. 优化连接关系的判断逻辑

如果你的力导向图是基于links数组(大部分普通力图都是这种结构),那用children来判断连接关系就不太合适了——children更多是树状图的专属结构。咱们应该直接从存储边数据的links数组里判断两个节点是否有连接:

修正后的isConnected函数

function isConnected(sourceNode, targetNode) {
  // 先判断是否是当前悬停的节点本身
  if (sourceNode.index === targetNode.index) return true;
  // 检查links数组中是否存在连接两者的边(无向图要双向检查)
  return links.some(link => {
    return (link.source.index === sourceNode.index && link.target.index === targetNode.index) ||
           (link.source.index === targetNode.index && link.target.index === sourceNode.index);
  });
}

这里的links就是你定义力图时的边数据数组,比如var links = [{"source": 0, "target": 1}, ...]这种结构。

3. 完善鼠标悬停事件的逻辑

你可以把颜色变量单独抽出来,后期修改更方便,同时别忘了加上鼠标移出时的恢复逻辑——不然节点颜色会一直停留在高亮状态:

// 定义默认颜色和高亮颜色,方便后期调整
const defaultNodeColor = 'blue';
const highlightColor = 'red';

function onMouseover(d) {
  // 修改节点颜色
  node.style("fill", function(o) {
    return isConnected(d, o) ? highlightColor : defaultNodeColor;
  });
  // 额外:如果需要高亮连接的边,也可以在这里处理
  link.style("stroke", function(l) {
    return (l.source.index === d.index || l.target.index === d.index) ? highlightColor : "#ccc";
  });
  force.resume();
}

// 鼠标移出时恢复所有节点和边的默认样式
function onMouseout() {
  node.style("fill", defaultNodeColor);
  link.style("stroke", "#ccc");
  force.resume();
}

4. 给节点绑定事件

最后要确保你的节点元素绑定了这两个事件:

node.on("mouseover", onMouseover)
    .on("mouseout", onMouseout);

为什么原来的逻辑有局限?

你之前用d.children来判断连接关系,只适用于树状结构的力导向图(比如D3的cluster或tree布局),但如果是普通的无向图/有向图,边都是存在links数组里的,这种情况下用children就没法正确识别所有邻接节点了。

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

火山引擎 最新活动