Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support plotting with multibyte characters #99

Merged
merged 4 commits into from
Nov 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ DESTDIR ?=
PREFIX ?= /usr/local
MANPREFIX ?= $(PREFIX)/man
CFLAGS += -Wall -Wextra
LDLIBS += `pkg-config --libs ncurses`
CFLAGS += `pkg-config --cflags ncursesw`
LDLIBS += `pkg-config --libs ncursesw`
torture: LDLIBS = -lm

all: ttyplot
Expand Down
57 changes: 36 additions & 21 deletions ttyplot.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@
// Apache License 2.0
//

// This is needed on macOS to get the ncurses widechar API, and pkg-config fails to define it.
#ifdef __APPLE__
#define _XOPEN_SOURCE_EXTENDED
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <float.h>
#include <time.h>
#include <locale.h>
#include <ncurses.h>
#include <signal.h>
#include <errno.h>
Expand All @@ -30,22 +36,20 @@
#define VERSION_STR STR(VERSION_MAJOR) "." STR(VERSION_MINOR) "." STR(VERSION_PATCH)
#endif

#define T_RARR '>'
#define T_UARR '^'
#ifdef NOACS
#define T_HLINE '-'
#define T_VLINE '|'
#define T_RARR '>'
#define T_UARR '^'
#define T_LLCR 'L'
#else
#define T_HLINE ACS_HLINE
#define T_VLINE ACS_VLINE
#define T_RARR ACS_RARROW
#define T_UARR ACS_UARROW
#define T_LLCR ACS_LLCORNER
#endif

sigset_t sigmsk;
chtype plotchar, max_errchar, min_errchar;
cchar_t plotchar, max_errchar, min_errchar;
time_t t1,t2,td;
struct tm *lt;
double max=FLT_MIN;
Expand Down Expand Up @@ -121,19 +125,26 @@ void draw_axes(int h, int ph, int pw, double max, double min, char *unit) {
mvaddch(h-3, 2, T_LLCR);
}

void draw_line(int x, int ph, int l1, int l2, chtype c1, chtype c2, chtype hce, chtype lce) {
void draw_line(int x, int ph, int l1, int l2, cchar_t *c1, cchar_t *c2, cchar_t *hce, cchar_t *lce) {
static cchar_t space = {
.attr = A_REVERSE,
.chars = {' ', '\0'}
};
cchar_t c1r = *c1, c2r = *c2;
c1r.attr |= A_REVERSE;
c2r.attr |= A_REVERSE;
if(l1 > l2) {
mvvline(ph+1-l1, x, c1, l1-l2 );
mvvline(ph+1-l2, x, c2|A_REVERSE, l2 );
mvvline_set(ph+1-l1, x, c1, l1-l2 );
mvvline_set(ph+1-l2, x, &c2r, l2 );
} else if(l1 < l2) {
mvvline(ph+1-l2, x, (c2==hce || c2==lce) ? c2|A_REVERSE : ' '|A_REVERSE, l2-l1 );
mvvline(ph+1-l1, x, c1|A_REVERSE, l1 );
mvvline_set(ph+1-l2, x, (c2==hce || c2==lce) ? &c2r : &space, l2-l1 );
mvvline_set(ph+1-l1, x, &c2r, l1 );
} else {
mvvline(ph+1-l2, x, c2|A_REVERSE, l2 );
mvvline_set(ph+1-l2, x, &c2r, l2 );
}
}

void plot_values(int ph, int pw, double *v1, double *v2, double max, double min, int n, chtype pc, chtype hce, chtype lce, double hm) {
void plot_values(int ph, int pw, double *v1, double *v2, double max, double min, int n, cchar_t *pc, cchar_t *hce, cchar_t *lce, double hm) {
const int first_col=3;
int i=(n+1)%pw;
int x;
Expand Down Expand Up @@ -199,7 +210,7 @@ void paint_plot(void) {
asctime_r(lt, ls);
mvaddstr(height-2, width-strlen(ls), ls);

mvvline(height-2, 5, plotchar|A_NORMAL, 1);
mvvline_set(height-2, 5, &plotchar, 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);
Expand All @@ -209,7 +220,7 @@ void paint_plot(void) {
mvprintw(height-1, 7, "last=%.1f min=%.1f max=%.1f avg=%.1f %s ", values2[n], min2, max2, avg2, unit);
}

plot_values(plotheight, plotwidth, values1, values2, max, hardmin, n, plotchar, max_errchar, min_errchar, hardmax);
plot_values(plotheight, plotwidth, values1, values2, max, hardmin, n, &plotchar, &max_errchar, &min_errchar, hardmax);

draw_axes(height, plotheight, plotwidth, max, hardmin, unit);

Expand Down Expand Up @@ -251,9 +262,13 @@ int main(int argc, char *argv[]) {
int show_ver;
int show_usage;

plotchar=T_VLINE;
max_errchar='e';
min_errchar='v';
setlocale(LC_ALL, "");
if (MB_CUR_MAX > 1) // if non-ASCII characters are supprted:
plotchar.chars[0]=0x2502; // U+2502 box drawings light vertical
else
plotchar.chars[0]='|'; // U+007C vertical line
max_errchar.chars[0]='e';
min_errchar.chars[0]='v';
edgar-bonet marked this conversation as resolved.
Show resolved Hide resolved

cached_opterr = opterr;
opterr=0;
Expand Down Expand Up @@ -303,16 +318,16 @@ int main(int argc, char *argv[]) {
break;
case '2':
two=1;
plotchar='|';
plotchar.chars[0]='|';
break;
case 'c':
plotchar=optarg[0];
mbtowc(&plotchar.chars[0], optarg, MB_CUR_MAX);
break;
case 'e':
max_errchar=optarg[0];
mbtowc(&max_errchar.chars[0], optarg, MB_CUR_MAX);
break;
case 'E':
min_errchar=optarg[0];
mbtowc(&min_errchar.chars[0], optarg, MB_CUR_MAX);
break;
case 's':
softmax=atof(optarg);
Expand Down