@@ -33,8 +33,7 @@ import { PlotUtils } from '../plot-utils';
3333 styleUrl : './plot-step.component.scss' ,
3434} )
3535export class PlotStepComponent
36- implements AfterViewInit , OnInit , OnDestroy , OnChanges
37- {
36+ implements AfterViewInit , OnInit , OnDestroy , OnChanges {
3837 @Input ( ) stepChannel : StepChannel | undefined ;
3938 @Input ( ) stepGlobalParameters : StepGlobalParameters | undefined ;
4039
@@ -57,7 +56,7 @@ export class PlotStepComponent
5756 backgroundColor : '' ,
5857 color : '' ,
5958 } ;
60- @Input ( ) color = '' ;
59+ @Input ( ) color = '' ;
6160 private mutationObserver : MutationObserver | undefined ;
6261 private originalBackgroundColor = '' ;
6362 activeBackgroundColor = '' ;
@@ -208,7 +207,7 @@ export class PlotStepComponent
208207 } ;
209208 private plotData = [ this . plotData1 , this . plotData2 ] ;
210209
211- constructor ( public elementRef : ElementRef ) { }
210+ constructor ( public elementRef : ElementRef ) { }
212211
213212 ngOnChanges ( changes : SimpleChanges ) : void {
214213 if ( changes [ 'isActive' ] && ! changes [ 'isActive' ] . isFirstChange ( ) ) {
@@ -272,44 +271,46 @@ export class PlotStepComponent
272271 private generatePlotData ( yData : number [ ] , type : string ) : void {
273272 if ( this . stepPoints && this . stepToSweepDelay ) {
274273 const delayTime = this . stepToSweepDelay ?. value ?? 0 ;
275- const targetLength = Math . max ( 2 , Math . floor ( this . plotWidth ) ) ;
274+ const targetLength = this . plotWidth ;
276275 let processedYData = [ ...yData ] ;
277276 let processedXData : number [ ] = [ ] ;
277+ const numberofSteps : number = this . stepPoints . value ;
278+ processedXData = Array . from ( { length : processedYData . length } , ( _ , i ) => ( i / ( processedYData . length - 1 ) * numberofSteps ) ) . concat ( numberofSteps ) . flat ( ) ;
278279
279- // Handle interpolation first if needed
280- if ( this . stepPoints . value > targetLength ) {
281- if ( type == 'LIN' ) {
282- const interpolated = PlotUtils . linearInterpolation ( processedYData , targetLength ) ;
283- processedXData = interpolated . x ;
284- processedYData = interpolated . y ;
285- } else if ( type == 'LOG' || type == 'LIST' ) {
286- const interpolated = PlotUtils . minMaxInterpolation ( processedYData , targetLength ) ;
287- processedXData = interpolated . x ;
288- processedYData = interpolated . y ;
289- }
290- } else {
291- processedXData = Array . from ( { length : this . stepPoints . value } , ( _ , i ) => i )
292- . concat ( this . stepPoints . value )
293- . flat ( ) ;
294- }
295-
280+ // Adding delay first if its exists
296281 if ( delayTime > 0 ) {
297282 const { x, y } = this . generateDataWithDelay ( processedYData , processedXData , delayTime ) ;
298- this . plotData1 . x = x ;
299- this . plotData1 . y = y ;
300- } else {
301- this . generateDataWithoutDelay ( processedYData , processedXData ) ;
283+ processedXData = x ;
284+ processedYData = y ;
302285 }
303-
304- // console.log('Plot data generated:', {
305- // x: this.plotData1.x,
306- // y: this.plotData1.y,
307- // });
308- // this.plotLayout.xaxis.dtick = (this.stepPoints.value + this.stepToSweepDelay?.value) / 10;
309- // Update x-axis range to include delay time for each step
310- // const delayTime = this.stepToSweepDelay?.value ?? 0;
286+
287+ if ( processedYData . length > targetLength ) {
288+ if ( type == 'LIN' || type == 'LOG' || type == 'LIST' ) {
289+ // If we have delay, we need to interpolate X,Y pairs together to maintain timing
290+ // This was suggested to be better than interpolation in this case so the graph is continous in all places and works well in our use case
291+ if ( delayTime > 0 ) {
292+ // Create indices for interpolation based on target length
293+ const indices = Array . from ( { length : targetLength } , ( _ , i ) =>
294+ Math . floor ( ( i / ( targetLength - 1 ) ) * ( processedYData . length - 1 ) )
295+ ) ;
296+
297+ // Interpolate by sampling the delay-generated data at calculated indices
298+ processedYData = indices . map ( i => processedYData [ i ] ) ;
299+ processedXData = indices . map ( i => processedXData [ i ] ) ;
300+ } else {
301+ // Without delay, use original interpolation method
302+ const interpolated = PlotUtils . minMaxInterpolation ( processedYData , targetLength ) ;
303+ processedYData = interpolated . y ;
304+ processedXData = Array . from ( { length : processedYData . length } , ( _ , i ) => ( i / ( processedYData . length - 1 ) * numberofSteps ) ) . concat ( numberofSteps ) . flat ( ) ;
305+ }
306+ }
307+ }
308+
309+ this . plotData1 . x = processedXData ;
310+ this . plotData1 . y = processedYData ;
311+
311312 const totalTime = this . stepPoints . value * ( 1 + delayTime ) ; // Each step now takes (1 + delayTime) units
312-
313+
313314 this . plotLayout . xaxis . dtick = totalTime / 10 ;
314315 this . plotLayout . xaxis . range = [ 0 , totalTime ] ;
315316 }
@@ -325,31 +326,26 @@ export class PlotStepComponent
325326 for ( let step = 0 ; step < numSteps ; step ++ ) {
326327 const stepStartTime = step * ( 1 + delayTime ) ;
327328 const currentYValue = yData [ step ] ;
328-
329+
329330 // Add delay period (repeat current y value) at the beginning of each step
330331 for ( let d = 0 ; d < delayPoints ; d ++ ) {
331332 finalX . push ( stepStartTime + ( d * delayTime ) / delayPoints ) ;
332333 finalY . push ( currentYValue ) ;
333334 }
334-
335+
335336 // Add the actual step point after delay
336337 finalX . push ( stepStartTime + delayTime ) ;
337338 finalY . push ( currentYValue ) ;
338339 }
339-
340+
340341 // Add final point
341342 if ( yData . length > 0 ) {
342343 const finalStepTime = numSteps * ( 1 + delayTime ) ;
343344 finalX . push ( finalStepTime ) ;
344345 finalY . push ( yData [ yData . length - 1 ] ) ;
345346 }
346-
347- return { x : finalX , y : finalY } ;
348- }
349347
350- private generateDataWithoutDelay ( yData : number [ ] , xData : number [ ] ) : void {
351- this . plotData1 . x = xData ;
352- this . plotData1 . y = yData ;
348+ return { x : finalX , y : finalY } ;
353349 }
354350
355351 private stepListPlot ( ) {
0 commit comments