Skip to content

kgdiff 查看器交互设计 ​

<kgdiff-viewer>(@kgdiff/viewer 包)的行为。视觉令牌和编码见 visual-language.md(英文)。

布局 ​

┌────────────────────────────────────────────────────────────────────────────────────────┐
│ ◆ kgdiff   go.obo  v2026-09 → v2026-10     ⟨Overlay│Swipe│Replay│Changes⟩   +12 −3 ~8  ◐ ? │  header 52px
├──────────────────────────────────────────────────────────────────┬─────────────────────┤
│                                                                  │ Changes  23   ⌕     │
│                                                                  │ ●Added ●Removed …   │  filter chips
│                          canvas                                  │ ▍Merged “A” into “B”│
│                                                                  │ ▍Renamed “x” → “y”  │  hunk list
│                                                                  │ …                   │
│  ┌legend┐                                          ┌minimap┐     ├─────────────────────┤
│  └──────┘        ⟨ ◀  ▶‖  ▶  ━━━●━━━━━━━  3/23  1× ⟩ └───────┘     │ detail panel        │
└──────────────────────────────────────────────────────────────────┴─────────────────────┘
  • 侧栏宽 360 px(可以用 \ 或标题栏按钮收起)。宽度小于 760 px 时变成底部抽屉(高度 40%,可拖动把手),视图切换控件只显示图标。
  • 浮动控件(图例、小地图、回放控制条)使用浮层样式,并且从不遮挡当前变更组:渲染器在适配视图时会通过 safeArea 为它们预留空间。

标题栏 ​

  • 品牌标志 + “变化前 → 变化后”的名称(取自图的元数据或文件名)、版本标签。
  • 视图分段控件:叠加(1)、滑动对比(2)、回放(3)、仅看变更(4)。切换视图时保持相机位置。
  • 统计徽章(按类别着色):+N 新增、−N 删除、~N 修改、⇄N 结构调整,每个都是筛选的快捷方式。
  • 主题切换(自动 / 浅色 / 深色);菜单里的配色切换(默认 / 色盲友好);适配视图;帮助(?)。

视图 ​

叠加。 并集图层。悬停在节点上:显示提示卡片(标签、id、状态、一行摘要)。点击:选中它所属的变更组(节点未变时选中节点)。点击空白画布:清除选择。

滑动对比。 垂直分隔线左侧是变化前,右侧是变化后(默认在 50% 处)。拖动把手(或分隔线上任意位置),← / → 每次移动 2%(按住 Shift 为 10%),双击复位。上方两角显示“变化前”/“变化后”标签。两侧都可以选择元素。

回放。 变化前的图按变更组逐步变成变化后的图(时间线来自 scene)。控制条:上一组 / 播放暂停 / 下一组;进度条上每组一个刻度(按类别着色,悬停显示标题);位置 3 / 23;速度 0.5× 1× 2× 4×。Space 播放 / 暂停,← / → 单步。在列表里选中一组,会跳到它时间窗口的末尾。除非用户在最近 2 秒内平移或缩放过,否则相机跟随当前变更组。播放到最后显示“回放结束 · 重新开始”。

仅看变更。 聚焦视图:变化的元素加上 1 跳的上下文(画布工具栏里可以在 0 / 1 / 2 之间切换);隐藏的节点汇总成“+38 个未变”这样的徽章;点击徽章可以展开(位置由 extendLayout 计算,其他元素不会移动)。图超过大图阈值时默认使用这个视图。

变更列表(侧栏) ​

  • 头部:“变更”和数量;搜索框(/):在整张图的节点标签、别名和 id 上模糊匹配;结果带状态圆点;选中一个结果会飞到该节点并选中它所属的变更组。
  • 每个类别一个筛选标签,带数量(可多选;都不选表示全部)。筛选后,不匹配的变更组在画布上变暗,并从列表中隐藏。
  • 各行按阶段分组(删除、结构调整、修改、新增),组标题吸顶。每行:3 px 的类别色条、符号(+ − ~ ⇄ ⊕ ⑂)、标题(单行,超出显示省略号,悬停显示全文)、副标题(弱化)和一个圆形的“已审阅”开关。选中的行:凸起的背景加强调色描边。
  • 键盘:j / ↓ 下一个,k / ↑ 上一个,Enter 飞到它,x 切换已审阅,Home / End。列表是带 aria-activedescendant 的 listbox。
  • 头部下方的审阅进度条:“已审阅 7 / 23”。审阅状态保存在 localStorage 中,键为 base.hash → target.hash(包在 try/catch 里)。

详情面板 ​

