0.8.4.0
This commit is contained in:
+55
-3
@@ -47,7 +47,7 @@ import type { D3OrgChartRef } from "@/components/tree/d3-org-chart-flow"
|
||||
type ViewMode = "traditional" | "d3-org-chart"
|
||||
|
||||
export default function TreePage() {
|
||||
const { treeData, currentTree, refreshData } = useFamily()
|
||||
const { treeData, currentTree, refreshData, highlightedMemberId, setHighlightedMemberId } = useFamily()
|
||||
const { calculateRelationship } = useRelationship()
|
||||
const { data: session, status } = useSession()
|
||||
const { showAlert } = useDialog()
|
||||
@@ -119,9 +119,14 @@ export default function TreePage() {
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const d3ChartRef = useRef<D3OrgChartRef>(null)
|
||||
|
||||
// 传统族谱初始定位到始祖并自适应缩放
|
||||
// 传统族谱初始定位到始祖并自适应缩放(如果有高亮成员则跳过)
|
||||
useEffect(() => {
|
||||
if (viewMode !== 'traditional' || hasInitialPositioned || !treeData.rootId) return
|
||||
// 如果有高亮成员,跳过初始定位,让高亮定位逻辑处理
|
||||
if (highlightedMemberId) {
|
||||
setHasInitialPositioned(true)
|
||||
return
|
||||
}
|
||||
|
||||
// 找到始祖成员:优先使用标记为 isFounder 的成员,否则使用 rootId 对应的成员
|
||||
const founderMember = Object.values(treeData.members).find(m => m.isFounder === true)
|
||||
@@ -180,7 +185,7 @@ export default function TreePage() {
|
||||
}, 500)
|
||||
|
||||
return () => clearTimeout(timer)
|
||||
}, [viewMode, treeData.rootId, treeData.members, hasInitialPositioned])
|
||||
}, [viewMode, treeData.rootId, treeData.members, hasInitialPositioned, highlightedMemberId])
|
||||
|
||||
// 切换视图模式时重置初始定位状态和缩放位置
|
||||
useEffect(() => {
|
||||
@@ -189,6 +194,53 @@ export default function TreePage() {
|
||||
setPosition({ x: 0, y: 0 })
|
||||
}, [viewMode])
|
||||
|
||||
// 当有高亮成员时,定位到该成员并居中显示,设置 scale 为 1.0
|
||||
useEffect(() => {
|
||||
if (viewMode !== 'traditional' || !highlightedMemberId) return
|
||||
|
||||
// 第一步:重置位置和缩放为初始状态
|
||||
setScale(1)
|
||||
setPosition({ x: 0, y: 0 })
|
||||
|
||||
// 延迟执行,等待 DOM 完全渲染(需要足够长的时间让树完全展开)
|
||||
const timer = setTimeout(() => {
|
||||
if (!containerRef.current) {
|
||||
return
|
||||
}
|
||||
|
||||
// 查找高亮成员的 DOM 元素
|
||||
const highlightedNode = containerRef.current.querySelector(`[data-member-id="${highlightedMemberId}"]`) as HTMLElement
|
||||
if (!highlightedNode) {
|
||||
return
|
||||
}
|
||||
|
||||
const containerRect = containerRef.current.getBoundingClientRect()
|
||||
const nodeRect = highlightedNode.getBoundingClientRect()
|
||||
|
||||
// 计算容器中心
|
||||
const containerCenterX = containerRect.width / 2
|
||||
const containerCenterY = containerRect.height / 2
|
||||
|
||||
// 此时 position 已经是 {x:0, y:0},所以节点位置就是相对于原点的位置
|
||||
// 我们需要计算让节点居中的偏移量
|
||||
const nodeCenterX = nodeRect.left - containerRect.left + nodeRect.width / 2
|
||||
const nodeCenterY = nodeRect.top - containerRect.top + nodeRect.height / 2
|
||||
|
||||
// 计算偏移量
|
||||
const offsetX = containerCenterX - nodeCenterX
|
||||
const offsetY = containerCenterY - nodeCenterY
|
||||
|
||||
setPosition({ x: offsetX, y: offsetY })
|
||||
|
||||
// 30秒后清除高亮状态
|
||||
setTimeout(() => {
|
||||
setHighlightedMemberId(null)
|
||||
}, 30000)
|
||||
}, 1000) // 增加到1秒,确保DOM完全渲染
|
||||
|
||||
return () => clearTimeout(timer)
|
||||
}, [viewMode, highlightedMemberId, setHighlightedMemberId])
|
||||
|
||||
// 传统族谱自适应视图函数
|
||||
const handleTraditionalFitView = useCallback(() => {
|
||||
if (!containerRef.current || !treeData.rootId) return
|
||||
|
||||
Reference in New Issue
Block a user