PLplot: plstripc.c Source File

PLplot 5.10.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plstripc.c
Go to the documentation of this file.
1 // $Id: plstripc.c 11973 2011-10-17 21:16:39Z andrewross $
2 //
3 // Plots a simple stripchart.
4 //
5 // Copyright (C) 2004 Alan W. Irwin
6 //
7 // This file is part of PLplot.
8 //
9 // PLplot is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU Library General Public License as published
11 // by the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // PLplot is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Library General Public License for more details.
18 //
19 // You should have received a copy of the GNU Library General Public License
20 // along with PLplot; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 //
24 // ToDo: better way of clearing plot. search for `plvsta'.
25 //
26
27 #include "plplotP.h"
28
29 // Data declarations for stripcharts.
30
31 #define PEN 4
32
33 typedef struct
34 {
35 PLFLT xmin, xmax, ymin, ymax, xjump, xlen;
36 PLFLT wxmin, wxmax, wymin, wymax; // FIXME - some redundancy might exist
37 char *xspec, *yspec, *labx, *laby, *labtop;
38 PLINT y_ascl, acc, colbox, collab;
39 PLFLT xlpos, ylpos;
40 PLFLT *x[PEN], *y[PEN];
41 PLINT npts[PEN], nptsmax[PEN];
42 PLINT colline[PEN], styline[PEN];
43 char *legline[PEN];
44 } PLStrip;
45
46 static int sid; // strip id number
47 #define MAX_STRIPC 1000 // Max allowed
48 static PLStrip *strip[MAX_STRIPC]; // Array of pointers
49 static PLStrip *stripc; // current strip chart
50
51 // Generates a complete stripchart plot.
52
53 static void
54 plstrip_gen( PLStrip *strip );
55
56 // draw legend
57
58 static void
59 plstrip_legend( PLStrip *strip, int flag );
60
61 //--------------------------------------------------------------------------
62 // plstripc
63 //
64 // Create 1d stripchart.
65 //--------------------------------------------------------------------------
66
67 void
68 c_plstripc( PLINT *id, const char *xspec, const char *yspec,
69 PLFLT xmin, PLFLT xmax, PLFLT xjump, PLFLT ymin, PLFLT ymax,
70 PLFLT xlpos, PLFLT ylpos,
71 PLINT y_ascl, PLINT acc,
72 PLINT colbox, PLINT collab,
73 const PLINT *colline, const PLINT *styline, const char *legline[],
74 const char *labx, const char *laby, const char *labtop )
75 {
76 int i;
77
78 // Get a free strip id and allocate it
79
80 for ( i = 0; i < MAX_STRIPC; i++ )
81 if ( strip[i] == NULL )
82 break;
83
84 if ( i == MAX_STRIPC )
85 {
86 plabort( "plstripc: Cannot create new strip chart" );
87 *id = -1;
88 return;
89 }
90 else
91 {
92 sid = *id = i;
93 strip[sid] = (PLStrip *) calloc( 1, (size_t) sizeof ( PLStrip ) );
94 if ( strip[sid] == NULL )
95 {
96 plabort( "plstripc: Out of memory." );
97 *id = -1;
98 return;
99 }
100 }
101
102 // Fill up the struct with all relevant info
103
104 stripc = strip[sid];
105
106 for ( i = 0; i < PEN; i++ )
107 {
108 stripc->npts[i] = 0;
109 stripc->nptsmax[i] = 100;
110 stripc->colline[i] = colline[i];
111 stripc->styline[i] = styline[i];
112 stripc->legline[i] = plstrdup( legline[i] );
113 stripc->x[i] = (PLFLT *) malloc( (size_t) sizeof ( PLFLT ) * (size_t) ( stripc->nptsmax[i] ) );
114 stripc->y[i] = (PLFLT *) malloc( (size_t) sizeof ( PLFLT ) * (size_t) ( stripc->nptsmax[i] ) );
115 if ( stripc->x[i] == NULL || stripc->y[i] == NULL )
116 {
117 plabort( "plstripc: Out of memory." );
118 plstripd( sid );
119 *id = -1;
120 return;
121 }
122 }
123
124 stripc->xlpos = xlpos; // legend position [0..1]
125 stripc->ylpos = ylpos;
126 stripc->xmin = xmin; // initial bounding box
127 stripc->xmax = xmax;
128 stripc->ymin = ymin;
129 stripc->ymax = ymax;
130 stripc->xjump = xjump; // jump x step(%) when x attains xmax (xmax is then set to xmax+xjump)
131 stripc->xlen = xmax - xmin; // length of x scale
132 stripc->y_ascl = y_ascl; // autoscale y between x jump scale
133 stripc->acc = acc; // accumulate plot (not really stripchart)
134 stripc->xspec = plstrdup( xspec ); // x axis specification
135 stripc->yspec = plstrdup( yspec );
136 stripc->labx = plstrdup( labx ); // x label
137 stripc->laby = plstrdup( laby );
138 stripc->labtop = plstrdup( labtop ); // title
139 stripc->colbox = colbox; // box color
140 stripc->collab = collab; // label color
141
142 // Generate the plot
143
144 plstrip_gen( stripc );
145 plstrip_legend( stripc, 1 );
146 }
147
148 static void plstrip_legend( PLStrip *stripcloc, int first )
149 {
150 int i;
151 PLFLT sc, dy;
152
153 // draw legend
154
155 plgchr( &sc, &dy );
156 sc = dy = dy / 100;
157 plwind( -0.01, 1.01, -0.01, 1.01 );
158 for ( i = 0; i < PEN; i++ )
159 {
160 if ( stripcloc->npts[i] || first )
161 {
162 plcol0( stripcloc->colline[i] ); pllsty( stripcloc->styline[i] );
163 pljoin( stripcloc->xlpos, stripcloc->ylpos - sc, stripcloc->xlpos + 0.1, stripcloc->ylpos - sc );
164 plcol0( stripcloc->collab );
165 plptex( stripcloc->xlpos + 0.11, stripcloc->ylpos - sc, 0., 0., 0, stripcloc->legline[i] ); sc += dy;
166 }
167 }
168 plwind( stripcloc->xmin, stripcloc->xmax, stripcloc->ymin, stripcloc->ymax );
169 plflush();
170 }
171
172 //--------------------------------------------------------------------------
173 // plstrip_gen
174 //
175 // Generates a complete stripchart plot. Used either initially or
176 // during rescaling.
177 //--------------------------------------------------------------------------
178
179 static void plstrip_gen( PLStrip *striploc )
180 {
181 int i;
182
183 // Set up window
184
185 plvpor( 0, 1, 0, 1 );
186 plwind( 0, 1, 0, 1 );
187 plcol0( 0 ); plpsty( 0 );
188 plclear();
189 plvsta();
190
191 // Draw box and same window dimensions
192 striploc->wxmin = striploc->xmin; striploc->wxmax = striploc->xmax;
193 striploc->wymin = striploc->ymin; striploc->wymax = striploc->ymax; // FIXME - can exist some redundancy here
194
195 plwind( striploc->xmin, striploc->xmax, striploc->ymin, striploc->ymax );
196
197 pllsty( 1 );
198 plcol0( striploc->colbox );
199 plbox( striploc->xspec, 0.0, 0, striploc->yspec, 0.0, 0 );
200
201 plcol0( striploc->collab );
202 pllab( striploc->labx, striploc->laby, striploc->labtop );
203
204 for ( i = 0; i < PEN; i++ )
205 {
206 if ( striploc->npts[i] > 0 )
207 {
208 plcol0( striploc->colline[i] ); pllsty( striploc->styline[i] );
209 plline( striploc->npts[i], striploc->x[i], striploc->y[i] );
210 }
211 }
212
213 plstrip_legend( striploc, 0 );
214 }
215
216 //--------------------------------------------------------------------------
217 // plstripa
218 //
219 // Add a point to a stripchart.
220 // Allocates memory and rescales as necessary.
221 //--------------------------------------------------------------------------
222
223 void c_plstripa( PLINT id, PLINT p, PLFLT x, PLFLT y )
224 {
225 int j, yasc = 0, istart;
226
227 if ( p >= PEN )
228 {
229 plabort( "Non existent pen" );
230 return;
231 }
232
233 if ( ( id < 0 ) || ( id >= MAX_STRIPC ) ||
234 ( ( stripc = strip[id] ) == NULL ) )
235 {
236 plabort( "Non existent stripchart" );
237 return;
238 }
239
240 // Add new point, allocating memory if necessary
241
242 if ( ++stripc->npts[p] > stripc->nptsmax[p] )
243 {
244 stripc->nptsmax[p] += 32;
245 stripc->x[p] = (PLFLT *) realloc( (void *) stripc->x[p], sizeof ( PLFLT ) * (size_t) ( stripc->nptsmax[p] ) );
246 stripc->y[p] = (PLFLT *) realloc( (void *) stripc->y[p], sizeof ( PLFLT ) * (size_t) ( stripc->nptsmax[p] ) );
247 if ( stripc->x[p] == NULL || stripc->y[p] == NULL )
248 {
249 plabort( "plstripc: Out of memory." );
250 plstripd( id );
251 return;
252 }
253 }
254
255 stripc->x[p][stripc->npts[p] - 1] = x;
256 stripc->y[p][stripc->npts[p] - 1] = y;
257
258 stripc->xmax = x;
259
260 if ( stripc->y_ascl == 1 && ( y > stripc->ymax || y < stripc->ymin ) )
261 yasc = 1;
262
263 if ( y > stripc->ymax )
264 stripc->ymax = stripc->ymin + 1.1 * ( y - stripc->ymin );
265 if ( y < stripc->ymin )
266 stripc->ymin = stripc->ymax - 1.1 * ( stripc->ymax - y );
267
268 // Now either plot new point or regenerate plot
269
270 if ( stripc->xmax - stripc->xmin < stripc->xlen )
271 {
272 if ( yasc == 0 )
273 {
274 // If user has changed subwindow, make shure we have the correct one
275 plvsta();
276 plwind( stripc->wxmin, stripc->wxmax, stripc->wymin, stripc->wymax ); // FIXME - can exist some redundancy here
277 plcol0( stripc->colline[p] ); pllsty( stripc->styline[p] );
278 if ( ( stripc->npts[p] - 2 ) < 0 )
279 plP_movwor( stripc->x[p][stripc->npts[p] - 1], stripc->y[p][stripc->npts[p] - 1] );
280 else
281 plP_movwor( stripc->x[p][stripc->npts[p] - 2], stripc->y[p][stripc->npts[p] - 2] );
282 plP_drawor( stripc->x[p][stripc->npts[p] - 1], stripc->y[p][stripc->npts[p] - 1] );
283 plflush();
284 }
285 else
286 {
287 stripc->xmax = stripc->xmin + stripc->xlen;
288 plstrip_gen( stripc );
289 }
290 }
291 else
292 {
293 // Regenerating plot
294 if ( stripc->acc == 0 )
295 {
296 for ( j = 0; j < PEN; j++ )
297 {
298 if ( stripc->npts[j] > 0 )
299 {
300 istart = 0;
301 while ( stripc->x[j][istart] < stripc->xmin + stripc->xlen * stripc->xjump )
302 istart++;
303
304 stripc->npts[j] = stripc->npts[j] - istart;
305 memcpy( &stripc->x[j][0], &stripc->x[j][istart], (size_t) ( stripc->npts[j] ) * sizeof ( PLFLT ) );
306 memcpy( &stripc->y[j][0], &stripc->y[j][istart], (size_t) ( stripc->npts[j] ) * sizeof ( PLFLT ) );
307 }
308 }
309 }
310 else
311 stripc->xlen = stripc->xlen * ( 1 + stripc->xjump );
312
313 if ( stripc->acc == 0 )
314 stripc->xmin = stripc->xmin + stripc->xlen * stripc->xjump;
315 else
316 stripc->xmin = stripc->x[p][0];
317 stripc->xmax = stripc->xmax + stripc->xlen * stripc->xjump;
318
319 plstrip_gen( stripc );
320 }
321 }
322
323 //--------------------------------------------------------------------------
324 // plstripd
325 //
326 // Deletes and releases memory used by a stripchart.
327 //--------------------------------------------------------------------------
328
329 void c_plstripd( PLINT id )
330 {
331 int i;
332
333 if ( ( id < 0 ) || ( id >= MAX_STRIPC ) ||
334 ( ( stripc = strip[id] ) == NULL ) )
335 {
336 plabort( "Non existent stripchart" );
337 return;
338 }
339
340 for ( i = 0; i < PEN; i++ )
341 {
342 if ( stripc->npts[i] )
343 {
344 free( (void *) stripc->x[i] );
345 free( (void *) stripc->y[i] );
346 free( stripc->legline[i] );
347 }
348 }
349
350 free( stripc->xspec );
351 free( stripc->yspec );
352 free( stripc->labx );
353 free( stripc->laby );
354 free( stripc->labtop );
355 free( (void *) stripc );
356 strip[id] = NULL;
357 }