@@ -506,14 +506,40 @@ export default {
506506 const config = {
507507 type: ' d3-force' ,
508508 link: {
509- distance: 300 ,
509+ // Dynamic distance:
510+ // Fixed distance for nodes with large number of neighbors will cause mass collision (a large circle)
511+ // Variable distance with multiple layers of variation will display the nodes in a spaced out manner (multiple circles around node)
512+ distance : (d ) => {
513+ // Get the source and target node degrees
514+ const sourceDegree = d .source .data ? .degree || 1 ;
515+ const targetDegree = d .target .data ? .degree || 1 ;
516+
517+ // Base distance for nodes with few connections
518+ const baseDistance = 150 ;
519+
520+ // For high-degree nodes (hubs), vary the distance based on connection index
521+ if (sourceDegree > 5 || targetDegree > 5 ) {
522+ // Use a hash of the edge ID to create pseudo-random but consistent distances
523+ const edgeHash = d .id ? d .id .split (' ' ).reduce ((a , b ) => a + b .charCodeAt (0 ), 0 ) : 0 ;
524+ const variation = (edgeHash % 6 ) * 100 + 100 ;
525+ return baseDistance + variation;
526+ }
527+
528+ // For regular nodes, use standard distance
529+ return baseDistance;
530+ },
510531 strength: 2 ,
511532 },
512533 collide: {
513- radius: 120 ,
534+ radius : (d ) => d .size / 2 + 20 , // Add padding for better collision detection
535+ strength: 1 , // Positive strength for stronger collision avoidance
514536 },
515537 manyBody: {
516- strength: - 300 ,
538+ strength: - 1200 , // Negative strength indicates repulsion
539+ },
540+ radial: {
541+ radius: 200 ,
542+
517543 },
518544 alpha: 1 ,
519545 alphaMin: 0.2 ,
@@ -574,7 +600,7 @@ export default {
574600 labelFontWeight: 350 ,
575601 labelBackground: true ,
576602 labelBackgroundFill: " #ffffff" ,
577- labelPadding: [4 , 8 ],
603+ labelPadding: [0 , 8 ],
578604 labelBackgroundRadius: 2 ,
579605 labelAutoRotate: true ,
580606 labelTextBaseline: ' bottom' ,
@@ -699,6 +725,15 @@ export default {
699725 this .deselectAll ();
700726 });
701727
728+ // Ensure force simulation continues after node dragging
729+ this .g6Graph .on (' node:dragend' , () => {
730+ // Restart the force simulation to ensure proper collision detection
731+ const layout = this .g6Graph .getLayout ();
732+ if (layout && layout .simulation ) {
733+ layout .simulation .alpha (0.3 ).restart ();
734+ }
735+ });
736+
702737 this .g6Graph .on (' canvas:click' , () => {
703738 this .deselectAll ();
704739 });
@@ -1042,6 +1077,18 @@ export default {
10421077 rel: totalRelCount,
10431078 },
10441079 };
1080+ // Calculate node degrees for dynamic distance
1081+ const nodeDegrees = {};
1082+ Object .values (edges).forEach (edge => {
1083+ nodeDegrees[edge .source ] = (nodeDegrees[edge .source ] || 0 ) + 1 ;
1084+ nodeDegrees[edge .target ] = (nodeDegrees[edge .target ] || 0 ) + 1 ;
1085+ });
1086+
1087+ // Add degree information to node data
1088+ Object .values (nodes).forEach (node => {
1089+ node .data .degree = nodeDegrees[node .id ] || 0 ;
1090+ });
1091+
10451092 if (totalNodeCount > this .settingsStore .performance .maxNumberOfNodesWithLabels ) {
10461093 for (let key in nodes) {
10471094 const node = nodes[key];
0 commit comments