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
- // STEP 1: Identify nodes and edges to keep
411
  const nodesToAdd = new Set<string>();
412
  const edgesToAdd = new Set<string>();
413
- const nodesWithDiscardedEdges = new Set<string>();
 
 
 
 
 
 
 
 
 
 
 
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
- // If no new connectable nodes found, show toast and return
434
- if (nodesToAdd.size === 0) {
435
- toast.info(t('graphPanel.propertiesView.node.noNewNodes'));
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
- } else {
447
- // Mark nodes that had edges discarded
448
  if (nodesToAdd.has(edge.source)) {
449
- nodesWithDiscardedEdges.add(edge.source);
450
  }
451
  if (nodesToAdd.has(edge.target)) {
 
 
 
 
 
 
 
 
 
 
 
 
 
452
  nodesWithDiscardedEdges.add(edge.target);
 
453
  }
454
  }
455
  }
456
 
457
- // STEP 2: Calculate node degrees and sizes
458
- const nodeDegrees = new Map<string, number>();
459
-
460
- // Calculate degrees from kept edges
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
- // Calculate size formula parameters
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
- // STEP 4: Update the expanded node's size
579
- if (sigmaGraph.hasNode(nodeId)) {
580
- // Get the new degree of the expanded node
581
- let expandedNodeDegree = sigmaGraph.degree(nodeId);
582
-
583
- // Check if the expanded node had any discarded edges
584
- if (nodesWithDiscardedEdges.has(nodeId)) {
585
- expandedNodeDegree += 1; // Add +1 for discarded edges
586
- }
587
-
588
- // Calculate new size for the expanded node
589
- const newSize = Math.round(
590
- Constants.minNodeSize + scale * Math.pow((expandedNodeDegree - minDegree) / range, 0.5)
591
- );
592
 
593
- // Update the size in sigma graph
594
- sigmaGraph.setNodeAttribute(nodeId, 'size', newSize);
595
 
596
- // Update the size in raw graph
597
- const expandedNodeIndex = rawGraph.nodeIdMap[nodeId];
598
- if (expandedNodeIndex !== undefined) {
599
- rawGraph.nodes[expandedNodeIndex].size = newSize;
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