Skip to content

feat(knowledge-graph): 统一画布外框 + 3D 标签 + 全屏 + 工具栏三段式 + 右栏抽屉 - #525

Merged
ThreeFish-AI merged 2 commits into
feature/1.x.xfrom
ThreeFish-AI/kg-canvas-layout
May 12, 2026
Merged

feat(knowledge-graph): 统一画布外框 + 3D 标签 + 全屏 + 工具栏三段式 + 右栏抽屉#525
ThreeFish-AI merged 2 commits into
feature/1.x.xfrom
ThreeFish-AI/kg-canvas-layout

Conversation

@ThreeFish-AI

Copy link
Copy Markdown
Owner

背景

  • 本次变更要解决的问题:Knowledge Graph 页面存在七项 UX/视觉缺陷——3D 渲染器节点缺持久文字标签、画布底边紧贴浏览器底沿、五大渲染器外框冗余且不一致且无全屏入口、「搜索实体」独占行浪费纵向空间、右栏「构建」卡片为单按钮过度结构化、「构建历史」无分页易淹没其他模块、右栏不可收起浪费横向空间。
  • 关联上下文/Issue/文档:用户附图与本会话中确认的七项优化诉求(参考工作计划 .claude/plans/system-instruction-you-are-working-bubbly-quill.md)。

核心变更

  • 新增 GraphCanvasFrame_components/GraphCanvasFrame.tsx):五大渲染器共享外框 + Stats 右上角浮层 + 全屏按钮(Fullscreen API + Safari webkitRequestFullscreen 兜底;data-fullscreen 修正全屏黑底;lucide-react Maximize2/Minimize2 切换)。
  • 新增 BuildButton_components/BuildButton.tsx):紧凑工具栏构建按钮,未选语料库自禁用并 title 提示,lastBuildError 时右上叠加红点;与既有 BuildPanel 正交,后者继续服务 d3 空态分支。
  • 3D 节点持久文字标签:引入 three-spritetext@^1.10.0nodeThreeObject 返回 SpriteTextnodeThreeObjectExtend=true 保留球体高亮,深浅模式背景/色对比度均充足。
  • 工具栏三段式重排:左 CorpusSelector / 中 SearchBar(结果浮层 absolute z-20 贴近输入框)/ 右 viewTab + 渲染器选择器 + BuildButton + KgBuildProgressPill;删除独占行的搜索栏卡片。
  • 右栏抽屉式收起w-72 ↔ w-0 平滑过渡、chevron toggle 嵌入 main/aside 间隙、localStoragekg.sidebarOpen 持久化、SSR 守卫;移除「构建」卡片。
  • 构建历史分页BuildHistoryList 默认每页 5 条,runs.length 变化时采用 React 19「render 期间根据 props 调整 state」范式(替代 useEffect+setState,规避 react-hooks/set-state-in-effect)。
  • d3 SVG 接入 GraphCanvasFrame:删除原「Graph Canvas 标题 + 虚线双层卡片」结构,与其他四渲染器视觉契约一致;空态分支统一为 rounded-2xl border-dashed
  • 底边间隙修正:内容 flex 行追加 pb-4,画布与浏览器底沿留 16px 留白。

风险与回滚

  • 主要风险
    • d3 SVG 改造选择「就地包裹」而非组件抽离(svgRef/simulationRef/layout 与 page.tsx 强耦合),未触碰 d3 simulation 逻辑,理论上行为零退化;但需关注 viewport resize 时的布局节奏。
    • three-spritetext 为新依赖(3KB,react-force-graph 同作者维护,复用已传递引入的 three);500 节点上限下显存占用约 1-2 MB,可接受。
    • 浏览器原生 Fullscreen API 在旧 Safari 需 webkitRequestFullscreen 兜底,已覆盖;全屏元素默认黑底由 data-[fullscreen=true]:bg-white dark:bg-zinc-900 显式声明。
    • localStorage SSR 安全已用 typeof window !== "undefined" 守卫,避免 Next.js hydration mismatch。
  • 回滚方式:单 commit fe650780 体量集中,git revert fe650780 即可整体回滚;新增的 three-spritetext 依赖未被其他模块引用,回滚后自动失活。

