11// Network visualization
22let coattendanceNetwork = null ;
3+ let initRetryCount = 0 ;
4+ const MAX_INIT_RETRIES = 10 ;
35
46function initCoattendanceNetwork ( ) {
5- if ( ! coattendanceGraphData || ! window . vis ) {
6- return ;
7- }
8-
9- const container = document . getElementById ( 'coattendance-network' ) ;
10- if ( ! container ) {
11- return ;
12- }
13-
14- // Destroy existing network if it exists
15- if ( coattendanceNetwork ) {
16- coattendanceNetwork . destroy ( ) ;
17- }
18-
19- // Calculate min/max values for scaling
20- const nodeValues = coattendanceGraphData . nodes . map ( n => n . value || 1 ) ;
21- const maxNodeValue = Math . max ( ...nodeValues ) ;
22- const minNodeValue = Math . min ( ...nodeValues ) ;
23- const nodeValueRange = maxNodeValue - minNodeValue ;
24-
25- const edgeValues = coattendanceGraphData . edges . map ( e => e . value || 1 ) ;
26- const maxEdgeValue = Math . max ( ...edgeValues ) ;
27- const minEdgeValue = Math . min ( ...edgeValues ) ;
28- const edgeValueRange = maxEdgeValue - minEdgeValue ;
7+ try {
8+ // Check prerequisites - wait for vis library if needed
9+ if ( ! window . vis || ! window . vis . Network || ! window . vis . DataSet ) {
10+ if ( initRetryCount < MAX_INIT_RETRIES ) {
11+ initRetryCount ++ ;
12+ console . warn ( `vis-network library not loaded yet, retrying (${ initRetryCount } /${ MAX_INIT_RETRIES } )...` ) ;
13+ setTimeout ( ( ) => {
14+ initCoattendanceNetwork ( ) ;
15+ } , 100 ) ;
16+ } else {
17+ console . error ( 'vis-network library failed to load after multiple retries' ) ;
18+ }
19+ return ;
20+ }
21+
22+ initRetryCount = 0 ; // Reset retry count on success
23+
24+ if ( ! coattendanceGraphData ) {
25+ console . error ( 'coattendanceGraphData not found' ) ;
26+ return ;
27+ }
28+
29+ if ( ! coattendanceGraphData . nodes || ! Array . isArray ( coattendanceGraphData . nodes ) || coattendanceGraphData . nodes . length === 0 ) {
30+ console . error ( 'No nodes data available' ) ;
31+ return ;
32+ }
33+
34+ const container = document . getElementById ( 'coattendance-network' ) ;
35+ if ( ! container ) {
36+ console . error ( 'Container element not found' ) ;
37+ return ;
38+ }
39+
40+ // Check if container is visible (not hidden by tab system)
41+ const tabPane = container . closest ( '.tab-pane' ) ;
42+ if ( tabPane && ! tabPane . classList . contains ( 'active' ) ) {
43+ console . log ( 'Container not visible, will initialize when tab is shown' ) ;
44+ return ;
45+ }
46+
47+ // Destroy existing network if it exists
48+ if ( coattendanceNetwork ) {
49+ coattendanceNetwork . destroy ( ) ;
50+ coattendanceNetwork = null ;
51+ }
52+
53+ // Calculate min/max values for scaling
54+ const nodeValues = coattendanceGraphData . nodes . map ( n => n . value || 1 ) ;
55+ if ( nodeValues . length === 0 ) {
56+ console . error ( 'No node values available' ) ;
57+ return ;
58+ }
59+
60+ const maxNodeValue = Math . max ( ...nodeValues ) ;
61+ const minNodeValue = Math . min ( ...nodeValues ) ;
62+ const nodeValueRange = maxNodeValue - minNodeValue ;
63+
64+ const edgeValues = coattendanceGraphData . edges && Array . isArray ( coattendanceGraphData . edges )
65+ ? coattendanceGraphData . edges . map ( e => e . value || 1 )
66+ : [ ] ;
67+ const maxEdgeValue = edgeValues . length > 0 ? Math . max ( ...edgeValues ) : 1 ;
68+ const minEdgeValue = edgeValues . length > 0 ? Math . min ( ...edgeValues ) : 1 ;
69+ const edgeValueRange = maxEdgeValue - minEdgeValue ;
2970
3071 // Scale nodes: size based on degree (value)
3172 // Node size between 10 and 50 pixels
@@ -47,7 +88,10 @@ function initCoattendanceNetwork() {
4788 const color = `rgb(${ r } , ${ g } , ${ b } )` ;
4889
4990 return {
50- ...node ,
91+ id : node . id ,
92+ label : node . label || node . id ,
93+ value : degree ,
94+ title : node . title || `${ node . id } - Degree: ${ degree } ` ,
5195 size : size ,
5296 color : {
5397 background : color ,
@@ -73,7 +117,11 @@ function initCoattendanceNetwork() {
73117 } ) ;
74118
75119 // Scale edges: width based on co-attendance frequency (weight)
76- const scaledEdges = coattendanceGraphData . edges . map ( edge => {
120+ const edgesData = coattendanceGraphData . edges && Array . isArray ( coattendanceGraphData . edges )
121+ ? coattendanceGraphData . edges
122+ : [ ] ;
123+
124+ const scaledEdges = edgesData . map ( edge => {
77125 const weight = edge . value || 1 ;
78126 // Edge width between 1 and 5 pixels
79127 const width = edgeValueRange > 0
@@ -86,8 +134,11 @@ function initCoattendanceNetwork() {
86134 : 0.5 ;
87135
88136 return {
89- ...edge ,
137+ from : edge . from ,
138+ to : edge . to ,
139+ value : weight ,
90140 width : width ,
141+ title : edge . title || `Co-attended ${ weight } time(s)` ,
91142 color : {
92143 color : `rgba(3, 102, 214, ${ opacity } )` ,
93144 highlight : '#0366d6' ,
@@ -96,9 +147,7 @@ function initCoattendanceNetwork() {
96147 smooth : {
97148 type : 'continuous' ,
98149 roundness : 0.5
99- } ,
100- selectionWidth : width * 2 ,
101- hoverWidth : width * 1.5
150+ }
102151 } ;
103152 } ) ;
104153
@@ -198,6 +247,15 @@ function initCoattendanceNetwork() {
198247 coattendanceNetwork . on ( 'blurNode' , function ( params ) {
199248 container . style . cursor = 'default' ;
200249 } ) ;
250+
251+ console . log ( 'Network visualization initialized successfully' ) ;
252+ } catch ( error ) {
253+ console . error ( 'Error initializing network visualization:' , error ) ;
254+ const container = document . getElementById ( 'coattendance-network' ) ;
255+ if ( container ) {
256+ container . innerHTML = '<p style="color: red; padding: 20px;">Error loading network visualization. Please check the browser console for details.</p>' ;
257+ }
258+ }
201259}
202260
203261// Tab switching functionality
@@ -240,10 +298,18 @@ function showTab(tabId) {
240298
241299 // Initialize network visualization if showing co-attendance tab
242300 if ( tabId === 'coattendance' ) {
243- // Small delay to ensure DOM is ready
301+ // Delay to ensure DOM is ready and tab is visible
244302 setTimeout ( ( ) => {
245303 initCoattendanceNetwork ( ) ;
246- } , 100 ) ;
304+ } , 200 ) ;
305+ } else if ( coattendanceNetwork ) {
306+ // Destroy network when switching away from co-attendance tab
307+ try {
308+ coattendanceNetwork . destroy ( ) ;
309+ coattendanceNetwork = null ;
310+ } catch ( e ) {
311+ console . error ( 'Error destroying network:' , e ) ;
312+ }
247313 }
248314
249315 // Update URL hash without scrolling
0 commit comments