@@ -11,6 +11,7 @@ import { applyLens1D, createLensXScale, createFisheyeScale, createHorizontalFish
1111import { computeIpSpans , createSpanData , renderRowLines , renderIpLabels , createLabelHoverHandler , createLabelMoveHandler , createLabelLeaveHandler , attachLabelHoverHandlers } from './src/rendering/rows.js' ;
1212import { createArcHoverHandler , createArcMoveHandler , createArcLeaveHandler , attachArcHandlers } from './src/rendering/arcInteractions.js' ;
1313import { loadAllMappings } from './src/mappings/loaders.js' ;
14+ import { setupWindowResizeHandler as setupWindowResizeHandlerFromModule } from './src/interaction/resize.js' ;
1415
1516// Network TimeArcs visualization
1617// Input CSV schema: timestamp,length,src_ip,dst_ip,protocol,count
@@ -163,6 +164,11 @@ import { loadAllMappings } from './src/mappings/loaders.js';
163164 let updateLensVisualizationFn = null ;
164165 // Reference to toggleLensing function so button can trigger it
165166 let toggleLensingFn = null ;
167+
168+ // State for last rendered data (for resize re-render)
169+ let lastRenderedData = null ;
170+ // Cleanup function for resize handler
171+ let resizeCleanup = null ;
166172
167173 // Initialize mappings, then try a default CSV load
168174 ( async function init ( ) {
@@ -183,9 +189,60 @@ import { loadAllMappings } from './src/mappings/loaders.js';
183189 } catch ( err ) {
184190 console . warn ( 'Mapping load failed:' , err ) ;
185191 }
192+ // Setup window resize handler
193+ resizeCleanup = setupWindowResizeHandler ( ) ;
186194 // After maps are ready (or failed gracefully), try default CSV
187195 tryLoadDefaultCsv ( ) ;
188196 } ) ( ) ;
197+
198+ // Window resize handler for responsive visualization
199+ function setupWindowResizeHandler ( ) {
200+ const handleResizeLogic = ( ) => {
201+ try {
202+ // Only proceed if we have data to re-render
203+ if ( ! lastRenderedData || lastRenderedData . length === 0 ) {
204+ return ;
205+ }
206+
207+ console . log ( 'Handling window resize, updating visualization dimensions' ) ;
208+
209+ // Store old dimensions for comparison
210+ const oldWidth = width ;
211+ const oldHeight = height ;
212+
213+ const containerEl = document . getElementById ( 'chart-container' ) ;
214+ if ( ! containerEl ) return ;
215+
216+ // Calculate new dimensions
217+ const containerRect = containerEl . getBoundingClientRect ( ) ;
218+ const availableWidth = containerRect . width || 1200 ;
219+ const viewportWidth = Math . max ( availableWidth , 800 ) ;
220+ const newWidth = viewportWidth - MARGIN . left - MARGIN . right ;
221+
222+ // Skip if dimensions haven't changed significantly
223+ if ( Math . abs ( newWidth - oldWidth ) < 10 ) {
224+ return ;
225+ }
226+
227+ console . log ( `Resize: ${ oldWidth } x${ oldHeight } -> ${ newWidth } x${ height } ` ) ;
228+
229+ // Re-render with the new dimensions
230+ // The render function will recalculate all scales and positions
231+ render ( lastRenderedData ) ;
232+
233+ console . log ( 'Window resize handling complete' ) ;
234+
235+ } catch ( e ) {
236+ console . warn ( 'Error during window resize:' , e ) ;
237+ }
238+ } ;
239+
240+ // Use module's resize handler with our custom logic
241+ return setupWindowResizeHandlerFromModule ( {
242+ debounceMs : 200 ,
243+ onResize : handleResizeLogic
244+ } ) ;
245+ }
189246
190247 // Stream-parse a CSV file incrementally to avoid loading entire file into memory
191248 // Pushes transformed rows directly into combinedData, returns {totalRows, validRows}
@@ -557,6 +614,9 @@ import { loadAllMappings } from './src/mappings/loaders.js';
557614 }
558615
559616 function render ( data ) {
617+ // Store data for resize re-render
618+ lastRenderedData = data ;
619+
560620 // Determine timestamp handling
561621 const tsMin = d3 . min ( data , d => d . timestamp ) ;
562622 const tsMax = d3 . max ( data , d => d . timestamp ) ;
0 commit comments