yangdx commited on
Commit
2f9681a
·
1 Parent(s): e41c826

Fix refresh layout button failure

Browse files
lightrag_webui/src/components/graph/Settings.tsx CHANGED
@@ -8,7 +8,9 @@ import Input from '@/components/ui/Input'
8
  import { controlButtonVariant } from '@/lib/constants'
9
  import { useSettingsStore } from '@/stores/settings'
10
  import { useBackendState } from '@/stores/state'
11
- import { useGraphStore } from '@/stores/graph'
 
 
12
 
13
  import { SettingsIcon, RefreshCwIcon } from 'lucide-react'
14
  import { useTranslation } from 'react-i18next';
@@ -115,7 +117,16 @@ const LabeledNumberInput = ({
115
  export default function Settings() {
116
  const [opened, setOpened] = useState<boolean>(false)
117
  const [tempApiKey, setTempApiKey] = useState<string>('')
118
- const refreshLayout = useGraphStore.use.refreshLayout()
 
 
 
 
 
 
 
 
 
119
 
120
  const showPropertyPanel = useSettingsStore.use.showPropertyPanel()
121
  const showNodeSearchBar = useSettingsStore.use.showNodeSearchBar()
 
8
  import { controlButtonVariant } from '@/lib/constants'
9
  import { useSettingsStore } from '@/stores/settings'
10
  import { useBackendState } from '@/stores/state'
11
+ import { useSigma } from '@react-sigma/core'
12
+ import { useLayoutForceAtlas2 } from '@react-sigma/layout-forceatlas2'
13
+ import { animateNodes } from 'sigma/utils'
14
 
15
  import { SettingsIcon, RefreshCwIcon } from 'lucide-react'
16
  import { useTranslation } from 'react-i18next';
 
117
  export default function Settings() {
118
  const [opened, setOpened] = useState<boolean>(false)
119
  const [tempApiKey, setTempApiKey] = useState<string>('')
120
+ const sigma = useSigma()
121
+ const maxIterations = useSettingsStore.use.graphLayoutMaxIterations()
122
+ const layout = useLayoutForceAtlas2({ iterations: maxIterations })
123
+
124
+ const refreshLayout = useCallback(() => {
125
+ if (!sigma) return
126
+ const graph = sigma.getGraph()
127
+ const positions = layout.positions()
128
+ animateNodes(graph, positions, { duration: 500 })
129
+ }, [sigma, layout])
130
 
131
  const showPropertyPanel = useSettingsStore.use.showPropertyPanel()
132
  const showNodeSearchBar = useSettingsStore.use.showNodeSearchBar()
lightrag_webui/src/hooks/useLightragGraph.tsx CHANGED
@@ -589,10 +589,6 @@ const useLightrangeGraph = () => {
589
  }
590
  }
591
 
592
- // We need to keep the refreshLayout call because Sigma doesn't automatically detect
593
- // changes to the DirectedGraph object. This is necessary to trigger a re-render.
594
- useGraphStore.getState().refreshLayout();
595
-
596
  } catch (error) {
597
  console.error('Error expanding node:', error);
598
  } finally {
@@ -713,9 +709,6 @@ const useLightrangeGraph = () => {
713
  toast.info(t('graphPanel.propertiesView.node.nodesRemoved', { count: nodesToDelete.size }));
714
  }
715
 
716
- // We need to keep the refreshLayout call because Sigma doesn't automatically detect
717
- // changes to the DirectedGraph object. This is necessary to trigger a re-render.
718
- useGraphStore.getState().refreshLayout();
719
 
720
  } catch (error) {
721
  console.error('Error pruning node:', error);
 
589
  }
590
  }
591
 
 
 
 
 
592
  } catch (error) {
593
  console.error('Error expanding node:', error);
594
  } finally {
 
709
  toast.info(t('graphPanel.propertiesView.node.nodesRemoved', { count: nodesToDelete.size }));
710
  }
