import React, { useEffect, useRef, useState } from 'react'; import { Transformer } from 'markmap-lib'; import { Markmap } from 'markmap-view'; import { Spin, Empty, Button, Space } from 'antd'; import { FullscreenOutlined, ZoomInOutlined, ZoomOutOutlined, SyncOutlined } from '@ant-design/icons'; const transformer = new Transformer(); const hasRenderableSize = (element) => { if (!element) return false; const rect = element.getBoundingClientRect(); return Number.isFinite(rect.width) && Number.isFinite(rect.height) && rect.width > 0 && rect.height > 0; }; const MindMap = ({ content }) => { const svgRef = useRef(null); const markmapRef = useRef(null); const latestRootRef = useRef(null); const [loading, setLoading] = useState(true); useEffect(() => { if (!content || !svgRef.current) return; setLoading(true); try { const { root } = transformer.transform(content); latestRootRef.current = root; if (markmapRef.current) { markmapRef.current.setData(root); } else { markmapRef.current = Markmap.create(svgRef.current, { autoFit: false, duration: 500, }, root); } requestAnimationFrame(() => { if (svgRef.current && hasRenderableSize(svgRef.current)) { markmapRef.current?.fit(); } }); } catch (error) { console.error('Markmap error:', error); } finally { setLoading(false); } }, [content]); useEffect(() => { const svgElement = svgRef.current; if (!svgElement || typeof ResizeObserver === 'undefined') { return undefined; } const observer = new ResizeObserver(() => { if (!hasRenderableSize(svgElement)) { return; } if (!markmapRef.current && latestRootRef.current) { markmapRef.current = Markmap.create(svgElement, { autoFit: false, duration: 500, }, latestRootRef.current); } requestAnimationFrame(() => { markmapRef.current?.fit(); }); }); observer.observe(svgElement); return () => observer.disconnect(); }, []); const handleFit = () => markmapRef.current?.fit(); const handleZoomIn = () => markmapRef.current?.rescale(1.2); const handleZoomOut = () => markmapRef.current?.rescale(0.8); if (!content) return ; return (
{loading && (
)}
); }; export default MindMap;