Files
mnote/design/思维导图方案.md
T
2025-11-23 10:55:04 +08:00

12 KiB
Raw Blame History

Wolai-clone 思维导图方案(v3.1)——复刻 MindManager 体验并与 BlockNote 大纲双向同步

0. 背景与目标

  • v3.0 架构已确定使用 Next.js + BlockNote + Yjs,需新增思维导图模块,实现与笔记大纲/块树实时联动,体验对齐 MindManager/Wolai/Kmind。
  • 核心诉求:极致整齐的自动布局节点富内容(图片/富文本/图标/link)跨文档/跨导图的链接能力与笔记大纲双向同步
  • 设计方向:继续使用 @xyflow/reactReact Flow 11+)作为画布内核,自研布局 & 样式层,数据完全托管在 Supabasedocuments 表)与独立 mindmap 表中。

1. 体验原则

  1. MindManager 级布局:节点水平/垂直间距固定,主干左右对称;支持“经典曲线”“直角线”两种连线;节点宽度随内容自动适配,最多两行后溢出省略。
  2. 富内容节点:每个节点可包含标题、富文本摘要、图标、emoji、标签、封面图片;支持 Markdown/快捷键编辑。
  3. 多级链接:节点可跳转到:
    • 当前文档某块(blockId)→ 通过 block://{id} 链接并高亮目标块。
    • 其他笔记(documentId)→ 打开对应页面。
    • 其他导图的节点(mindmapId+nodeId)→ 支持导图嵌套导航。
  4. 实时同步:导图结构映射到笔记大纲(Tree);改导图 = 改大纲;在 BlockNote 中增删标题块 = 导图自动更新节点。
  5. Wolai/Kmind 外观:圆角矩形 + 轻投影,hover 显示手型 + 菜单,选中高亮;暗黑/亮色一致。支持缩放、平移、迷你地图。

2. 技术架构

BlockNote (Y.Doc: document_tree)
      │
      ├─ outline nodes ↔ mindmap nodes (双向映射表)
      │
Mindmap SubDoc (Y.Doc: mindmap_{document_id})
      │
React Flow 画布 + 自研 MindLayout Engine
      │
Supabase tables:
  documents (content jsonb)
  mindmap_meta (id, document_id, layout_prefs, theme)
  mindmap_nodes (id, mindmap_id, block_id, parent_id, data jsonb, position cache)
  • 每份文档默认有一份 mindmap(也支持多个 mindmap);mindmap 数据存于 mindmap_nodes,并同步缓存到 BlockNote content(便于离线/导出)。
  • 协作层使用 Yjs SubDoc:当打开导图时订阅 mindmap_{document_id}React Flow 节点/边与 SubDoc 同步,保持毫秒级更新。

