11import ForceGraph3D from "3d-force-graph" ;
22import { Colors } from "design/theme" ;
33import React , { useEffect , useRef } from "react" ;
4+ import { useNavigate } from "react-router-dom" ;
45import * as THREE from "three" ;
56import {
67 CSS2DObject ,
78 CSS2DRenderer ,
89} from "three/examples/jsm/renderers/CSS2DRenderer" ;
910import { Database } from "types/responses/registry.interface" ;
1011
11- // Define the interface for NodeObject
12- interface NodeObject {
12+ export interface NodeObject {
1313 id : string ;
1414 name : string ;
1515 dbname : string ;
@@ -21,6 +21,7 @@ interface NodeObject {
2121}
2222
2323const NeuroJsonGraph : React . FC < { registry : Database [ ] } > = ( { registry } ) => {
24+ const navigate = useNavigate ( ) ;
2425 const graphRef = useRef < HTMLDivElement > ( null ) ;
2526
2627 // Function to determine color and size based on node size
@@ -77,33 +78,67 @@ const NeuroJsonGraph: React.FC<{ registry: Database[] }> = ({ registry }) => {
7778 . graphData ( graphData )
7879 . nodeRelSize ( 2 )
7980 . nodeColor ( ( node ) => ( node as NodeObject ) . color )
80- . linkWidth ( 2 ) // Set the thickness of the links
81- . backgroundColor ( "rgba(0,0,0,0)" ) // Transparent background
81+ . linkWidth ( 2 )
82+ . backgroundColor ( "rgba(0,0,0,0)" )
8283 . nodeLabel ( "name" )
84+ . onNodeHover ( ( node ) => {
85+ // Change cursor on hover
86+ graphRef . current ! . style . cursor = node ? "pointer" : "default" ;
87+ } )
88+ . onNodeClick ( ( node ) => {
89+ const castNode = node as NodeObject ;
90+ navigate ( `/databases/${ castNode . id } ` ) ;
91+ } )
8392 . nodeThreeObject ( ( node ) => {
8493 const castNode = node as NodeObject ;
8594
95+ // Create a group to hold sphere and glow
96+ const group = new THREE . Group ( ) ;
97+
8698 // Create a 3D sphere for the node
8799 const sphereGeometry = new THREE . SphereGeometry (
88100 ( castNode as any ) . size ,
89101 16 ,
90102 16
91- ) ; // Dynamic radius
103+ ) ;
92104 const sphereMaterial = new THREE . MeshBasicMaterial ( {
93105 color : ( castNode as any ) . color ,
94106 } ) ;
95107 const sphere = new THREE . Mesh ( sphereGeometry , sphereMaterial ) ;
108+ group . add ( sphere ) ;
109+
110+ // Create glow effect
111+ const glowGeometry = new THREE . SphereGeometry (
112+ ( castNode as any ) . size * 1.2 ,
113+ 16 ,
114+ 16
115+ ) ;
116+ const glowMaterial = new THREE . MeshBasicMaterial ( {
117+ color : ( castNode as any ) . color ,
118+ transparent : true ,
119+ opacity : 0.2 ,
120+ } ) ;
121+ const glow = new THREE . Mesh ( glowGeometry , glowMaterial ) ;
122+
123+ // Animate glow
124+ const animate = ( ) => {
125+ glow . scale . setScalar ( 1 + Math . sin ( Date . now ( ) * 0.003 ) * 0.1 ) ;
126+ requestAnimationFrame ( animate ) ;
127+ } ;
128+ animate ( ) ;
129+
130+ group . add ( glow ) ;
96131
97132 // Add label as CSS2DObject
98133 const label = new CSS2DObject ( document . createElement ( "div" ) ) ;
99134 label . element . textContent = castNode . dbname || "Unnamed" ;
100135 label . element . style . color = Colors . primary . main ;
101136 label . element . style . fontSize = "12px" ;
102- label . element . style . pointerEvents = "none" ; // Prevent interaction
103- label . position . set ( 0 , 10 , 0 ) ; // Position label above the node
104- sphere . add ( label ) ;
137+ label . element . style . pointerEvents = "none" ;
138+ label . position . set ( 0 , 10 , 0 ) ;
139+ group . add ( label ) ;
105140
106- return sphere ;
141+ return group ;
107142 } ) ;
108143
109144 // Initialize CSS2DRenderer for 2D labels
0 commit comments