From 413d2015256b66ae65698fddf1310dd01ebace13 Mon Sep 17 00:00:00 2001 From: yangdx Date: Sat, 15 Mar 2025 00:00:29 +0800 Subject: [PATCH] Fix refresh layout button failure --- .../src/components/graph/Settings.tsx | 15 ++++++- lightrag_webui/src/hooks/useLightragGraph.tsx | 7 --- lightrag_webui/src/stores/graph.ts | 44 +------------------ 3 files changed, 14 insertions(+), 52 deletions(-) diff --git a/lightrag_webui/src/components/graph/Settings.tsx b/lightrag_webui/src/components/graph/Settings.tsx index a24c86e9..86939436 100644 --- a/lightrag_webui/src/components/graph/Settings.tsx +++ b/lightrag_webui/src/components/graph/Settings.tsx @@ -8,7 +8,9 @@ import Input from '@/components/ui/Input' import { controlButtonVariant } from '@/lib/constants' import { useSettingsStore } from '@/stores/settings' import { useBackendState } from '@/stores/state' -import { useGraphStore } from '@/stores/graph' +import { useSigma } from '@react-sigma/core' +import { useLayoutForceAtlas2 } from '@react-sigma/layout-forceatlas2' +import { animateNodes } from 'sigma/utils' import { SettingsIcon, RefreshCwIcon } from 'lucide-react' import { useTranslation } from 'react-i18next'; @@ -115,7 +117,16 @@ const LabeledNumberInput = ({ export default function Settings() { const [opened, setOpened] = useState(false) const [tempApiKey, setTempApiKey] = useState('') - const refreshLayout = useGraphStore.use.refreshLayout() + const sigma = useSigma() + const maxIterations = useSettingsStore.use.graphLayoutMaxIterations() + const layout = useLayoutForceAtlas2({ iterations: maxIterations }) + + const refreshLayout = useCallback(() => { + if (!sigma) return + const graph = sigma.getGraph() + const positions = layout.positions() + animateNodes(graph, positions, { duration: 500 }) + }, [sigma, layout]) const showPropertyPanel = useSettingsStore.use.showPropertyPanel() const showNodeSearchBar = useSettingsStore.use.showNodeSearchBar() diff --git a/lightrag_webui/src/hooks/useLightragGraph.tsx b/lightrag_webui/src/hooks/useLightragGraph.tsx index d02c0f8c..6e4e1c32 100644 --- a/lightrag_webui/src/hooks/useLightragGraph.tsx +++ b/lightrag_webui/src/hooks/useLightragGraph.tsx @@ -589,10 +589,6 @@ const useLightrangeGraph = () => { } } - // We need to keep the refreshLayout call because Sigma doesn't automatically detect - // changes to the DirectedGraph object. This is necessary to trigger a re-render. - useGraphStore.getState().refreshLayout(); - } catch (error) { console.error('Error expanding node:', error); } finally { @@ -713,9 +709,6 @@ const useLightrangeGraph = () => { toast.info(t('graphPanel.propertiesView.node.nodesRemoved', { count: nodesToDelete.size })); } - // We need to keep the refreshLayout call because Sigma doesn't automatically detect - // changes to the DirectedGraph object. This is necessary to trigger a re-render. - useGraphStore.getState().refreshLayout(); } catch (error) { console.error('Error pruning node:', error); diff --git a/lightrag_webui/src/stores/graph.ts b/lightrag_webui/src/stores/graph.ts index c68b78c5..081576b3 100644 --- a/lightrag_webui/src/stores/graph.ts +++ b/lightrag_webui/src/stores/graph.ts @@ -77,7 +77,6 @@ interface GraphState { graphDataFetchAttempted: boolean labelsFetchAttempted: boolean - refreshLayout: () => void setSigmaInstance: (instance: any) => void setSelectedNode: (nodeId: string | null, moveToSelectedNode?: boolean) => void setFocusedNode: (nodeId: string | null) => void @@ -127,43 +126,6 @@ const useGraphStoreBase = create()((set, get) => ({ sigmaInstance: null, allDatabaseLabels: ['*'], - refreshLayout: () => { - const { sigmaInstance, sigmaGraph } = get(); - - // Debug information to help diagnose issues - console.log('refreshLayout called with:', { - hasSigmaInstance: !!sigmaInstance, - hasSigmaGraph: !!sigmaGraph, - sigmaInstanceType: sigmaInstance ? typeof sigmaInstance : 'null', - sigmaGraphNodeCount: sigmaGraph ? sigmaGraph.order : 0 - }); - - if (sigmaInstance && sigmaGraph) { - try { - // 先尝试直接刷新 - if (typeof sigmaInstance.refresh === 'function') { - sigmaInstance.refresh(); - console.log('Graph refreshed using sigma.refresh()'); - return; - } - - // 如果没有refresh方法,尝试重新绑定graph - if (typeof sigmaInstance.setGraph === 'function') { - sigmaInstance.setGraph(sigmaGraph); - console.log('Rebound graph to sigma instance'); - } else { - // 如果setGraph方法不存在,尝试直接设置graph属性 - (sigmaInstance as any).graph = sigmaGraph; - console.log('Set graph property directly on sigma instance'); - } - } catch (error) { - console.error('Error during refresh:', error); - } - } - - // 通知UI需要重新渲染 - set(state => ({ ...state })); - }, setIsFetching: (isFetching: boolean) => set({ isFetching }), setShouldRender: (shouldRender: boolean) => set({ shouldRender }), @@ -412,9 +374,6 @@ const useGraphStoreBase = create()((set, get) => ({ } }); - // Refresh the layout - state.refreshLayout(); - } catch (error) { console.error('Error expanding node:', error); } finally { @@ -489,8 +448,7 @@ const useGraphStoreBase = create()((set, get) => ({ state.rawGraph.buildDynamicMap(); } - // Refresh the layout to update the visualization - state.refreshLayout(); + // 图形更新后会自动触发重新布局 } catch (error) { console.error('Error pruning node:', error);