3. 视觉规格(融合 MindManager 细节)

  • 节点样式

    • 尺寸:min-w 240px,默认 280px,最大 384px;高度随内容自动撑开,不超过两行,超出显示省略。

    • 圆角 24px、2px 边框;选中 border-blue-500 ring-4 ring-blue-100 scale-105,未选中 border-slate-300 hover:border-blue-400 hover:shadow-2xl

    • 背景渐变 linear-gradient(135deg,#ffffff 0%,#f8fafc 100%),阴影 0 4px 15px rgba(0,0,0,0.08);选中提升到 0 10px 25px rgba(59,130,246,0.15)

    • 左上角支持图标徽章(36px 圆形),顶部可插入封面(最大高 160px),右侧有链接指示器。

    • 示例 className

      const base = `
        relative px-5 py-3 min-w-60 max-w-96 rounded-2xl
        bg-white border-2 shadow-lg transition-all duration-200
      `;
      const active = 'border-blue-500 ring-4 ring-blue-100 scale-105';
      const idle = 'border-slate-300 hover:border-blue-400 hover:shadow-2xl';
      
  • 连线样式

    • MindManager 曲线:M sx sy C sx+100 sy targetX-100 targetY targetX targetY,颜色 #94a3b8,宽度 3px。
    • 备选直角线(smoothstep)满足 Kmind 用户;末端 arrowhead 半径 6px。
  • 画布与工具栏

    • 画布背景 bg-gradient-to-br from-slate-50 to-slate-100,使用 React Flow Background gap 24px。
    • 顶部 56px 工具栏,包含自动排版、主题切换、导出、折叠/展开、缩放重置;工具栏按钮遵循 px-4 py-2 rounded-lg 规范。

4. 对齐 MindManager 的布局策略

  1. 层级布局:根节点居中,一级节点左右分布;根据用户设置(左/右/双向)动态计算。
  2. 自动间距:使用自研 MindLayout Engine(基于 DAG 布局),输入节点树 + 样式参数,输出绝对坐标;支持:
    • 同层节点纵向等距排列。
    • 子节点根据最长文本宽度自动算水平偏移,保证连线整齐。
    • 支持节点折叠/展开,折叠时子树隐藏但保留布局缓存。
  3. 连线样式:提供“曲线(贝塞尔)”“直角线”两种;线条宽度、颜色可继承主题。
  4. 对齐辅助:拖动节点时展示辅助线,松手后自动吸附至推荐位置;支持 Shift+拖拽 只在水平或垂直方向移动。

5. 节点内容设计

字段结构(存储于 mindmap_nodes.data):

{
  "title": "节点标题",
  "richText": "<p>富文本</p>",
  "icon": "mdi-lightbulb",
  "emoji": "💡",
  "tags": ["优先级:高", "待讨论"],
  "image": { "url": "...", "width": 200, "height": 120 },
  "link": {
    "type": "block" | "document" | "mindmap-node" | "url",
    "targetId": "block_xxx / doc_xxx / mindmap_y/node_z",
    "title": "跳转提示"
  },
  "status": "todo | doing | done",
  "collapsed": false
}
  • 富文本编辑器使用 @tiptap/react 迷你实例或 BlockNote 内嵌 mini editor,支持粗体/斜体/高亮/超链接。
  • 图片可从 Supabase Storage 选择或粘贴上传,节点支持设置小型封面或内嵌图片。
  • 节点图标:内置 MindManager 风格图标库(优先级、进度、标记),同时支持 emoji。

6. 链接和导航

类型 格式 交互
块链接 block://{blockId} hover 显示块摘要,点击在文档中滚动并高亮该块。
文档链接 doc://{documentId} 打开对应页面,可在侧边栏预览。
导图节点 mind://{mindmapId}/{nodeId} 若当前导图即目标,则定位;否则打开目标导图并定位。
外部 URL https://... 新标签页打开。
  • 链接编辑面板提供快速搜索(块/页面/导图节点),并记录最近使用项。
  • 支持「一键转块」:把导图节点转换为 BlockNote 内的块,或把块拖入导图生成节点。

7. 大纲与导图的双向同步

数据映射

  • 维护 outlineNodeId ↔ mindmapNodeId 映射表,存储在 mindmap_nodes.block_id 字段。
  • BlockNote 标题块(H1~H4)与导图层级对应;非标题块可作为节点备注(richText)。

同步策略

  1. 导图 → 大纲
    • 新建节点:创建对应 BlockNote 标题块(Yjs 操作),插入到同级相应位置。
    • 删除节点:删除/归档对应块。
    • 拖动节点:更新块的父级和排序(BlockNote reorder API)。
  2. 大纲 → 导图
    • 在大纲中新建/调整标题块时,触发同步 Hook 更新 mindmap SubDoc。
    • 对于仅存在于导图的节点,可标记 detached=true,大纲不显示;用户可手动“附着”到大纲。

冲突处理

  • 通过 Yjs transaction + lastWriterWins 策略;若同一节点同时被导图与大纲修改,变更合并后派生 diff,在 UI 中提示“有更新,点击同步”。
  • 提供“锁定导图”开关,当导图处于演示模式时暂停同步,避免误差。

8. 前端组件分层

  1. MindmapCanvas:封装 React Flow + 主题/布局;负责渲染节点、连线、背景、缩放器。
  2. MindLayoutEngine:输入节点树返回位置/尺寸,支持缓存与局部更新。
  3. MindNodeCard:节点内容组件,内嵌富文本、标签、图片、链接、hover toolbar。
  4. MindLinkPanel:统一链接管理,搜索块/文档/导图节点。
  5. OutlineSyncController:监听 BlockNote、导图 SubDoc,执行同步动作。
  6. MindHistorySidebar:展示导图版本历史/快照(可依赖 Supabase table versions)。

9. 数据库 & API

create table mindmap_meta (
  id uuid primary key default uuid_generate_v4(),
  document_id uuid references documents(id),
  title text,
  layout_prefs jsonb,   -- 左/右布局、连线样式、主题
  theme text default 'wolai-light',
  created_by uuid references auth.users,
  created_at timestamptz default now(),
  updated_at timestamptz default now()
);

create table mindmap_nodes (
  id uuid primary key default uuid_generate_v4(),
  mindmap_id uuid references mindmap_meta(id) on delete cascade,
  parent_id uuid references mindmap_nodes(id),
  block_id uuid,        -- 可为空(纯导图节点)
  order_index integer,
  data jsonb,
  cached_position jsonb,
  created_at timestamptz default now(),
  updated_at timestamptz default now()
);
  • FastAPI Endpoints
    • GET /mindmaps/{id}:返回 meta + nodes + outline mapping。
    • POST /mindmaps:创建新导图(可附加到文档)。
    • PATCH /mindmaps/{id}:更新布局/主题。
    • POST /mindmaps/{id}/nodesPATCH /.../{nodeId}DELETE ...:供批量导入/AI/脚本使用。
    • POST /mindmaps/{id}/export:导出为 MMAP、OPML、PNG、SVG。

10. 实施计划

阶段 目标 核心任务 输出
P0 需求确认(0.5d 对齐视觉规范 & 交互 - 与设计确认节点样式、主题变量、连线风格
- 列出与大纲同步的详细规则/边界
- 明确链接搜索/跳转需求
更新 PRD + Figma 草图
P1 数据与 API1.5d 建表 + 后端接口 - Supabase 建 mindmap_meta/mindmap_nodes + RLS
- FastAPI mindmap CRUD + 导出占位
- 单元测试覆盖
后端 PR + Swagger
P2 前端内核(2d React Flow + 布局引擎 - 封装 MindLayoutEngine,实现左右对称/直角/曲线
- 节点/连线主题实现,支持折叠/缩放
画布 demo
P3 节点富内容(2d 节点编辑能力 - 富文本/图标/图片/标签/状态组件
- 链接面板 + 搜索块/文档/导图节点
- 粘贴逻辑(从 MindManager/文本导入)
节点交互完成
P4 同步控制器(2d 导图 ↔ 大纲 - 建立 block ↔ node 映射 SubDoc
- 实现双向增删改同步/冲突提示
- E2E 测试(Cypress + Playwright 多窗口)
同步稳定
P5 打磨 & 导出(1.5d 性能/体验 - 虚拟化/懒加载,支持 2k+ 节点
- 导出 PNG/SVG/OPML
- 快捷键、迷你地图、历史记录
发布候选

11. 验收标准

  • 导图布局与 MindManager 对齐:节点间距统一,拖动自动吸附。
  • 节点支持图片/富文本/图标/标签/链接,复制 MindManager 内容可无损粘贴。
  • 节点链接在不同类型 (block/doc/mind/node) 下跳转准确,带 hover 预览。
  • 与 BlockNote 大纲实时同步,双向修改 200ms 内可见,无冲突。
  • 多人协作时节点光标、拖拽、折叠状态实时共享,无明显抖动。
  • 支持导出 PNG/SVG/OPML/MMAP(后续),可导入 MindManager 文件(可放在扩展阶段)。

12. 落地提示

  • P2 阶段可直接引入 grok 方案中的 MindManagerNode/MindManagerEdge 作为主题模板,结合 Tailwind CSS 变量封装成 MindNodeCard 多主题体系。
  • 布局计算使用 elkjsalgorithm=layeredelk.layered.nodePlacement.strategy=BRANDES_KOEPF),封装 getMindManagerLayout 并缓存,确保自动排版按钮在 200ms 内完成 500+ 节点重新布局。
  • 同步控制器上线前,编写 OPML/MMAP → mindmap_nodes 的导入脚本,用真实 MindManager 数据验证字段与链接策略,并准备导图 ↔ 大纲操作回放工具以排查协作冲突。

此方案在保留 MindManager 用户习惯的同时,借助 Supabase + React Flow 构建可扩展的思维导图系统,并与 BlockNote 文档深度联动。按 P0-P5 推进,可在 1.5~2 周内完成 MVP 并持续迭代高级功能。