Files
llm-wiki/docs/spark/2026-06-26-global-sigma-community-spotlight-design.md
T
2026-07-12 21:26:08 +08:00

16 KiB
Raw Blame History

全局 Sigma 社区高亮交互设计

日期:2026-06-26 状态:已确认方向,待用户复核 当前分支:codex/global-sigma-community-spotlight-design

实现勘误(plan-eng-review 2026-06-26:核实代码后两点收口,实现以 workbench/docs/global-sigma-community-spotlight-plan.md 为准。

  1. 本文“点社区后地图几乎没有反馈”部分不成立——现状点社区已驱动云团/标签/边 dim(selectioncommunity.selectedsigma-global-renderer.ts:251/679/716/1034)。真正缺的只有:其他社区节点 dim + 相机轻量动画。
  2. 下文“新增 spotlightCommunityId 独立状态”按 plan 收口为复用现有 selection(高亮社区与选中社区始终同步,无需平行字段);正文 spotlightCommunityId 字样一律读作“selection 的社区视觉态”。focusCommunity() 仍绝不复用。

目的

这份设计用于补齐 llm-wiki 全局图谱里“点击社区之后,图本身几乎没有反馈”的体验缺口。

当前全局图已经承担“知识库地图”的职责:用户可以看到社区分布、节点点位、少量地标标签和跨社区关系。点击社区后,右侧抽屉会显示社区简介;只有点击抽屉里的“进入社区”,才会进入 DOM/SVG 社区阅读视图。这个两步边界是正确的,应该保留。

但现在点击社区后,地图本身没有形成足够强的“我正在看这个社区”的状态:用户主要靠右侧抽屉理解选择结果,图谱区域更像静态背景。本设计要补的是全局图内部的临时高亮态。

一句话:

点击社区后仍停留在全局地图,但地图要轻量高亮当前社区;真正进入社区仍由抽屉里的“进入社区”按钮负责。

术语说明

本设计避免继续使用“社区聚焦”命名这个新状态。

在现有 PRODUCT / ADR 语境里,“社区聚焦视图”已经指向进入社区后的 DOM/SVG 局部阅读视图,也就是 focusCommunity() 会切过去的那条路径。本文要设计的是“仍停留在全局 Sigma 地图里的临时强调状态”,两者不是一回事。

因此,本文统一使用:

  • 全局社区高亮态:留在 Sigma 全局图里,当前社区被强调,其他社区弱化。
  • 社区阅读视图 / 社区聚焦视图:进入 DOM/SVG 社区视图,主要用于阅读和深入探索。
  • spotlightCommunityId:后续实现中建议使用的临时状态名,避免继续复用 focus / focusCommunity

设计结论

采用“全局内高亮”方案。

  1. 点击社区后,不切到社区视图。
  2. 右侧抽屉继续显示社区简介。
  3. 全局 Sigma 图进入临时社区高亮态。
  4. 当前社区变清晰、变突出。
  5. 其他社区明显弱化但仍可见。
  6. 视角只做轻量构图调整,不做强镜头推进。
  7. 左上“回全图”按钮复用为退出高亮入口。
  8. 点空白处也可以退出高亮并清空当前选择。
  9. 抽屉里的“进入社区”按钮继续负责进入 DOM/SVG 社区阅读。

这个方案保留了“全局图是地图”的心智:用户是在地图里选中一片区域,而不是已经进入那片区域阅读。

为什么不直接进入社区

点击社区直接进入社区视图会让操作更快,但会牺牲全局地图的浏览能力。

全局图里的社区点击有两个不同目的:

  • 看这个社区在全局里的位置。
  • 进入这个社区阅读细节。

这两个目的不应该合并成一个动作。当前产品已经用“点击社区打开简介抽屉,再点进入社区”的方式把它们分开,这是合理的。

因此,本设计不改变已有两步逻辑,只增强第一步的地图反馈。

为什么不强拉近镜头

最初可以想到一种动画:点击社区后,镜头明显拉近到该社区,其他社区隐藏,像进入一个局部世界。

这个方案不推荐,原因是它会和“尚未进入社区视图”的心智冲突。用户看到画面只剩一个社区时,很容易以为自己已经进入社区;这会削弱抽屉里“进入社区”按钮的意义。

更好的体验是“高亮构图”,不是“深入切换”:

  • 视角可以轻微平移,让当前社区处在更舒服的位置。
  • 视角可以轻微放大,但不能放大到只剩当前社区。
  • 主要靠高亮、清晰度和弱化规则表达当前对象。
  • 其他社区仍然在场,维持全局空间感。

最终感觉应该是:

我仍在看整张知识地图,只是当前社区被重点标出来了。

现有代码边界

这次设计基于当前代码事实,不把全局和社区两条路线混在一起。

当前已有边界:

  • focusCommunity(id) 会把路由切到 dom-svg-community,它代表“进入社区阅读”。
  • Sigma 全局路线里的社区点击现在走 selectOnSigma({ kind: "community", id }),代表“选中社区并打开摘要”。
  • Sigma 全局路线的适配数据目前显式传入 focus: null,所以全局路线不会消费 DOM 社区视图的 focus 状态。
  • Sigma 全局已经有社区云团覆盖层、社区标签覆盖层、节点命中热区、空白点击、相机状态读取和恢复。
  • Sigma 全局的“回全图”按钮现在只在本路线内清空 focus/selection;社区视图里的“回全图”通过全局路由回调切回 Sigma。

因此,后续实现不应复用 focusCommunity(id) 来做全局高亮。需要新增一个只属于全局 Sigma 的临时状态,例如 spotlightCommunityId。它和“进入社区阅读”的 focus 必须分开。

与既有 ADR 和阶段关系

本设计不推翻 ADR-21 / ADR-22 的社区点击修订,而是增强它们的第一步。

ADR-21 和 ADR-22 已经明确:全局图里点击社区不再直接进入社区聚焦视图,而是先显示社区摘要,再由明确按钮进入社区。本设计继续遵守这条边界,只是在“先显示社区摘要”的同时,让全局地图也给出足够清楚的视觉反馈。

阶段归属上,本设计应作为阶段 4.7 之后的独立图谱交互任务处理,建议归入后续阶段 4.8 或独立 issue。它依赖阶段 4.7 已完成的“地图心智”和 Sigma 覆盖层性能地基,但不属于 #70 标签兜底,也不应混入社区阅读视图改造。

进入实现前,需要同步 PRODUCT.md 的对应阶段记录和 ADR-21 / ADR-22 关系说明,避免“社区聚焦视图”和“全局社区高亮态”在产品文档里继续混用。

用户交互规则

1. 普通全局状态

用户打开图谱时,默认进入普通全局状态。

普通全局状态显示:

  • 社区分布。
  • 节点点位。
  • 关系骨架。
  • 少量地标标签。
  • 搜索、筛选、Pin、选中等已有状态。

普通全局状态不显示:

  • 全量标签。
  • 节点卡片。
  • 大段正文。
  • 社区内部阅读布局。

2. 点击社区

用户点击社区云团、社区区域或社区图例时:

  • 保持在 Sigma 全局路线。
  • 选中该社区。
  • 右侧抽屉显示社区简介。
  • 图谱进入全局社区高亮态。
  • 当前社区视觉增强。
  • 其他社区明显弱化但仍可见。
  • 不自动进入社区视图。

如果用户再次点击另一个社区:

  • 高亮态切换到新社区。
  • 抽屉切换到新社区简介。
  • 视角做一次轻量构图调整。

3. 进入社区

用户只有点击抽屉里的“进入社区”按钮,才进入 DOM/SVG 社区阅读视图。

进入社区视图后:

  • 图谱切到社区阅读路线。
  • 社区内节点可以使用更高信息密度。
  • 社区视图继续承担阅读和探索任务。
  • 这不属于全局社区高亮态。

4. 回全图按钮复用

左上“回全图”按钮保留同一文案和同一入口,但按当前状态分层处理。

在社区视图中点击:

  • 切回 Sigma 全局路线。

在 Sigma 全局高亮态中点击:

  • 不切路线。
  • 清除全局社区高亮态。
  • 清空当前社区选择并关闭抽屉。
  • 视角回到完整全局构图。

在普通 Sigma 全局状态中点击:

  • 重置全局视角。
  • 清空临时选择。
  • 保持筛选、Pin、搜索等明确用户状态。

这样用户只需要理解一个含义:“回到全局地图”。系统内部根据当前层级选择正确动作。

5. 点空白处

点空白处是“退出当前临时高亮”的快捷动作。

如果当前在全局社区高亮态:

  • 退出高亮态。
  • 清空当前社区选择。
  • 抽屉同步关闭。
  • 视角回到普通全局构图。

如果当前只是普通全局选中节点或社区:

  • 清空选择。
  • 关闭抽屉。

如果工具栏面板打开:

  • 先关闭工具栏面板,再处理选择或高亮,保持现有空白点击优先级。

“回全图”和“点空白处”在全局社区高亮态下做相同清理动作,这是有意冗余:前者给用户一个可发现按钮,后者给熟练用户一个快速退出手势。两者都代表“离开当前社区摘要,回到普通全局地图”,所以都清空选择并关闭抽屉。

高亮态视觉规则

全局社区高亮态的核心不是“把当前社区单独放大”,而是“在全局地图上强调当前社区”。

当前社区:

  • 社区云团不弱化。
  • 社区标签优先显示。
  • 社区内重要节点标签优先显示。
  • 社区内节点和内部关系保持正常或略增强。
  • 与当前社区相关的跨社区关系可以保留一部分。

其他社区:

  • 社区云团降低不透明度。
  • 节点降低不透明度,但仍保留可辨认的点位。
  • 普通节点标签隐藏或明显弱化。
  • 普通关系线弱化。
  • 与当前社区存在强关系的邻近社区可以弱化得更轻。

这种“弱化但仍可见”的规则优于完全隐藏。完全隐藏会让用户误以为已经进入社区视图;弱化保留全局定位。

叠加优先级

全局社区高亮态必须和搜索、筛选、Pin、选中状态同时工作,不能互相覆盖。

优先级建议如下:

  1. 筛选决定对象是否属于当前可见集合。被筛掉的对象不因为高亮态强行出现;如果当前抽屉对象被筛掉,沿用既有“对象不在当前结果中”的提示和“显示该对象 / 清除选择”动作。
  2. 搜索命中优先于社区弱化。即使搜索结果在其他社区,也不能被当前社区高亮态压到看不见;命中节点、命中社区标签和必要路径应保持可见。
  3. 当前选中对象优先于普通弱化。当前抽屉对象必须始终可辨认。
  4. Pin / 固定节点优先于普通节点。被用户固定过的节点不能因为高亮态突然消失。
  5. 社区高亮态只处理剩余普通对象的强弱关系。

典型例子:用户正在高亮社区 A,同时搜索命中社区 B 的节点。此时社区 A 仍是当前上下文,但社区 B 的搜索命中节点必须清晰可见,不能被当作普通非当前社区节点压暗。

动画规则

动画采用“轻量构图调整”,不采用强镜头推进。

点击社区后:

  1. 抽屉立即打开,不等待动画结束。
  2. 当前社区马上进入高亮状态。
  3. 视角在短时间内轻微平移,让该社区落到更舒服的位置。
  4. 如果社区已经处于良好位置,不必移动视角。
  5. 如果社区在画面边缘,可以适度平移。
  6. 可以轻微放大,但放大比例必须受上限约束。
  7. 右侧抽屉打开时,构图中心应略偏左,避免当前社区被抽屉遮挡。

连续点击不同社区时:

  • 新点击立即接管当前高亮状态。
  • 新构图动画立即打断旧动画。
  • 动画不排队、不叠加。
  • 如果旧动画已经接近终点,可以从当前相机状态平滑过渡到新目标。
  • 抽屉内容以最后一次点击为准。

动画时长建议:

  • 普通情况:约 300-500ms。
  • 用户开启系统减少动态效果时:直接跳到终态或使用极短过渡。

动画目标:

  • 让用户感觉“视线被带到当前社区”。
  • 不制造“已经进入社区”的错觉。
  • 不让全图位置关系发生重排。

明确不做:

  • 不移动节点真实坐标。
  • 不重新布局整张图。
  • 不把当前社区节点物理拖到中心。
  • 不隐藏所有其他社区。
  • 不用强 zoom 取代高亮表达。

状态模型

后续实现应区分三类状态。

路由状态

决定用户在哪种视图:

  • Sigma 全局。
  • DOM/SVG 社区阅读。
  • DOM 小图兜底。
  • 超限或不可用提示。

“进入社区”改变路由状态。

全局社区高亮状态

只在 Sigma 全局路线内存在。

它记录当前被全局高亮的社区 id,建议命名为 spotlightCommunityId,用来驱动:

  • 当前社区高亮。
  • 其他社区弱化。
  • 社区标签优先级。
  • 轻量构图动画。
  • “回全图”在全局路线内的行为。

它不等于进入社区。

状态落点建议:

  • 放在 Sigma 全局 route renderer / facade renderer 的局部状态里。
  • 不进入顶层 GraphFacadeState.focus
  • 不复用 focusCommunity()
  • 不写入知识库文件。
  • 路由离开 Sigma 全局时可以丢弃。
  • 底层 Sigma renderer 只消费这个视觉状态,不把它当成业务数据源。

选择状态

继续记录当前抽屉对象,例如选中某个社区或节点。

点击社区时,选择状态和全局社区高亮状态通常同步:

  • 选择状态决定抽屉显示什么。
  • 全局社区高亮状态决定地图如何表达。

退出高亮时,同时清空选择并关闭抽屉。这样“回全图”和“点空白处”的结果一致,用户不会看到地图已经回全局、抽屉还停在旧社区的割裂状态。

性能边界

这次交互不能把每次点击变成一次昂贵的全图重建。

优先策略:

  • 节点真实坐标不变。
  • 布局不重算。
  • 相机只做平移和轻微缩放。
  • 视觉弱化通过渲染状态或属性控制。
  • 社区云团和标签覆盖层继续复用现有结构。
  • 相机移动过程中只更新覆盖层位置,不重建覆盖层 DOM。

现有 Sigma 全局已经做过覆盖层拆分:结构更新和相机重定位分开。这个方向应继续保持。

需要避免:

  • 点击社区就重新计算全图布局。
  • 每一帧重建社区云团 DOM。
  • 大量新增 hover DOM 元素。
  • 用全量标签显示解决高亮反馈问题。
  • 在全局社区高亮态中引入社区阅读级别的富内容。

后续实现边界

建议后续实现拆成一项独立任务,不和 #70 标签兜底混在一起。

#70 适合继续保持小修复:只给全局已显示标签加长度兜底,防止长标签破图。

全局社区高亮是新交互能力,应另开 issue 或设计任务实现。它至少会涉及:

  • Sigma 全局路线的临时高亮状态。
  • 社区点击后的 spotlightCommunityId 写入。
  • 回全图按钮的分层行为。
  • 空白点击退出高亮。
  • 相机轻量构图动画。
  • 高亮态视觉弱化规则。
  • 搜索、筛选、Pin、抽屉选择的状态协调。
  • 浏览器交互验证。

验收标准

实现完成后,应至少验证以下路径。

  1. 普通全局图点击社区:右侧抽屉打开,当前社区高亮,其他社区弱化但仍可见,不进入社区视图。
  2. 点击抽屉“进入社区”:进入 DOM/SVG 社区阅读视图。
  3. 社区视图点“回全图”:回到 Sigma 全局路线。
  4. 全局高亮态点“回全图”:停留在 Sigma,全图恢复普通构图。
  5. 全局高亮态点空白处:退出高亮,抽屉关闭,选择清空。
  6. 连续点击不同社区:抽屉和图谱高亮同步切换,动画不抖动。
  7. 高亮状态下搜索和筛选:不丢失明确用户状态,不出现空白图。
  8. 节点 Pin 和拖拽后的固定位置:不因高亮和回全图丢失。
  9. 右侧抽屉打开时:高亮社区不被抽屉遮挡。
  10. 减少动态效果设置开启时:动画降级为无动画或极短过渡。

不在本设计内

本设计不包含:

  • 改写社区阅读视图。
  • 把社区视图迁移到 Sigma。
  • 全局 hover 完整方案。
  • 全局节点详情卡片重做。
  • 社区内部布局重排。
  • 大图聚合系统。
  • #70 标签长度兜底实现。

全局 hover 可以在本设计之后另开一份设计:它应基于这里定义的全局社区高亮状态继续补,而不是重新定义点击社区的意义。