Spaces:
Sleeping
Sleeping
| import styles from './index.module.less'; | |
| import { useState, useEffect } from 'react'; | |
| import MindMapItem from '../mind-map-item'; | |
| interface IEndStyle { | |
| top: string; | |
| height: number; | |
| } | |
| const MindMapGraph = (props: any) => { | |
| const { isEnd, renderData, handleNodeClick } = props; | |
| const [mapId] = useState(Date.now()); | |
| const [showEndNode, setShowEndNode] = useState(false); | |
| const [mapWidth, setMapWidth] = useState(0); | |
| const [endStyle, setEndStyle] = useState<IEndStyle>({ | |
| top: '50%', | |
| height: 0, | |
| }); | |
| const generateWidth = () => { | |
| const articles = document.getElementById(`mindMap-${mapId}`)?.querySelectorAll('article'); | |
| // 确保至少有两个元素 | |
| if (articles?.length) { | |
| let maxRight = 0; | |
| articles.forEach((item, index) => { | |
| if (item.getBoundingClientRect().right > maxRight) { | |
| maxRight = item.getBoundingClientRect().right; | |
| } | |
| }); | |
| const firstArticle = articles[0].getBoundingClientRect(); | |
| if (maxRight - firstArticle.left + 200 > mapWidth) { | |
| return maxRight - firstArticle.left + 200; | |
| } else { | |
| return mapWidth; | |
| } | |
| } else { | |
| return 100; | |
| } | |
| }; | |
| const generateEndStyle = () => { | |
| // 获取所有class为endline的div元素 | |
| const mindMap = document.getElementById(`mindMap-${mapId}`); | |
| const endlineDivs = document.getElementById(`mindMap-${mapId}`)?.querySelectorAll('.endline') || []; | |
| // console.log('generateEndStyle-----', mapId, `mindMap-${mapId}`, document.getElementById(`mindMap-${mapId}`), mindMap, endlineDivs, endlineDivs?.length); | |
| // 确保至少有两个元素 | |
| if (endlineDivs?.length >= 2 && mindMap) { | |
| // 获取第一个和最后一个元素的边界框(bounding rectangle) | |
| const firstRect = endlineDivs?.[0].getBoundingClientRect(); | |
| const lastRect = endlineDivs?.[endlineDivs.length - 1].getBoundingClientRect(); | |
| const mindMapRect = mindMap?.getBoundingClientRect(); | |
| // 计算y值的差值 | |
| const yDiff = lastRect.top - firstRect.top; | |
| // const top = firstRect.top - mindMapRect.top; | |
| // 如果需要包含元素的完整高度(不仅仅是顶部位置),可以加上元素的高度 | |
| // const yDiffWithHeight = yDiff + (lastRect.height - firstRect.height); | |
| return { | |
| top: firstRect.top - mindMapRect.top, | |
| height: yDiff + 1, | |
| }; | |
| } else { | |
| return { | |
| top: '50%', | |
| height: 0, | |
| }; | |
| } | |
| }; | |
| useEffect(() => { | |
| setMapWidth(generateWidth()); | |
| }, [renderData.length]); | |
| useEffect(() => { | |
| if (!isEnd) return; | |
| setMapWidth(generateWidth()); | |
| setTimeout(() => { | |
| setEndStyle(generateEndStyle() as IEndStyle); | |
| setShowEndNode(true); | |
| }, 200); | |
| }, [isEnd]); | |
| return ( | |
| <div className={styles.mapArea}> | |
| <ul className={styles.mindmap} id={`mindMap-${mapId}`} style={isEnd ? { width: mapWidth, overflow: 'hidden' } : {}}> | |
| {renderData.map((item: any) => ( | |
| <MindMapItem | |
| key={item.name} | |
| item={item} | |
| isEnd={isEnd} | |
| selectNode={handleNodeClick} | |
| /> | |
| ))} | |
| {showEndNode && ( | |
| <div className={styles.end} style={endStyle}> | |
| <div className={styles.node}> | |
| <article>最终回复</article> | |
| </div> | |
| </div> | |
| )} | |
| </ul> | |
| </div> | |
| ); | |
| }; | |
| export default MindMapGraph; | |