Skip to content

Latest commit

 

History

History
147 lines (116 loc) · 4.8 KB

File metadata and controls

147 lines (116 loc) · 4.8 KB
domain contrib
title knowledge graph ux patterns from high star projects
verification metadata-normalized
{"title" 知识图谱 UX 增强: 从高星项目提炼的 7 个交互模式", "domain": "development", "tags": ["knowledge-graph", "d3js", "ux", "graph-visualization", "force-directed"], "domain_expert": "unknown"}
created 2026-07-06
source unknown

背景

知识图谱可视化项目存在典型问题: 节点过多导致信息过载、关系缺乏上下文、无法聚焦局部视图。 参考 GitHub 高星项目 (GraphRAG 25k⭐, Logseq 32k⭐, Cytoscape.js 10k⭐, react-force-graph 10k⭐) 的设计模式, 提炼出 7 个可复用的交互增强方案。

根因

知识图谱可视化的核心矛盾是 全局概览 vs 局部细节 的平衡。 高星项目的共同策略是 渐进式披露 (Progressive Disclosure): 先展示局部, 再允许探索全局。

修复

1. 局部图谱视图 (Logseq 模式)

点击节点后只展示 N 跳邻居, 解决信息过载:

function getNHopNeighbors(nodeId, hops, edges) {
  const visited = new Set([nodeId]);
  let frontier = [nodeId];
  for (let i = 0; i < hops; i++) {
    const next = new Set();
    frontier.forEach(id => {
      edges.forEach(e => {
        const sid = e.source?.id || e.source;
        const tid = e.target?.id || e.target;
        if (sid === id && !visited.has(tid)) { next.add(tid); visited.add(tid); }
        if (tid === id && !visited.has(sid)) { next.add(sid); visited.add(sid); }
      });
    });
    frontier = [...next];
  }
  return visited;
}

面包屑导航支持逐级返回: 全局图谱 > 节点A > 节点B

2. 社区聚类布局 (GraphRAG 模式)

给 D3 force simulation 添加自定义聚类力:

function forceCluster(nodes, getCategory) {
  const clusterCenters = {};
  const categories = [...new Set(nodes.map(n => getCategory(n)))];
  const radius = 250;
  categories.forEach((cat, i) => {
    const angle = (2 * Math.PI * i) / categories.length;
    clusterCenters[cat] = { x: Math.cos(angle) * radius, y: Math.sin(angle) * radius };
  });
  return alpha => {
    nodes.forEach(d => {
      const center = clusterCenters[getCategory(d)];
      if (center) {
        d.vx += (center.x - d.x) * alpha * 0.08;
        d.vy += (center.y - d.y) * alpha * 0.08;
      }
    });
  };
}

同类节点间距缩小, 不同类间距增大, 形成视觉分组。

3. 边悬浮 tooltip (Cytoscape 模式)

用透明宽线条作为 hover 区域, 解决细线条难以 hover 的问题:

// 透明 hover 区域 (12px 宽)
linkGroup.selectAll('.edge-hit-area').data(links).join('line')
  .attr('class', 'edge-hit-area')  // stroke: transparent; stroke-width: 12;
  .on('mouseover', showEdgeTooltip)
  .on('mousemove', showEdgeTooltip)
  .on('mouseout', hideEdgeTooltip);

4. 高级筛选器 (Logseq 模式)

多维筛选: 节点类型 / 实体类型 / 分类, 加上孤立节点隐藏和核心节点高亮:

function isNodeVisible(node, filterState) {
  if (!filterState.types.has(node.type)) return false;
  if (node.type === 'entity' && !filterState.entityTypes.has(node.entityType)) return false;
  if (filterState.hideOrphans && !connectedIds.has(node.id)) return false;
  return true;
}

5. 物理参数控制 (react-force-graph 模式)

滑块控制引力、连接距离、碰撞半径, 实时更新 simulation:

function updatePhysics(simulation, charge, dist, collide) {
  simulation.force('charge').strength(-charge);
  simulation.force('link').distance(dist);
  simulation.force('collision').radius(d => baseRadius(d) + collide);
  simulation.alpha(0.3).restart();
}

6. 核心节点高亮

按连接数标记高权重节点, 帮助识别关键节点:

// 连接数 >= threshold 的节点加红色边框
d3.select(this).select('circle')
  .attr('stroke-width', isHub ? 3 : 2)
  .attr('stroke', isHub ? '#f85149' : defaultStroke);

7. 双击导航

双击任意节点进入局部图谱, 单击打开详情面板。两种交互互不干扰。

验证

  1. 局部视图: 双击高连接节点 → 只显示 10-30 个邻居, 面包屑可见
  2. 筛选器: 取消某类型 → 对应节点和边消失, 计数正确
  3. 聚类: 同类节点自动聚集, 不同类间距增大
  4. 边悬浮: hover 细线条 → tooltip 显示关系类型
  5. 物理控制: 拖动滑块 → 节点间距实时变化
  6. 核心高亮: 启用后 → 高连接节点出现红色边框

关键设计原则

  • 渐进式披露: 默认局部视图, 按需展开全局
  • 多维筛选: 不只是类型过滤, 要支持属性维度
  • 物理可调: 让用户自定义布局参数, 而非固定
  • 边可读: 细线条需要 hover 区域增强
  • 聚类力: 自定义 D3 force 实现社区分组