@@ -615,6 +615,58 @@ function FlightLogGrapher(flightLog, graphConfig, canvas, craftCanvas, analyserC
615615 canvasContext . fillRect ( 0 , - plotHeight / 2 , canvas . width , plotHeight ) ;
616616 }
617617
618+ // Human-friendly time intervals in microseconds
619+ var FRIENDLY_INTERVALS_MICROS = [
620+ 10000 , // 10ms
621+ 25000 , // 25ms
622+ 50000 , // 50ms
623+ 100000 , // 100ms
624+ 250000 , // 250ms
625+ 500000 , // 500ms
626+ 1000000 , // 1 second
627+ 2000000 , // 2 seconds
628+ 5000000 , // 5 seconds
629+ 10000000 , // 10 seconds
630+ 30000000 , // 30 seconds
631+ 60000000 , // 1 minute
632+ 300000000 , // 5 minutes
633+ 900000000 , // 15 minutes
634+ ] ;
635+
636+ function calculateGridInterval ( windowWidth ) {
637+ var idealInterval = windowWidth / 8 ;
638+ return FRIENDLY_INTERVALS_MICROS . reduce ( function ( prev , curr ) {
639+ return Math . abs ( curr - idealInterval ) < Math . abs ( prev - idealInterval ) ? curr : prev ;
640+ } ) ;
641+ }
642+
643+ function formatTimeLabel ( timeMicros , intervalMicros ) {
644+ var timeSec = timeMicros / 1000000 ;
645+ var timeMin = timeSec / 60 ;
646+ var mins = Math . floor ( timeMin ) ;
647+ var secs = timeSec % 60 ;
648+
649+ // Determine decimal places needed based on interval
650+ var decimalPlaces = 0 ;
651+ if ( intervalMicros < 100000 ) {
652+ decimalPlaces = 2 ; // 10ms, 25ms, 50ms intervals
653+ } else if ( intervalMicros < 1000000 ) {
654+ decimalPlaces = 1 ; // 100ms-500ms intervals
655+ }
656+
657+ if ( timeSec < 60 ) {
658+ // Under 1 minute: show as seconds
659+ return timeSec . toFixed ( decimalPlaces ) + "s" ;
660+ } else {
661+ // Over 1 minute: show as min:sec
662+ var secsStr = secs . toFixed ( decimalPlaces ) ;
663+ if ( secs < 10 ) {
664+ secsStr = "0" + secsStr ;
665+ }
666+ return mins + ":" + secsStr ;
667+ }
668+ }
669+
618670 //Draw a grid
619671 function drawGrid ( curve , plotHeight ) {
620672 var settings = curve . getCurve ( ) ,
@@ -625,7 +677,7 @@ function FlightLogGrapher(flightLog, graphConfig, canvas, craftCanvas, analyserC
625677 yScale = - plotHeight / 2 ;
626678
627679 canvasContext . strokeStyle = "rgba(255,255,255,0.5)" ; // Grid Color
628- canvasContext . setLineDash ( [ 1 , 10 ] ) ; // Make the grid line a dash
680+ canvasContext . setLineDash ( [ 1 , 10 ] ) ; // Make the grid line a dash
629681 canvasContext . lineWidth = 1 ;
630682 canvasContext . beginPath ( ) ;
631683
@@ -637,21 +689,44 @@ function FlightLogGrapher(flightLog, graphConfig, canvas, craftCanvas, analyserC
637689 canvasContext . lineTo ( canvas . width , yValue ) ;
638690 }
639691 }
640- // vertical lines
641- for ( var i = ( windowStartTime / 100000 ) . toFixed ( 0 ) * 100000 ; i < windowEndTime ; i += 100000 ) {
642- var x = timeToCanvasX ( i ) ;
692+
693+ // vertical lines with scaled intervals, aligned to log start time
694+ var timeInterval = calculateGridInterval ( windowWidthMicros ) ;
695+ var logMinTime = flightLog . getMinTime ( ) ;
696+ var startTime = logMinTime + Math . floor ( ( windowStartTime - logMinTime ) / timeInterval ) * timeInterval ;
697+
698+ for ( var t = startTime ; t < windowEndTime ; t += timeInterval ) {
699+ var x = timeToCanvasX ( t ) ;
643700 canvasContext . moveTo ( x , yScale ) ;
644701 canvasContext . lineTo ( x , - yScale ) ;
645- }
702+ }
646703
647704 canvasContext . stroke ( ) ;
648705 canvasContext . setLineDash ( [ ] ) ; // clear the dash
706+ }
649707
650- // range values,
651- //drawAxisLabel(max.toFixed(0), yScale + 12);
652- //drawAxisLabel(min.toFixed(0), -yScale - 8);
653-
708+ // Draw time labels at the bottom of the canvas
709+ function drawTimeAxisLabels ( ) {
710+ var timeInterval = calculateGridInterval ( windowWidthMicros ) ;
711+ var logMinTime = flightLog . getMinTime ( ) ;
712+ // Align grid to log start time so labels show time from beginning of log
713+ var startTime = logMinTime + Math . floor ( ( windowStartTime - logMinTime ) / timeInterval ) * timeInterval ;
714+ // Leave margin on right for frame label
715+ var rightMargin = 120 ;
654716
717+ canvasContext . font = drawingParams . fontSizeAxisLabel + "pt " + DEFAULT_FONT_FACE ;
718+ canvasContext . fillStyle = "rgba(255,255,255,0.7)" ;
719+ canvasContext . textAlign = 'center' ;
720+
721+ for ( var t = startTime ; t < windowEndTime ; t += timeInterval ) {
722+ var x = timeToCanvasX ( t ) ;
723+ // Only draw if within visible canvas area, with right margin for frame label
724+ if ( x >= 0 && x <= canvas . width - rightMargin ) {
725+ var relativeTime = t - logMinTime ;
726+ var label = formatTimeLabel ( relativeTime , timeInterval ) ;
727+ canvasContext . fillText ( label , x , canvas . height - 4 ) ;
728+ }
729+ }
655730 }
656731
657732 function drawAxisLabel ( axisLabel , y ) {
@@ -993,7 +1068,7 @@ function FlightLogGrapher(flightLog, graphConfig, canvas, craftCanvas, analyserC
9931068
9941069 //Draw a bar highlighting the current time if we are drawing any graphs
9951070 if ( graphs . length ) {
996- var
1071+ var
9971072 centerX = canvas . width / 2 ;
9981073
9991074 canvasContext . strokeStyle = 'rgba(255, 64, 64, 0.2)' ;
@@ -1010,9 +1085,11 @@ function FlightLogGrapher(flightLog, graphConfig, canvas, craftCanvas, analyserC
10101085 canvasContext . moveTo ( centerX , 0 ) ;
10111086 canvasContext . lineTo ( centerX , canvas . height ) ;
10121087 canvasContext . stroke ( ) ;
1013-
1088+
1089+ // Draw time axis labels at bottom
1090+ drawTimeAxisLabels ( ) ;
10141091 }
1015-
1092+
10161093 // Draw events - if option set or even if option is not set but there are graphs
10171094 // the option is for video export; if you export the video without any graphs set,
10181095 // then the events are not shown either (to keep the video clean. but
0 commit comments