TraceStudio-dev/docs/web1.0/PHASE2_FINAL_POLISH.md
2026-01-07 19:34:45 +08:00

11 KiB
Raw Blame History

Phase 2 极致体验优化 - 完成报告

🎯 优化概览

本次更新实现了 TraceStudio 第二阶段的最终抛光,从基础交互到极致体验的全面提升。

完成的核心功能

1. Inspector 深度修复

双向绑定机制

  • 参数修改实时同步到 Zustand Store
  • 💾 修改后切换节点不会丢失数据
  • 🔄 通过 updateNodeData(nodeId, { key: value }) 即时更新

只读属性分离

┌─ 系统信息(只读)────┐
│ 节点 ID: n_xxx       │ ← 灰色背景,禁用输入
│ 节点类型: universal  │
│ 分类: Loader         │
├─ 参数配置(可编辑)──┤
│ file_path: [输入框]  │ ← 白色背景,可编辑
│ delimiter: [输入框]  │
│ (CSV 文件路径)       │ ← 描述文字
└────────────────────┘

智能类型处理

  • integer 类型 → <input type="number">
  • string 类型 → <input type="text">
  • 支持 default 值和 description 提示

2. 自定义右键菜单

画布右键(空白处)

┌────────────────┐
│ 💾 保存工作流   │ → localStorage
│ 📥 导入工作流   │ → 文件选择器
│ 📤 导出工作流   │ → JSON 下载
│ ───────────── │
│ 🗑️ 清空画布    │ → 确认对话框
└────────────────┘

节点右键

┌────────────────┐
│ 📋 复制节点     │ → 偏移 50px
│ ───────────── │
│ 🗑️ 删除节点    │ → 同时删除连线
└────────────────┘

视觉设计

  • 毛玻璃背景 (backdrop-filter: blur(12px))
  • 蓝色边框 (rgba(59,130,246,0.2))
  • Hover 高亮(蓝色/红色)
  • 危险操作红色标记

3. 贝塞尔连线优化

连线样式升级

  • 类型:smoothstepdefault (贝塞尔曲线)
  • 粗细2px → 3px静态/ 4px运行时
  • 透明度0.7 → 0.8(静态)/ 1.0(运行时)

单输入顶替逻辑

onConnect: (connection) => {
  // 删除目标 Handle 的旧连线
  const filtered = edges.filter(e => 
    !(e.target === connection.target && 
      e.targetHandle === connection.targetHandle)
  )
  // 添加新连线
  addEdge({ ...connection, style: {...} }, filtered)
}

效果

  • 每个输入口只保留一条连线
  • 新连线自动替换旧连线
  • 符合 DAG 拓扑约束

4. 节点运行态视觉反馈

状态指示灯系统

状态 颜色 动画 说明
idle 灰色 未执行
running 黄色 闪烁脉冲 执行中
success 绿色 执行成功
error 红色 闪烁脉冲 执行失败

CSS 动画

@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.7; transform: scale(1.2); }
}

执行耗时显示

  • 位置:节点底部右侧
  • 格式:12ms(单色编码)
  • 颜色规则:
    • < 50ms → 绿色(快速)
    • 50-100ms → 橙色(适中)
    • > 100ms → 红色(慢)

数据结构

data: {
  status: 'idle' | 'running' | 'success' | 'error'
  executionTime: 42  // 毫秒
}

📊 功能对比表

功能 Phase 2 初版 Phase 2 Final
参数持久化 切换丢失 实时同步
右键菜单 ⚠️ 简单确认 完整菜单
连线类型 smoothstep 贝塞尔曲线
连线粗细 2px 3px → 4px
单输入约束 自动顶替
状态反馈 ⚠️ 基础 4 态 + 动画
执行耗时 彩色显示

🎨 交互流程优化

工作流保存/加载

保存流程

  1. 画布空白处右键 → 选择"保存工作流"
  2. 数据存入 localStorage['tracestudio.workflow']
  3. 弹出提示" 工作流已保存到本地存储"

