@@ -57,7 +57,8 @@ var car_index = 0;
5757var car_colors = [ "blue" , "red" , "green" , "yellow" , "teal" , "purple" ] ;
5858var balloon_index = 0 ;
5959var balloon_colors_name = [ "red" , "blue" , "green" , "yellow" , "purple" , "orange" , "cyan" ] ;
60- var balloon_colors = [ "#f00" , "blue" , "green" , "#FDFC30" , "#c700e6" , "#ff8a0f" , "#0fffca" ] ;
60+ // Yellow was #FDFC30, darker version is "#caca02"
61+ var balloon_colors = [ "#f00" , "blue" , "green" , "#caca02" , "#c700e6" , "#ff8a0f" , "#0fffca" ] ;
6162
6263var nyan_color_index = 0 ;
6364var nyan_colors = [ 'nyan' , 'nyan-coin' , 'nyan-mon' , 'nyan-pirate' , 'nyan-cool' , 'nyan-tothemax' , 'nyan-pumpkin' , 'nyan-afro' , 'nyan-coin' , 'nyan-mummy' ] ;
@@ -83,13 +84,14 @@ var modeList = [
8384 "12h" ,
8485 "1d" ,
8586 "3d" ,
86- "7d" , // New time periods, as of 2023-04, only available if filtering is on.
87- "31d" ,
87+ "7d" ,
88+ "31d" , // New time periods, as of 2023-04, only available if filtering is on.
8889 "186d" ,
8990 "366d"
9091] ;
9192var modeDefault = "12h" ;
9293var modeDefaultMobile = "12h" ;
94+ var longModes = [ '31d' , '186d' , '366d' ] ; // These modes only available if filtering is on.
9395
9496// order of map elements
9597var Z_RANGE = 1 ;
@@ -640,7 +642,7 @@ function load() {
640642 onAdd : function ( map ) {
641643 var div = L . DomUtil . create ( 'div' ) ;
642644
643- div . innerHTML = '<select name="timeperiod" id="timeperiod" style="width:auto !important;height:30px;" onchange="clean_refresh(this.value)"><option value="0">Live Only</option><option value="1h">1 hour</option><option value="3h">3 hours</option><option value="6h">6 hours</option><option value="12h">12 hours</option><option value="1d" selected="selected">1 day</option><option value="3d">3 days</option><option value="7d">7 days</option></select>' ;
645+ div . innerHTML = '<select name="timeperiod" id="timeperiod" style="width:auto !important;height:30px;" onchange="clean_refresh(this.value)"><option value="0">Live Only</option><option value="1h">1 hour</option><option value="3h">3 hours</option><option value="6h">6 hours</option><option value="12h">12 hours</option><option value="1d" selected="selected">1 day</option><option value="3d">3 days</option><option value="7d">7 days</option><option value="31d" disabled>1 month</option><option value="186d" disabled>6 months</option><option value="366d" disabled>1 year</option>< /select>' ;
644646 div . innerHTML . onload = setTimeValue ( ) ;
645647
646648 return div ;
@@ -803,6 +805,22 @@ function load() {
803805 } , 500 ) ;
804806}
805807
808+ function setLongTimePeriods ( state ) {
809+ // Enable or disable the 'long' timeperiod settings (>1 month)
810+ $ ( "#timeperiod option" ) . each ( function ( ) {
811+ var $thisOption = $ ( this ) ;
812+
813+ if ( longModes . includes ( $thisOption . val ( ) ) ) {
814+ if ( state ) {
815+ $thisOption . attr ( "disabled" , false ) ;
816+ } else {
817+ $thisOption . attr ( "disabled" , true ) ;
818+ }
819+ }
820+ } ) ;
821+ }
822+
823+
806824function setTimeValue ( ) {
807825 setTimeout ( function ( ) {
808826 document . getElementById ( "timeperiod" ) . value = wvar . mode ;
@@ -1827,7 +1845,7 @@ function redrawPrediction(vcallsign) {
18271845 } else {
18281846 vehicle . prediction_polyline = new L . Wrapped . Polyline ( line , {
18291847 color : balloon_colors [ vehicle . color_index ] ,
1830- opacity : 0.4 ,
1848+ opacity : 0.5 ,
18311849 weight : 3 ,
18321850 } ) . addTo ( map ) ;
18331851 vehicle . prediction_polyline . on ( 'click' , function ( e ) {
@@ -1924,10 +1942,20 @@ function updatePolyline(vcallsign) {
19241942}
19251943
19261944function drawAltitudeProfile ( c1 , c2 , series , alt_max , chase ) {
1945+ // Updated 2023-04-10 to make use of position time data to set
1946+ // the x-coordinate. This helps resolve issues with backlog vs live data.
19271947 alt_max = ( alt_max < 2000 ) ? 2000 : alt_max ;
19281948 var alt_list = series . data ;
1949+ var first_time = alt_list [ 0 ] [ 0 ] ;
19291950 var len = alt_list . length ;
19301951 var real_len = len - series . nulls ;
1952+ var last_time = alt_list [ len - 1 ] [ 0 ] ;
1953+ var time_range = last_time - first_time ;
1954+
1955+ // Only attempt to draw if we have more than 1 data point.
1956+ if ( len == 1 ) {
1957+ return ;
1958+ }
19311959
19321960 var ctx1 = c1 . getContext ( "2d" ) ;
19331961 var ctx2 = c2 . getContext ( "2d" ) ;
@@ -1960,16 +1988,19 @@ function drawAltitudeProfile(c1, c2, series, alt_max, chase) {
19601988 ctx2 . strokeStyle = "#f53333" ;
19611989 }
19621990
1963- var xt1 = ( cw1 - ( 2 * ratio ) ) / real_len ;
1991+ //var xt1 = (cw1 - (2 * ratio)) / real_len;
1992+ var xt1 = ( cw1 - ( 2 * ratio ) ) / time_range ;
19641993 var yt1 = ( ch1 - ( 6 * ratio ) ) / alt_max ;
1965- var xt2 = ( cw2 - ( 2 * ratio ) ) / real_len ;
1994+ //var xt2 = (cw2 - (2 * ratio)) / real_len;
1995+ var xt2 = ( cw2 - ( 2 * ratio ) ) / time_range ;
19661996 var yt2 = ( ch2 - ( 6 * ratio ) ) / alt_max ;
19671997
19681998 xt1 = ( xt1 > 1 ) ? 1 : xt1 ;
19691999 yt1 = ( yt1 > 1 ) ? 1 : yt1 ;
19702000 xt2 = ( xt2 > 1 ) ? 1 : xt2 ;
19712001 yt2 = ( yt2 > 1 ) ? 1 : yt2 ;
19722002
2003+
19732004 ctx1 . beginPath ( ) ;
19742005 ctx2 . beginPath ( ) ;
19752006
@@ -1985,26 +2016,33 @@ function drawAltitudeProfile(c1, c2, series, alt_max, chase) {
19852016 if ( cw1 * 2 > real_len ) {
19862017 for ( i = 0 ; i < real_len ; i ++ ) {
19872018 alt = alt_list [ i ] [ 1 ] ;
2019+ alt_time = last_time - alt_list [ i ] [ 0 ] ;
19882020
1989- ctx1 . lineTo ( 1 + ( ( i + 1 ) * xt1 ) , ch1 - ( alt * yt1 ) ) ;
1990- ctx2 . lineTo ( 1 + ( ( i + 1 ) * xt2 ) , ch2 - ( alt * yt2 ) ) ;
2021+ //
2022+ //ctx1.lineTo(1+((i+1)*xt1), ch1 - (alt * yt1));
2023+ //ctx2.lineTo(1+((i+1)*xt2), ch2 - (alt * yt2));
2024+ ctx1 . lineTo ( cw1 - ( alt_time * xt1 ) , ch1 - ( alt * yt1 ) ) ;
2025+ ctx2 . lineTo ( cw2 - ( alt_time * xt2 ) , ch2 - ( alt * yt2 ) ) ;
19912026
19922027 if ( i + 2 < len && alt_list [ i + 2 ] [ 1 ] === null ) i += 2 ;
19932028 }
19942029 }
19952030 // if they are too many, downsample to keep the loop short
19962031 else {
1997- xt1 = 0.5 ;
1998- xt2 = 0.16 ;
2032+ // xt1 = 0.5;
2033+ // xt2 = 0.16;
19992034 var max = cw1 * 2 ;
20002035 var step = ( 1.0 * len ) / max ;
20012036
20022037 for ( i = 0 ; i < max ; i ++ ) {
20032038 alt = alt_list [ Math . floor ( i * step ) ] [ 1 ] ;
2039+ alt_time = last_time - alt_list [ Math . floor ( i * step ) ] [ 0 ] ;
20042040 if ( alt === null ) continue ;
20052041
2006- ctx1 . lineTo ( 1 + ( ( i + 1 ) * xt1 ) , ch1 - ( alt * yt1 ) ) ;
2007- ctx2 . lineTo ( 1 + ( ( i + 1 ) * xt2 ) , ch2 - ( alt * yt2 ) ) ;
2042+ //ctx1.lineTo(1+((i+1)*xt1), ch1 - (alt * yt1));
2043+ //ctx2.lineTo(1+((i+1)*xt2), ch2 - (alt * yt2));
2044+ ctx1 . lineTo ( cw1 - ( alt_time * xt1 ) , ch1 - ( alt * yt1 ) ) ;
2045+ ctx2 . lineTo ( cw2 - ( alt_time * xt2 ) , ch2 - ( alt * yt2 ) ) ;
20082046 }
20092047
20102048 // fix index for fill
@@ -2015,8 +2053,13 @@ function drawAltitudeProfile(c1, c2, series, alt_max, chase) {
20152053 ctx2 . stroke ( ) ;
20162054
20172055 // close the path, so it can be filled
2018- ctx1 . lineTo ( 1 + ( ( i + 1 ) * xt1 ) , ch1 ) ;
2019- ctx2 . lineTo ( 1 + ( ( i + 1 ) * xt2 ) , ch2 ) ;
2056+ //ctx1.lineTo(1+((i+1)*xt1), ch1);
2057+ //ctx2.lineTo(1+((i+1)*xt2), ch2);
2058+ end_x1 = cw1 - ( last_time - alt_list [ len - 1 ] [ 0 ] ) * xt1 ;
2059+ end_x2 = cw2 - ( last_time - alt_list [ len - 1 ] [ 0 ] ) * xt2 ;
2060+
2061+ ctx1 . lineTo ( end_x1 , ch1 ) ;
2062+ ctx2 . lineTo ( end_x2 , ch2 ) ;
20202063 ctx1 . lineTo ( 0 , ch1 ) ;
20212064 ctx2 . lineTo ( 0 , ch2 ) ;
20222065
@@ -3213,8 +3256,10 @@ function refresh() {
32133256
32143257 if ( wvar . query ) {
32153258 var data_str = "duration=" + mode + "&payload_callsign=" + encodeURIComponent ( wvar . query ) ;
3259+ setLongTimePeriods ( true ) ;
32163260 } else {
32173261 var data_str = "duration=" + mode ;
3262+ setLongTimePeriods ( false ) ;
32183263 }
32193264
32203265 ajax_positions = $ . ajax ( {
0 commit comments