验证证据

  • 单元测试:现有 vitest 套件不涉及本次改造范围;BuildHistoryList/GraphCanvas3D 此前无单元用例,未新增。
  • 集成测试pnpm typecheck ✅ + pnpm lint ✅ 全过;ESLint react-hooks 规则触发后已切换至 React 19 推荐范式。
  • E2E/Workflow:Playwright E2E 未触达 Knowledge Graph 路由;本次以浏览器实机验证为主。
  • 覆盖率/关键截图:浏览器 mcp__chrome_devtools__* 端到端验证 10 项(见 .context/kg-*.png)——
    1. 底边距浏览器底沿 16px(脚本探测 viewportHeight - rect.bottom === 16
    2. 五大渲染器外框圆角/边框/深浅模式背景一致,stats 后缀分别显示 Cytoscape / d3 SVG / 3D WebGL / Sigma WebGL / Force Canvas
    3. 全屏按钮进入/退出正常,全屏期间背景为深色不穿黑
    4. 3D SpriteText 持久标签可见(如 Canyon Robbins / Marina Long
    5. 搜索栏位于工具栏中段,结果以 absolute z-20 浮层渲染
    6. 构建图谱按钮位于渲染器选择器右侧,KgBuildProgressPill 仍正常
    7. 构建历史 17 条 → 4 页(每页 5 条),「上一页/下一页」切换正常
    8. 抽屉收起后 main 扩展占满,localStorage kg.sidebarOpen=0/1 持久化
    9. 全屏期间切换渲染器、点击搜索不致崩溃,退出全屏 ResizeObserver 自动重适应
    10. 节点点击高亮、双击/右键扩展子图、时间穿梭等右栏功能行为不变

影响范围

  • 前端apps/negentropy-ui/app/knowledge/graph/page.tsx + 5 个渲染器组件 + BuildPanel.tsx,新增 GraphCanvasFrame.tsxBuildButton.tsxpackage.json 新增 three-spritetext@^1.10.0
  • 后端:无变更。
  • GitHub Actions / 文档:无 CI 变更;后续可在 docs/issue.md 补充本次 UI 重构摘要(按 AGENTS.md「Issue」准则)。

Next Best Action

  • Reviewer 重点审视:① GraphCanvasFrame 全屏切换在 Safari 的兜底分支;② 构建历史分页是否影响实时构建中状态的可见性(默认在第 1 页,应能立即看到最新构建);③ 工具栏在更窄屏(< 1280px)下三段式是否仍可读,必要时引入 flex-wrap
  • 合并后建议同步更新 docs/issue.md,登记本次 UI 重构条目以便跨上下文检索。

🤖 Generated with Claude Code, CodeX, Gemini

- 新增 GraphCanvasFrame 公共外框组件:收敛 Cytoscape/d3/3D/Sigma/Force Graph 五大渲染器
  的圆角边框、stats 浮层与全屏按钮(Fullscreen API + Safari webkitRequestFullscreen 兜底;
  data-fullscreen 修正全屏黑底;lucide-react Maximize2/Minimize2 切换);
- 新增 BuildButton 紧凑工具栏构建按钮:无 corpusId 自禁用、lastBuildError 红点指示,
  与既有 BuildPanel 正交(后者继续服务 d3 空态分支);
- 3D 节点持久文字标签:引入 three-spritetext,nodeThreeObjectExtend=true 在球体上叠加
  SpriteText,深浅模式背景/色对比度均充足;
- 工具栏三段式重排:左 CorpusSelector / 中 SearchBar(结果浮层 z-20 absolute 贴近输入框)/
  右 viewTab + 渲染器选择器 + 构建图谱按钮 + KgBuildProgressPill;
- 右栏抽屉式收起:w-72 ↔ w-0 平滑过渡、chevron toggle 嵌入 main/aside 间隙、
  localStorage 持久化(kg.sidebarOpen)、SSR 守卫;
- 构建历史分页:BuildHistoryList 默认每页 5 条,runs.length 变化时采用 React 19
  「render 期间根据 props 调整 state」范式重置分页索引,避免 useEffect+setState 级联渲染;
- d3 SVG 接入 GraphCanvasFrame:删除原「Graph Canvas 标题 + 虚线双层卡片」结构,
  与其他四渲染器视觉契约一致;空态分支统一为 rounded-2xl border-dashed 范式;
- 底边间隙修正:内容 flex 行追加 pb-4,画布与浏览器底沿留 16px 留白;
- 移除右栏「构建」卡片:能力已迁入工具栏。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
…n 与分页跨语料库重置

- 修复右栏抽屉首屏开→收动画 + storage 噪声:用 hasHydratedRef 区分挂载读 vs
  用户写,挂载阶段写 effect 短路;新增 sidebarHydrated 状态条件挂载
  `transition-[width]`/`transition-opacity`,避免 localStorage 持久值为 "0"
  时首屏可见的 200ms 关闭动画与回写 "1" 引发的 storage 事件抖动;
- GraphCanvasFrame 全屏切换吞掉 Promise rejection:requestFullscreen /
  exitFullscreen 在用户拒绝权限、跨域 iframe 缺 allow="fullscreen"、
  其它元素已占据全屏等场景会 reject,旧 `await` 直接冒泡为 unhandled
  rejection 污染控制台;现以 try/catch 包裹并 console.warn 保留可观测性;
- BuildHistoryList 分页重置改为引用比较:原按 runs.length 比较,两个语料库
  恰好等长的构建历史互切时不会重置,用户停留在第 N 页却看着新语料的数据;
  改比 runs 引用(父 useMemo 在 payload 切换时整体重建),覆盖切语料 /
  时间穿梭 / 构建后重拉所有刷新场景。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
@ThreeFish-AI
ThreeFish-AI merged commit 5111169 into feature/1.x.x May 12, 2026
12 checks passed
@ThreeFish-AI
ThreeFish-AI deleted the ThreeFish-AI/kg-canvas-layout branch May 12, 2026 04:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant