@@ -43,6 +43,47 @@ var ls_pred = false;
4343
4444var plot = null ;
4545var plot_open = false ;
46+ var plot_holder = "#telemetry_graph .holder" ;
47+ var plot_options = {
48+ crosshair : {
49+ mode : "x"
50+ } ,
51+ legend : {
52+ show : true ,
53+ sorted : false ,
54+ position : 'nw' ,
55+ noColumns : 1 ,
56+ backgroundColor : null ,
57+ backgroundOpacity : 0
58+ } ,
59+ grid : {
60+ show : true ,
61+ hoverable : true ,
62+ aboveData : true ,
63+ borderWidth : 0 ,
64+ } ,
65+ selection : {
66+ mode : "x"
67+ } ,
68+ yaxes : [
69+ { show : false , min : 0 } ,
70+ { show : false , min : 0 } ,
71+ { show : false , min : 0 } ,
72+ { show : false , min : 0 } ,
73+ { show : false , min : 0 } ,
74+ { show : false , min : 0 } ,
75+ { show : false , min : 0 } ,
76+ { show : false , min : 0 } ,
77+ { show : false , min : 0 } ,
78+ ] ,
79+ xaxes : [
80+ {
81+ show : true ,
82+ mode : "time" ,
83+ timeformat : "%m/%d %H:%M"
84+ }
85+ ]
86+ } ;
4687
4788// weather
4889var weatherOverlayId = "nexrad-n0q-900913" ;
@@ -707,7 +748,7 @@ function updateVehicleInfo(index, newPosition) {
707748 // redraw canvas
708749 if ( ! embed . latestonly ) {
709750 var c = $ ( '.vehicle' + index + ' .graph' ) ;
710- drawAltitudeProfile ( c . get ( 0 ) , c . get ( 1 ) , vehicles [ index ] . alt_list , vehicles [ index ] . alt_max ) ;
751+ drawAltitudeProfile ( c . get ( 0 ) , c . get ( 1 ) , vehicles [ index ] . graph_data [ 0 ] , vehicles [ index ] . max_alt ) ;
711752 }
712753
713754 // mark vehicles as redrawn
@@ -832,8 +873,11 @@ function updatePolyline(vehicle_index) {
832873 }
833874}
834875
835- function drawAltitudeProfile ( c1 , c2 , alt_list , alt_max ) {
876+ function drawAltitudeProfile ( c1 , c2 , series , alt_max ) {
836877 alt_max = ( alt_max < 2000 ) ? 2000 : alt_max ;
878+ var alt_list = series . data ;
879+ var len = alt_list . length ;
880+ var real_len = len - series . nulls ;
837881
838882 var ctx1 = c1 . getContext ( "2d" ) ;
839883 var ctx2 = c2 . getContext ( "2d" ) ;
@@ -842,7 +886,7 @@ function drawAltitudeProfile(c1, c2, alt_list, alt_max) {
842886 c2 = $ ( c2 ) ;
843887
844888 var ratio = window . devicePixelRatio ;
845- var cw1 = 150 * ratio ;
889+ var cw1 = 180 * ratio ;
846890 var ch1 = 40 * ratio ;
847891 var cw2 = 60 * ratio ;
848892 var ch2 = 40 * ratio ;
@@ -857,9 +901,9 @@ function drawAltitudeProfile(c1, c2, alt_list, alt_max) {
857901 ctx2 . lineWidth = 2 * ratio ;
858902 ctx2 . strokeStyle = "#33B5F5" ;
859903
860- var xt1 = ( cw1 - ( 2 * ratio ) ) / alt_list . length ;
904+ var xt1 = ( cw1 - ( 2 * ratio ) ) / real_len ;
861905 var yt1 = ( ch1 - ( 6 * ratio ) ) / alt_max ;
862- var xt2 = ( cw2 - ( 2 * ratio ) ) / alt_list . length ;
906+ var xt2 = ( cw2 - ( 2 * ratio ) ) / real_len ;
863907 var yt2 = ( ch2 - ( 6 * ratio ) ) / alt_max ;
864908
865909 xt1 = ( xt1 > 1 ) ? 1 : xt1 ;
@@ -868,21 +912,54 @@ function drawAltitudeProfile(c1, c2, alt_list, alt_max) {
868912 yt2 = ( yt2 > 1 ) ? 1 : yt2 ;
869913
870914 ctx1 . beginPath ( ) ;
871- ctx1 . moveTo ( 0 , c1 . height ) ;
872915 ctx2 . beginPath ( ) ;
873- ctx2 . moveTo ( 0 , c2 . height ) ;
916+
917+ // start line at the ground, depending in the first altitude datum
918+ if ( alt_list [ 0 ] [ 1 ] < 2000 ) {
919+ ctx1 . lineTo ( 0 , ch1 ) ;
920+ ctx2 . lineTo ( 0 , ch2 ) ;
921+ }
922+
874923
875924 var i ;
876- for ( i = 0 ; i < alt_list . length ; i ++ ) {
877- ctx1 . lineTo ( 1 + ( ( i + 1 ) * xt1 ) , ch1 - ( alt_list [ i ] * yt1 ) ) ;
878- ctx2 . lineTo ( 1 + ( ( i + 1 ) * xt2 ) , ch2 - ( alt_list [ i ] * yt2 ) ) ;
925+ // draw all altitude points, if they are not too many
926+ if ( cw1 * 2 > real_len ) {
927+ for ( i = 0 ; i < real_len ; i ++ ) {
928+ var alt = alt_list [ i ] [ 1 ] ;
929+
930+ ctx1 . lineTo ( 1 + ( ( i + 1 ) * xt1 ) , ch1 - ( alt * yt1 ) ) ;
931+ ctx2 . lineTo ( 1 + ( ( i + 1 ) * xt2 ) , ch2 - ( alt * yt2 ) ) ;
932+
933+ if ( i + 2 < len && alt_list [ i + 2 ] [ 1 ] == null ) i += 2 ;
934+ }
935+ }
936+ // if they are too many, downsample to keep the loop short
937+ else {
938+ xt1 = 0.5 ;
939+ xt2 = 0.16666666666 ;
940+ var max = cw1 * 2 ;
941+ var step = ( 1.0 * len ) / max ;
942+
943+ for ( i = 0 ; i < max ; i ++ ) {
944+ var alt = alt_list [ Math . floor ( i * step ) ] [ 1 ] ;
945+ if ( alt == null ) continue ;
946+
947+ ctx1 . lineTo ( 1 + ( ( i + 1 ) * xt1 ) , ch1 - ( alt * yt1 ) ) ;
948+ ctx2 . lineTo ( 1 + ( ( i + 1 ) * xt2 ) , ch2 - ( alt * yt2 ) ) ;
949+ }
950+
951+ // fix index for fill
952+ i = len - 1 ;
879953 }
880954
881955 ctx1 . stroke ( ) ;
882956 ctx2 . stroke ( ) ;
883957
958+ // close the path, so it can be filled
884959 ctx1 . lineTo ( 1 + ( ( i + 1 ) * xt1 ) , ch1 ) ;
885960 ctx2 . lineTo ( 1 + ( ( i + 1 ) * xt2 ) , ch2 ) ;
961+ ctx1 . lineTo ( 0 , ch1 ) ;
962+ ctx2 . lineTo ( 0 , ch2 ) ;
886963
887964 ctx1 . closePath ( ) ;
888965 ctx2 . closePath ( ) ;
@@ -1102,9 +1179,6 @@ function addPosition(position) {
11021179 color_index : c ,
11031180 prediction_traget : null ,
11041181 prediction_burst : null ,
1105- alt_list : [ 0 ] ,
1106- time_last_alt : 0 ,
1107- alt_max : 100 ,
11081182 graph_data_updated : false ,
11091183 graph_data_map : { } ,
11101184 graph_data : [ ] ,
@@ -1114,7 +1188,7 @@ function addPosition(position) {
11141188 } ;
11151189
11161190 // deep copy yaxes config for graph
1117- if ( plot ) $ . each ( $ . extend ( false , plot_options . yaxes , { } ) , function ( k , v ) { vehicle_info . graph_yaxes . push ( v ) } ) ;
1191+ $ . each ( $ . extend ( false , plot_options . yaxes , { } ) , function ( k , v ) { vehicle_info . graph_yaxes . push ( v ) } ) ;
11181192
11191193 // nyan mod
11201194 if ( nyan_mode && vehicle_info . vehicle_type == "balloon" ) {
@@ -1199,20 +1273,11 @@ function addPosition(position) {
11991273 new google . maps . LatLng ( vehicle . curr_position . gps_lat , vehicle . curr_position . gps_lon ) ) / dt ;
12001274 }
12011275
1202- // record altitude values for the drowing a mini profile
1203- // only record altitude values in 2minute interval
1204- if ( ! embed . lastestonly && curr_ts - vehicle . time_last_alt >= 120000 ) { // 120s = 2minutes
1205- vehicle . time_last_alt = curr_ts ;
1206- var alt = parseInt ( vehicle . curr_position . gps_alt ) ;
1207-
1208- if ( alt > vehicle . alt_max ) vehicle . alt_max = alt ; // larged value in the set is required for encoding later
1209-
1210- vehicle . alt_list . push ( alt ) ; // push value to the list
1211- }
1212-
12131276 // add the new position
12141277 if ( embed . latestonly ) {
12151278 vehicle . num_positions = 1 ;
1279+ vehicle . positions . push ( new_latlng ) ;
1280+ vehicle . positions_ts . push ( new_ts ) ;
12161281 } else {
12171282 vehicle . positions . push ( new_latlng ) ;
12181283 vehicle . positions_ts . push ( new_ts ) ;
@@ -1228,10 +1293,6 @@ function addPosition(position) {
12281293
12291294 }
12301295 else if ( vehicle . positions_ts . indexOf ( new_ts ) == - 1 ) { // backlog packets, need to splice them into the array
1231- // TODO:
1232- // 1. altitude profile, will bug out if packets are in reverse order for example, fix or redo it
1233- // 2. check TODO on graphAddPosition()
1234-
12351296 // find out the index at which we should insert the new point
12361297 var xref = vehicle . positions_ts ;
12371298 var idx = - 1 , len = xref . length ;
@@ -1301,7 +1362,6 @@ function updateGraph(idx, reset_selection) {
13011362}
13021363
13031364function graphAddPosition ( idx , new_data ) {
1304- if ( ! plot ) return ;
13051365
13061366 var vehicle = vehicles [ idx ] ;
13071367 vehicle . graph_data_updated = true ;
@@ -1412,6 +1472,10 @@ function graphAddPosition(idx, new_data) {
14121472
14131473 if ( parseInt ( new_data . gps_alt ) < 0 ) delete vehicle . graph_yaxes [ i ] . min ;
14141474
1475+ // we don't record extra data, if there is no telemetry graph loaded
1476+ // altitude is used for altitude profile
1477+ if ( ! plot ) return ;
1478+
14151479 // the rest of the series is from the data field
14161480 var json = $ . parseJSON ( new_data . data ) ;
14171481 if ( ! json ) return ;
0 commit comments