PLplot 5.9.6
|
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 }