yangdx
commited on
Commit
·
19d53d6
1
Parent(s):
69a5e66
Feat: replace min_degree with max_nodes in webui
Browse files- lightrag_webui/src/api/lightrag.ts +2 -2
- lightrag_webui/src/components/graph/Settings.tsx +9 -9
- lightrag_webui/src/components/graph/SettingsDisplay.tsx +2 -2
- lightrag_webui/src/hooks/useLightragGraph.tsx +8 -8
- lightrag_webui/src/locales/ar.json +1 -1
- lightrag_webui/src/locales/en.json +1 -1
- lightrag_webui/src/locales/fr.json +1 -1
- lightrag_webui/src/locales/zh.json +1 -1
- lightrag_webui/src/stores/settings.ts +9 -5
lightrag_webui/src/api/lightrag.ts
CHANGED
@@ -221,9 +221,9 @@ axiosInstance.interceptors.response.use(
|
|
221 |
export const queryGraphs = async (
|
222 |
label: string,
|
223 |
maxDepth: number,
|
224 |
-
|
225 |
): Promise<LightragGraphType> => {
|
226 |
-
const response = await axiosInstance.get(`/graphs?label=${encodeURIComponent(label)}&max_depth=${maxDepth}&
|
227 |
return response.data
|
228 |
}
|
229 |
|
|
|
221 |
export const queryGraphs = async (
|
222 |
label: string,
|
223 |
maxDepth: number,
|
224 |
+
maxNodes: number
|
225 |
): Promise<LightragGraphType> => {
|
226 |
+
const response = await axiosInstance.get(`/graphs?label=${encodeURIComponent(label)}&max_depth=${maxDepth}&max_nodes=${maxNodes}`)
|
227 |
return response.data
|
228 |
}
|
229 |
|
lightrag_webui/src/components/graph/Settings.tsx
CHANGED
@@ -121,7 +121,7 @@ export default function Settings() {
|
|
121 |
const enableHideUnselectedEdges = useSettingsStore.use.enableHideUnselectedEdges()
|
122 |
const showEdgeLabel = useSettingsStore.use.showEdgeLabel()
|
123 |
const graphQueryMaxDepth = useSettingsStore.use.graphQueryMaxDepth()
|
124 |
-
const
|
125 |
const graphLayoutMaxIterations = useSettingsStore.use.graphLayoutMaxIterations()
|
126 |
|
127 |
const enableHealthCheck = useSettingsStore.use.enableHealthCheck()
|
@@ -180,15 +180,14 @@ export default function Settings() {
|
|
180 |
}, 300)
|
181 |
}, [])
|
182 |
|
183 |
-
const
|
184 |
-
if (
|
185 |
-
useSettingsStore.setState({
|
186 |
const currentLabel = useSettingsStore.getState().queryLabel
|
187 |
useSettingsStore.getState().setQueryLabel('')
|
188 |
setTimeout(() => {
|
189 |
useSettingsStore.getState().setQueryLabel(currentLabel)
|
190 |
}, 300)
|
191 |
-
|
192 |
}, [])
|
193 |
|
194 |
const setGraphLayoutMaxIterations = useCallback((iterations: number) => {
|
@@ -277,10 +276,11 @@ export default function Settings() {
|
|
277 |
onEditFinished={setGraphQueryMaxDepth}
|
278 |
/>
|
279 |
<LabeledNumberInput
|
280 |
-
label={t('graphPanel.sideBar.settings.
|
281 |
-
min={
|
282 |
-
|
283 |
-
|
|
|
284 |
/>
|
285 |
<LabeledNumberInput
|
286 |
label={t('graphPanel.sideBar.settings.maxLayoutIterations')}
|
|
|
121 |
const enableHideUnselectedEdges = useSettingsStore.use.enableHideUnselectedEdges()
|
122 |
const showEdgeLabel = useSettingsStore.use.showEdgeLabel()
|
123 |
const graphQueryMaxDepth = useSettingsStore.use.graphQueryMaxDepth()
|
124 |
+
const graphMaxNodes = useSettingsStore.use.graphMaxNodes()
|
125 |
const graphLayoutMaxIterations = useSettingsStore.use.graphLayoutMaxIterations()
|
126 |
|
127 |
const enableHealthCheck = useSettingsStore.use.enableHealthCheck()
|
|
|
180 |
}, 300)
|
181 |
}, [])
|
182 |
|
183 |
+
const setGraphMaxNodes = useCallback((nodes: number) => {
|
184 |
+
if (nodes < 1 || nodes > 1000) return
|
185 |
+
useSettingsStore.setState({ graphMaxNodes: nodes })
|
186 |
const currentLabel = useSettingsStore.getState().queryLabel
|
187 |
useSettingsStore.getState().setQueryLabel('')
|
188 |
setTimeout(() => {
|
189 |
useSettingsStore.getState().setQueryLabel(currentLabel)
|
190 |
}, 300)
|
|
|
191 |
}, [])
|
192 |
|
193 |
const setGraphLayoutMaxIterations = useCallback((iterations: number) => {
|
|
|
276 |
onEditFinished={setGraphQueryMaxDepth}
|
277 |
/>
|
278 |
<LabeledNumberInput
|
279 |
+
label={t('graphPanel.sideBar.settings.maxNodes')}
|
280 |
+
min={1}
|
281 |
+
max={1000}
|
282 |
+
value={graphMaxNodes}
|
283 |
+
onEditFinished={setGraphMaxNodes}
|
284 |
/>
|
285 |
<LabeledNumberInput
|
286 |
label={t('graphPanel.sideBar.settings.maxLayoutIterations')}
|
lightrag_webui/src/components/graph/SettingsDisplay.tsx
CHANGED
@@ -8,12 +8,12 @@ import { useTranslation } from 'react-i18next'
|
|
8 |
const SettingsDisplay = () => {
|
9 |
const { t } = useTranslation()
|
10 |
const graphQueryMaxDepth = useSettingsStore.use.graphQueryMaxDepth()
|
11 |
-
const
|
12 |
|
13 |
return (
|
14 |
<div className="absolute bottom-4 left-[calc(1rem+2.5rem)] flex items-center gap-2 text-xs text-gray-400">
|
15 |
<div>{t('graphPanel.sideBar.settings.depth')}: {graphQueryMaxDepth}</div>
|
16 |
-
<div>{t('graphPanel.sideBar.settings.
|
17 |
</div>
|
18 |
)
|
19 |
}
|
|
|
8 |
const SettingsDisplay = () => {
|
9 |
const { t } = useTranslation()
|
10 |
const graphQueryMaxDepth = useSettingsStore.use.graphQueryMaxDepth()
|
11 |
+
const graphMaxNodes = useSettingsStore.use.graphMaxNodes()
|
12 |
|
13 |
return (
|
14 |
<div className="absolute bottom-4 left-[calc(1rem+2.5rem)] flex items-center gap-2 text-xs text-gray-400">
|
15 |
<div>{t('graphPanel.sideBar.settings.depth')}: {graphQueryMaxDepth}</div>
|
16 |
+
<div>{t('graphPanel.sideBar.settings.maxNodes')}: {graphMaxNodes}</div>
|
17 |
</div>
|
18 |
)
|
19 |
}
|
lightrag_webui/src/hooks/useLightragGraph.tsx
CHANGED
@@ -70,7 +70,7 @@ export type NodeType = {
|
|
70 |
}
|
71 |
export type EdgeType = { label: string }
|
72 |
|
73 |
-
const fetchGraph = async (label: string, maxDepth: number,
|
74 |
let rawData: any = null;
|
75 |
|
76 |
// Check if we need to fetch all database labels first
|
@@ -89,8 +89,8 @@ const fetchGraph = async (label: string, maxDepth: number, minDegree: number) =>
|
|
89 |
const queryLabel = label || '*';
|
90 |
|
91 |
try {
|
92 |
-
console.log(`Fetching graph label: ${queryLabel}, depth: ${maxDepth},
|
93 |
-
rawData = await queryGraphs(queryLabel, maxDepth,
|
94 |
} catch (e) {
|
95 |
useBackendState.getState().setErrorMessage(errorMessage(e), 'Query Graphs Error!');
|
96 |
return null;
|
@@ -218,7 +218,7 @@ const useLightrangeGraph = () => {
|
|
218 |
const rawGraph = useGraphStore.use.rawGraph()
|
219 |
const sigmaGraph = useGraphStore.use.sigmaGraph()
|
220 |
const maxQueryDepth = useSettingsStore.use.graphQueryMaxDepth()
|
221 |
-
const
|
222 |
const isFetching = useGraphStore.use.isFetching()
|
223 |
const nodeToExpand = useGraphStore.use.nodeToExpand()
|
224 |
const nodeToPrune = useGraphStore.use.nodeToPrune()
|
@@ -292,14 +292,14 @@ const useLightrangeGraph = () => {
|
|
292 |
// Use a local copy of the parameters
|
293 |
const currentQueryLabel = queryLabel
|
294 |
const currentMaxQueryDepth = maxQueryDepth
|
295 |
-
const
|
296 |
|
297 |
// Declare a variable to store data promise
|
298 |
let dataPromise;
|
299 |
|
300 |
// 1. If query label is not empty, use fetchGraph
|
301 |
if (currentQueryLabel) {
|
302 |
-
dataPromise = fetchGraph(currentQueryLabel, currentMaxQueryDepth,
|
303 |
} else {
|
304 |
// 2. If query label is empty, set data to null
|
305 |
console.log('Query label is empty, show empty graph')
|
@@ -384,7 +384,7 @@ const useLightrangeGraph = () => {
|
|
384 |
state.setLastSuccessfulQueryLabel('') // Clear last successful query label on error
|
385 |
})
|
386 |
}
|
387 |
-
}, [queryLabel, maxQueryDepth,
|
388 |
|
389 |
// Handle node expansion
|
390 |
useEffect(() => {
|
@@ -407,7 +407,7 @@ const useLightrangeGraph = () => {
|
|
407 |
}
|
408 |
|
409 |
// Fetch the extended subgraph with depth 2
|
410 |
-
const extendedGraph = await queryGraphs(label, 2,
|
411 |
|
412 |
if (!extendedGraph || !extendedGraph.nodes || !extendedGraph.edges) {
|
413 |
console.error('Failed to fetch extended graph');
|
|
|
70 |
}
|
71 |
export type EdgeType = { label: string }
|
72 |
|
73 |
+
const fetchGraph = async (label: string, maxDepth: number, maxNodes: number) => {
|
74 |
let rawData: any = null;
|
75 |
|
76 |
// Check if we need to fetch all database labels first
|
|
|
89 |
const queryLabel = label || '*';
|
90 |
|
91 |
try {
|
92 |
+
console.log(`Fetching graph label: ${queryLabel}, depth: ${maxDepth}, nodes: ${maxNodes}`);
|
93 |
+
rawData = await queryGraphs(queryLabel, maxDepth, maxNodes);
|
94 |
} catch (e) {
|
95 |
useBackendState.getState().setErrorMessage(errorMessage(e), 'Query Graphs Error!');
|
96 |
return null;
|
|
|
218 |
const rawGraph = useGraphStore.use.rawGraph()
|
219 |
const sigmaGraph = useGraphStore.use.sigmaGraph()
|
220 |
const maxQueryDepth = useSettingsStore.use.graphQueryMaxDepth()
|
221 |
+
const maxNodes = useSettingsStore.use.graphMaxNodes()
|
222 |
const isFetching = useGraphStore.use.isFetching()
|
223 |
const nodeToExpand = useGraphStore.use.nodeToExpand()
|
224 |
const nodeToPrune = useGraphStore.use.nodeToPrune()
|
|
|
292 |
// Use a local copy of the parameters
|
293 |
const currentQueryLabel = queryLabel
|
294 |
const currentMaxQueryDepth = maxQueryDepth
|
295 |
+
const currentMaxNodes = maxNodes
|
296 |
|
297 |
// Declare a variable to store data promise
|
298 |
let dataPromise;
|
299 |
|
300 |
// 1. If query label is not empty, use fetchGraph
|
301 |
if (currentQueryLabel) {
|
302 |
+
dataPromise = fetchGraph(currentQueryLabel, currentMaxQueryDepth, currentMaxNodes);
|
303 |
} else {
|
304 |
// 2. If query label is empty, set data to null
|
305 |
console.log('Query label is empty, show empty graph')
|
|
|
384 |
state.setLastSuccessfulQueryLabel('') // Clear last successful query label on error
|
385 |
})
|
386 |
}
|
387 |
+
}, [queryLabel, maxQueryDepth, maxNodes, isFetching, t])
|
388 |
|
389 |
// Handle node expansion
|
390 |
useEffect(() => {
|
|
|
407 |
}
|
408 |
|
409 |
// Fetch the extended subgraph with depth 2
|
410 |
+
const extendedGraph = await queryGraphs(label, 2, 1000);
|
411 |
|
412 |
if (!extendedGraph || !extendedGraph.nodes || !extendedGraph.edges) {
|
413 |
console.error('Failed to fetch extended graph');
|
lightrag_webui/src/locales/ar.json
CHANGED
@@ -148,7 +148,7 @@
|
|
148 |
"hideUnselectedEdges": "إخفاء الحواف غير المحددة",
|
149 |
"edgeEvents": "أحداث الحافة",
|
150 |
"maxQueryDepth": "أقصى عمق للاستعلام",
|
151 |
-
"
|
152 |
"maxLayoutIterations": "أقصى تكرارات التخطيط",
|
153 |
"depth": "العمق",
|
154 |
"degree": "الدرجة",
|
|
|
148 |
"hideUnselectedEdges": "إخفاء الحواف غير المحددة",
|
149 |
"edgeEvents": "أحداث الحافة",
|
150 |
"maxQueryDepth": "أقصى عمق للاستعلام",
|
151 |
+
"maxNodes": "الحد الأقصى للعقد",
|
152 |
"maxLayoutIterations": "أقصى تكرارات التخطيط",
|
153 |
"depth": "العمق",
|
154 |
"degree": "الدرجة",
|
lightrag_webui/src/locales/en.json
CHANGED
@@ -148,7 +148,7 @@
|
|
148 |
"hideUnselectedEdges": "Hide Unselected Edges",
|
149 |
"edgeEvents": "Edge Events",
|
150 |
"maxQueryDepth": "Max Query Depth",
|
151 |
-
"
|
152 |
"maxLayoutIterations": "Max Layout Iterations",
|
153 |
"depth": "Depth",
|
154 |
"degree": "Degree",
|
|
|
148 |
"hideUnselectedEdges": "Hide Unselected Edges",
|
149 |
"edgeEvents": "Edge Events",
|
150 |
"maxQueryDepth": "Max Query Depth",
|
151 |
+
"maxNodes": "Max Nodes",
|
152 |
"maxLayoutIterations": "Max Layout Iterations",
|
153 |
"depth": "Depth",
|
154 |
"degree": "Degree",
|
lightrag_webui/src/locales/fr.json
CHANGED
@@ -148,7 +148,7 @@
|
|
148 |
"hideUnselectedEdges": "Masquer les arêtes non sélectionnées",
|
149 |
"edgeEvents": "Événements des arêtes",
|
150 |
"maxQueryDepth": "Profondeur maximale de la requête",
|
151 |
-
"
|
152 |
"maxLayoutIterations": "Itérations maximales de mise en page",
|
153 |
"depth": "Profondeur",
|
154 |
"degree": "Degré",
|
|
|
148 |
"hideUnselectedEdges": "Masquer les arêtes non sélectionnées",
|
149 |
"edgeEvents": "Événements des arêtes",
|
150 |
"maxQueryDepth": "Profondeur maximale de la requête",
|
151 |
+
"maxNodes": "Nombre maximum de nœuds",
|
152 |
"maxLayoutIterations": "Itérations maximales de mise en page",
|
153 |
"depth": "Profondeur",
|
154 |
"degree": "Degré",
|
lightrag_webui/src/locales/zh.json
CHANGED
@@ -148,7 +148,7 @@
|
|
148 |
"hideUnselectedEdges": "隐藏未选中的边",
|
149 |
"edgeEvents": "边事件",
|
150 |
"maxQueryDepth": "最大查询深度",
|
151 |
-
"
|
152 |
"maxLayoutIterations": "最大布局迭代次数",
|
153 |
"depth": "深度",
|
154 |
"degree": "邻边",
|
|
|
148 |
"hideUnselectedEdges": "隐藏未选中的边",
|
149 |
"edgeEvents": "边事件",
|
150 |
"maxQueryDepth": "最大查询深度",
|
151 |
+
"maxNodes": "最大返回节点数",
|
152 |
"maxLayoutIterations": "最大布局迭代次数",
|
153 |
"depth": "深度",
|
154 |
"degree": "邻边",
|
lightrag_webui/src/stores/settings.ts
CHANGED
@@ -27,8 +27,8 @@ interface SettingsState {
|
|
27 |
graphQueryMaxDepth: number
|
28 |
setGraphQueryMaxDepth: (depth: number) => void
|
29 |
|
30 |
-
|
31 |
-
|
32 |
|
33 |
graphLayoutMaxIterations: number
|
34 |
setGraphLayoutMaxIterations: (iterations: number) => void
|
@@ -77,7 +77,7 @@ const useSettingsStoreBase = create<SettingsState>()(
|
|
77 |
enableEdgeEvents: false,
|
78 |
|
79 |
graphQueryMaxDepth: 3,
|
80 |
-
|
81 |
graphLayoutMaxIterations: 15,
|
82 |
|
83 |
queryLabel: defaultQueryLabel,
|
@@ -130,7 +130,7 @@ const useSettingsStoreBase = create<SettingsState>()(
|
|
130 |
|
131 |
setGraphQueryMaxDepth: (depth: number) => set({ graphQueryMaxDepth: depth }),
|
132 |
|
133 |
-
|
134 |
|
135 |
setEnableHealthCheck: (enable: boolean) => set({ enableHealthCheck: enable }),
|
136 |
|
@@ -150,7 +150,7 @@ const useSettingsStoreBase = create<SettingsState>()(
|
|
150 |
{
|
151 |
name: 'settings-storage',
|
152 |
storage: createJSONStorage(() => localStorage),
|
153 |
-
version:
|
154 |
migrate: (state: any, version: number) => {
|
155 |
if (version < 2) {
|
156 |
state.showEdgeLabel = false
|
@@ -196,6 +196,10 @@ const useSettingsStoreBase = create<SettingsState>()(
|
|
196 |
if (version < 9) {
|
197 |
state.showFileName = false
|
198 |
}
|
|
|
|
|
|
|
|
|
199 |
return state
|
200 |
}
|
201 |
}
|
|
|
27 |
graphQueryMaxDepth: number
|
28 |
setGraphQueryMaxDepth: (depth: number) => void
|
29 |
|
30 |
+
graphMaxNodes: number
|
31 |
+
setGraphMaxNodes: (nodes: number) => void
|
32 |
|
33 |
graphLayoutMaxIterations: number
|
34 |
setGraphLayoutMaxIterations: (iterations: number) => void
|
|
|
77 |
enableEdgeEvents: false,
|
78 |
|
79 |
graphQueryMaxDepth: 3,
|
80 |
+
graphMaxNodes: 1000,
|
81 |
graphLayoutMaxIterations: 15,
|
82 |
|
83 |
queryLabel: defaultQueryLabel,
|
|
|
130 |
|
131 |
setGraphQueryMaxDepth: (depth: number) => set({ graphQueryMaxDepth: depth }),
|
132 |
|
133 |
+
setGraphMaxNodes: (nodes: number) => set({ graphMaxNodes: nodes }),
|
134 |
|
135 |
setEnableHealthCheck: (enable: boolean) => set({ enableHealthCheck: enable }),
|
136 |
|
|
|
150 |
{
|
151 |
name: 'settings-storage',
|
152 |
storage: createJSONStorage(() => localStorage),
|
153 |
+
version: 10,
|
154 |
migrate: (state: any, version: number) => {
|
155 |
if (version < 2) {
|
156 |
state.showEdgeLabel = false
|
|
|
196 |
if (version < 9) {
|
197 |
state.showFileName = false
|
198 |
}
|
199 |
+
if (version < 10) {
|
200 |
+
delete state.graphMinDegree // 删除废弃参数
|
201 |
+
state.graphMaxNodes = 1000 // 添加新参数
|
202 |
+
}
|
203 |
return state
|
204 |
}
|
205 |
}
|