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