@@ -91,29 +91,76 @@ const SerialPlotter = () => {
9191 } , [ selectedChannels , viewMode , isConnected ] ) ;
9292
9393 useEffect ( ( ) => {
94- const smoothingFactor = 0.5 ; // Adjust this between 0 (no change) and 1 (immediate change)
95- // Update frequently for a continuous effect (e.g., every 50ms)
96- const interval = setInterval ( ( ) => {
94+ const smoothingFactor = 0.5 ; // Between 0 (no smoothing) and 1 (instant change)
95+ const MIN_POINTS_FOR_SCALING = 10 ;
96+
97+ // Realtime update for new points using sweep logic.
98+ const realtimeInterval = setInterval ( ( ) => {
9799 if ( ! wglpRef . current || linesRef . current . length === 0 || dataRef . current . length === 0 ) return ;
98100
99- // Compute the new autoscale parameters from the full data window
100- const allValues = dataRef . current . flatMap ( dp => dp . values ) ;
101- const MIN_POINTS_FOR_SCALING = 10 ;
102- let newYMin = - 1 , newYMax = 1 ;
101+ // Compute autoscale parameters using the full data buffer.
102+ const allValues = dataRef . current . flatMap ( ( dp ) => dp . values ) ;
103+ let newYMin = - 1 ,
104+ newYMax = 1024 ;
103105 if ( allValues . length >= MIN_POINTS_FOR_SCALING ) {
104106 newYMin = Math . min ( ...allValues ) ;
105107 newYMax = Math . max ( ...allValues ) ;
106108 }
107109
108- // Smoothly interpolate between the current scale and the new scale
110+ // Smoothly interpolate the current scale.
109111 currentScaleRef . current . yMin += smoothingFactor * ( newYMin - currentScaleRef . current . yMin ) ;
110112 currentScaleRef . current . yMax += smoothingFactor * ( newYMax - currentScaleRef . current . yMax ) ;
111113
112114 const currentYMin = currentScaleRef . current . yMin ;
113115 const currentYMax = currentScaleRef . current . yMax ;
114116 const yRange = currentYMax - currentYMin || 1 ;
115117
116- // Update every point in the buffer using the smoothed scale
118+ // Update only the latest data point with sweep logic.
119+ const latestDataPoint = dataRef . current [ dataRef . current . length - 1 ] ;
120+ if ( latestDataPoint ) {
121+ linesRef . current . forEach ( ( line , channelIndex ) => {
122+ if ( channelIndex >= latestDataPoint . values . length ) return ;
123+ const yValue = ( ( latestDataPoint . values [ channelIndex ] - currentYMin ) / yRange ) * 2 - 1 ;
124+ const currentPos = sweepPositions . current [ channelIndex ] % line . numPoints ;
125+ try {
126+ line . setY ( currentPos , yValue ) ;
127+ } catch ( error ) {
128+ console . error (
129+ `Error plotting data for channel ${ channelIndex } at pos ${ currentPos } :` ,
130+ error
131+ ) ;
132+ }
133+ // Advance the circular buffer pointer.
134+ sweepPositions . current [ channelIndex ] = ( currentPos + 1 ) % line . numPoints ;
135+ } ) ;
136+ }
137+
138+ if ( wglpRef . current ) {
139+ wglpRef . current . update ( ) ;
140+ }
141+ } , 10 ) ;
142+
143+ // Periodically update the entire buffer so that all points reflect the current autoscale.
144+ const bufferInterval = setInterval ( ( ) => {
145+ if ( ! wglpRef . current || linesRef . current . length === 0 || dataRef . current . length === 0 ) return ;
146+
147+ // Compute autoscale parameters using the full data window.
148+ const allValues = dataRef . current . flatMap ( ( dp ) => dp . values ) ;
149+ let newYMin = - 1 ,
150+ newYMax = 1024 ;
151+ if ( allValues . length >= MIN_POINTS_FOR_SCALING ) {
152+ newYMin = Math . min ( ...allValues ) ;
153+ newYMax = Math . max ( ...allValues ) ;
154+ }
155+
156+ currentScaleRef . current . yMin += smoothingFactor * ( newYMin - currentScaleRef . current . yMin ) ;
157+ currentScaleRef . current . yMax += smoothingFactor * ( newYMax - currentScaleRef . current . yMax ) ;
158+
159+ const currentYMin = currentScaleRef . current . yMin ;
160+ const currentYMax = currentScaleRef . current . yMax ;
161+ const yRange = currentYMax - currentYMin || 1 ;
162+
163+ // Replot the entire buffer with the updated scale.
117164 linesRef . current . forEach ( ( line , channelIndex ) => {
118165 const numPoints = dataRef . current . length ;
119166 for ( let j = 0 ; j < numPoints ; j ++ ) {
@@ -131,12 +178,16 @@ const SerialPlotter = () => {
131178 if ( wglpRef . current ) {
132179 wglpRef . current . update ( ) ;
133180 }
134- } , 10 ) ; // Update every 50ms for a continuous, smooth effect
181+ } , 5000 ) ;
135182
136- return ( ) => clearInterval ( interval ) ;
183+ return ( ) => {
184+ clearInterval ( realtimeInterval ) ;
185+ clearInterval ( bufferInterval ) ;
186+ } ;
137187 } , [ ] ) ;
138188
139189
190+
140191 const getLineColor = ( index : number ) : ColorRGBA => {
141192 const hex = channelColors [ index % channelColors . length ] ;
142193 const r = parseInt ( hex . slice ( 1 , 3 ) , 16 ) / 255 ;
@@ -464,4 +515,4 @@ const SerialPlotter = () => {
464515 ) ;
465516} ;
466517
467- export default SerialPlotter ;
518+ export default SerialPlotter ;
0 commit comments