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
<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 格式化。中文界面使用「」引号,英文使用 “ ”。