711
 
 
 
 
712
 
713
  } catch (error) {
714
  console.error('Error pruning node:', error);
lightrag_webui/src/stores/graph.ts CHANGED
@@ -77,7 +77,6 @@ interface GraphState {
77
  graphDataFetchAttempted: boolean
78
  labelsFetchAttempted: boolean
79
 
80
- refreshLayout: () => void
81
  setSigmaInstance: (instance: any) => void
82
  setSelectedNode: (nodeId: string | null, moveToSelectedNode?: boolean) => void
83
  setFocusedNode: (nodeId: string | null) => void
@@ -127,43 +126,6 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
127
  sigmaInstance: null,
128
  allDatabaseLabels: ['*'],
129
 
130
- refreshLayout: () => {
131
- const { sigmaInstance, sigmaGraph } = get();
132
-
133
- // Debug information to help diagnose issues
134
- console.log('refreshLayout called with:', {
135
- hasSigmaInstance: !!sigmaInstance,
136
- hasSigmaGraph: !!sigmaGraph,
137
- sigmaInstanceType: sigmaInstance ? typeof sigmaInstance : 'null',
138
- sigmaGraphNodeCount: sigmaGraph ? sigmaGraph.order : 0
139
- });
140
-
141
- if (sigmaInstance && sigmaGraph) {
142
- try {
143
- // 先尝试直接刷新
144
- if (typeof sigmaInstance.refresh === 'function') {
145
- sigmaInstance.refresh();
146
- console.log('Graph refreshed using sigma.refresh()');
147
- return;
148
- }
149
-
150
- // 如果没有refresh方法,尝试重新绑定graph
151
- if (typeof sigmaInstance.setGraph === 'function') {
152
- sigmaInstance.setGraph(sigmaGraph);
153
- console.log('Rebound graph to sigma instance');
154
- } else {
155
- // 如果setGraph方法不存在,尝试直接设置graph属性
156
- (sigmaInstance as any).graph = sigmaGraph;
157
- console.log('Set graph property directly on sigma instance');
158
- }
159
- } catch (error) {
160
- console.error('Error during refresh:', error);
161
- }
162
- }
163
-
164
- // 通知UI需要重新渲染
165
- set(state => ({ ...state }));
166
- },
167
 
168
  setIsFetching: (isFetching: boolean) => set({ isFetching }),
169
  setShouldRender: (shouldRender: boolean) => set({ shouldRender }),
@@ -412,9 +374,6 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
412
  }
413
  });
414
 
415
- // Refresh the layout
416
- state.refreshLayout();
417
-
418
  } catch (error) {
419
  console.error('Error expanding node:', error);
420
  } finally {
@@ -489,8 +448,7 @@ const useGraphStoreBase = create<GraphState>()((set, get) => ({
489
  state.rawGraph.buildDynamicMap();
490
  }
491
 
492
- // Refresh the layout to update the visualization
493
- state.refreshLayout();
494
 
495
  } catch (error) {
496
  console.error('Error pruning node:', error);
 
77
  graphDataFetchAttempted: boolean
78
  labelsFetchAttempted: boolean
79
 
 
80
  setSigmaInstance: (instance: any) => void
81
  setSelectedNode: (nodeId: string | null, moveToSelectedNode?: boolean) => void
82
  setFocusedNode: (nodeId: string | null) => void
 
126
  sigmaInstance: null,
127
  allDatabaseLabels: ['*'],
128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
  setIsFetching: (isFetching: boolean) => set({ isFetching }),
131
  setShouldRender: (shouldRender: boolean) => set({ shouldRender }),
 
374
  }
375
  });
376
 
 
 
 
377
  } catch (error) {
378
  console.error('Error expanding node:', error);
379
  } finally {
 
448
  state.rawGraph.buildDynamicMap();
449
  }
450
 
451
+ // 图形更新后会自动触发重新布局
 
452
 
453
  } catch (error) {
454
  console.error('Error pruning node:', error);