导出流程

  1. 画布空白处右键 → 选择"导出工作流"
  2. 生成 JSON 文件:workflow_{timestamp}.json
  3. 自动触发浏览器下载

导入流程

  1. 画布空白处右键 → 选择"导入工作流"
  2. 打开文件选择器(.json
  3. 解析并验证 JSON 结构
  4. 成功 → 替换当前画布,失败 → 提示错误

节点复制流程

  1. 右键目标节点 → 选择"复制节点"
  2. 创建新节点:
    • IDn_{timestamp}_{random}
    • 位置:原位置 + (50, 50)
    • 数据:完全克隆
  3. 添加到画布

参数编辑流程

  1. 点击节点 → Inspector 显示详情
  2. 修改参数值 → onChange 触发
  3. 调用 updateNodeData(nodeId, { param: value })
  4. Zustand Store 更新
  5. 节点体实时刷新预览

🔧 技术实现细节

Inspector 参数渲染逻辑

// 遍历 param_schema
{Object.entries(node.data.meta.param_schema).map(([key, schema]) => {
  const currentValue = node.data[key] ?? schema.default
  
  return schema.type === 'integer' ? (
    <input type="number" 
           value={currentValue} 
           onChange={(e) => updateNodeData(node.id, {
             [key]: parseInt(e.target.value) || 0
           })} />
  ) : (
    <input type="text" 
           value={currentValue} 
           onChange={(e) => updateNodeData(node.id, {
             [key]: e.target.value
           })} />
  )
})}

右键菜单状态管理

const [contextMenu, setContextMenu] = useState<{
  x: number
  y: number
  type: 'pane' | 'node'
  nodeId?: string
} | null>(null)

// 画布右键
onPaneContextMenu={(e) => {
  e.preventDefault()
  setContextMenu({ x: e.clientX, y: e.clientY, type: 'pane' })
}}

// 节点右键
onNodeContextMenu={(e, node) => {
  e.preventDefault()
  setContextMenu({ 
    x: e.clientX, 
    y: e.clientY, 
    type: 'node', 
    nodeId: node.id 
  })
}}

单输入顶替算法

setEdges((eds) => {
  // 过滤:删除目标 Handle 的旧连线
  const filtered = eds.filter((e) => {
    if (e.target === connection.target && 
        e.targetHandle === connection.targetHandle) {
      return false  // 删除旧连线
    }
    return true
  })
  
  // 添加新连线
  return addEdge({
    ...connection,
    style: { stroke: edgeColor, strokeWidth: 3 }
  }, filtered)
})

运行态动画触发

// UniversalNode 中
const statusConfig = {
  running: { color: '#f59e0b', animated: true },
  // ...
}

<div style={{
  background: currentStatus.color,
  boxShadow: currentStatus.animated 
    ? `0 0 12px ${currentStatus.color}` 
    : 'none',
  animation: currentStatus.animated 
    ? 'pulse 1.5s ease-in-out infinite' 
    : 'none'
}} />

🧪 测试清单

Inspector 测试

  • 修改参数后切换节点,再切回来值仍保留
  • 系统属性ID/Type/Category无法编辑
  • integer 类型使用数字输入框
  • string 类型使用文本输入框
  • placeholder 显示 default 值

右键菜单测试

  • 画布空白处右键显示 4 个选项
  • 节点上右键显示 2 个选项
  • "保存工作流"存入 localStorage
  • "导出工作流"下载 JSON 文件
  • "导入工作流"加载 JSON 文件
  • "清空画布"删除所有节点和连线
  • "复制节点"创建偏移副本
  • "删除节点"同时删除关联连线

连线测试

  • 新连线使用贝塞尔曲线
  • 静态连线粗细 3px
  • 运行时连线粗细 4px
  • 单输入口只保留最新连线
  • 旧连线被新连线顶替

运行态测试

  • idle 状态显示灰色指示灯
  • running 状态显示黄色闪烁
  • success 状态显示绿色常亮
  • error 状态显示红色闪烁
  • 执行耗时显示在节点底部
  • 耗时颜色根据阈值变化

📁 文件变更清单

修改文件

  1. web/src/components/Inspector.tsx - 双向绑定 + 只读分离
  2. web/src/components/Workspace.tsx - 右键菜单 + 连线优化
  3. web/src/components/nodes/UniversalNode.tsx - 运行态反馈

核心改动统计

  • Inspector: +150 lines参数系统重构
  • Workspace: +120 lines右键菜单 + 单输入逻辑)
  • UniversalNode: +40 lines状态灯 + 耗时显示)
  • 总计:+310 lines

