diff --git a/doc/man/man3/notcurses_plot.3.md b/doc/man/man3/notcurses_plot.3.md index 92c733589..4563a3153 100644 --- a/doc/man/man3/notcurses_plot.3.md +++ b/doc/man/man3/notcurses_plot.3.md @@ -22,10 +22,11 @@ typedef struct ncplot_options { ncgridgeom_e gridtype; // independent variable is a contiguous range uint64_t rangex; - // y axis min and max. set both equal to 0 - // for autodiscovery of range. + // y axis min and max. set both equal to 0 for + // use with range autodiscovery. int64_t miny, maxy; bool exponentialy; // is y-axis exponential? + bool discoverrange; } ncplot_options; ``` @@ -44,6 +45,10 @@ typedef struct ncplot_options { # RETURN VALUES +**ncplot_create** will return an error if **discoverrange** is set, and either +**miny** or **maxy** are non-zero. It will also return an error if +**maxy** < **miny**. + **ncplot_plane** returns the **ncplane** on which the plot is drawn. It cannot fail. diff --git a/include/notcurses/notcurses.h b/include/notcurses/notcurses.h index ee7a1ea8d..0450f1c55 100644 --- a/include/notcurses/notcurses.h +++ b/include/notcurses/notcurses.h @@ -2531,10 +2531,11 @@ typedef struct ncplot_options { // of keys. for a time range, say the previous hour sampled with second // resolution, the independent variable would be the range [0..3600): 3600. uint64_t rangex; - // y axis min and max. set the two equal (to any stand-in value; 0 is - // recommended) for autodiscovery of range. + // y axis min and max. for autodiscovery, these both must be equal to 0, + // and detectrange must be additionally be set. int64_t miny, maxy; bool exponentialy; // is y-axis exponential? + bool detectrange; // if set, miny must == maxy } ncplot_options; // Use the provided plane 'n' for plotting according to the options 'opts'. diff --git a/python/src/notcurses/build_notcurses.py b/python/src/notcurses/build_notcurses.py index 31c84d90d..325f95fe3 100644 --- a/python/src/notcurses/build_notcurses.py +++ b/python/src/notcurses/build_notcurses.py @@ -418,6 +418,7 @@ typedef struct ncplot_options { uint64_t rangex; int64_t miny, maxy; bool exponentialy; + bool detectrange; } ncplot_options; struct ncplot* ncplot_create(struct ncplane* n, const ncplot_options* opts); struct ncplane* ncplot_plane(struct ncplot* n); diff --git a/src/lib/internal.h b/src/lib/internal.h index 621656ed3..ad0c4b82b 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -155,9 +155,11 @@ typedef struct ncplot { uint64_t minchannel; bool vertical_indep; ncgridgeom_e gridtype; - uint64_t rangex; + int64_t windowbase; // first valid x value + uint64_t rangex; // windowbase + rangex - 1 -> last valid x int64_t miny, maxy; bool exponentialy; + bool detectrange; } ncplot; typedef struct ncmenu { diff --git a/src/lib/plot.c b/src/lib/plot.c index 4e454d681..fe516cc6b 100644 --- a/src/lib/plot.c +++ b/src/lib/plot.c @@ -1,6 +1,13 @@ #include "internal.h" ncplot* ncplot_create(ncplane* n, const ncplot_options* opts){ + // detectrange requires that miny == maxy + if(opts->detectrange && opts->miny != opts->maxy){ + return NULL; + } + if(opts->maxy < opts->miny){ + return NULL; + } ncplot* ret = malloc(sizeof(*ret)); if(ret){ ret->ncp = n; @@ -12,6 +19,8 @@ ncplot* ncplot_create(ncplane* n, const ncplot_options* opts){ ret->vertical_indep = opts->vertical_indep; ret->gridtype = opts->gridtype; ret->exponentialy = opts->exponentialy; + ret->windowbase = 0; + ret->detectrange = opts->detectrange; } return ret; } @@ -20,14 +29,30 @@ ncplane* ncplot_plane(ncplot* n){ return n->ncp; } +static inline bool +invalid_y(ncplot* n, int64_t y){ + if(y > n->maxy || y < n->miny){ + return true; + } + return false; +} + // Add to or set the value corresponding to this x. If x is beyond the current // x window, the x window is advanced to include x, and values passing beyond // the window are lost. The first call will place the initial window. The plot // will be redrawn, but notcurses_render() is not called. -int ncplot_add_sample(struct ncplot* n, uint64_t x, int64_t y){ +int ncplot_add_sample(ncplot* n, uint64_t x, int64_t y){ + if(invalid_y(n, y)){ + return -1; + } + return 0; } -int ncplot_set_sample(struct ncplot* n, uint64_t x, int64_t y){ +int ncplot_set_sample(ncplot* n, uint64_t x, int64_t y){ + if(invalid_y(n, y)){ + return -1; + } + return 0; } void ncplot_destroy(ncplot* n){