针对选中的变更组(或节点),先列变了什么,没变的放在最后:

  • 标题、类别徽章、上一个 / 下一个箭头、已审阅开关。
  • 变更内容:每个变了的方面一行,写成变化前 → 变化后。
    • 名称和 id:按字符高亮差异;更换 id 时附匹配置信度。
    • 属性:每个键一行。文本按词比较差异;两边加起来超过 60 个字符的值,前后各占一行,过长的截断并可展开。新增和删除的键用 + / − 标出。
    • 别名、类型、父节点和列表值:只删了一个、加了一个时,读作一次修改(老赖 → 失信人);否则至少一半字符相同的删除和新增按相似度从高到低配对,其余显示为带 + / − 的标签。
    • 弃用,以及替代关系(用所指节点的名称显示)。
  • 合并 / 拆分的组成:来源 → 目标,附置信度和“依据替代声明 / 启发式判断”。
  • 关系:变化的关系以句子形式显示,例如 → 持股 → 上市公司(原为 企业),每条都可点击。
  • 匹配依据(更换 id 和匹配建议):标签 / 邻居 / 类型 / 属性的得分条。
  • 基本信息:没变的 id、类型、别名和状态。未变的属性收在一个开关后面。
  • 新增和删除的节点,以及单独点开的未变节点,先显示基本信息和全部属性,再显示关系。

快捷键 ​

按键操作
1 2 3 4叠加 / 滑动对比 / 回放 / 仅看变更
j ↓ / k ↑下一个 / 上一个变化
Enter飞到选中的变化
Esc清除选择,关闭弹出层
Space播放 / 暂停(回放)
← →单步(回放)· 移动分隔线(滑动对比)
f适配全部
+ −放大 / 缩小
/搜索
x切换已审阅
\切换侧栏
t循环切换主题
?快捷键帮助

在输入框中打字时,快捷键不生效。

嵌入 API ​

html
<kgdiff-viewer theme="auto" locale="zh-CN" mode="overlay"></kgdiff-viewer>
<script type="module">
  import '@kgdiff/viewer';
  const viewer = document.querySelector('kgdiff-viewer');
  await viewer.load({ before, after, options }); // GraphInput | KGraph | { text, filename }
  // 或者:viewer.payload = reportPayload;       // 预先计算好的(命令行报告)
</script>

属性:mode、theme(auto|light|dark)、palette、locale(en|zh-CN,默认取自 navigator.language)、sidebar(open|closed)、sync-hash(深链接 #kgdiff=hunk:<id>;mode:<mode>)、header(compact 时标题栏不显示品牌和比较的图名,适合宿主页面自己显示这些信息的场合)、chrome(none 时只显示图本身,适合嵌入小块区域:不显示标题栏、变化列表、步骤说明、播放条、缩放按钮、小地图和图例卡片,保留悬停提示和一行图例;点击和快捷键不起作用,最小高度降到 120px,画布尺寸变化时和每轮循环开始时都重新放进画布)、legend(auto|full|mini|none)、loop(回放自动播放,播完停 loop-delay 毫秒后重新开始,默认 1200)、pause-on-hover(false 时鼠标停在图上也不暂停循环回放)。方法:load()、selectHunk(id)、next()、prev()、play()、pause()、fit({ animate, padding })(连同节点名称一起放进画布)、exportDelta()、reviewState()。事件(CustomEvent,冒泡,composed):kgdiff-ready { stats }、kgdiff-select { hunk, node }、kgdiff-mode { mode }、kgdiff-review { hunk, reviewed, progress }、kgdiff-error { error }、kgdiff-replay-end { loop }(回放播到结尾;loop 表示之后会重新开始)。

状态 ​

  • 加载中:骨架画布加上步骤文字(“解析中… · 匹配节点… · 布局中…”)。
  • 完全相同:平静的空状态,例如“没有差异。两个版本都有 512 个节点和 1,490 条关系。”,配一个淡淡的对勾符号。
  • 出错:错误信息加可展开的详情;从不显示空白屏幕。

无障碍 ​

  • 每个控件都是真正的按钮或输入框,带有可访问的名称;焦点环清晰可见(强调色)。
  • 画布带有 role="img" 和概括统计信息的 aria-label;导航时,一个礼貌(polite)的实时区域会播报“第 3 / 23 个变化:「x」改名为「y」”。
  • 对比度令牌经过测试;颜色从来不是唯一的提示;尊重“减少动态效果”设置。
  • 所有功能都能用键盘使用;指针点击目标不小于 28 px。

国际化 ​

界面文字有 en 和 zh-CN 两种;变更组标题来自 core 的 formatHunk;数字用 Intl.NumberFormat 格式化。中文界面使用「」引号,英文使用 “ ”。

基于 MIT 许可证发布。示例数据采用 CC0-1.0。