🎯 设计亮点

1. 数据持久化分层

  • 实时层React Flow state交互响应
  • 持久层Zustand Store应用状态
  • 存储层localStorage跨会话

2. 类型感知输入控件

  • 根据 param_schema.type 动态渲染
  • integer → number input支持步进
  • string → text input支持占位符

3. 智能连线管理

  • 自动删除冲突连线
  • 保持 DAG 拓扑约束
  • 颜色继承源节点类型

4. 渐进式视觉反馈

  • 静态:基础颜色 + 细线
  • Hover高亮 + 边框
  • 运行:加粗 + 动画 + 发光
  • 完成:颜色变化 + 耗时显示

🚀 使用示例

创建并保存工作流

  1. 构建流程

    • 拖拽 CSVLoader → 配置 file_path
    • 拖拽 FilterRows → 配置 column/condition
    • 连接 Loader 输出 → Filter 输入
  2. 保存工作流

    • 画布空白处右键
    • 点击"保存工作流"
    • localStorage 自动存储
  3. 导出分享

    • 画布空白处右键
    • 点击"导出工作流"
    • 下载 workflow_1704672000000.json

编辑节点参数

  1. 选中节点:点击 CSVLoader
  2. 修改参数Inspector 中输入 data.csv
  3. 实时生效:节点体显示新值
  4. 切换节点:点击其他节点
  5. 验证持久:再次点击 CSVLoader值仍为 data.csv

复制节点快速建模

  1. 配置模板节点:设置 FilterRows 的所有参数
  2. 右键复制:节点上右键 → "复制节点"
  3. 微调副本:修改副本的 column 参数
  4. 批量处理:重复步骤 2-3 创建多个过滤器

💡 性能优化

防抖优化(未来)

// 建议添加参数输入防抖
const debouncedUpdate = useMemo(
  () => debounce(updateNodeData, 300),
  []
)

虚拟滚动(未来)

  • 当节点数 > 100 时启用
  • 使用 react-window 优化渲染

增量更新

  • 仅更新变化的节点
  • 避免全量 re-render

🐛 已知限制

  1. localStorage 大小限制

    • 最大 5-10MB浏览器差异
    • 建议大工作流使用导出功能
  2. 节点状态手动管理

    • 需要后端返回 status/executionTime
    • 目前为演示数据
  3. 右键菜单定位

    • 固定定位(可能超出视口)
    • 未来可添加自适应调整

🔮 下一步建议

Phase 3: 真实数据处理

  1. DAG 执行引擎

    • 拓扑排序
    • 并行执行
    • 缓存机制
  2. 节点状态管理

    • 后端返回真实 status
    • WebSocket 实时更新
    • 执行队列可视化
  3. 数据流追踪

    • 连线上显示数据量
    • 中间结果缓存
    • 性能瓶颈分析

用户体验增强

  1. 快捷键系统

    • Ctrl+S 保存
    • Ctrl+C/V 复制粘贴
    • Delete 删除节点
  2. 撤销/重做

    • 操作历史栈
    • Ctrl+Z/Ctrl+Y
  3. 迷你地图增强

    • 节点状态色彩映射
    • 执行进度可视化

完成时间2026-01-07
版本Phase 2 Final Polish v1.0
状态 已完成,极致体验达成