diff --git a/ttyplot.c b/ttyplot.c index fec54ac..e2a062e 100644 --- a/ttyplot.c +++ b/ttyplot.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -46,14 +47,13 @@ sigset_t sigmsk; chtype plotchar, max_errchar, min_errchar; -time_t t1,t2,td; +struct timeval now; +double td; struct tm *lt; double max=FLT_MIN; double softmax=FLT_MIN, hardmax=FLT_MAX, hardmin=0.0; char title[256]=".: ttyplot :.", unit[64]={0}, ls[256]={0}; double values1[1024]={0}, values2[1024]={0}; -double cval1=FLT_MAX, pval1=FLT_MAX; -double cval2=FLT_MAX, pval2=FLT_MAX; double min1=FLT_MAX, max1=FLT_MIN, avg1=0; double min2=FLT_MAX, max2=FLT_MIN, avg2=0; int width=0, height=0, n=0, r=0, v=0, c=0, rate=0, two=0, plotwidth=0, plotheight=0; @@ -79,6 +79,35 @@ void version(void) { printf("ttyplot %s\n", VERSION_STR); } +// Replace *x and *y (if non-NULL) by their time derivatives. +// - x, y: addresses of input data and storage for results +// - now: current time +// Return time since previous call. +double derivative(double *x, double *y, const struct timeval *now) +{ + static double previous_x, previous_y, previous_t = DBL_MAX; + double t = now->tv_sec + 1e-6 * now->tv_usec; + double dt = t - previous_t; + previous_t = t; + if (x) { + double dx = *x - previous_x; + previous_x = *x; + if (dt <= 0) + *x = 0; + else + *x = dx / dt; + } + if (y) { + double dy = *y - previous_y; + previous_y = *y; + if (dt <= 0) + *y = 0; + else + *y = dy / dt; + } + return dt; +} + void getminmax(int pw, double *values, double *min, double *max, double *avg, int v) { double tot=0; int i=0; @@ -202,14 +231,14 @@ void paint_plot(void) { mvaddstr(height-1, width-strlen(verstring)-1, verstring); - lt=localtime(&t1); + lt=localtime(&now.tv_sec); asctime_r(lt, ls); mvaddstr(height-2, width-strlen(ls), ls); mvvline(height-2, 5, plotchar|A_NORMAL, 1); mvprintw(height-2, 7, "last=%.1f min=%.1f max=%.1f avg=%.1f %s ", values1[n], min1, max1, avg1, unit); if(rate) - printw(" interval=%llds", (long long int)td); + printw(" interval=%.3gs", td); if(two) { mvaddch(height-1, 5, ' '|A_REVERSE); @@ -357,7 +386,7 @@ int main(int argc, char *argv[]) { err(1, "pledge"); #endif - time(&t1); + gettimeofday(&now, NULL); noecho(); curs_set(FALSE); erase(); @@ -410,39 +439,9 @@ int main(int argc, char *argv[]) { if(values2[n] < 0) values2[n] = 0; - if(rate) { - t2=t1; - time(&t1); - td=t1-t2; - if(td==0) - td=1; - - if(cval1==FLT_MAX) - pval1=values1[n]; - else - pval1=cval1; - cval1=values1[n]; - - values1[n]=(cval1-pval1)/td; - - if(values1[n] < 0) // counter rewind - values1[n]=0; - - if(two) { - if(cval2==FLT_MAX) - pval2=values2[n]; - else - pval2=cval2; - cval2=values2[n]; - - values2[n]=(cval2-pval2)/td; - - if(values2[n] < 0) // counter rewind - values2[n]=0; - } - } else { - time(&t1); - } + gettimeofday(&now, NULL); + if (rate) + td=derivative(&values1[n], two ? &values2[n] : NULL, &now); paint_plot();