@@ -74,13 +74,9 @@ static int signal_read_fd, signal_write_fd;
7474static cchar_t plotchar , max_errchar , min_errchar ;
7575static struct timeval now ;
7676static double td ;
77- static struct tm * lt ;
78- static double max = FLT_MIN ;
79- static double softmax = FLT_MIN , hardmax = FLT_MAX , hardmin = 0.0 ;
77+ static double softmax = 0.0 , hardmax = FLT_MAX , softmin = 0.0 , hardmin = - FLT_MAX ;
8078static char title [256 ] = ".: ttyplot :." , unit [64 ] = {0 }, ls [256 ] = {0 };
8179static double values1 [1024 ] = {0 }, values2 [1024 ] = {0 };
82- static double min1 = FLT_MAX , max1 = FLT_MIN , avg1 = 0 ;
83- static double min2 = FLT_MAX , max2 = FLT_MIN , avg2 = 0 ;
8480static int width = 0 , height = 0 , n = -1 , v = 0 , c = 0 , rate = 0 , two = 0 ,
8581 plotwidth = 0 , plotheight = 0 ;
8682static bool fake_clock = false;
@@ -102,7 +98,8 @@ static void usage(void) {
10298 " -e character to use for error line when value exceeds hardmax (default: e)\n"
10399 " -E character to use for error symbol displayed when value is less than "
104100 "hardmin (default: v)\n"
105- " -s initial scale of the plot (can go above if data input has larger value)\n"
101+ " -s initial maximum value (can go above if data input has larger value)\n"
102+ " -S initial minimum value (can go below if data input has smaller value)\n"
106103 " -m maximum value, if exceeded draws error line (see -e), upper-limit of "
107104 "plot scale is fixed\n"
108105 " -M minimum value, if entered less than this, draws error symbol (see -E), "
@@ -155,8 +152,7 @@ static void getminmax(int pw, double *values, double *min, double *max, double *
155152 int i = 0 ;
156153
157154 * min = FLT_MAX ;
158- * max = FLT_MIN ;
159- tot = FLT_MIN ;
155+ * max = - FLT_MAX ;
160156
161157 for (i = 0 ; i < pw && i < v ; i ++ ) {
162158 if (values [i ] > * max )
@@ -203,27 +199,43 @@ static void draw_line(int x, int ph, int l1, int l2, cchar_t *c1, cchar_t *c2,
203199}
204200
205201static void plot_values (int ph , int pw , double * v1 , double * v2 , double max , double min ,
206- int n , cchar_t * pc , cchar_t * hce , cchar_t * lce , double hm ) {
202+ int n , cchar_t * pc , cchar_t * hce , cchar_t * lce , double hardmax ,
203+ double hardmin ) {
207204 const int first_col = 3 ;
208205 int i = (n + 1 ) % pw ;
209206 int x ;
210- max -= min ;
211-
212- for (x = first_col ; x < first_col + pw ; x ++ , i = (i + 1 ) % pw )
213- draw_line (x , ph ,
214- (v1 [i ] > hm ) ? ph
215- : (v1 [i ] < min ) ? 1
216- : (int )(((v1 [i ] - min ) / max ) * (double )ph ),
217- (v2 [i ] > hm ) ? ph
218- : (v2 [i ] < min ) ? 1
219- : (int )(((v2 [i ] - min ) / max ) * (double )ph ),
220- (v1 [i ] > hm ) ? hce
221- : (v1 [i ] < min ) ? lce
222- : pc ,
223- (v2 [i ] > hm ) ? hce
224- : (v2 [i ] < min ) ? lce
225- : pc ,
207+ int l1 , l2 ;
208+
209+ for (x = first_col ; x < first_col + pw ; x ++ , i = (i + 1 ) % pw ) {
210+ /* suppress drawing uninitialized entries */
211+ if (! v1 || isnan (v1 [i ]))
212+ continue ;
213+
214+ if (v1 [i ] > hardmax )
215+ l1 = ph ;
216+ else if (v1 [i ] < hardmin )
217+ l1 = 1 ;
218+ else
219+ l1 = lrint ((v1 [i ] - min ) / (max - min ) * ph );
220+
221+ if (! v2 || isnan (v2 [i ]))
222+ l2 = 0 ;
223+ else if (v2 [i ] > hardmax )
224+ l2 = ph ;
225+ else if (v2 [i ] < hardmin )
226+ l2 = 1 ;
227+ else
228+ l2 = lrint ((v2 [i ] - min ) / (max - min ) * ph );
229+
230+ draw_line (x , ph , l1 , l2 ,
231+ (v1 [i ] > hardmax ) ? hce
232+ : (v1 [i ] < hardmin ) ? lce
233+ : pc ,
234+ (v2 && v2 [i ] > hardmax ) ? hce
235+ : (v2 && v2 [i ] < hardmin ) ? lce
236+ : pc ,
226237 hce , lce );
238+ }
227239}
228240
229241static void show_all_centered (const char * message ) {
@@ -242,6 +254,10 @@ static void show_window_size_error(void) {
242254}
243255
244256static void paint_plot (void ) {
257+ double min , max ;
258+ double min1 = FLT_MAX , max1 = - FLT_MAX , avg1 = 0 ;
259+ double min2 = FLT_MAX , max2 = - FLT_MAX , avg2 = 0 ;
260+ struct tm * lt ;
245261 erase ();
246262 getmaxyx (stdscr , height , width );
247263
@@ -253,16 +269,18 @@ static void paint_plot(void) {
253269 getminmax (plotwidth , values1 , & min1 , & max1 , & avg1 , v );
254270 getminmax (plotwidth , values2 , & min2 , & max2 , & avg2 , v );
255271
256- if (max1 > max2 )
257- max = max1 ;
258- else
259- max = max2 ;
260-
272+ max = max1 > max2 ? max1 : max2 ;
261273 if (max < softmax )
262274 max = softmax ;
263275 if (hardmax != FLT_MAX )
264276 max = hardmax ;
265277
278+ min = min1 < min2 ? min1 : min2 ;
279+ if (min > softmin )
280+ min = softmin ;
281+ if (hardmin != - FLT_MAX )
282+ min = hardmin ;
283+
266284 mvaddstr (height - 1 , width - strlen (verstring ) - 1 , verstring );
267285
268286 const char * clock_display ;
@@ -290,10 +308,10 @@ static void paint_plot(void) {
290308 }
291309 }
292310
293- plot_values (plotheight , plotwidth , values1 , values2 , max , hardmin , n , & plotchar ,
294- & max_errchar , & min_errchar , hardmax );
311+ plot_values (plotheight , plotwidth , values1 , two ? values2 : NULL , max , min , n ,
312+ & plotchar , & max_errchar , & min_errchar , hardmax , hardmin );
295313
296- draw_axes (height , plotheight , plotwidth , max , hardmin , unit );
314+ draw_axes (height , plotheight , plotwidth , max , min , unit );
297315
298316 mvaddstr (0 , (width / 2 ) - (strlen (title ) / 2 ), title );
299317
@@ -528,10 +546,17 @@ int main(int argc, char *argv[]) {
528546 int i ;
529547 bool stdin_is_open = true;
530548 int cached_opterr ;
531- const char * optstring = "2rc:e:E:s:m:M:t:u:vh" ;
549+ const char * optstring = "2rc:e:E:s:S: m:M:t:u:vh" ;
532550 int show_ver ;
533551 int show_usage ;
534552
553+ // Initialize values to NAN, rather than 0, so that we know when not to
554+ // draw them
555+ for (i = 0 ; i < (int )(sizeof (values1 ) / sizeof (* values1 )); i ++ ) {
556+ values1 [i ] = NAN ;
557+ values2 [i ] = NAN ;
558+ }
559+
535560 // To make UI testing more robust, we display a clock that is frozen at
536561 // "Thu Jan 1 00:00:03 1970" when variable FAKETIME is set
537562 fake_clock = (getenv ("FAKETIME" ) != NULL );
@@ -606,15 +631,14 @@ int main(int argc, char *argv[]) {
606631 case 's' :
607632 softmax = atof (optarg );
608633 break ;
634+ case 'S' :
635+ softmin = atof (optarg );
636+ break ;
609637 case 'm' :
610638 hardmax = atof (optarg );
611639 break ;
612640 case 'M' :
613641 hardmin = atof (optarg );
614- for (i = 0 ; i < 1024 ; i ++ ) {
615- values1 [i ] = hardmin ;
616- values2 [i ] = hardmin ;
617- }
618642 break ;
619643 case 't' :
620644 snprintf (title , sizeof (title ), "%s" , optarg );
0 commit comments