@@ -24,55 +24,89 @@ document.addEventListener('DOMContentLoaded', function() {
2424
2525 // Initialize the visualization
2626 function init ( ) {
27+ console . log ( "Initializing visualization..." ) ;
2728 // Load data and set up the visualization
2829 loadGraph ( ) ;
2930 }
3031
3132 // Set up the visualization after data is loaded
3233 function setupVisualization ( ) {
34+ console . log ( "Setting up visualization..." ) ;
35+
36+ // Create SVG and container for the visualization
37+ svg = d3 . select ( '#chart' )
38+ . append ( 'svg' )
39+ . attr ( 'width' , '100%' )
40+ . attr ( 'height' , '100%' ) ;
41+
42+ // Add a background rect to handle zoom events on empty space
43+ svg . append ( 'rect' )
44+ . attr ( 'width' , '100%' )
45+ . attr ( 'height' , '100%' )
46+ . attr ( 'fill' , 'transparent' ) ;
47+
48+ gContainer = svg . append ( 'g' )
49+ . attr ( 'class' , 'everything' ) ;
50+
51+ // Setup zoom behavior
52+ zoomBehavior = d3 . zoom ( )
53+ . scaleExtent ( [ 0.1 , 10 ] )
54+ . on ( 'zoom' , ( event ) => {
55+ gContainer . attr ( 'transform' , event . transform ) ;
56+ } ) ;
57+
58+ svg . call ( zoomBehavior ) ;
59+
3360 // Process data
3461 processData ( ) ;
3562
36- // Calculate stats
37- updateStats ( ) ;
38-
3963 // Draw graph
4064 drawGraph ( ) ;
4165
66+ // Calculate stats
67+ updateStats ( ) ;
68+
4269 // Set up event listeners
4370 setupEventListeners ( ) ;
71+
72+ console . log ( "Visualization setup complete" ) ;
4473 }
4574
4675 // Load graph data
4776 function loadGraph ( ) {
48- d3 . json ( 'graph.json' ) . then ( data => {
49- // Store the data
50- graph = data ;
51-
52- // Ensure all nodes have the required properties
53- graph . nodes . forEach ( node => {
54- // Make sure all properties exist
55- node . group = node . group || '' ;
56- node . label = node . label || '' ;
57- node . id = node . id || '' ;
58- node . used = node . used || false ;
77+ console . log ( "Loading graph data..." ) ;
78+ d3 . json ( 'graph.json' )
79+ . then ( data => {
80+ console . log ( "Graph data loaded successfully" ) ;
81+ // Store the data
82+ graph = data ;
5983
60- // Convert isexternal from string to boolean if needed
61- // This handles potential issues with JSON serialization
62- if ( typeof node . isexternal === 'string' ) {
63- node . isexternal = node . isexternal . toLowerCase ( ) === 'true' ;
64- } else {
65- node . isexternal = Boolean ( node . isexternal ) ;
66- }
84+ // Ensure all nodes have the required properties
85+ graph . nodes . forEach ( node => {
86+ // Make sure all properties exist
87+ node . group = node . group || '' ;
88+ node . label = node . label || '' ;
89+ node . id = node . id || '' ;
90+ node . used = node . used || false ;
91+
92+ // Convert isexternal from string to boolean if needed
93+ // This handles potential issues with JSON serialization
94+ if ( typeof node . isexternal === 'string' ) {
95+ node . isexternal = node . isexternal . toLowerCase ( ) === 'true' ;
96+ } else {
97+ node . isexternal = Boolean ( node . isexternal ) ;
98+ }
99+
100+ console . log ( `Node ${ node . id } : isexternal=${ node . isexternal } (${ typeof node . isexternal } ), group=${ node . group } , used=${ node . used } ` ) ;
101+ } ) ;
67102
68- console . log ( `Node ${ node . id } : isexternal=${ node . isexternal } (type: ${ typeof node . isexternal } )` ) ;
103+ // Set up visualization
104+ setupVisualization ( ) ;
105+ } )
106+ . catch ( error => {
107+ console . error ( 'Error loading graph data:' , error ) ;
108+ alert ( "Failed to load graph data. Check the console for details." ) ;
69109 } ) ;
70-
71- // Set up visualization
72- setupVisualization ( ) ;
73- } ) . catch ( error => {
74- console . error ( 'Error loading graph data:' , error ) ;
75- } ) ;
76110 }
77111
78112 // Process the data to analyze usage patterns
@@ -143,30 +177,6 @@ document.addEventListener('DOMContentLoaded', function() {
143177 // Clear previous visualization
144178 d3 . select ( '#chart' ) . html ( '' ) ;
145179
146- // Create SVG and container for the visualization
147- svg = d3 . select ( '#chart' )
148- . append ( 'svg' )
149- . attr ( 'width' , '100%' )
150- . attr ( 'height' , '100%' ) ;
151-
152- // Add a background rect to handle zoom events on empty space
153- svg . append ( 'rect' )
154- . attr ( 'width' , '100%' )
155- . attr ( 'height' , '100%' )
156- . attr ( 'fill' , 'transparent' ) ;
157-
158- gContainer = svg . append ( 'g' )
159- . attr ( 'class' , 'everything' ) ;
160-
161- // Setup zoom behavior
162- zoomBehavior = d3 . zoom ( )
163- . scaleExtent ( [ 0.1 , 10 ] )
164- . on ( 'zoom' , ( event ) => {
165- gContainer . attr ( 'transform' , event . transform ) ;
166- } ) ;
167-
168- svg . call ( zoomBehavior ) ;
169-
170180 // Get element and window sizes
171181 const width = chartContainer . clientWidth ;
172182 const height = chartContainer . clientHeight ;
@@ -253,10 +263,35 @@ document.addEventListener('DOMContentLoaded', function() {
253263 . attr ( 'data-used' , d => d . used )
254264 . attr ( 'data-external' , d => d . isexternal )
255265 . call ( d3 . drag ( )
256- . on ( 'start' , dragstarted )
257- . on ( 'drag' , dragged )
258- . on ( 'end' , dragended ) )
259- . on ( 'click' , handleNodeClick ) ;
266+ . on ( 'start' , function ( event , d ) {
267+ if ( ! event . active ) simulation . alphaTarget ( 0.3 ) . restart ( ) ;
268+ d . fx = d . x ;
269+ d . fy = d . y ;
270+ } )
271+ . on ( 'drag' , function ( event , d ) {
272+ d . fx = event . x ;
273+ d . fy = event . y ;
274+ } )
275+ . on ( 'end' , function ( event , d ) {
276+ if ( ! event . active ) simulation . alphaTarget ( 0 ) ;
277+ d . fx = null ;
278+ d . fy = null ;
279+ } ) )
280+ . on ( 'click' , function ( event , d ) {
281+ // Clear previous selection
282+ gContainer . selectAll ( '.node.selected' ) . classed ( 'selected' , false ) ;
283+
284+ // Mark this node as selected
285+ d3 . select ( this ) . classed ( 'selected' , true ) ;
286+ selectedNode = d ;
287+
288+ // Highlight connected nodes
289+ highlightNodeConnections ( d . id ) ;
290+
291+ // Show node details panel
292+ showNodeDetails ( d ) ;
293+ detailPanel . classList . add ( 'active' ) ;
294+ } ) ;
260295
261296 // Add circles to nodes
262297 node . append ( 'circle' )
@@ -728,7 +763,7 @@ document.addEventListener('DOMContentLoaded', function() {
728763 }
729764
730765 // Highlight connections for a node
731- function highlightConnections ( nodeId ) {
766+ function highlightNodeConnections ( nodeId ) {
732767 // Reset previous highlights
733768 resetHighlights ( ) ;
734769
@@ -1052,9 +1087,15 @@ document.addEventListener('DOMContentLoaded', function() {
10521087
10531088 // Update node stats
10541089 function updateStats ( ) {
1090+ if ( ! graph || ! graph . nodes ) {
1091+ console . log ( "Cannot update stats - graph data not loaded yet" ) ;
1092+ return ;
1093+ }
1094+
10551095 loadingOverlay . style . display = 'flex' ;
10561096
10571097 setTimeout ( ( ) => {
1098+ // Calculate stats directly
10581099 const stats = {
10591100 namespaces : graph . nodes . filter ( n => n . group === 'namespace' ) . length ,
10601101 classes : graph . nodes . filter ( n => n . group === 'class' ) . length ,
@@ -1067,6 +1108,7 @@ document.addEventListener('DOMContentLoaded', function() {
10671108 total : graph . nodes . length
10681109 } ;
10691110
1111+ // Update DOM with stats
10701112 document . getElementById ( 'namespace-count' ) . textContent = stats . namespaces ;
10711113 document . getElementById ( 'class-count' ) . textContent = stats . classes ;
10721114 document . getElementById ( 'method-count' ) . textContent = stats . methods ;
0 commit comments