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 {
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
//
|
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);
|