Back to index

plt-scheme  4.2.1
plstripc.c
Go to the documentation of this file.
00001 /* $Id: plstripc.c,v 1.1 2004/03/01 20:54:53 cozmic Exp $
00002 
00003  * Plots a simple stripchart.
00004 
00005  * ToDo: better way of clearing plot. search for `plvsta'.
00006  */
00007 
00008 #include "plplotP.h"
00009 
00010 /* Data declarations for stripcharts. */
00011 
00012 #define PEN   4
00013 
00014 typedef struct {
00015     PLFLT xmin, xmax, ymin, ymax, xjump, xlen;
00016     PLFLT wxmin, wxmax, wymin, wymax;     /* FIXME - some redundancy might exist */
00017     char *xspec, *yspec, *labx, *laby, *labtop;
00018     PLINT y_ascl, acc, colbox, collab;
00019     PLFLT xlpos, ylpos;
00020     PLFLT *x[PEN], *y[PEN];
00021     PLINT npts[PEN], nptsmax[PEN];
00022     PLINT colline[PEN], styline[PEN];
00023     char *legline[PEN];
00024 } PLStrip;
00025 
00026 static int sid;                           /* strip id number */
00027 #define MAX_STRIPC 1000                   /* Max allowed */
00028 static PLStrip *strip[MAX_STRIPC]; /* Array of pointers */
00029 static PLStrip *stripc;                   /* current strip chart */
00030 
00031 /* Generates a complete stripchart plot.  */
00032 
00033 static void
00034 plstrip_gen(PLStrip *strip);
00035 
00036 /* draw legend */
00037 
00038 static void
00039 plstrip_legend(PLStrip *strip, int flag);
00040 
00041 /*--------------------------------------------------------------------------*\
00042  * plstripc
00043  *
00044  * Create 1d stripchart.
00045 \*--------------------------------------------------------------------------*/
00046 
00047 void
00048 c_plstripc( PLINT *id, char *xspec, char *yspec,
00049             PLFLT xmin, PLFLT xmax, PLFLT xjump, PLFLT ymin, PLFLT ymax,
00050             PLFLT xlpos, PLFLT ylpos,
00051             PLINT y_ascl, PLINT acc,
00052             PLINT colbox,  PLINT collab,
00053             PLINT *colline,  PLINT *styline, char *legline[],
00054             char *labx, char *laby, char *labtop )
00055 {
00056     int i;
00057 
00058     if (!plsc->termin) {
00059        plabort("Stripchart plot requires a terminal output device");
00060        return;
00061     }
00062 
00063 /* Get a free strip id and allocate it */
00064 
00065     for (i = 0; i < MAX_STRIPC; i++)
00066        if (strip[i] == NULL)
00067            break;
00068 
00069     if (i == MAX_STRIPC) {
00070        plabort("plstripc: Cannot create new strip chart");
00071        *id = -1;
00072        return;
00073     }
00074     else {
00075        sid = *id = i;
00076        strip[sid] = (PLStrip *) calloc(1, (size_t) sizeof(PLStrip));
00077        if (strip[sid] == NULL) {
00078            plabort("plstripc: Out of memory.");
00079            *id = -1;
00080            return;
00081        }
00082     }
00083 
00084 /* Fill up the struct with all relevant info */
00085 
00086     stripc = strip[sid];
00087 
00088     for (i=0; i<PEN; i++) {
00089        stripc->npts[i] =  0;
00090        stripc->nptsmax[i] =  100;
00091        stripc->colline[i] = colline[i];
00092        stripc->styline[i] = styline[i];
00093        stripc->legline[i] = plstrdup(legline[i]);
00094        stripc->x[i] = (PLFLT *) malloc((size_t) sizeof(PLFLT) * stripc->nptsmax[i]);;
00095        stripc->y[i] = (PLFLT *) malloc((size_t) sizeof(PLFLT) * stripc->nptsmax[i]);;
00096        if (stripc->x[i] == NULL || stripc->y[i] == NULL) {
00097            plabort("plstripc: Out of memory.");
00098            plstripd(sid);
00099            *id = -1;
00100            return;
00101        }
00102     }
00103 
00104     stripc->xlpos = xlpos;  /* legend position [0..1] */
00105     stripc->ylpos = ylpos;  
00106     stripc->xmin = xmin;    /* initial bounding box */
00107     stripc->xmax = xmax;
00108     stripc->ymin = ymin;
00109     stripc->ymax = ymax;
00110     stripc->xjump = xjump;  /* jump x step(%) when x attains xmax (xmax is then set to xmax+xjump) */
00111     stripc->xlen = xmax - xmin;    /* length of x scale */
00112     stripc->y_ascl = y_ascl;       /* autoscale y between x jump scale */
00113     stripc->acc = acc;             /* accumulate plot (not really stripchart) */
00114     stripc->xspec = plstrdup(xspec); /* x axis specification */
00115     stripc->yspec = plstrdup(yspec);
00116     stripc->labx = plstrdup(labx); /* x label */
00117     stripc->laby = plstrdup(laby);
00118     stripc->labtop = plstrdup(labtop); /* title */
00119     stripc->colbox = colbox;       /* box color */
00120     stripc->collab = collab;       /* label color */
00121 
00122 /* Generate the plot */
00123 
00124     plstrip_gen(stripc);
00125     plstrip_legend(stripc,1);
00126 }
00127 
00128 static void plstrip_legend(PLStrip *stripc, int first)
00129 {
00130     int i;
00131     PLFLT sc, dy;
00132 
00133 /* draw legend */
00134        
00135     plgchr(&sc, &dy);
00136     sc = dy = dy/100;
00137     plwind(-0.01, 1.01, -0.01, 1.01);
00138     for (i=0; i<PEN; i++) {
00139        if (stripc->npts[i] || first) {
00140            plcol(stripc->colline[i]); pllsty(stripc->styline[i]);
00141            pljoin(stripc->xlpos, stripc->ylpos - sc, stripc->xlpos + 0.1, stripc->ylpos - sc);
00142            plcol(stripc->collab);
00143            plptex(stripc->xlpos + 0.11, stripc->ylpos - sc, 0., 0., 0, stripc->legline[i]);sc += dy;
00144        }
00145     }
00146     plwind(stripc->xmin, stripc->xmax, stripc->ymin, stripc->ymax);
00147     plflush();
00148 }
00149 
00150 /*--------------------------------------------------------------------------*\
00151  * plstrip_gen
00152  *
00153  * Generates a complete stripchart plot.  Used either initially or
00154  * during rescaling.
00155 \*--------------------------------------------------------------------------*/
00156 
00157 PLFLT oxm,oxM, oym,oyM;
00158 static void plstrip_gen( PLStrip *strip )
00159 {
00160     int i;
00161     PLFLT x[]={0.,1.,1.,0.}, y[]={0.,0.,1.,1.};
00162 
00163 /* Set up window */
00164 
00165     plvpor(0,1,0,1);
00166     plwind(0,1,0,1);
00167     plcol(0);plpsty(0);
00168     plfill(4, &x[0], &y[0]);
00169     plvsta();
00170 
00171 /* Draw box and same window dimensions */
00172     strip->wxmin=strip->xmin; strip->wxmax=strip->xmax;
00173     strip->wymin=strip->ymin; strip->wymax=strip->ymax; /* FIXME - can exist some redundancy here */
00174 
00175     plwind(strip->xmin, strip->xmax, strip->ymin, strip->ymax);
00176     
00177     pllsty(1);
00178     plcol(strip->colbox);
00179     plbox(strip->xspec, 0.0, 0, strip->yspec, 0.0, 0);
00180 
00181     plcol(strip->collab);
00182     pllab(strip->labx, strip->laby, strip->labtop);
00183         
00184     for (i=0; i<PEN; i++) {
00185         if (strip->npts[i] > 0) {
00186             plcol(strip->colline[i]);pllsty(strip->styline[i]);
00187             plline(strip->npts[i], strip->x[i], strip->y[i]);
00188         }
00189     }
00190 
00191     plstrip_legend(strip,0);
00192 }
00193 
00194 /*--------------------------------------------------------------------------*\
00195  * plstripa
00196  *
00197  * Add a point to a stripchart.  
00198  * Allocates memory and rescales as necessary.
00199 \*--------------------------------------------------------------------------*/
00200 
00201 void c_plstripa( PLINT id, PLINT p, PLFLT x, PLFLT y )
00202 {
00203     int j, yasc=0, istart;
00204 
00205     if (p >= PEN) {
00206        plabort("Non existent pen");
00207        return;
00208     }
00209 
00210     if ((id < 0) || (id >= MAX_STRIPC) || 
00211        ((stripc = strip[id]) == NULL)) {
00212        plabort("Non existent stripchart");
00213        return;
00214     }
00215 
00216 /* Add new point, allocating memory if necessary */
00217 
00218     if (++stripc->npts[p] > stripc->nptsmax[p]) {
00219        stripc->nptsmax[p] += 32;
00220        stripc->x[p] = (PLFLT *) realloc((void *) stripc->x[p], sizeof(PLFLT)*stripc->nptsmax[p]);
00221        stripc->y[p] = (PLFLT *) realloc((void *) stripc->y[p], sizeof(PLFLT)*stripc->nptsmax[p]);
00222        if (stripc->x[p] == NULL || stripc->y[p] == NULL) {
00223            plabort("plstripc: Out of memory.");
00224            plstripd(id);
00225            return;
00226        }
00227     }
00228     
00229     stripc->x[p][stripc->npts[p]-1] = x;
00230     stripc->y[p][stripc->npts[p]-1] = y;
00231 
00232     stripc->xmax = x;
00233            
00234     if (stripc->y_ascl == 1 && (y > stripc->ymax || y < stripc->ymin))
00235        yasc=1;
00236 
00237     if (y > stripc->ymax)
00238        stripc->ymax = stripc->ymin + 1.1*(y - stripc->ymin);
00239        if (y < stripc->ymin)
00240          stripc->ymin = stripc->ymax - 1.1*(stripc->ymax - y);
00241 
00242 /* Now either plot new point or regenerate plot */
00243 
00244         if (stripc->xmax - stripc->xmin < stripc->xlen) {
00245             if( yasc == 0) {
00246 
00247             /* If user has changed subwindow, make shure we have the correct one */
00248                 plvsta();
00249                 plwind(stripc->wxmin, stripc->wxmax, stripc->wymin, stripc->wymax); /* FIXME - can exist some redundancy here */
00250               plcol(stripc->colline[p]); pllsty(stripc->styline[p]);
00251               if ((stripc->npts[p]-2) < 0)
00252                 plP_movwor(stripc->x[p][stripc->npts[p]-1], stripc->y[p][stripc->npts[p]-1]);
00253               else
00254                 plP_movwor(stripc->x[p][stripc->npts[p]-2], stripc->y[p][stripc->npts[p]-2]);
00255               plP_drawor(stripc->x[p][stripc->npts[p]-1], stripc->y[p][stripc->npts[p]-1]);
00256               plflush();
00257             }
00258             else {
00259               stripc->xmax = stripc->xmin + stripc->xlen;
00260                 plstrip_gen(stripc);
00261            }
00262        }
00263     else {
00264 /* Regenerating plot */
00265        if (stripc->acc == 0) {
00266            for (j=0; j<PEN; j++) {
00267               if (stripc->npts[j] > 0) {
00268                   istart = 0;
00269                   while (stripc->x[j][istart] < stripc->xmin + stripc->xlen*stripc->xjump)
00270                      istart++;
00271                      
00272                   stripc->npts[j] = stripc->npts[j] - istart;
00273                   memcpy( &stripc->x[j][0], &stripc->x[j][istart], (stripc->npts[j])*sizeof(PLFLT));
00274                   memcpy( &stripc->y[j][0], &stripc->y[j][istart], (stripc->npts[j])*sizeof(PLFLT));
00275               }
00276            }
00277        } else
00278            stripc->xlen = stripc->xlen * (1 + stripc->xjump);
00279 
00280        stripc->xmin = stripc->x[p][0];
00281        stripc->xmax = stripc->xmax + stripc->xlen*stripc->xjump;
00282 
00283        plstrip_gen(stripc);
00284     }
00285 }
00286 
00287 /*--------------------------------------------------------------------------*\
00288  * plstripd
00289  *
00290  * Deletes and releases memory used by a stripchart.  
00291 \*--------------------------------------------------------------------------*/
00292 
00293 void c_plstripd( PLINT id )
00294 {
00295     int i;
00296 
00297     if ((id < 0) || (id >= MAX_STRIPC) || 
00298        ((stripc = strip[id]) == NULL)) {
00299        plabort("Non existent stripchart");
00300        return;
00301     }
00302 
00303     for (i=0; i<PEN; i++) {
00304        if (stripc->npts[i]) {
00305             free((void *) stripc->x[i]);
00306             free((void *) stripc->y[i]);
00307             free(stripc->legline[i]);
00308         }
00309     }
00310 
00311     free(stripc->xspec);
00312     free(stripc->yspec);
00313     free(stripc->labx);
00314     free(stripc->laby);
00315     free(stripc->labtop);    
00316     free((void *) stripc);
00317     strip[id] = NULL;
00318 }