PLplot 5.9.6
plstripc.c
00001 /* $Id$
00002  *
00003  * Plots a simple stripchart.
00004  *
00005  * Copyright (C) 2004  Alan W. Irwin
00006  *
00007  * This file is part of PLplot.
00008  *
00009  * PLplot is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Library Public License as published
00011  * by the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * PLplot is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU Library General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Library General Public License
00020  * along with PLplot; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00022  *
00023  *
00024  * ToDo: better way of clearing plot. search for `plvsta'.
00025  */
00026 
00027 #include "plplotP.h"
00028 
00029 /* Data declarations for stripcharts. */
00030 
00031 #define PEN    4
00032 
00033 typedef struct
00034 {
00035     PLFLT xmin, xmax, ymin, ymax, xjump, xlen;
00036     PLFLT wxmin, wxmax, wymin, wymax;   /* FIXME - some redundancy might exist */
00037     char  *xspec, *yspec, *labx, *laby, *labtop;
00038     PLINT y_ascl, acc, colbox, collab;
00039     PLFLT xlpos, ylpos;
00040     PLFLT *x[PEN], *y[PEN];
00041     PLINT npts[PEN], nptsmax[PEN];
00042     PLINT colline[PEN], styline[PEN];
00043     char  *legline[PEN];
00044 } PLStrip;
00045 
00046 static int     sid;                     /* strip id number */
00047 #define MAX_STRIPC    1000              /* Max allowed */
00048 static PLStrip *strip[MAX_STRIPC];      /* Array of pointers */
00049 static PLStrip *stripc;                 /* current strip chart */
00050 
00051 /* Generates a complete stripchart plot.  */
00052 
00053 static void
00054 plstrip_gen( PLStrip *strip );
00055 
00056 /* draw legend */
00057 
00058 static void
00059 plstrip_legend( PLStrip *strip, int flag );
00060 
00061 /*--------------------------------------------------------------------------*\
00062  * plstripc
00063  *
00064  * Create 1d stripchart.
00065  \*--------------------------------------------------------------------------*/
00066 
00067 void
00068 c_plstripc( PLINT *id, const char *xspec, const char *yspec,
00069             PLFLT xmin, PLFLT xmax, PLFLT xjump, PLFLT ymin, PLFLT ymax,
00070             PLFLT xlpos, PLFLT ylpos,
00071             PLINT y_ascl, PLINT acc,
00072             PLINT colbox, PLINT collab,
00073             PLINT *colline, PLINT *styline, const char *legline[],
00074             const char *labx, const char *laby, const char *labtop )
00075 {
00076     int i;
00077 
00078 /* Get a free strip id and allocate it */
00079 
00080     for ( i = 0; i < MAX_STRIPC; i++ )
00081         if ( strip[i] == NULL )
00082             break;
00083 
00084     if ( i == MAX_STRIPC )
00085     {
00086         plabort( "plstripc: Cannot create new strip chart" );
00087         *id = -1;
00088         return;
00089     }
00090     else
00091     {
00092         sid        = *id = i;
00093         strip[sid] = (PLStrip *) calloc( 1, (size_t) sizeof ( PLStrip ) );
00094         if ( strip[sid] == NULL )
00095         {
00096             plabort( "plstripc: Out of memory." );
00097             *id = -1;
00098             return;
00099         }
00100     }
00101 
00102 /* Fill up the struct with all relevant info */
00103 
00104     stripc = strip[sid];
00105 
00106     for ( i = 0; i < PEN; i++ )
00107     {
00108         stripc->npts[i]    = 0;
00109         stripc->nptsmax[i] = 100;
00110         stripc->colline[i] = colline[i];
00111         stripc->styline[i] = styline[i];
00112         stripc->legline[i] = plstrdup( legline[i] );
00113         stripc->x[i]       = (PLFLT *) malloc( (size_t) sizeof ( PLFLT ) * stripc->nptsmax[i] );;
00114         stripc->y[i]       = (PLFLT *) malloc( (size_t) sizeof ( PLFLT ) * stripc->nptsmax[i] );;
00115         if ( stripc->x[i] == NULL || stripc->y[i] == NULL )
00116         {
00117             plabort( "plstripc: Out of memory." );
00118             plstripd( sid );
00119             *id = -1;
00120             return;
00121         }
00122     }
00123 
00124     stripc->xlpos  = xlpos;     /* legend position [0..1] */
00125     stripc->ylpos  = ylpos;
00126     stripc->xmin   = xmin;      /* initial bounding box */
00127     stripc->xmax   = xmax;
00128     stripc->ymin   = ymin;
00129     stripc->ymax   = ymax;
00130     stripc->xjump  = xjump;              /* jump x step(%) when x attains xmax (xmax is then set to xmax+xjump) */
00131     stripc->xlen   = xmax - xmin;        /* length of x scale */
00132     stripc->y_ascl = y_ascl;             /* autoscale y between x jump scale */
00133     stripc->acc    = acc;                /* accumulate plot (not really stripchart) */
00134     stripc->xspec  = plstrdup( xspec );  /* x axis specification */
00135     stripc->yspec  = plstrdup( yspec );
00136     stripc->labx   = plstrdup( labx );   /* x label */
00137     stripc->laby   = plstrdup( laby );
00138     stripc->labtop = plstrdup( labtop ); /* title */
00139     stripc->colbox = colbox;             /* box color */
00140     stripc->collab = collab;             /* label color */
00141 
00142 /* Generate the plot */
00143 
00144     plstrip_gen( stripc );
00145     plstrip_legend( stripc, 1 );
00146 }
00147 
00148 static void plstrip_legend( PLStrip *stripc, int first )
00149 {
00150     int   i;
00151     PLFLT sc, dy;
00152 
00153 /* draw legend */
00154 
00155     plgchr( &sc, &dy );
00156     sc = dy = dy / 100;
00157     plwind( -0.01, 1.01, -0.01, 1.01 );
00158     for ( i = 0; i < PEN; i++ )
00159     {
00160         if ( stripc->npts[i] || first )
00161         {
00162             plcol( stripc->colline[i] ); pllsty( stripc->styline[i] );
00163             pljoin( stripc->xlpos, stripc->ylpos - sc, stripc->xlpos + 0.1, stripc->ylpos - sc );
00164             plcol( stripc->collab );
00165             plptex( stripc->xlpos + 0.11, stripc->ylpos - sc, 0., 0., 0, stripc->legline[i] ); sc += dy;
00166         }
00167     }
00168     plwind( stripc->xmin, stripc->xmax, stripc->ymin, stripc->ymax );
00169     plflush();
00170 }
00171 
00172 /*--------------------------------------------------------------------------*\
00173  * plstrip_gen
00174  *
00175  * Generates a complete stripchart plot.  Used either initially or
00176  * during rescaling.
00177  \*--------------------------------------------------------------------------*/
00178 
00179 static void plstrip_gen( PLStrip *strip )
00180 {
00181     int i;
00182 
00183 /* Set up window */
00184 
00185     plvpor( 0, 1, 0, 1 );
00186     plwind( 0, 1, 0, 1 );
00187     plcol( 0 ); plpsty( 0 );
00188     plclear();
00189     plvsta();
00190 
00191 /* Draw box and same window dimensions */
00192     strip->wxmin = strip->xmin; strip->wxmax = strip->xmax;
00193     strip->wymin = strip->ymin; strip->wymax = strip->ymax; /* FIXME - can exist some redundancy here */
00194 
00195     plwind( strip->xmin, strip->xmax, strip->ymin, strip->ymax );
00196 
00197     pllsty( 1 );
00198     plcol( strip->colbox );
00199     plbox( strip->xspec, 0.0, 0, strip->yspec, 0.0, 0 );
00200 
00201     plcol( strip->collab );
00202     pllab( strip->labx, strip->laby, strip->labtop );
00203 
00204     for ( i = 0; i < PEN; i++ )
00205     {
00206         if ( strip->npts[i] > 0 )
00207         {
00208             plcol( strip->colline[i] ); pllsty( strip->styline[i] );
00209             plline( strip->npts[i], strip->x[i], strip->y[i] );
00210         }
00211     }
00212 
00213     plstrip_legend( strip, 0 );
00214 }
00215 
00216 /*--------------------------------------------------------------------------*\
00217  * plstripa
00218  *
00219  * Add a point to a stripchart.
00220  * Allocates memory and rescales as necessary.
00221  \*--------------------------------------------------------------------------*/
00222 
00223 void c_plstripa( PLINT id, PLINT p, PLFLT x, PLFLT y )
00224 {
00225     int j, yasc = 0, istart;
00226 
00227     if ( p >= PEN )
00228     {
00229         plabort( "Non existent pen" );
00230         return;
00231     }
00232 
00233     if ( ( id < 0 ) || ( id >= MAX_STRIPC ) ||
00234          ( ( stripc = strip[id] ) == NULL ) )
00235     {
00236         plabort( "Non existent stripchart" );
00237         return;
00238     }
00239 
00240 /* Add new point, allocating memory if necessary */
00241 
00242     if ( ++stripc->npts[p] > stripc->nptsmax[p] )
00243     {
00244         stripc->nptsmax[p] += 32;
00245         stripc->x[p]        = (PLFLT *) realloc( (void *) stripc->x[p], sizeof ( PLFLT ) * stripc->nptsmax[p] );
00246         stripc->y[p]        = (PLFLT *) realloc( (void *) stripc->y[p], sizeof ( PLFLT ) * stripc->nptsmax[p] );
00247         if ( stripc->x[p] == NULL || stripc->y[p] == NULL )
00248         {
00249             plabort( "plstripc: Out of memory." );
00250             plstripd( id );
00251             return;
00252         }
00253     }
00254 
00255     stripc->x[p][stripc->npts[p] - 1] = x;
00256     stripc->y[p][stripc->npts[p] - 1] = y;
00257 
00258     stripc->xmax = x;
00259 
00260     if ( stripc->y_ascl == 1 && ( y > stripc->ymax || y < stripc->ymin ) )
00261         yasc = 1;
00262 
00263     if ( y > stripc->ymax )
00264         stripc->ymax = stripc->ymin + 1.1 * ( y - stripc->ymin );
00265     if ( y < stripc->ymin )
00266         stripc->ymin = stripc->ymax - 1.1 * ( stripc->ymax - y );
00267 
00268 /* Now either plot new point or regenerate plot */
00269 
00270     if ( stripc->xmax - stripc->xmin < stripc->xlen )
00271     {
00272         if ( yasc == 0 )
00273         {
00274             /* If user has changed subwindow, make shure we have the correct one */
00275             plvsta();
00276             plwind( stripc->wxmin, stripc->wxmax, stripc->wymin, stripc->wymax );   /* FIXME - can exist some redundancy here */
00277             plcol( stripc->colline[p] ); pllsty( stripc->styline[p] );
00278             if ( ( stripc->npts[p] - 2 ) < 0 )
00279                 plP_movwor( stripc->x[p][stripc->npts[p] - 1], stripc->y[p][stripc->npts[p] - 1] );
00280             else
00281                 plP_movwor( stripc->x[p][stripc->npts[p] - 2], stripc->y[p][stripc->npts[p] - 2] );
00282             plP_drawor( stripc->x[p][stripc->npts[p] - 1], stripc->y[p][stripc->npts[p] - 1] );
00283             plflush();
00284         }
00285         else
00286         {
00287             stripc->xmax = stripc->xmin + stripc->xlen;
00288             plstrip_gen( stripc );
00289         }
00290     }
00291     else
00292     {
00293 /* Regenerating plot */
00294         if ( stripc->acc == 0 )
00295         {
00296             for ( j = 0; j < PEN; j++ )
00297             {
00298                 if ( stripc->npts[j] > 0 )
00299                 {
00300                     istart = 0;
00301                     while ( stripc->x[j][istart] < stripc->xmin + stripc->xlen * stripc->xjump )
00302                         istart++;
00303 
00304                     stripc->npts[j] = stripc->npts[j] - istart;
00305                     memcpy( &stripc->x[j][0], &stripc->x[j][istart], ( stripc->npts[j] ) * sizeof ( PLFLT ) );
00306                     memcpy( &stripc->y[j][0], &stripc->y[j][istart], ( stripc->npts[j] ) * sizeof ( PLFLT ) );
00307                 }
00308             }
00309         }
00310         else
00311             stripc->xlen = stripc->xlen * ( 1 + stripc->xjump );
00312 
00313         if ( stripc->acc == 0 )
00314             stripc->xmin = stripc->xmin + stripc->xlen * stripc->xjump;
00315         else
00316             stripc->xmin = stripc->x[p][0];
00317         stripc->xmax = stripc->xmax + stripc->xlen * stripc->xjump;
00318 
00319         plstrip_gen( stripc );
00320     }
00321 }
00322 
00323 /*--------------------------------------------------------------------------*\
00324  * plstripd
00325  *
00326  * Deletes and releases memory used by a stripchart.
00327  \*--------------------------------------------------------------------------*/
00328 
00329 void c_plstripd( PLINT id )
00330 {
00331     int i;
00332 
00333     if ( ( id < 0 ) || ( id >= MAX_STRIPC ) ||
00334          ( ( stripc = strip[id] ) == NULL ) )
00335     {
00336         plabort( "Non existent stripchart" );
00337         return;
00338     }
00339 
00340     for ( i = 0; i < PEN; i++ )
00341     {
00342         if ( stripc->npts[i] )
00343         {
00344             free( (void *) stripc->x[i] );
00345             free( (void *) stripc->y[i] );
00346             free( stripc->legline[i] );
00347         }
00348     }
00349 
00350     free( stripc->xspec );
00351     free( stripc->yspec );
00352     free( stripc->labx );
00353     free( stripc->laby );
00354     free( stripc->labtop );
00355     free( (void *) stripc );
00356     strip[id] = NULL;
00357 }
 All Data Structures Files Functions