@@ -116,12 +116,12 @@ const SerialPlotter = () => {
116116 await selectedPort . open ( { baudRate } ) ; // Use selected baud rate
117117 setPort ( selectedPort ) ;
118118 setIsConnected ( true ) ;
119-
119+ setRawData ( "" ) ;
120120 wglpRef . current = null ;
121121 linesRef . current = [ ] ;
122122 setData ( [ ] ) ;
123123 setSelectedChannels ( [ ] ) ;
124-
124+
125125 readSerialData ( selectedPort ) ;
126126 } catch ( err ) {
127127 console . error ( "Error connecting to serial:" , err ) ;
@@ -194,6 +194,7 @@ const SerialPlotter = () => {
194194 console . error ( "Error reading serial data:" , err ) ;
195195 }
196196 } ;
197+
197198 // ✅ RE-INITIALIZE WebGL when `selectedChannels` updates
198199 useEffect ( ( ) => {
199200 if ( ! canvasRef . current || selectedChannels . length === 0 ) return ;
@@ -295,8 +296,6 @@ const SerialPlotter = () => {
295296 } ) ;
296297 } ;
297298
298-
299-
300299 const disconnectSerial = async ( ) => {
301300 if ( reader ) {
302301 await reader . cancel ( ) ;
@@ -334,110 +333,106 @@ const SerialPlotter = () => {
334333 } ;
335334
336335 return (
337- < div className = "w-full mx-auto border rounded-2xl shadow-xl flex flex-col gap-4 h-screen" >
338- < h1 className = "text-2xl font-bold text-center" > Chords Serial Plotter & Monitor </ h1 >
339-
340- < div className = "flex justify-center flex-wrap gap-2" >
341- < Button onClick = { connectToSerial } disabled = { isConnected } className = "px-4 py-2 text-sm font-semibold" >
342- { isConnected ? "Connected" : "Connect Serial" }
343- </ Button >
344- < Button onClick = { disconnectSerial } disabled = { ! isConnected } className = "px-4 py-2 text-sm font-semibold" >
345- Disconnect
346- </ Button >
336+ < div className = "w-full h-screen mx-auto border rounded-2xl shadow-xl flex flex-col gap-4 overflow-hidden p-4" >
337+ < h1 className = "text-2xl font-bold text-center" > Chords Serial Plotter & Monitor </ h1 >
338+
339+ < div className = "flex justify-center flex-wrap gap-2" >
340+ < Button onClick = { connectToSerial } disabled = { isConnected } className = "px-4 py-2 text-sm font-semibold" >
341+ { isConnected ? "Connected" : "Connect Serial" }
342+ </ Button >
343+ < Button onClick = { disconnectSerial } disabled = { ! isConnected } className = "px-4 py-2 text-sm font-semibold" >
344+ Disconnect
345+ </ Button >
346+ </ div >
347+
348+ { /* Zoom Control */ }
349+ < div className = "w-full flex justify-center items-center" >
350+ < label className = "mr-2 text-sm" > Zoom:</ label >
351+ < input
352+ type = "range"
353+ min = "0.1"
354+ max = "5"
355+ step = "0.1"
356+ value = { zoomFactor }
357+ className = "w-1/3"
358+ onChange = { ( e ) => {
359+ const newZoom = parseFloat ( e . target . value ) ;
360+ setZoomFactor ( newZoom ) ;
361+ linesRef . current . forEach ( ( line ) => {
362+ if ( line ) line . scaleY = newZoom ;
363+ } ) ;
364+ separateLinesRefs . current . forEach ( ( line ) => {
365+ if ( line ) line . scaleY = newZoom ;
366+ } ) ;
367+ wglpRef . current ?. update ( ) ;
368+ separateWglpRefs . current . forEach ( ( wglp ) => wglp ?. update ( ) ) ;
369+ } }
370+ />
371+ < span className = "ml-2 text-sm" > { zoomFactor . toFixed ( 1 ) } x</ span >
372+ </ div >
373+
374+ { /* Graph Container - Dynamic Height */ }
375+ < div className = "w-full flex-grow flex flex-col gap-2" >
376+ { showCombined && (
377+ < div className = "border rounded-xl shadow-lg bg-[#1a1a2e] p-2 w-full h-full flex flex-col" >
378+ < h2 className = "text-sm font-semibold text-center mb-1 text-white" > Combined Plot</ h2 >
379+ < canvas ref = { canvasRef } className = "w-full h-full rounded-xl" />
347380 </ div >
348-
349- { /* Zoom Control */ }
350- < div className = "w-full flex justify-center items-center " >
351- < label className = "mr-2 text-sm" > Zoom:</ label >
352- < input
353- type = "range"
354- min = "0.1"
355- max = "5"
356- step = "0.1"
357- value = { zoomFactor }
358- className = "w-1/3"
359- onChange = { ( e ) => {
360- const newZoom = parseFloat ( e . target . value ) ;
361- setZoomFactor ( newZoom ) ;
362- linesRef . current . forEach ( ( line ) => {
363- if ( line ) line . scaleY = newZoom ;
364- } ) ;
365- separateLinesRefs . current . forEach ( ( line ) => {
366- if ( line ) line . scaleY = newZoom ;
367- } ) ;
368- wglpRef . current ?. update ( ) ;
369- separateWglpRefs . current . forEach ( ( wglp ) => wglp ?. update ( ) ) ;
370- } }
371- />
372- < span className = "ml-2 text-sm" > { zoomFactor . toFixed ( 1 ) } x</ span >
381+ ) }
382+ </ div >
383+
384+ { /* Raw Data Output / Command Input - Responsive Height */ }
385+ < div ref = { rawDataRef } className = "w-full border rounded-xl shadow-lg bg-[#1a1a2e] text-white overflow-auto min-h-[160px] max-h-[40vh] flex flex-col relative" >
386+ { /* Sticky Top-right Controls */ }
387+ < div className = "sticky top-0 right-0 flex items-center justify-end space-x-2 bg-[#1a1a2e] p-2 z-10" >
388+ { /* Baud Rate Selector */ }
389+ < div className = "flex items-center space-x-2" >
390+ < label className = "text-xs font-semibold" > Baud Rate:</ label >
391+ < select
392+ value = { baudRate }
393+ onChange = { ( e ) => setBaudRate ( Number ( e . target . value ) ) }
394+ className = "p-1 border rounded bg-gray-800 text-white text-xs"
395+ >
396+ { [ 9600 , 19200 , 38400 , 57600 , 115200 , 230400 , 460800 , 921600 ] . map ( ( rate ) => (
397+ < option key = { rate } value = { rate } >
398+ { rate }
399+ </ option >
400+ ) ) }
401+ </ select >
373402 </ div >
374403
375- { /* Graph Container */ }
376- < div className = "w-full h-[500px] flex flex-col gap-2" >
377- { /* Combined Canvas */ }
378- { showCombined && (
379- < div className = "border rounded-xl shadow-lg bg-[#1a1a2e] p-2 w-full h-full flex flex-col" >
380- < h2 className = "text-sm font-semibold text-center mb-1 text-white" > Combined Plot</ h2 >
381- < canvas ref = { canvasRef } className = "w-full h-full rounded-xl" />
382- </ div >
383- ) }
384- </ div >
404+ { /* Clear Data Button */ }
405+ < button
406+ onClick = { ( ) => setRawData ( "" ) }
407+ className = "px-2 py-1 text-xs bg-red-600 text-white rounded shadow-md hover:bg-red-700 transition"
408+ >
409+ Clear
410+ </ button >
411+ </ div >
385412
386- { /* Raw Data Output / Command Input */ }
387- { /* Raw Data Output / Command Input */ }
388- < div ref = { rawDataRef } className = "w-full border rounded-xl shadow-lg bg-[#1a1a2e] text-white overflow-auto min-h-[160px] relative" >
389-
390- { /* Sticky Top-right Controls */ }
391- < div className = "sticky top-0 right-0 flex items-center justify-end space-x-2 bg-[#1a1a2e] p-2 z-10" >
392- { /* Baud Rate Selector */ }
393- < div className = "flex items-center space-x-2" >
394- < label className = "text-xs font-semibold" > Baud Rate:</ label >
395- < select
396- value = { baudRate }
397- onChange = { ( e ) => setBaudRate ( Number ( e . target . value ) ) }
398- className = "p-1 border rounded bg-gray-800 text-white text-xs"
399- >
400- { [ 9600 , 19200 , 38400 , 57600 , 115200 , 230400 , 460800 , 921600 ] . map ( ( rate ) => (
401- < option key = { rate } value = { rate } >
402- { rate }
403- </ option >
404- ) ) }
405- </ select >
406- </ div >
407-
408- { /* Clear Data Button */ }
409- < button
410- onClick = { ( ) => setRawData ( "" ) }
411- className = "px-2 py-1 text-xs bg-red-600 text-white rounded shadow-md hover:bg-red-700 transition"
412- >
413- Clear
414- </ button >
415- </ div >
416-
417- { /* Title */ }
418- < h2 className = "text-sm font-semibold text-center mb-4" >
419- { boardName ? `Connected to: ${ boardName } ` : "Raw Data Output" }
420- </ h2 >
421-
422- { /* Command Input or Raw Data */ }
423- { showCommandInput ? (
424- < div className = "flex items-center space-x-1 p-1" >
425- < input
426- type = "text"
427- value = { command }
428- onChange = { ( e ) => setCommand ( e . target . value ) }
429- placeholder = "Enter command (WHORU, START)"
430- className = "w-full p-1 rounded bg-gray-800 text-white border border-gray-600 text-xs"
431- />
432- < Button onClick = { sendCommand } className = "px-2 py-1 text-xs font-semibold" > Send</ Button >
433- </ div >
434- ) : (
435- < pre className = "text-xs whitespace-pre-wrap break-words px-4 pb-4" > { rawData } </ pre >
436- ) }
437- </ div >
413+ { /* Title */ }
414+ < h2 className = "text-sm font-semibold text-center mb-4" >
415+ { boardName ? `Connected to: ${ boardName } ` : "Raw Data Output" }
416+ </ h2 >
438417
418+ { /* Command Input or Raw Data */ }
419+ { showCommandInput ? (
420+ < div className = "flex items-center space-x-1 p-1" >
421+ < input
422+ type = "text"
423+ value = { command }
424+ onChange = { ( e ) => setCommand ( e . target . value ) }
425+ placeholder = "Enter command (WHORU, START)"
426+ className = "w-full p-1 rounded bg-gray-800 text-white border border-gray-600 text-xs"
427+ />
428+ < Button onClick = { sendCommand } className = "px-2 py-1 text-xs font-semibold" > Send</ Button >
429+ </ div >
430+ ) : (
431+ < pre className = "text-xs whitespace-pre-wrap break-words px-4 pb-4 flex-grow" > { rawData } </ pre >
432+ ) }
433+ </ div >
434+ </ div >
439435
440- </ div >
441436
442437 ) ;
443438} ;
0 commit comments