Feat: replace min_degree with max_nodes in webui

This commit is contained in:
yangdx
2025-04-02 18:35:32 +08:00
parent d7d04a0d94
commit 1a1f934e27
9 changed files with 34 additions and 30 deletions

View File

@@ -221,9 +221,9 @@ axiosInstance.interceptors.response.use(
export const queryGraphs = async ( export const queryGraphs = async (
label: string, label: string,
maxDepth: number, maxDepth: number,
minDegree: number maxNodes: number
): Promise<LightragGraphType> => { ): Promise<LightragGraphType> => {
const response = await axiosInstance.get(`/graphs?label=${encodeURIComponent(label)}&max_depth=${maxDepth}&min_degree=${minDegree}`) const response = await axiosInstance.get(`/graphs?label=${encodeURIComponent(label)}&max_depth=${maxDepth}&max_nodes=${maxNodes}`)
return response.data return response.data
} }

View File

@@ -121,7 +121,7 @@ export default function Settings() {
const enableHideUnselectedEdges = useSettingsStore.use.enableHideUnselectedEdges() const enableHideUnselectedEdges = useSettingsStore.use.enableHideUnselectedEdges()
const showEdgeLabel = useSettingsStore.use.showEdgeLabel() const showEdgeLabel = useSettingsStore.use.showEdgeLabel()
const graphQueryMaxDepth = useSettingsStore.use.graphQueryMaxDepth() const graphQueryMaxDepth = useSettingsStore.use.graphQueryMaxDepth()
const graphMinDegree = useSettingsStore.use.graphMinDegree() const graphMaxNodes = useSettingsStore.use.graphMaxNodes()
const graphLayoutMaxIterations = useSettingsStore.use.graphLayoutMaxIterations() const graphLayoutMaxIterations = useSettingsStore.use.graphLayoutMaxIterations()
const enableHealthCheck = useSettingsStore.use.enableHealthCheck() const enableHealthCheck = useSettingsStore.use.enableHealthCheck()
@@ -180,15 +180,14 @@ export default function Settings() {
}, 300) }, 300)
}, []) }, [])
const setGraphMinDegree = useCallback((degree: number) => { const setGraphMaxNodes = useCallback((nodes: number) => {
if (degree < 0) return if (nodes < 1 || nodes > 1000) return
useSettingsStore.setState({ graphMinDegree: degree }) useSettingsStore.setState({ graphMaxNodes: nodes })
const currentLabel = useSettingsStore.getState().queryLabel const currentLabel = useSettingsStore.getState().queryLabel
useSettingsStore.getState().setQueryLabel('') useSettingsStore.getState().setQueryLabel('')
setTimeout(() => { setTimeout(() => {
useSettingsStore.getState().setQueryLabel(currentLabel) useSettingsStore.getState().setQueryLabel(currentLabel)
}, 300) }, 300)
}, []) }, [])
const setGraphLayoutMaxIterations = useCallback((iterations: number) => { const setGraphLayoutMaxIterations = useCallback((iterations: number) => {
@@ -277,10 +276,11 @@ export default function Settings() {
onEditFinished={setGraphQueryMaxDepth} onEditFinished={setGraphQueryMaxDepth}
/> />
<LabeledNumberInput <LabeledNumberInput
label={t('graphPanel.sideBar.settings.minDegree')} label={t('graphPanel.sideBar.settings.maxNodes')}
min={0} min={1}
value={graphMinDegree} max={1000}
onEditFinished={setGraphMinDegree} value={graphMaxNodes}
onEditFinished={setGraphMaxNodes}
/> />
<LabeledNumberInput <LabeledNumberInput
label={t('graphPanel.sideBar.settings.maxLayoutIterations')} label={t('graphPanel.sideBar.settings.maxLayoutIterations')}

View File

@@ -8,12 +8,12 @@ import { useTranslation } from 'react-i18next'
const SettingsDisplay = () => { const SettingsDisplay = () => {
const { t } = useTranslation() const { t } = useTranslation()
const graphQueryMaxDepth = useSettingsStore.use.graphQueryMaxDepth() const graphQueryMaxDepth = useSettingsStore.use.graphQueryMaxDepth()
const graphMinDegree = useSettingsStore.use.graphMinDegree() const graphMaxNodes = useSettingsStore.use.graphMaxNodes()
return ( return (
<div className="absolute bottom-4 left-[calc(1rem+2.5rem)] flex items-center gap-2 text-xs text-gray-400"> <div className="absolute bottom-4 left-[calc(1rem+2.5rem)] flex items-center gap-2 text-xs text-gray-400">
<div>{t('graphPanel.sideBar.settings.depth')}: {graphQueryMaxDepth}</div> <div>{t('graphPanel.sideBar.settings.depth')}: {graphQueryMaxDepth}</div>
<div>{t('graphPanel.sideBar.settings.degree')}: {graphMinDegree}</div> <div>{t('graphPanel.sideBar.settings.maxNodes')}: {graphMaxNodes}</div>
</div> </div>
) )
} }

View File

@@ -70,7 +70,7 @@ export type NodeType = {
} }
export type EdgeType = { label: string } export type EdgeType = { label: string }
const fetchGraph = async (label: string, maxDepth: number, minDegree: number) => { const fetchGraph = async (label: string, maxDepth: number, maxNodes: number) => {
let rawData: any = null; let rawData: any = null;
// Check if we need to fetch all database labels first // Check if we need to fetch all database labels first
@@ -89,8 +89,8 @@ const fetchGraph = async (label: string, maxDepth: number, minDegree: number) =>
const queryLabel = label || '*'; const queryLabel = label || '*';
try { try {
console.log(`Fetching graph label: ${queryLabel}, depth: ${maxDepth}, deg: ${minDegree}`); console.log(`Fetching graph label: ${queryLabel}, depth: ${maxDepth}, nodes: ${maxNodes}`);
rawData = await queryGraphs(queryLabel, maxDepth, minDegree); rawData = await queryGraphs(queryLabel, maxDepth, maxNodes);
} catch (e) { } catch (e) {
useBackendState.getState().setErrorMessage(errorMessage(e), 'Query Graphs Error!'); useBackendState.getState().setErrorMessage(errorMessage(e), 'Query Graphs Error!');
return null; return null;
@@ -218,7 +218,7 @@ const useLightrangeGraph = () => {
const rawGraph = useGraphStore.use.rawGraph() const rawGraph = useGraphStore.use.rawGraph()
const sigmaGraph = useGraphStore.use.sigmaGraph() const sigmaGraph = useGraphStore.use.sigmaGraph()
const maxQueryDepth = useSettingsStore.use.graphQueryMaxDepth() const maxQueryDepth = useSettingsStore.use.graphQueryMaxDepth()
const minDegree = useSettingsStore.use.graphMinDegree() const maxNodes = useSettingsStore.use.graphMaxNodes()
const isFetching = useGraphStore.use.isFetching() const isFetching = useGraphStore.use.isFetching()
const nodeToExpand = useGraphStore.use.nodeToExpand() const nodeToExpand = useGraphStore.use.nodeToExpand()
const nodeToPrune = useGraphStore.use.nodeToPrune() const nodeToPrune = useGraphStore.use.nodeToPrune()
@@ -292,14 +292,14 @@ const useLightrangeGraph = () => {
// Use a local copy of the parameters // Use a local copy of the parameters
const currentQueryLabel = queryLabel const currentQueryLabel = queryLabel
const currentMaxQueryDepth = maxQueryDepth const currentMaxQueryDepth = maxQueryDepth
const currentMinDegree = minDegree const currentMaxNodes = maxNodes
// Declare a variable to store data promise // Declare a variable to store data promise
let dataPromise; let dataPromise;
// 1. If query label is not empty, use fetchGraph // 1. If query label is not empty, use fetchGraph
if (currentQueryLabel) { if (currentQueryLabel) {
dataPromise = fetchGraph(currentQueryLabel, currentMaxQueryDepth, currentMinDegree); dataPromise = fetchGraph(currentQueryLabel, currentMaxQueryDepth, currentMaxNodes);
} else { } else {
// 2. If query label is empty, set data to null // 2. If query label is empty, set data to null
console.log('Query label is empty, show empty graph') console.log('Query label is empty, show empty graph')
@@ -384,7 +384,7 @@ const useLightrangeGraph = () => {
state.setLastSuccessfulQueryLabel('') // Clear last successful query label on error state.setLastSuccessfulQueryLabel('') // Clear last successful query label on error
}) })
} }
}, [queryLabel, maxQueryDepth, minDegree, isFetching, t]) }, [queryLabel, maxQueryDepth, maxNodes, isFetching, t])
// Handle node expansion // Handle node expansion
useEffect(() => { useEffect(() => {
@@ -407,7 +407,7 @@ const useLightrangeGraph = () => {
} }
// Fetch the extended subgraph with depth 2 // Fetch the extended subgraph with depth 2
const extendedGraph = await queryGraphs(label, 2, 0); const extendedGraph = await queryGraphs(label, 2, 1000);
if (!extendedGraph || !extendedGraph.nodes || !extendedGraph.edges) { if (!extendedGraph || !extendedGraph.nodes || !extendedGraph.edges) {
console.error('Failed to fetch extended graph'); console.error('Failed to fetch extended graph');

View File

@@ -148,7 +148,7 @@
"hideUnselectedEdges": "إخفاء الحواف غير المحددة", "hideUnselectedEdges": "إخفاء الحواف غير المحددة",
"edgeEvents": "أحداث الحافة", "edgeEvents": "أحداث الحافة",
"maxQueryDepth": "أقصى عمق للاستعلام", "maxQueryDepth": "أقصى عمق للاستعلام",
"minDegree": "الدرجة الدنيا", "maxNodes": "الحد الأقصى للعقد",
"maxLayoutIterations": "أقصى تكرارات التخطيط", "maxLayoutIterations": "أقصى تكرارات التخطيط",
"depth": "العمق", "depth": "العمق",
"degree": "الدرجة", "degree": "الدرجة",

View File

@@ -148,7 +148,7 @@
"hideUnselectedEdges": "Hide Unselected Edges", "hideUnselectedEdges": "Hide Unselected Edges",
"edgeEvents": "Edge Events", "edgeEvents": "Edge Events",
"maxQueryDepth": "Max Query Depth", "maxQueryDepth": "Max Query Depth",
"minDegree": "Minimum Degree", "maxNodes": "Max Nodes",
"maxLayoutIterations": "Max Layout Iterations", "maxLayoutIterations": "Max Layout Iterations",
"depth": "Depth", "depth": "Depth",
"degree": "Degree", "degree": "Degree",

View File

@@ -148,7 +148,7 @@
"hideUnselectedEdges": "Masquer les arêtes non sélectionnées", "hideUnselectedEdges": "Masquer les arêtes non sélectionnées",
"edgeEvents": "Événements des arêtes", "edgeEvents": "Événements des arêtes",
"maxQueryDepth": "Profondeur maximale de la requête", "maxQueryDepth": "Profondeur maximale de la requête",
"minDegree": "Degré minimum", "maxNodes": "Nombre maximum de nœuds",
"maxLayoutIterations": "Itérations maximales de mise en page", "maxLayoutIterations": "Itérations maximales de mise en page",
"depth": "Profondeur", "depth": "Profondeur",
"degree": "Degré", "degree": "Degré",

View File

@@ -148,7 +148,7 @@
"hideUnselectedEdges": "隐藏未选中的边", "hideUnselectedEdges": "隐藏未选中的边",
"edgeEvents": "边事件", "edgeEvents": "边事件",
"maxQueryDepth": "最大查询深度", "maxQueryDepth": "最大查询深度",
"minDegree": "最小邻边数", "maxNodes": "最大返回节点数",
"maxLayoutIterations": "最大布局迭代次数", "maxLayoutIterations": "最大布局迭代次数",
"depth": "深度", "depth": "深度",
"degree": "邻边", "degree": "邻边",

View File

@@ -27,8 +27,8 @@ interface SettingsState {
graphQueryMaxDepth: number graphQueryMaxDepth: number
setGraphQueryMaxDepth: (depth: number) => void setGraphQueryMaxDepth: (depth: number) => void
graphMinDegree: number graphMaxNodes: number
setGraphMinDegree: (degree: number) => void setGraphMaxNodes: (nodes: number) => void
graphLayoutMaxIterations: number graphLayoutMaxIterations: number
setGraphLayoutMaxIterations: (iterations: number) => void setGraphLayoutMaxIterations: (iterations: number) => void
@@ -77,7 +77,7 @@ const useSettingsStoreBase = create<SettingsState>()(
enableEdgeEvents: false, enableEdgeEvents: false,
graphQueryMaxDepth: 3, graphQueryMaxDepth: 3,
graphMinDegree: 0, graphMaxNodes: 1000,
graphLayoutMaxIterations: 15, graphLayoutMaxIterations: 15,
queryLabel: defaultQueryLabel, queryLabel: defaultQueryLabel,
@@ -130,7 +130,7 @@ const useSettingsStoreBase = create<SettingsState>()(
setGraphQueryMaxDepth: (depth: number) => set({ graphQueryMaxDepth: depth }), setGraphQueryMaxDepth: (depth: number) => set({ graphQueryMaxDepth: depth }),
setGraphMinDegree: (degree: number) => set({ graphMinDegree: degree }), setGraphMaxNodes: (nodes: number) => set({ graphMaxNodes: nodes }),
setEnableHealthCheck: (enable: boolean) => set({ enableHealthCheck: enable }), setEnableHealthCheck: (enable: boolean) => set({ enableHealthCheck: enable }),
@@ -150,7 +150,7 @@ const useSettingsStoreBase = create<SettingsState>()(
{ {
name: 'settings-storage', name: 'settings-storage',
storage: createJSONStorage(() => localStorage), storage: createJSONStorage(() => localStorage),
version: 9, version: 10,
migrate: (state: any, version: number) => { migrate: (state: any, version: number) => {
if (version < 2) { if (version < 2) {
state.showEdgeLabel = false state.showEdgeLabel = false
@@ -196,6 +196,10 @@ const useSettingsStoreBase = create<SettingsState>()(
if (version < 9) { if (version < 9) {
state.showFileName = false state.showFileName = false
} }
if (version < 10) {
delete state.graphMinDegree // 删除废弃参数
state.graphMaxNodes = 1000 // 添加新参数
}
return state return state
} }
} }