@@ -77,6 +77,27 @@ const NeuroJsonGraph: React.FC<{
7777 // if (size > 3) return { color: Colors.primary.main, size: 7 };
7878 // return { color: Colors.primary.light, size: 5 };
7979 // };
80+ // Custom random number generator (same as `mulberry32`)
81+ const mulberry32 = ( a : number ) => {
82+ return function ( ) {
83+ let t = ( a += 0x6d2b79f5 ) ;
84+ t = Math . imul ( t ^ ( t >>> 15 ) , t | 1 ) ;
85+ t ^= t + Math . imul ( t ^ ( t >>> 7 ) , t | 61 ) ;
86+ return ( ( t ^ ( t >>> 14 ) ) >>> 0 ) / 4294967296 ;
87+ } ;
88+ } ;
89+
90+ const rngfun = mulberry32 ( 0x123456789 ) ; // Seeded random function
91+
92+ // // Shuffle nodes
93+ // const nodenum = registry.length;
94+ // const randnode = [...Array(nodenum).keys()];
95+
96+ // Fisher-Yates Shuffle
97+ // for (let i = 0; i < nodenum; i++) {
98+ // const j = Math.floor(rngfun() * (i + 1));
99+ // [randnode[i], randnode[j]] = [randnode[j], randnode[i]];
100+ // }
80101
81102 useEffect ( ( ) => {
82103 // Ensure registry and graphRef are properly initialized
@@ -90,6 +111,33 @@ const NeuroJsonGraph: React.FC<{
90111 return ;
91112 }
92113
114+ let colorlist : { brightness : number ; index : number } [ ] = registry . map (
115+ ( db , index ) => {
116+ const colorStr = blendColors ( db . datatype ) ; // Get color in "rgb(R,G,B)" format
117+
118+ // **Extract RGB values from the string**
119+ const match = colorStr . match ( / \d + / g) ; // Get numbers from "rgb(R,G,B)"
120+ if ( ! match ) return { brightness : 255 , index } ; // Default to white if extraction fails
121+
122+ const [ r , g , b ] = match . map ( Number ) ; // Convert to numbers
123+ const brightness = 0.2126 * r + 0.7152 * g + 0.0722 * b ; // Compute brightness
124+
125+ return { brightness, index } ;
126+ }
127+ ) ;
128+
129+ // **2️⃣ Sort nodes by brightness (dark → bright)**
130+ colorlist . sort ( ( a , b ) => a . brightness - b . brightness ) ;
131+
132+ // // **3️⃣ Create shuffled node list using Fisher-Yates algorithm**
133+ // const nodenum = registry.length;
134+ // const randnode = colorlist.map((item) => item.index); // Get sorted indices
135+
136+ // for (let i = 0; i < nodenum; i++) {
137+ // const j = Math.floor(rngfun() * (i + 1));
138+ // [randnode[i], randnode[j]] = [randnode[j], randnode[i]];
139+ // }
140+
93141 // Prepare graph data
94142 const graphData = {
95143 nodes : registry . map ( ( db ) => {
@@ -107,35 +155,81 @@ const NeuroJsonGraph: React.FC<{
107155 url : db . url ,
108156 datasets : db . datasets ,
109157 size : size ,
110- standard : db . standard || [ ] , // add standard property
158+ standard : db . standard || [ ] ,
111159 } ;
112160 } ) ,
113- links : registry . flatMap ( ( db , index ) => {
114- const connections = [ ] ;
115- const nextIndex = ( index + 1 ) % registry . length ;
116- // const { color } = size2colorAndSize(db.datasets);
117- const color = blendColors ( db . datatype ) ;
118- connections . push ( {
119- source : db . id ,
120- target : registry [ nextIndex ] . id ,
121- color : color ,
122- visible : true ,
123- } ) ;
124- return connections ;
125161
126- // non-circle rendering
127- // const similarNodes = registry.filter(
128- // (otherDb) =>
129- // db.datatype.some((type) => otherDb.datatype.includes(type)) &&
130- // db.id !== otherDb.id
131- // );
162+ links : registry . flatMap ( ( db , index ) => {
163+ // const color = blendColors(db.datatype);
164+ // return registry
165+ // .filter(
166+ // (otherDb) =>
167+ // db.id !== otherDb.id &&
168+ // db.datatype.some((type) => otherDb.datatype.includes(type))
169+ // )
170+ // .map((otherDB) => ({
171+ // source: db.id,
172+ // target: otherDB.id,
173+ // color: Colors.lightGray,
174+ // visible: true,
175+ // }));
132176
133- // return similarNodes.map((otherDb) => ({
177+ // const connections = [];
178+ // const nextIndex = (index + 1) % registry.length;
179+ // // const { color } = size2colorAndSize(db.datasets);
180+ // const color = blendColors(db.datatype);
181+ // connections.push({
134182 // source: db.id,
135- // target: otherDb .id,
136- // color: blendColors(db.datatype), // Link color based on datatype
183+ // target: registry[nextIndex] .id,
184+ // color: color,
137185 // visible: true,
138- // }));
186+ // });
187+ // return connections;
188+
189+ // use original website logic
190+ const coloridx = index ;
191+ const i = colorlist [ coloridx ] . index ; // Get shuffled node index
192+ const node = registry [ i ] ; // Get actual node
193+
194+ // Determine number of connections (proportional to dataset size)
195+ const conn = 1 + Math . round ( rngfun ( ) * Math . max ( 1 , node . datasets / 20 ) ) ;
196+ // const numConnections = 4;
197+ const connections : {
198+ source : string ;
199+ target : string ;
200+ color : string ;
201+ visible : boolean ;
202+ } [ ] = [ ] ;
203+
204+ // for (let j = -conn; j <= conn; j++) {
205+ // if (j === 0) continue; // Skip linking to itself
206+ // if (coloridx + j >= nodenum) break; // Prevent out-of-bounds errors
207+
208+ // const targetNode = registry[randnode[Math.max(0, coloridx + j)]]; // Pick a nearby node from shuffled list
209+
210+ // connections.push({
211+ // source: node.id,
212+ // target: targetNode.id,
213+ // color: blendColors(node.datatype), // Match node's color
214+ // visible: true, // Make links visible
215+ // });
216+ // }
217+
218+ for ( let j = 1 ; j <= conn ; j ++ ) {
219+ if ( index + j >= registry . length ) break ; // Prevent out-of-bounds errors
220+
221+ const targetIdx = colorlist [ index + j ] . index ; // Get next closest in brightness
222+ const targetNode = registry [ targetIdx ] ;
223+
224+ connections . push ( {
225+ source : node . id ,
226+ target : targetNode . id ,
227+ color : blendColors ( node . datatype ) , // Keep consistent coloring
228+ visible : true , // Make links visible
229+ } ) ;
230+ }
231+
232+ return connections ;
139233 } ) ,
140234 } ;
141235
@@ -144,7 +238,7 @@ const NeuroJsonGraph: React.FC<{
144238 . graphData ( graphData )
145239 . nodeRelSize ( 2 )
146240 . nodeColor ( ( node ) => ( node as NodeObject ) . color )
147- . linkWidth ( 2 )
241+ . linkWidth ( 0.5 )
148242 . backgroundColor ( "rgba(0,0,0,0)" )
149243 . nodeLabel ( "name" )
150244 . onNodeHover ( ( node ) => {
@@ -201,7 +295,7 @@ const NeuroJsonGraph: React.FC<{
201295 // Add label as CSS2DObject
202296 const label = new CSS2DObject ( document . createElement ( "div" ) ) ;
203297 label . element . textContent = castNode . dbname || "Unnamed" ;
204- label . element . style . color = Colors . primary . main ;
298+ label . element . style . color = Colors . white ;
205299 label . element . style . fontSize = "12px" ;
206300 label . element . style . pointerEvents = "none" ;
207301 label . position . set ( 0 , 10 , 0 ) ;
0 commit comments