Files
structrail-design/.trae/documents/visualization-library-design.md
skycurtain a9eaaa6023 docs: 新增项目文档并更新开发规则
- 新增品牌命名、商业化策略、SDK视觉噪音处理、可视化库设计和系统架构文档
- 更新开发规则,明确禁止主动修改项目源代码文件
- 所有文档均为中文编写,用于记录项目设计讨论和决策
2026-02-18 00:18:35 +08:00

92 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 前端可视化库设计草案 (@structrail/viz)
本文档描述了将平台前端渲染逻辑沉淀为独立可视化库的设计构想。
## 1. 项目定位
我们将“数据生成”Tracer SDK与“数据展示”Visualization Lib完全解耦旨在沉淀一套标准化的、可嵌入的前端可视化引擎。
* **Tracer SDK (后端/客户端)**:负责生成标准化的、语言无关的 JSON 指令流Trace Protocol
* **Visualization Lib (前端)**:负责解析指令流,重建数据状态,并提供交互式的可视化组件。
这套库不仅服务于 StructRail 平台,未来也可被嵌入到博客、电子书或教学文档中,成为算法可视化的基础设施。
## 2. 核心架构 (Architecture)
库的核心遵循 **Player + Store + Renderer** 的分层架构本质上是一个支持时间旅行Time Travel的确定性状态机。
### 2.1 Player (播放器/控制器)
* **职责**:负责解析 Tracer 生成的 JSON 指令流控制播放进度Frame/Step
* **功能**:提供 `play()`, `pause()`, `next()`, `prev()`, `seek(index)` 等 API。
* **特性**:它不关心具体怎么画,只关心“当前是第几步”以及“播放速度”。
### 2.2 Store (状态仓库/沙盒)
* **职责**:负责根据指令重构数据结构的状态。
* **机制**维护一个“影子内存”Shadow Memory
* 当 Player 处于第 0 步时Store 是空的。
* 当收到 `ArrayTracer.create` 指令时Store 里建立一个数组模型。
* 当收到 `patch` 指令时Store 更新对应数组的元素值。
* 当收到 `pick` 指令时Store 标记对应元素为“高亮状态”。
* **输出**:它能在任何时间点,输出一份**只读的、标准化的数据快照 (Snapshot)** 给渲染层。
### 2.3 Renderer (渲染器/组件库)
* **职责**:纯粹的 UI 展示层View遵循 `f(state) => UI` 的原则。
* **实现**:可以使用 React/Vue 组件,也可以是 Canvas/WebGL针对大规模数据
* **特点**:它完全不知道“指令”的存在,它只接收 `Store` 给它的快照。
* 例如:`<ArrayVisualizer data={[1, 2, 3]} highlights={[1]} />`
## 3. 库的形态设计 (API Preview)
如果这个库被开发出来,它在前端项目中的使用方式可能如下(以 React 为例):
```typescript
import { Player, ArrayVisualizer, GraphVisualizer } from '@structrail/viz';
// 1. 载入 Tracer 生成的 JSON 数据
const events = await fetch('algorithm-trace.json');
const player = new Player(events);
// 2. 绑定到 UI
function AlgorithmDemo() {
// 使用 player 的 hook 获取当前帧的数据快照
const snapshot = usePlayerSnapshot(player);
return (
<div>
{/* 播放控制栏 */}
<ControlBar player={player} />
{/* 渲染区域:根据 snapshot 中的数据自动渲染 */}
<div className="canvas">
{snapshot.tracers.map(tracer => {
if (tracer.type === 'array') {
return <ArrayVisualizer key={tracer.id} model={tracer} />
}
if (tracer.type === 'graph') {
return <GraphVisualizer key={tracer.id} model={tracer} />
}
})}
</div>
</div>
);
}
```
## 4. 关键技术挑战 (Technical Challenges)
### 4.1 增量计算与快照管理
* **问题**:如果算法有 100 万步,不能每一步都存一个深拷贝的快照。
* **策略**:使用类似 Git 的机制或 immer.js。Store 只记录关键帧Keyframe的快照中间步骤通过重放指令Replay动态计算。
### 4.2 动画过渡 (Animation)
* **问题**:当从“第 1 步”跳到“第 2 步”时如果只是数据的突变1 -> 2体验很生硬。
* **策略**:渲染层需要比较 `PrevSnapshot``CurrentSnapshot`Diff
* 如果发现数组 index 0 的元素位置变了,它应该生成一个移动动画。
* 这就是为什么我们的 `patch` / `swap` 指令语义很重要,它们对应了不同的动画原语。
### 4.3 自动布局 (Auto-Layout)
* **问题**:后端 Tracer 通常不包含坐标信息(除非我们以后添加坐标指令,但通常不建议耦合 UI 细节)。
* **策略**:前端库需要内置强大的自动布局算法。
* Graph: Force-directed graph (力导向图)
* Tree: Reingold-Tilford 树布局