Skip to main content

streaming-mindmap-rendering

Implement real-time streaming mindmap rendering using Mind Elixir in web applications. Supports streaming text parsing and incremental updates.

Quellinformationen

Repository
SSShooter/obsidian-mindmap
Letzte Quellaktivität
13. Februar 2026 um 13:32
Erkannte Sprache von SKILL.md
Englisch
Sterne
52
Forks
2

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
Streaming Mindmap Rendering
description
Implement real-time streaming mindmap rendering using Mind Elixir in web applications. Supports streaming text parsing and incremental updates.
# Streaming Mindmap Rendering This skill guides you through implementing a streaming mindmap renderer using `mind-elixir`. This technique allows you to display a mindmap that grows in real-time as data is generated by an AI model or fetched from a stream. ## Prerequisites - React (or any frontend framework, examples use React) - `mind-elixir` library ## 1. Install Dependencies First, ensure you have `mind-elixir` installed. ```bash npm install mind-elixir ``` ## 2. Component Structure Create a wrapper component for `mind-elixir` to handle the lifecycle and updates. ```tsx 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. Streaming & Parsing Logic The core of this skill is efficiently handling the stream and parsing potentially incomplete data. ### Data Formats Mind Elixir supports two main formats: 1. **JSON (Native)**: Hierarchical tree structure. Hard to stream because JSON is invalid until complete. 2. **Plain Text (Recommended for Streaming)**: Indentation-based or markdown-list-based text. Easier to parse partially. #### Plain Text Format Example ```text - 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] ``` ### Parsing Implementation Use `mind-elixir/plaintextConverter` (or a custom parser) to convert text to the Mind Elixir JSON format. ````typescript 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. Optimization Tips - **Throttling**: Do not re-parse and re-render on every single byte. Use a throttle (e.g., 200-500ms). - **Stable Root**: Ensure the parsing logic maintains a stable root ID if possible, to prevent the whole graph from flashing. - **Scroll to Last**: To follow the generation, you can programmatically scroll to the last added node. ```typescript // 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. Integrating with AI Prompts When generating mindmaps with LLMs, instruct the model to use the plaintext format.
Auf GitHub ansehen