Merge pull request #1156 from danielaskdd/main
Improve node size calculation logic for node expansion to prevent oversize
This commit is contained in:
1
lightrag/api/webui/assets/index-BcBS1RaQ.css
generated
1
lightrag/api/webui/assets/index-BcBS1RaQ.css
generated
File diff suppressed because one or more lines are too long
1
lightrag/api/webui/assets/index-Cq65VeVX.css
generated
Normal file
1
lightrag/api/webui/assets/index-Cq65VeVX.css
generated
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
lightrag/api/webui/index.html
generated
4
lightrag/api/webui/index.html
generated
@@ -8,8 +8,8 @@
|
||||
<link rel="icon" type="image/svg+xml" href="logo.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Lightrag</title>
|
||||
<script type="module" crossorigin src="/webui/assets/index-DpQ0dh7t.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/webui/assets/index-BcBS1RaQ.css">
|
||||
<script type="module" crossorigin src="/webui/assets/index-DPOdOU_f.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/webui/assets/index-Cq65VeVX.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
@@ -218,8 +218,8 @@ const LayoutsControl = () => {
|
||||
maxIterations: maxIterations,
|
||||
settings: {
|
||||
attraction: 0.0003, // Lower attraction force to reduce oscillation
|
||||
repulsion: 0.05, // Lower repulsion force to reduce oscillation
|
||||
gravity: 0.01, // Increase gravity to make nodes converge to center faster
|
||||
repulsion: 0.02, // Lower repulsion force to reduce oscillation
|
||||
gravity: 0.02, // Increase gravity to make nodes converge to center faster
|
||||
inertia: 0.4, // Lower inertia to add damping effect
|
||||
maxMove: 100 // Limit maximum movement per step to prevent large jumps
|
||||
}
|
||||
|
@@ -76,7 +76,7 @@ const fetchGraph = async (label: string, maxDepth: number, minDegree: number) =>
|
||||
// Check if we need to fetch all database labels first
|
||||
const lastSuccessfulQueryLabel = useGraphStore.getState().lastSuccessfulQueryLabel;
|
||||
if (!lastSuccessfulQueryLabel) {
|
||||
console.log('Last successful query label is empty, fetching all database labels first...');
|
||||
console.log('Last successful queryLabel is empty');
|
||||
try {
|
||||
await useGraphStore.getState().fetchAllDatabaseLabels();
|
||||
} catch (e) {
|
||||
@@ -89,7 +89,7 @@ const fetchGraph = async (label: string, maxDepth: number, minDegree: number) =>
|
||||
const queryLabel = label || '*';
|
||||
|
||||
try {
|
||||
console.log(`Fetching graph data with label: ${queryLabel}, maxDepth: ${maxDepth}, minDegree: ${minDegree}`);
|
||||
console.log(`Fetching graph label: ${queryLabel}, depth: ${maxDepth}, deg: ${minDegree}`);
|
||||
rawData = await queryGraphs(queryLabel, maxDepth, minDegree);
|
||||
} catch (e) {
|
||||
useBackendState.getState().setErrorMessage(errorMessage(e), 'Query Graphs Error!');
|
||||
@@ -163,7 +163,7 @@ const fetchGraph = async (label: string, maxDepth: number, minDegree: number) =>
|
||||
|
||||
if (!validateGraph(rawGraph)) {
|
||||
rawGraph = null
|
||||
console.error('Invalid graph data')
|
||||
console.warn('Invalid graph data')
|
||||
}
|
||||
console.log('Graph data loaded')
|
||||
}
|
||||
@@ -360,8 +360,6 @@ const useLightrangeGraph = () => {
|
||||
|
||||
// Reset camera view
|
||||
state.setMoveToSelectedNode(true);
|
||||
|
||||
console.log('Graph data loaded successfully');
|
||||
}
|
||||
|
||||
// Update flags
|
||||
@@ -466,7 +464,7 @@ const useLightrangeGraph = () => {
|
||||
const nodesToAdd = new Set<string>();
|
||||
const edgesToAdd = new Set<string>();
|
||||
|
||||
// Get degree range from existing graph for size calculations
|
||||
// Get degree maxDegree from existing graph for size calculations
|
||||
const minDegree = 1;
|
||||
let maxDegree = 0;
|
||||
sigmaGraph.forEachNode(node => {
|
||||
@@ -474,10 +472,6 @@ const useLightrangeGraph = () => {
|
||||
maxDegree = Math.max(maxDegree, degree);
|
||||
});
|
||||
|
||||
// Calculate size formula parameters
|
||||
const range = maxDegree - minDegree || 1; // Avoid division by zero
|
||||
const scale = Constants.maxNodeSize - Constants.minNodeSize;
|
||||
|
||||
// First identify connectable nodes (nodes connected to the expanded node)
|
||||
for (const node of processedNodes) {
|
||||
// Skip if node already exists
|
||||
@@ -498,6 +492,7 @@ const useLightrangeGraph = () => {
|
||||
|
||||
// Calculate node degrees and track discarded edges in one pass
|
||||
const nodeDegrees = new Map<string, number>();
|
||||
const existingNodeDegreeIncrements = new Map<string, number>(); // Track degree increments for existing nodes
|
||||
const nodesWithDiscardedEdges = new Set<string>();
|
||||
|
||||
for (const edge of processedEdges) {
|
||||
@@ -506,12 +501,19 @@ const useLightrangeGraph = () => {
|
||||
|
||||
if (sourceExists && targetExists) {
|
||||
edgesToAdd.add(edge.id);
|
||||
// Add degrees for valid edges
|
||||
// Add degrees for both new and existing nodes
|
||||
if (nodesToAdd.has(edge.source)) {
|
||||
nodeDegrees.set(edge.source, (nodeDegrees.get(edge.source) || 0) + 1);
|
||||
} else if (existingNodeIds.has(edge.source)) {
|
||||
// Track degree increments for existing nodes
|
||||
existingNodeDegreeIncrements.set(edge.source, (existingNodeDegreeIncrements.get(edge.source) || 0) + 1);
|
||||
}
|
||||
|
||||
if (nodesToAdd.has(edge.target)) {
|
||||
nodeDegrees.set(edge.target, (nodeDegrees.get(edge.target) || 0) + 1);
|
||||
} else if (existingNodeIds.has(edge.target)) {
|
||||
// Track degree increments for existing nodes
|
||||
existingNodeDegreeIncrements.set(edge.target, (existingNodeDegreeIncrements.get(edge.target) || 0) + 1);
|
||||
}
|
||||
} else {
|
||||
// Track discarded edges for both new and existing nodes
|
||||
@@ -535,16 +537,21 @@ const useLightrangeGraph = () => {
|
||||
sigmaGraph: DirectedGraph,
|
||||
nodesWithDiscardedEdges: Set<string>,
|
||||
minDegree: number,
|
||||
range: number,
|
||||
scale: number
|
||||
maxDegree: number
|
||||
) => {
|
||||
// Calculate derived values inside the function
|
||||
const range = maxDegree - minDegree || 1; // Avoid division by zero
|
||||
const scale = Constants.maxNodeSize - Constants.minNodeSize;
|
||||
|
||||
for (const nodeId of nodesWithDiscardedEdges) {
|
||||
if (sigmaGraph.hasNode(nodeId)) {
|
||||
let newDegree = sigmaGraph.degree(nodeId);
|
||||
newDegree += 1; // Add +1 for discarded edges
|
||||
// Limit newDegree to maxDegree + 1 to prevent nodes from being too large
|
||||
const limitedDegree = Math.min(newDegree, maxDegree + 1);
|
||||
|
||||
const newSize = Math.round(
|
||||
Constants.minNodeSize + scale * Math.pow((newDegree - minDegree) / range, 0.5)
|
||||
Constants.minNodeSize + scale * Math.pow((limitedDegree - minDegree) / range, 0.5)
|
||||
);
|
||||
|
||||
const currentSize = sigmaGraph.getNodeAttribute(nodeId, 'size');
|
||||
@@ -558,16 +565,27 @@ const useLightrangeGraph = () => {
|
||||
|
||||
// If no new connectable nodes found, show toast and return
|
||||
if (nodesToAdd.size === 0) {
|
||||
updateNodeSizes(sigmaGraph, nodesWithDiscardedEdges, minDegree, range, scale);
|
||||
updateNodeSizes(sigmaGraph, nodesWithDiscardedEdges, minDegree, maxDegree);
|
||||
toast.info(t('graphPanel.propertiesView.node.noNewNodes'));
|
||||
return;
|
||||
}
|
||||
|
||||
// Update maxDegree with new node degrees
|
||||
// Update maxDegree considering all nodes (both new and existing)
|
||||
// 1. Consider degrees of new nodes
|
||||
for (const [, degree] of nodeDegrees.entries()) {
|
||||
maxDegree = Math.max(maxDegree, degree);
|
||||
}
|
||||
|
||||
// 2. Consider degree increments for existing nodes
|
||||
for (const [nodeId, increment] of existingNodeDegreeIncrements.entries()) {
|
||||
const currentDegree = sigmaGraph.degree(nodeId);
|
||||
const projectedDegree = currentDegree + increment;
|
||||
maxDegree = Math.max(maxDegree, projectedDegree);
|
||||
}
|
||||
|
||||
const range = maxDegree - minDegree || 1; // Avoid division by zero
|
||||
const scale = Constants.maxNodeSize - Constants.minNodeSize;
|
||||
|
||||
// SAdd nodes and edges to the graph
|
||||
// Calculate camera ratio and spread factor once before the loop
|
||||
const cameraRatio = useGraphStore.getState().sigmaInstance?.getCamera().ratio || 1;
|
||||
@@ -587,8 +605,10 @@ const useLightrangeGraph = () => {
|
||||
const nodeDegree = nodeDegrees.get(nodeId) || 0;
|
||||
|
||||
// Calculate node size
|
||||
// Limit nodeDegree to maxDegree + 1 to prevent new nodes from being too large
|
||||
const limitedDegree = Math.min(nodeDegree, maxDegree + 1);
|
||||
const nodeSize = Math.round(
|
||||
Constants.minNodeSize + scale * Math.pow((nodeDegree - minDegree) / range, 0.5)
|
||||
Constants.minNodeSize + scale * Math.pow((limitedDegree - minDegree) / range, 0.5)
|
||||
);
|
||||
|
||||
// Calculate angle for polar coordinates
|
||||
@@ -663,7 +683,18 @@ const useLightrangeGraph = () => {
|
||||
useGraphStore.getState().resetSearchEngine();
|
||||
|
||||
// Update sizes for all nodes with discarded edges
|
||||
updateNodeSizes(sigmaGraph, nodesWithDiscardedEdges, minDegree, range, scale);
|
||||
updateNodeSizes(sigmaGraph, nodesWithDiscardedEdges, minDegree, maxDegree);
|
||||
|
||||
if (sigmaGraph.hasNode(nodeId)) {
|
||||
const finalDegree = sigmaGraph.degree(nodeId);
|
||||
const limitedDegree = Math.min(finalDegree, maxDegree + 1);
|
||||
const newSize = Math.round(
|
||||
Constants.minNodeSize + scale * Math.pow((limitedDegree - minDegree) / range, 0.5)
|
||||
);
|
||||
sigmaGraph.setNodeAttribute(nodeId, 'size', newSize);
|
||||
nodeToExpand.size = newSize;
|
||||
nodeToExpand.degree = finalDegree;
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error expanding node:', error);
|
||||
|
@@ -164,7 +164,7 @@
|
||||
"labels": "التسميات",
|
||||
"degree": "الدرجة",
|
||||
"properties": "الخصائص",
|
||||
"relationships": "العلاقات",
|
||||
"relationships": "العلاقات (داخل الرسم الفرعي)",
|
||||
"expandNode": "توسيع العقدة",
|
||||
"pruneNode": "تقليم العقدة",
|
||||
"deleteAllNodesError": "رفض حذف جميع العقد في الرسم البياني",
|
||||
|
@@ -167,7 +167,7 @@
|
||||
"labels": "Labels",
|
||||
"degree": "Degree",
|
||||
"properties": "Properties",
|
||||
"relationships": "Relationships",
|
||||
"relationships": "Relations(within subgraph)",
|
||||
"expandNode": "Expand Node",
|
||||
"pruneNode": "Prune Node",
|
||||
"deleteAllNodesError": "Refuse to delete all nodes in the graph",
|
||||
|
@@ -164,7 +164,7 @@
|
||||
"labels": "Étiquettes",
|
||||
"degree": "Degré",
|
||||
"properties": "Propriétés",
|
||||
"relationships": "Relations",
|
||||
"relationships": "Relations(dans le sous-graphe)",
|
||||
"expandNode": "Développer le nœud",
|
||||
"pruneNode": "Élaguer le nœud",
|
||||
"deleteAllNodesError": "Refus de supprimer tous les nœuds du graphe",
|
||||
|
@@ -164,7 +164,7 @@
|
||||
"labels": "标签",
|
||||
"degree": "度数",
|
||||
"properties": "属性",
|
||||
"relationships": "关系",
|
||||
"relationships": "关系(子图内)",
|
||||
"expandNode": "扩展节点",
|
||||
"pruneNode": "修剪节点",
|
||||
"deleteAllNodesError": "拒绝删除图中的所有节点",
|
||||
|
Reference in New Issue
Block a user