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

3d-force-graph双向边优化:合并双向链接为双箭头单边

解决3d-force-graph双向边合并为双箭头单链接的问题

步骤1:预处理图数据,合并双向边

先把成对的A→B和B→A边合并为一条带标记的边,消除数据冗余。通过生成统一的边键(将两个节点ID按升序拼接)来识别双向边:

function mergeBidirectionalEdges(graphData) {
  const edgeMap = new Map();
  const { nodes, links } = graphData;

  links.forEach(link => {
    // 生成统一边键,确保A-B和B-A对应同一个标识
    const edgeKey = [link.source, link.target].sort((a, b) => {
      // 兼容节点对象或纯ID的情况
      const idA = typeof a === 'object' ? a.id : a;
      const idB = typeof b === 'object' ? b.id : b;
      return idA.localeCompare(idB);
    }).join('-');

    if (!edgeMap.has(edgeKey)) {
      edgeMap.set(edgeKey, { ...link, bidirectional: false });
    } else {
      // 标记该边为双向
      edgeMap.get(edgeKey).bidirectional = true;
    }
  });

  return {
    nodes,
    links: Array.from(edgeMap.values())
  };
}

// 处理原始图数据
const mergedData = mergeBidirectionalEdges(gData);

步骤2:自定义链接的双箭头渲染

利用库的linkThreeObjectExtend配置,给标记为双向的边添加反向箭头,实现单条边带双箭头的视觉效果:

const Graph = ForceGraph3D()
  (document.getElementById('3d-graph'))
  .graphData(mergedData)
  .linkDirectionalArrowLength(3.5)
  .linkDirectionalArrowRelPos(1)
  .linkCurvature(0) // 合并后使用直边
  .linkThreeObjectExtend(true) // 允许扩展链接的3D对象
  .linkThreeObject(link => {
    if (link.bidirectional) {
      // 创建反向箭头几何体
      const reverseArrow = new THREE.Mesh(
        new THREE.ConeGeometry(0.5, 3.5, 8),
        new THREE.MeshBasicMaterial({ color: link.color || '#aaa' })
      );
      reverseArrow.position.set(-1, 0, 0); // 定位到链接起点
      reverseArrow.rotation.set(Math.PI, 0, 0); // 反转箭头朝向
      return reverseArrow;
    }
    return null;
  });

补充说明

  • 数据合并后,原本的两条双向边变为一条,减少了大型图的数据量,同时提升渲染性能。
  • 若需要调整箭头样式,可修改ConeGeometry的尺寸参数或MeshBasicMaterial的颜色、材质属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:34:58