import { useState, useCallback, useEffect } from 'react'; import type { GraphData, Node, SearchNode } from '../types/graph'; import { graphApi } from '../services/graphApi'; import { SAMPLE_GRAPH_DATA } from '../config/sampleData'; import { resetColorAssignment } from '../config/colors'; /** * 知识图谱数据管理 Hook * 负责图谱数据的加载、搜索和节点选择 */ export const useGraphData = () => { const [graphData, setGraphData] = useState({ nodes: [], edges: [] }); const [selectedNode, setSelectedNode] = useState(null); const [hoveredNode, setHoveredNode] = useState(null); const [searchResults, setSearchResults] = useState([]); const [loading, setLoading] = useState(true); // 从后端加载图谱数据 const loadGraphData = useCallback(async () => { try { setLoading(true); const data = await graphApi.getData(); // 重置颜色分配缓存,确保每次加载数据时颜色分配一致 resetColorAssignment(); // 如果后端返回空数据,使用示例数据 if (data.nodes.length === 0) { setGraphData({ ...SAMPLE_GRAPH_DATA, id: `sample-${Date.now()}` }); } else { setGraphData({ ...data, id: `data-${Date.now()}` }); } } catch (error) { console.error('Failed to load graph data:', error); // 重置颜色分配缓存 resetColorAssignment(); // API 失败时使用示例数据作为降级方案 setGraphData({ ...SAMPLE_GRAPH_DATA, id: `fallback-${Date.now()}` }); } finally { setLoading(false); } }, []); // 搜索节点(前端过滤,可根据需要切换到后端搜索) const handleSearch = useCallback((query: string) => { const results = graphData.nodes .filter((node: Node) => node.label.toLowerCase().includes(query.toLowerCase()) || node.id.toLowerCase().includes(query.toLowerCase()) ) .map((node: Node) => ({ id: node.id, label: node.label, type: node.type, matched: true, })); setSearchResults(results); }, [graphData]); // 通过 ID 选择节点(用于搜索结果点击) const handleNodeSelectById = useCallback((nodeId: string) => { console.log('[useGraphData] handleNodeSelectById called with id:', nodeId); const node = graphData.nodes.find((n: Node) => n.id === nodeId); console.log('[useGraphData] Found node:', node); if (node) { console.log('[useGraphData] Setting selectedNode:', node); setSelectedNode(node); } else { console.log('[useGraphData] Node not found with id:', nodeId); } }, [graphData.nodes]); // 选择节点(用于图谱点击) const handleNodeSelect = useCallback((node: Node | null) => { console.log('[useGraphData] handleNodeSelect called with node:', node); console.log('[useGraphData] About to call setSelectedNode'); setSelectedNode(node); console.log('[useGraphData] setSelectedNode called'); }, []); // 悬停节点(用于图谱悬停) const handleNodeHover = useCallback((node: Node | null) => { setHoveredNode(node); }, []); // 监听 selectedNode 变化,用于调试 useEffect(() => { console.log('[useGraphData] selectedNode state changed:', selectedNode); console.log('[useGraphData] selectedNode truthiness:', !!selectedNode); }, [selectedNode]); // 组件挂载时加载数据 useEffect(() => { loadGraphData(); }, [loadGraphData]); return { graphData, selectedNode, hoveredNode, searchResults, loading, setSelectedNode, handleSearch, handleNodeSelectById, handleNodeSelect, handleNodeHover, }; };