yangdx
commited on
Commit
·
63a4981
1
Parent(s):
958ad51
Optimize node degree and size calculation for expanded graph nodes
Browse files
lightrag_webui/src/hooks/useLightragGraph.tsx
CHANGED
@@ -407,10 +407,21 @@ const useLightrangeGraph = () => {
|
|
407 |
// Get existing node IDs
|
408 |
const existingNodeIds = new Set(sigmaGraph.nodes());
|
409 |
|
410 |
-
//
|
411 |
const nodesToAdd = new Set<string>();
|
412 |
const edgesToAdd = new Set<string>();
|
413 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
414 |
|
415 |
// First identify connectable nodes (nodes connected to the expanded node)
|
416 |
for (const node of processedNodes) {
|
@@ -430,69 +441,59 @@ const useLightrangeGraph = () => {
|
|
430 |
}
|
431 |
}
|
432 |
|
433 |
-
//
|
434 |
-
|
435 |
-
|
436 |
-
return;
|
437 |
-
}
|
438 |
|
439 |
-
// Then identify valid edges (edges where both nodes exist in the graph)
|
440 |
for (const edge of processedEdges) {
|
441 |
const sourceExists = existingNodeIds.has(edge.source) || nodesToAdd.has(edge.source);
|
442 |
const targetExists = existingNodeIds.has(edge.target) || nodesToAdd.has(edge.target);
|
443 |
|
444 |
if (sourceExists && targetExists) {
|
445 |
edgesToAdd.add(edge.id);
|
446 |
-
|
447 |
-
// Mark nodes that had edges discarded
|
448 |
if (nodesToAdd.has(edge.source)) {
|
449 |
-
|
450 |
}
|
451 |
if (nodesToAdd.has(edge.target)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
452 |
nodesWithDiscardedEdges.add(edge.target);
|
|
|
453 |
}
|
454 |
}
|
455 |
}
|
456 |
|
457 |
-
//
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
for (const edgeId of edgesToAdd) {
|
462 |
-
const edge = processedEdges.find(e => e.id === edgeId)!;
|
463 |
-
nodeDegrees.set(edge.source, (nodeDegrees.get(edge.source) || 0) + 1);
|
464 |
-
nodeDegrees.set(edge.target, (nodeDegrees.get(edge.target) || 0) + 1);
|
465 |
-
}
|
466 |
-
|
467 |
-
// Add +1 to degree for nodes that had edges discarded
|
468 |
-
for (const nodeId of nodesWithDiscardedEdges) {
|
469 |
-
nodeDegrees.set(nodeId, (nodeDegrees.get(nodeId) || 0) + 1);
|
470 |
}
|
471 |
|
472 |
-
// Get degree range from existing graph for size calculations
|
473 |
-
const minDegree = 1;
|
474 |
-
let maxDegree = 0;
|
475 |
-
sigmaGraph.forEachNode(node => {
|
476 |
-
const degree = sigmaGraph.degree(node);
|
477 |
-
maxDegree = Math.max(maxDegree, degree);
|
478 |
-
});
|
479 |
-
|
480 |
// Update maxDegree with new node degrees
|
481 |
for (const [, degree] of nodeDegrees.entries()) {
|
482 |
maxDegree = Math.max(maxDegree, degree);
|
483 |
}
|
484 |
|
485 |
-
//
|
486 |
-
const range = maxDegree - minDegree || 1; // Avoid division by zero
|
487 |
-
const scale = Constants.maxNodeSize - Constants.minNodeSize;
|
488 |
-
|
489 |
-
// STEP 3: Add nodes and edges to the graph
|
490 |
// Calculate camera ratio and spread factor once before the loop
|
491 |
const cameraRatio = useGraphStore.getState().sigmaInstance?.getCamera().ratio || 1;
|
492 |
const spreadFactor = Math.max(
|
493 |
Math.sqrt(nodeToExpand.size) * 4, // Base on node size
|
494 |
Math.sqrt(nodesToAdd.size) * 3 // Scale with number of nodes
|
495 |
) / cameraRatio; // Adjust for zoom level
|
|
|
496 |
const randomAngle = Math.random() * 2 * Math.PI
|
497 |
|
498 |
console.log('nodeSize:', nodeToExpand.size, 'nodesToAdd:', nodesToAdd.size);
|
@@ -575,29 +576,25 @@ const useLightrangeGraph = () => {
|
|
575 |
searchCache.graph = null;
|
576 |
searchCache.searchEngine = null;
|
577 |
|
578 |
-
//
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
const newSize = Math.round(
|
590 |
-
Constants.minNodeSize + scale * Math.pow((expandedNodeDegree - minDegree) / range, 0.5)
|
591 |
-
);
|
592 |
|
593 |
-
|
594 |
-
|
595 |
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
rawGraph.nodes[expandedNodeIndex].degree = expandedNodeDegree;
|
601 |
}
|
602 |
}
|
603 |
|
|
|
407 |
// Get existing node IDs
|
408 |
const existingNodeIds = new Set(sigmaGraph.nodes());
|
409 |
|
410 |
+
// Identify nodes and edges to keep
|
411 |
const nodesToAdd = new Set<string>();
|
412 |
const edgesToAdd = new Set<string>();
|
413 |
+
|
414 |
+
// Get degree range from existing graph for size calculations
|
415 |
+
const minDegree = 1;
|
416 |
+
let maxDegree = 0;
|
417 |
+
sigmaGraph.forEachNode(node => {
|
418 |
+
const degree = sigmaGraph.degree(node);
|
419 |
+
maxDegree = Math.max(maxDegree, degree);
|
420 |
+
});
|
421 |
+
|
422 |
+
// Calculate size formula parameters
|
423 |
+
const range = maxDegree - minDegree || 1; // Avoid division by zero
|
424 |
+
const scale = Constants.maxNodeSize - Constants.minNodeSize;
|
425 |
|
426 |
// First identify connectable nodes (nodes connected to the expanded node)
|
427 |
for (const node of processedNodes) {
|
|
|
441 |
}
|
442 |
}
|
443 |
|
444 |
+
// Calculate node degrees and track discarded edges in one pass
|
445 |
+
const nodeDegrees = new Map<string, number>();
|
446 |
+
const nodesWithDiscardedEdges = new Set<string>();
|
|
|
|
|
447 |
|
|
|
448 |
for (const edge of processedEdges) {
|
449 |
const sourceExists = existingNodeIds.has(edge.source) || nodesToAdd.has(edge.source);
|
450 |
const targetExists = existingNodeIds.has(edge.target) || nodesToAdd.has(edge.target);
|
451 |
|
452 |
if (sourceExists && targetExists) {
|
453 |
edgesToAdd.add(edge.id);
|
454 |
+
// Add degrees for valid edges
|
|
|
455 |
if (nodesToAdd.has(edge.source)) {
|
456 |
+
nodeDegrees.set(edge.source, (nodeDegrees.get(edge.source) || 0) + 1);
|
457 |
}
|
458 |
if (nodesToAdd.has(edge.target)) {
|
459 |
+
nodeDegrees.set(edge.target, (nodeDegrees.get(edge.target) || 0) + 1);
|
460 |
+
}
|
461 |
+
} else {
|
462 |
+
// Track discarded edges for both new and existing nodes
|
463 |
+
if (sigmaGraph.hasNode(edge.source)) {
|
464 |
+
nodesWithDiscardedEdges.add(edge.source);
|
465 |
+
} else if (nodesToAdd.has(edge.source)) {
|
466 |
+
nodesWithDiscardedEdges.add(edge.source);
|
467 |
+
nodeDegrees.set(edge.source, (nodeDegrees.get(edge.source) || 0) + 1); // +1 for discarded edge
|
468 |
+
}
|
469 |
+
if (sigmaGraph.hasNode(edge.target)) {
|
470 |
+
nodesWithDiscardedEdges.add(edge.target);
|
471 |
+
} else if (nodesToAdd.has(edge.target)) {
|
472 |
nodesWithDiscardedEdges.add(edge.target);
|
473 |
+
nodeDegrees.set(edge.target, (nodeDegrees.get(edge.target) || 0) + 1); // +1 for discarded edge
|
474 |
}
|
475 |
}
|
476 |
}
|
477 |
|
478 |
+
// If no new connectable nodes found, show toast and return
|
479 |
+
if (nodesToAdd.size === 0) {
|
480 |
+
toast.info(t('graphPanel.propertiesView.node.noNewNodes'));
|
481 |
+
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
482 |
}
|
483 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
484 |
// Update maxDegree with new node degrees
|
485 |
for (const [, degree] of nodeDegrees.entries()) {
|
486 |
maxDegree = Math.max(maxDegree, degree);
|
487 |
}
|
488 |
|
489 |
+
// SAdd nodes and edges to the graph
|
|
|
|
|
|
|
|
|
490 |
// Calculate camera ratio and spread factor once before the loop
|
491 |
const cameraRatio = useGraphStore.getState().sigmaInstance?.getCamera().ratio || 1;
|
492 |
const spreadFactor = Math.max(
|
493 |
Math.sqrt(nodeToExpand.size) * 4, // Base on node size
|
494 |
Math.sqrt(nodesToAdd.size) * 3 // Scale with number of nodes
|
495 |
) / cameraRatio; // Adjust for zoom level
|
496 |
+
seedrandom(Date.now().toString(), { global: true });
|
497 |
const randomAngle = Math.random() * 2 * Math.PI
|
498 |
|
499 |
console.log('nodeSize:', nodeToExpand.size, 'nodesToAdd:', nodesToAdd.size);
|
|
|
576 |
searchCache.graph = null;
|
577 |
searchCache.searchEngine = null;
|
578 |
|
579 |
+
// Update sizes for all nodes with discarded edges
|
580 |
+
for (const nodeId of nodesWithDiscardedEdges) {
|
581 |
+
if (sigmaGraph.hasNode(nodeId)) {
|
582 |
+
// Get the new degree of the node
|
583 |
+
let newDegree = sigmaGraph.degree(nodeId);
|
584 |
+
newDegree += 1; // Add +1 for discarded edges
|
585 |
+
|
586 |
+
// Calculate new size for the node
|
587 |
+
const newSize = Math.round(
|
588 |
+
Constants.minNodeSize + scale * Math.pow((newDegree - minDegree) / range, 0.5)
|
589 |
+
);
|
|
|
|
|
|
|
590 |
|
591 |
+
// Get current size
|
592 |
+
const currentSize = sigmaGraph.getNodeAttribute(nodeId, 'size');
|
593 |
|
594 |
+
// Only update if new size is larger
|
595 |
+
if (newSize > currentSize) {
|
596 |
+
sigmaGraph.setNodeAttribute(nodeId, 'size', newSize);
|
597 |
+
}
|
|
|
598 |
}
|
599 |
}
|
600 |
|