Merge branch 'feat-node-expand' into webui-node-expansion
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -8,7 +8,7 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="./logo.png" />
|
<link rel="icon" type="image/svg+xml" href="./logo.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Lightrag</title>
|
<title>Lightrag</title>
|
||||||
<script type="module" crossorigin src="./assets/index-BpDMZCmZ.js"></script>
|
<script type="module" crossorigin src="./assets/index-DuxTk-ly.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="./assets/index-BEGlBF11.css">
|
<link rel="stylesheet" crossorigin href="./assets/index-BEGlBF11.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@@ -2,14 +2,17 @@ import { useCallback, useEffect, useRef } from 'react'
|
|||||||
import { AsyncSelect } from '@/components/ui/AsyncSelect'
|
import { AsyncSelect } from '@/components/ui/AsyncSelect'
|
||||||
import { useSettingsStore } from '@/stores/settings'
|
import { useSettingsStore } from '@/stores/settings'
|
||||||
import { useGraphStore } from '@/stores/graph'
|
import { useGraphStore } from '@/stores/graph'
|
||||||
import { labelListLimit } from '@/lib/constants'
|
import { labelListLimit, controlButtonVariant } from '@/lib/constants'
|
||||||
import MiniSearch from 'minisearch'
|
import MiniSearch from 'minisearch'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { RefreshCw } from 'lucide-react'
|
||||||
|
import Button from '@/components/ui/Button'
|
||||||
|
|
||||||
const GraphLabels = () => {
|
const GraphLabels = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const label = useSettingsStore.use.queryLabel()
|
const label = useSettingsStore.use.queryLabel()
|
||||||
const allDatabaseLabels = useGraphStore.use.allDatabaseLabels()
|
const allDatabaseLabels = useGraphStore.use.allDatabaseLabels()
|
||||||
|
const rawGraph = useGraphStore.use.rawGraph()
|
||||||
const labelsLoadedRef = useRef(false)
|
const labelsLoadedRef = useRef(false)
|
||||||
|
|
||||||
// Track if a fetch is in progress to prevent multiple simultaneous fetches
|
// Track if a fetch is in progress to prevent multiple simultaneous fetches
|
||||||
@@ -83,47 +86,70 @@ const GraphLabels = () => {
|
|||||||
[getSearchEngine]
|
[getSearchEngine]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const handleRefresh = useCallback(() => {
|
||||||
|
const currentLabel = useSettingsStore.getState().queryLabel
|
||||||
|
|
||||||
|
useGraphStore.getState().setGraphDataFetchAttempted(false)
|
||||||
|
|
||||||
|
useGraphStore.getState().reset()
|
||||||
|
|
||||||
|
useSettingsStore.getState().setQueryLabel(currentLabel)
|
||||||
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncSelect<string>
|
<div className="flex items-center">
|
||||||
className="ml-2"
|
{rawGraph && (
|
||||||
triggerClassName="max-h-8"
|
<Button
|
||||||
searchInputClassName="max-h-8"
|
size="icon"
|
||||||
triggerTooltip={t('graphPanel.graphLabels.selectTooltip')}
|
variant={controlButtonVariant}
|
||||||
fetcher={fetchData}
|
onClick={handleRefresh}
|
||||||
renderOption={(item) => <div>{item}</div>}
|
tooltip={t('graphPanel.graphLabels.refreshTooltip')}
|
||||||
getOptionValue={(item) => item}
|
className="mr-1"
|
||||||
getDisplayValue={(item) => <div>{item}</div>}
|
>
|
||||||
notFound={<div className="py-6 text-center text-sm">No labels found</div>}
|
<RefreshCw className="h-4 w-4" />
|
||||||
label={t('graphPanel.graphLabels.label')}
|
</Button>
|
||||||
placeholder={t('graphPanel.graphLabels.placeholder')}
|
)}
|
||||||
value={label !== null ? label : '*'}
|
<AsyncSelect<string>
|
||||||
onChange={(newLabel) => {
|
className="ml-2"
|
||||||
const currentLabel = useSettingsStore.getState().queryLabel
|
triggerClassName="max-h-8"
|
||||||
|
searchInputClassName="max-h-8"
|
||||||
|
triggerTooltip={t('graphPanel.graphLabels.selectTooltip')}
|
||||||
|
fetcher={fetchData}
|
||||||
|
renderOption={(item) => <div>{item}</div>}
|
||||||
|
getOptionValue={(item) => item}
|
||||||
|
getDisplayValue={(item) => <div>{item}</div>}
|
||||||
|
notFound={<div className="py-6 text-center text-sm">No labels found</div>}
|
||||||
|
label={t('graphPanel.graphLabels.label')}
|
||||||
|
placeholder={t('graphPanel.graphLabels.placeholder')}
|
||||||
|
value={label !== null ? label : '*'}
|
||||||
|
onChange={(newLabel) => {
|
||||||
|
const currentLabel = useSettingsStore.getState().queryLabel
|
||||||
|
|
||||||
// select the last item means query all
|
// select the last item means query all
|
||||||
if (newLabel === '...') {
|
if (newLabel === '...') {
|
||||||
newLabel = '*'
|
newLabel = '*'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the fetch attempted flag to force a new data fetch
|
// Reset the fetch attempted flag to force a new data fetch
|
||||||
useGraphStore.getState().setGraphDataFetchAttempted(false)
|
useGraphStore.getState().setGraphDataFetchAttempted(false)
|
||||||
|
|
||||||
// Clear current graph data to ensure complete reload when label changes
|
// Clear current graph data to ensure complete reload when label changes
|
||||||
if (newLabel !== currentLabel) {
|
if (newLabel !== currentLabel) {
|
||||||
const graphStore = useGraphStore.getState();
|
const graphStore = useGraphStore.getState();
|
||||||
// Reset the all graph objects and status
|
// Reset the all graph objects and status
|
||||||
graphStore.reset();
|
graphStore.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newLabel === currentLabel && newLabel !== '*') {
|
if (newLabel === currentLabel && newLabel !== '*') {
|
||||||
// reselect the same itme means qery all
|
// reselect the same itme means qery all
|
||||||
useSettingsStore.getState().setQueryLabel('*')
|
useSettingsStore.getState().setQueryLabel('*')
|
||||||
} else {
|
} else {
|
||||||
useSettingsStore.getState().setQueryLabel(newLabel)
|
useSettingsStore.getState().setQueryLabel(newLabel)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
clearable={false} // Prevent clearing value on reselect
|
clearable={false} // Prevent clearing value on reselect
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -203,10 +203,19 @@ const LayoutsControl = () => {
|
|||||||
const layoutCircular = useLayoutCircular()
|
const layoutCircular = useLayoutCircular()
|
||||||
const layoutCirclepack = useLayoutCirclepack()
|
const layoutCirclepack = useLayoutCirclepack()
|
||||||
const layoutRandom = useLayoutRandom()
|
const layoutRandom = useLayoutRandom()
|
||||||
const layoutNoverlap = useLayoutNoverlap({ settings: { margin: 1 } })
|
const layoutNoverlap = useLayoutNoverlap({
|
||||||
|
maxIterations: maxIterations,
|
||||||
|
settings: {
|
||||||
|
margin: 2,
|
||||||
|
expansion: 1.1,
|
||||||
|
gridSize: 5,
|
||||||
|
ratio: 1,
|
||||||
|
speed: 3,
|
||||||
|
}
|
||||||
|
})
|
||||||
// Add parameters for Force Directed layout to improve convergence
|
// Add parameters for Force Directed layout to improve convergence
|
||||||
const layoutForce = useLayoutForce({
|
const layoutForce = useLayoutForce({
|
||||||
maxIterations: maxIterations * 3, // Triple the iterations for better convergence
|
maxIterations: maxIterations,
|
||||||
settings: {
|
settings: {
|
||||||
attraction: 0.0003, // Lower attraction force to reduce oscillation
|
attraction: 0.0003, // Lower attraction force to reduce oscillation
|
||||||
repulsion: 0.05, // Lower repulsion force to reduce oscillation
|
repulsion: 0.05, // Lower repulsion force to reduce oscillation
|
||||||
|
@@ -182,7 +182,8 @@
|
|||||||
"noLabels": "No labels found",
|
"noLabels": "No labels found",
|
||||||
"label": "Label",
|
"label": "Label",
|
||||||
"placeholder": "Search labels...",
|
"placeholder": "Search labels...",
|
||||||
"andOthers": "And {count} others"
|
"andOthers": "And {count} others",
|
||||||
|
"refreshTooltip": "Reload graph data"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"retrievePanel": {
|
"retrievePanel": {
|
||||||
|
@@ -179,7 +179,8 @@
|
|||||||
"noLabels": "未找到标签",
|
"noLabels": "未找到标签",
|
||||||
"label": "标签",
|
"label": "标签",
|
||||||
"placeholder": "搜索标签...",
|
"placeholder": "搜索标签...",
|
||||||
"andOthers": "还有 {count} 个"
|
"andOthers": "还有 {count} 个",
|
||||||
|
"refreshTooltip": "重新加载图形数据"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"retrievePanel": {
|
"retrievePanel": {
|
||||||
|
Reference in New Issue
Block a user