Merge branch 'feat-edge-thickness' into merge-edge-thickness

This commit is contained in:
yangdx
2025-04-05 13:06:28 +08:00
9 changed files with 149 additions and 4 deletions

View File

@@ -655,7 +655,7 @@ The `apipeline_enqueue_documents` and `apipeline_process_enqueue_documents` func
This is useful for scenarios where you want to process documents in the background while still allowing the main thread to continue executing.
And using a routine to process news documents.
And using a routine to process new documents.
```python
rag = LightRAG(..)

View File

@@ -36,6 +36,8 @@ const GraphControl = ({ disableHoverEffect }: { disableHoverEffect?: boolean })
const enableEdgeEvents = useSettingsStore.use.enableEdgeEvents()
const renderEdgeLabels = useSettingsStore.use.showEdgeLabel()
const renderLabels = useSettingsStore.use.showNodeLabel()
const minEdgeSize = useSettingsStore.use.minEdgeSize()
const maxEdgeSize = useSettingsStore.use.maxEdgeSize()
const selectedNode = useGraphStore.use.selectedNode()
const focusedNode = useGraphStore.use.focusedNode()
const selectedEdge = useGraphStore.use.selectedEdge()
@@ -136,6 +138,51 @@ const GraphControl = ({ disableHoverEffect }: { disableHoverEffect?: boolean })
registerEvents(events)
}, [registerEvents, enableEdgeEvents])
/**
* When edge size settings change, recalculate edge sizes and refresh the sigma instance
* to ensure changes take effect immediately
*/
useEffect(() => {
if (sigma && sigmaGraph) {
// Get the graph from sigma
const graph = sigma.getGraph()
// Find min and max weight values
let minWeight = Number.MAX_SAFE_INTEGER
let maxWeight = 0
graph.forEachEdge(edge => {
// Get original weight (before scaling)
const weight = graph.getEdgeAttribute(edge, 'originalWeight') || 1
if (typeof weight === 'number') {
minWeight = Math.min(minWeight, weight)
maxWeight = Math.max(maxWeight, weight)
}
})
// Scale edge sizes based on weight range and current min/max edge size settings
const weightRange = maxWeight - minWeight
if (weightRange > 0) {
const sizeScale = maxEdgeSize - minEdgeSize
graph.forEachEdge(edge => {
const weight = graph.getEdgeAttribute(edge, 'originalWeight') || 1
if (typeof weight === 'number') {
const scaledSize = minEdgeSize + sizeScale * Math.pow((weight - minWeight) / weightRange, 0.5)
graph.setEdgeAttribute(edge, 'size', scaledSize)
}
})
} else {
// If all weights are the same, use default size
graph.forEachEdge(edge => {
graph.setEdgeAttribute(edge, 'size', minEdgeSize)
})
}
// Refresh the sigma instance to apply changes
sigma.refresh()
}
}, [sigma, sigmaGraph, minEdgeSize, maxEdgeSize])
/**
* When component mount or hovered node change
* => Setting the sigma reducers

View File

@@ -144,6 +144,8 @@ export default function Settings() {
const enableNodeDrag = useSettingsStore.use.enableNodeDrag()
const enableHideUnselectedEdges = useSettingsStore.use.enableHideUnselectedEdges()
const showEdgeLabel = useSettingsStore.use.showEdgeLabel()
const minEdgeSize = useSettingsStore.use.minEdgeSize()
const maxEdgeSize = useSettingsStore.use.maxEdgeSize()
const graphQueryMaxDepth = useSettingsStore.use.graphQueryMaxDepth()
const graphMaxNodes = useSettingsStore.use.graphMaxNodes()
const graphLayoutMaxIterations = useSettingsStore.use.graphLayoutMaxIterations()
@@ -292,6 +294,40 @@ export default function Settings() {
label={t('graphPanel.sideBar.settings.edgeEvents')}
/>
<div className="flex flex-col gap-2">
<label className="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
{t('graphPanel.sideBar.settings.edgeSizeRange')}
</label>
<div className="flex items-center gap-2">
<Input
type="number"
value={minEdgeSize}
onChange={(e) => {
const newValue = Number(e.target.value);
if (!isNaN(newValue) && newValue >= 1 && newValue <= maxEdgeSize) {
useSettingsStore.setState({ minEdgeSize: newValue });
}
}}
className="h-6 w-16 min-w-0 pr-1"
min={1}
max={maxEdgeSize}
/>
<span>-</span>
<Input
type="number"
value={maxEdgeSize}
onChange={(e) => {
const newValue = Number(e.target.value);
if (!isNaN(newValue) && newValue >= minEdgeSize && newValue >= 1) {
useSettingsStore.setState({ maxEdgeSize: newValue });
}
}}
className="h-6 w-16 min-w-0 pr-1"
min={minEdgeSize}
/>
</div>
</div>
<Separator />
<LabeledNumberInput
label={t('graphPanel.sideBar.settings.maxQueryDepth')}

View File

@@ -68,7 +68,13 @@ export type NodeType = {
color: string
highlighted?: boolean
}
export type EdgeType = { label: string }
export type EdgeType = {
label: string
originalWeight?: number
size?: number
color?: string
hidden?: boolean
}
const fetchGraph = async (label: string, maxDepth: number, maxNodes: number) => {
let rawData: any = null;
@@ -174,6 +180,9 @@ const fetchGraph = async (label: string, maxDepth: number, maxNodes: number) =>
// Create a new graph instance with the raw graph data
const createSigmaGraph = (rawGraph: RawGraph | null) => {
// Get edge size settings from store
const minEdgeSize = useSettingsStore.getState().minEdgeSize
const maxEdgeSize = useSettingsStore.getState().maxEdgeSize
// Skip graph creation if no data or empty nodes
if (!rawGraph || !rawGraph.nodes.length) {
console.log('No graph data available, skipping sigma graph creation');
@@ -204,8 +213,40 @@ const createSigmaGraph = (rawGraph: RawGraph | null) => {
// Add edges from raw graph data
for (const rawEdge of rawGraph?.edges ?? []) {
// Get weight from edge properties or default to 1
const weight = rawEdge.properties?.weight !== undefined ? Number(rawEdge.properties.weight) : 1
rawEdge.dynamicId = graph.addDirectedEdge(rawEdge.source, rawEdge.target, {
label: rawEdge.properties?.keywords || undefined
label: rawEdge.properties?.keywords || undefined,
size: weight, // Set initial size based on weight
originalWeight: weight, // Store original weight for recalculation
})
}
// Calculate edge size based on weight range, similar to node size calculation
let minWeight = Number.MAX_SAFE_INTEGER
let maxWeight = 0
// Find min and max weight values
graph.forEachEdge(edge => {
const weight = graph.getEdgeAttribute(edge, 'originalWeight') || 1
minWeight = Math.min(minWeight, weight)
maxWeight = Math.max(maxWeight, weight)
})
// Scale edge sizes based on weight range
const weightRange = maxWeight - minWeight
if (weightRange > 0) {
const sizeScale = maxEdgeSize - minEdgeSize
graph.forEachEdge(edge => {
const weight = graph.getEdgeAttribute(edge, 'originalWeight') || 1
const scaledSize = minEdgeSize + sizeScale * Math.pow((weight - minWeight) / weightRange, 0.5)
graph.setEdgeAttribute(edge, 'size', scaledSize)
})
} else {
// If all weights are the same, use default size
graph.forEachEdge(edge => {
graph.setEdgeAttribute(edge, 'size', minEdgeSize)
})
}

View File

@@ -157,6 +157,7 @@
"maxNodes": "الحد الأقصى للعقد",
"maxLayoutIterations": "أقصى تكرارات التخطيط",
"resetToDefault": "إعادة التعيين إلى الافتراضي",
"edgeSizeRange": "نطاق حجم الحافة",
"depth": "D",
"max": "Max",
"degree": "الدرجة",

View File

@@ -157,6 +157,7 @@
"maxNodes": "Max Nodes",
"maxLayoutIterations": "Max Layout Iterations",
"resetToDefault": "Reset to default",
"edgeSizeRange": "Edge Size Range",
"depth": "D",
"max": "Max",
"degree": "Degree",

View File

@@ -157,6 +157,7 @@
"maxNodes": "Nombre maximum de nœuds",
"maxLayoutIterations": "Itérations maximales de mise en page",
"resetToDefault": "Réinitialiser par défaut",
"edgeSizeRange": "Plage de taille des arêtes",
"depth": "D",
"max": "Max",
"degree": "Degré",

View File

@@ -157,6 +157,7 @@
"maxNodes": "最大返回节点数",
"maxLayoutIterations": "最大布局迭代次数",
"resetToDefault": "重置为默认值",
"edgeSizeRange": "边粗细范围",
"depth": "深",
"max": "Max",
"degree": "邻边",

View File

@@ -24,6 +24,12 @@ interface SettingsState {
enableHideUnselectedEdges: boolean
enableEdgeEvents: boolean
minEdgeSize: number
setMinEdgeSize: (size: number) => void
maxEdgeSize: number
setMaxEdgeSize: (size: number) => void
graphQueryMaxDepth: number
setGraphQueryMaxDepth: (depth: number) => void
@@ -76,6 +82,9 @@ const useSettingsStoreBase = create<SettingsState>()(
enableHideUnselectedEdges: true,
enableEdgeEvents: false,
minEdgeSize: 1,
maxEdgeSize: 1,
graphQueryMaxDepth: 3,
graphMaxNodes: 1000,
graphLayoutMaxIterations: 15,
@@ -132,6 +141,10 @@ const useSettingsStoreBase = create<SettingsState>()(
setGraphMaxNodes: (nodes: number) => set({ graphMaxNodes: nodes }),
setMinEdgeSize: (size: number) => set({ minEdgeSize: size }),
setMaxEdgeSize: (size: number) => set({ maxEdgeSize: size }),
setEnableHealthCheck: (enable: boolean) => set({ enableHealthCheck: enable }),
setApiKey: (apiKey: string | null) => set({ apiKey }),
@@ -150,7 +163,7 @@ const useSettingsStoreBase = create<SettingsState>()(
{
name: 'settings-storage',
storage: createJSONStorage(() => localStorage),
version: 10,
version: 11,
migrate: (state: any, version: number) => {
if (version < 2) {
state.showEdgeLabel = false
@@ -200,6 +213,10 @@ const useSettingsStoreBase = create<SettingsState>()(
delete state.graphMinDegree // 删除废弃参数
state.graphMaxNodes = 1000 // 添加新参数
}
if (version < 11) {
state.minEdgeSize = 1
state.maxEdgeSize = 1
}
return state
}
}