关于 Streaming Mindmap Rendering
Streaming Mindmap Rendering 是一项使用 mind-elixir 实现实时思维导图渲染的技能,指导前端开发者解析流式文本,并随生成或获取的数据更新导图。
主要功能
- 01流式导图增量渲染
- 02解析不完整的纯文本输入
- 03集成 mind-elixir 转换器
- 04节流解析与渲染
- 05滚动到最新节点
适用场景
- 01实时展示 AI 生成的导图
- 02根据传入的文本流渲染思维导图
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ ssshooter/ mind-elixir-core --skill streaming-mindmap-rendering安装后在 Claude Code 中输入/streaming-mindmap-rendering确认已加载。
详细介绍
流式思维导图渲染
本技能将引导你使用 mind-elixir 实现流式思维导图渲染器。借助这项技术,你可以实时显示不断扩展的思维导图,数据由 AI 模型生成或从流中获取。
前置条件
- React(或任何前端框架,示例使用 React)
mind-elixir库
1. 安装依赖
首先,确保已安装 mind-elixir。
npm install mind-elixir
2. 组件结构
创建一个 mind-elixir 包装组件,用于处理生命周期和更新。
import MindElixir, { type MindElixirData, type MindElixirInstance } from 'mind-elixir'
import { useEffect, useRef } from 'react'
export function MindmapRenderer({ data }: { data: MindElixirData | null }) {
const elRef = useRef<HTMLDivElement>(null)
const meRef = useRef<MindElixirInstance | null>(null)
useEffect(() => {
if (!elRef.current) return
meRef.current = new MindElixir({
el: elRef.current,
direction: MindElixir.RIGHT,
})
// Initial empty state or loading state
meRef.current.init(data || { nodeData: { topic: 'Loading...', id: 'root' } })
return () => {
// Cleanup if necessary
}
}, [])
// Update effect
useEffect(() => {
if (meRef.current && data) {
// Refresh the graph with new data
meRef.current.refresh(data)
}
}, [data])
return <div ref={elRef} style={{ height: '500px', width: '100%' }} />
}
3. 流式处理与解析逻辑
这项技能的核心是高效处理数据流,并解析可能不完整的数据。
数据格式
Mind Elixir 支持两种主要格式:
- JSON(原生格式):层级树结构。由于 JSON 在完整生成之前无效,因此难以进行流式处理。
- 纯文本(推荐用于流式处理):基于缩进或 Markdown 列表的文本,更容易进行部分解析。
纯文本格式示例
- Root Node
- Child Node 1
- Child Node 1-1
- Child Node 1-2
- Child Node 1-3
- }:2 Summary of first two nodes
- Child Node 2
- Child Node 2-1 [^id1]
- Child Node 2-2 [^id2]
- Child Node 2-3 {color: "#e87a90"}
- > [^id1] <-Bidirectional Link-> [^id2]
- Child Node 3
- Child Node 3-1 [^id3]
- Child Node 3-2 [^id4]
- Child Node 3-3 [^id5]
- > [^id3] >-Unidirectional Link-> [^id4]
- > [^id3] <-Unidirectional Link-< [^id5]
- Child Node 4
- Child Node 4-1 [^id6]
- Child Node 4-2 [^id7]
- Child Node 4-3 [^id8]
- } Summary of all previous nodes
- Child Node 4-4
- > [^id1] <-Link position is not restricted, as long as the id can be found during rendering-> [^id8]
解析实现
使用 mind-elixir/plaintextConverter(或自定义解析器)将文本转换为 Mind Elixir JSON 格式。
import { plaintextToMindElixir } from 'mind-elixir/plaintextConverter'
// Helper to clean Markdown code blocks if your stream includes them
function cleanStreamContent(content: string): string {
return content
.replace(/^```[\w]*\n?/gm, '')
.replace(/```$/gm, '')
.trim()
}
// State hooks in your parent component
const [mindmapData, setMindmapData] = useState<MindElixirData | null>(null)
const accumulatedText = useRef('')
const lastRenderTime = useRef(0)
// Streaming function (Generic Example)
async function startStreaming(url: string) {
const response = await fetch(url)
const reader = response.body?.getReader()
const decoder = new TextDecoder()
if (!reader) return
while (true) {
const { done, value } = await reader.read()
if (done) break
const chunk = decoder.decode(value)
accumulatedText.current += chunk
// Throttle updates to avoid freezing the UI
const now = Date.now()
if (now - lastRenderTime.current > 500) {
// 500ms throttle
updateMindmap()
lastRenderTime.current = now
}
}
// Final update
updateMindmap()
}
function updateMindmap() {
try {
const cleanText = cleanStreamContent(accumulatedText.current)
const data = plaintextToMindElixir(cleanText)
setMindmapData(data) // This triggers the useEffect in MindmapRenderer
} catch (e) {
// Ignore parse errors from incomplete chunks
console.warn('Partial parse error ignored')
}
}
4. 优化技巧
- 节流:不要对每个字节都重新解析和渲染。使用节流(例如,200-500ms)。
- 稳定根节点:确保解析逻辑尽可能保持根节点 ID 稳定,以避免整个图表闪烁。
- 滚动到最后一个节点:为了跟随生成过程,你可以通过编程方式滚动到最后添加的节点。
// Scroll to last node (inside MindmapRenderer update effect)
const lastNode = findLastNode(data.nodeData) // Implement traversal to find last node
if (lastNode?.id) {
const nodeEle = meRef.current.findEle(lastNode.id)
if (nodeEle) meRef.current.scrollIntoView(nodeEle)
}
5. 与 AI 提示词集成
使用大模型生成思维导图时,指示模型使用纯文本格式。
评论
支持 Markdown