v21i036: 2D graphic system with table beautifier, Part05/14

Rich Salz rsalz at uunet.uu.net
Sat Mar 24 06:19:58 AEST 1990


Submitted-by: Steve Grubb <uunet!lsr-vax!scg>
Posting-number: Volume 21, Issue 36
Archive-name: ipl/part05

# ipl part05
#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#---------------------- cut here -----------------------------
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#		src/areadef.c
#		src/areadress.c
#		src/areas.h
#		src/arrow.c
#		src/bargraph.c
#		src/boxplot.c
#		src/constraint_check.c
cat << SHAR_EOF > src/areadef.c
/* Set up a graphics area and do axes, etc. */
#include "ipl.x"
#include "areas.h"

Areadef( )
{
char paper[12],
	areaname[30],
	s1[12], s2[12], s3[12], s4[12],
	uin[12];
double	xlo,
	xhi,
	ylo,
	yhi,
	dxlo,
	dxhi,
	dylo,
	dyhi;
int	n,
	areasrc,
	p,
	bad,
	loadflag,
	i;

/* see where area is coming from..  */
areasrc = 0;
gget( uin, "Area" ); if( strlen( uin ) > 0 ) areasrc = 1;
gget( uin, "Area.rectangle" ); if( strlen( uin ) > 0 ) areasrc = 2;
gget( uin, "Area.left" ); if( strlen( uin ) > 0 ) areasrc = 3;
if( areasrc < 1 ) { 
	fprintf( stderr, "Area or Area.rectangle, or Area.left+right+top+bottom must be specified.\n" ); 
	gdp_exit(); 
	}

if( areasrc == 1 ) {  /* preset area name */
	gget( areaname, "Area" );
	for( i = 0; i < Nareas; i++ ) if( strncmp( areaname, Areacoords[i], strlen( areaname )) ==0 ) break;
	if( i == Nareas ) { fprintf( stderr, "Can't find preset area '%s'.\n", areaname ); gdp_exit(); }
	if( Paper == 0 ) /* portrait */
		n = sscanf( Areacoords[i], "%*s %s %s %s %s", s1, s2, s3, s4 );
	else n = sscanf( Areacoords[i], "%*s %*s %*s %*s %*s %s %s %s %s", s1, s2, s3, s4 ); /* landscape */
	if( n != 4 ) { fprintf( stderr, "Error in area presets.\n" ); gdp_exit(); }
	xlo = atof( s1 ); ylo = atof( s2 ); xhi = atof( s3 ); yhi = atof( s4 ); 
	}
else if( areasrc == 2 ) { /* rectangle */
	gget( uin, "Area.rectangle" );
	if( strlen( uin ) > 0 ) n = sscanf( uin, "%lf %lf %lf %lf", &xlo, &ylo, &xhi, &yhi );
	if( n != 4 ) { 
		fprintf( stderr, "Area.rectangle must contain two coord pairs (low left, up right).\n" ); 
		gdp_exit(); 
		}
	}
else if( areasrc == 3 ) { /* left, right, bottom, top */
	int bad = NO;
	xlo = atof( uin );
	gget( uin, "Area.left" );if( !goodnum( uin, &p ))bad = YES; xlo = atof( uin );
	gget( uin, "Area.right" );if( !goodnum( uin, &p ))bad = YES; xhi = atof( uin );
	gget( uin, "Area.bottom" ); if( !goodnum( uin, &p ))bad = YES; ylo = atof( uin );
	gget( uin, "Area.top" ); if( !goodnum( uin, &p ))bad = YES; yhi = atof( uin );
	if( bad ) { fprintf( stderr, "Area.left+right+bottom+top incompletely specified." ); gdp_exit(); }
	}

/* scale discipline */
gget( uin, "Xscaletype" );
if( strcmp( uin, "log" )==0 ) Scale_discipline_x = LOG; 
else if( strcmp( uin, "yymm" )==0 ) Scale_discipline_x = YYMM; 
else Scale_discipline_x = LINEAR;

gget( uin, "Yscaletype" );
if( strcmp( uin, "log" )==0 ) Scale_discipline_y = LOG; 
else Scale_discipline_y = LINEAR;

/* scale bounds */
bad = NO;
gget( uin, "Xmin" ); if( ! goodnum( uin, &p )) bad = YES; dxlo = atof( uin );
gget( uin, "Xmax" ); if( ! goodnum( uin, &p )) bad = YES; dxhi = atof( uin );
gget( uin, "Ymin" ); if( ! goodnum( uin, &p )) bad = YES; dylo = atof( uin );
gget( uin, "Ymax" ); if( ! goodnum( uin, &p )) bad = YES; dyhi = atof( uin );
if( bad ) { fprintf( stderr, "Scale bounds (Xmin, Xmax, Ymin, Ymax) not all specified.\n" ); gdp_exit(); }


/* tic increment */
bad = NO;
gget( uin, "Xinc" ); if( ! goodnum( uin, &p )) bad = YES; DXtic = atof( uin );
gget( uin, "Yinc" ); if( ! goodnum( uin, &p )) bad = YES; DYtic = atof( uin );
if( bad ) { fprintf( stderr, "Tic increments incomplete.\n" ); }

/* get tic numbering format */
gget( DXticfmt, "Xticfmt" );
gget( DYticfmt, "Yticfmt" );

/* fprintf( stderr, "Scaling in x: %5.1f to %5.1f by %3.1f   in y: %5.1f to %5.1f by %3.1f\n", 
	dxlo, dxhi, DXtic, dylo, dyhi, DYtic ); */


setscale_x( xlo, xhi, dxlo, dxhi );
setscale_y( ylo, yhi, dylo, dyhi );


/* do the graphic work for axes, ticks, etc. */
areadress( );

}
SHAR_EOF
############################

cat << SHAR_EOF > src/areadress.c
/* areadress() - do axis scaling stubs, labels, and title */
/*  ..gets called by areadef (only) */
#include "ipl.x" 
#define LINE 1
#define SHADE 2
#define WLINE 3
#define NUMERIC 0
#define FROM_FILE 1
#define VAR 2
#define LITERAL 3


areadress( )
{
char 	str[50], 
	do_x[10], do_y[10],
	shade[12],
	month[6], year[6];
int 	i, j,
	n,
	tl, tr, 
	sl, sr, 
	grid, 
	even, 
	minor,
	stub0or1,
	varfield,
	nrows,
	no_lone_tics,
	stubisrc;
double 	tcl = 0.08, 
	mtcl = 0.035, /* tic length, major and minor */
	stop,
	xstubyofs,
	ystubxofs,
	sh,
	f, g, h;
FILE 	*fp;

/* set to uer's standard font */
gget( Buf, "Font" );
NTfont( Buf );


/* frame of the graphics area */
gget( Buf, "Frame" );
if( strcmp( Buf, "double" ) == 0 ) ab_rect( Xlo-mtcl, Ylo-mtcl, Xhi+mtcl, Yhi+mtcl, 1.0, 1 );
if( strcmp( Buf, "none" ) != 0 ) ab_rect( Xlo, Ylo, Xhi, Yhi, 1.0, 1 );
/* shade the area */
gget( Buf, "Shade" );
if( strlen( Buf ) > 0 ) {
	sh = atof( Buf );
	ab_rect( Xlo, Ylo, Xhi, Yhi, sh, 0 );
	}

gget( Buf, "Ystub.ticlen" ); tcl = atof( Buf );
gget( Buf, "Ystub.ticlen.minor" ); mtcl = atof( Buf );

/**** Y ****/
/* draw axis line */
gget( do_y, "Yaxis" ); 
if( do_y[0] == 'n' ) goto BEGIN_X; /* if 'no', skip all the y axis code */


/* stub text can be numeric, from a data field, from a file, or literally specified. */
gget( Buf, "Ystub" ); 
if( strcmp( Buf, "num" )==0 ) stubisrc = NUMERIC;
else if( Buf[0] == '@' ) { 
	stubisrc = VAR;
	varfield = atoi( &Buf[1] ); 
	if( varfield < 1 || varfield > N_d_fields ) { fprintf( stderr, "bad stub var field\n" ); gdp_exit(); }
	}
else if( strlen( Buf ) < 1 ) fprintf( stderr, "Warning, Ystub not specified.\n" );
else 	{
	stubisrc = FROM_FILE;
	fp = fopen( Buf, "r" );
	if( fp != NULL ) {
		gget( Buf, "Ystub.fileline" );
		for( i = 0; i < atoi( Buf ); i++ ) fgets( str, 30, fp );
		}
	else if( fp == NULL ) {
		sprintf( Buf2, "%s/%s", Templatepath, Buf );
		fp = fopen( Buf2, "r" );
		if( fp != NULL ) {
			gget( Buf, "Ystub.fileline" );
			for( i = 0; i < atoi( Buf ); i++ ) fgets( str, 30, fp );
			}
		else if( fp == NULL ) {
			text_tofile( Buf, Tempfile );
			fp = fopen( Tempfile, "r" );
			}
		}
	}


/* sides to put tics on */
gget( Buf, "Ystub.tics" ); 
if( smember( Buf, "left both" )) tl = YES; else tl = NO;
if( smember( Buf, "right both" )) tr = YES; else tr = NO;

/* sides to put stubs on */
gget( Buf, "Ystub.stubs" ); 
if( smember( Buf, "left both" )) sl = YES; else sl = NO;
if( smember( Buf, "right both" )) sr = YES; else sr = NO;

/* point size of stubs */
gget( Buf, "Ystub.size" ); NTptsize( atoi( Buf ) );

/* shade level for shaded blocks */
gget( shade, "Ystub.shade" );

/* grid style */
gget( Buf, "Ystub.grid" ); 
if( strcmp( Buf, "line" )==0 ) grid = LINE;
else if( strcmp( Buf, "shade" )==0 ) grid = SHADE;
else if( strcmp( Buf, "wline" )==0 ) grid = WLINE;
else grid = NO;

/* minor tics */
gget( Buf, "Ystub.minor" ); minor = atoi( Buf );

gget( Buf, "Ystub.xofs" ); ystubxofs = - atof( Buf ); /* note sign change */
gget( Buf, "Ystub.nolonetics" ); if( Buf[0] == 'y' ) no_lone_tics = 1; else no_lone_tics = 0;

/**** loop for doing y axis tics and stubs ****/
even = YES;
n = 0; /* counter for stub from var */
gget( Buf, "Ystart.0or1" ); stub0or1 = atoi( Buf );
if( stub0or1 ) { f = DYlo + (stub0or1 * DYtic); stop = DYhi - DYtic; }
else { f = DYlo; stop = DYhi; }
for( ; f <= stop +.0001; f+= DYtic ) {

	/* get stub text */
	if( stubisrc == NUMERIC )sprintf( str, DYticfmt, f );
	else if( stubisrc == VAR ) {
		if( n < N_d_rows ) strcpy( str, D[ n++ ][ atoi( &Buf[1] ) -1 ] );
		else str[0] = '\0';
		}
	else if( stubisrc == FROM_FILE) { 
		if( fgets( str, 30, fp ) == NULL ) str[0] = '\0';
		str[ strlen( str )-1 ] = '\0'; 
		if( str[0] == '!' ) { str[0] = ' '; sscanf( &str[1], "%lf", &f ); if( f > stop ) break; }
		}

	if( no_lone_tics && strlen( str ) < 1 ) { even = !even; continue; }

	if( tl ) { NTm( DXlo, f ); NTlin( da_x( DXlo ) - tcl , da_y( f ) ); } /* tics, left */
	if( tr ) { NTm( DXhi, f ); NTlin( da_x( DXhi ) + tcl , da_y( f ) ); } /* tics, right */
	if( f <= (DYhi-DYtic)+.0001 ) for( i = 0, g = f; i < minor; i++ ) {  /* minor tics */
		g+= DYtic / (double) minor ;
		if( tl ) { NTm( DXlo, g ); NTlin( da_x( DXlo ) - mtcl , da_y( g ) ); } /* tics, left */
		if( tr ) { NTm( DXhi, g ); NTlin( da_x( DXhi ) + mtcl , da_y( g ) ); } /* tics, right */
		}
	if( sl ) { NTmov( da_x( DXlo ) - 2, da_y( f ) - 0.03 ); NTrightjust( str, (2+ystubxofs) ); } /* text left */
	if( sr ) { NTmov( da_x( DXhi ) - ystubxofs , da_y( f ) - 0.03 ); NTtext( str ); }	/* text right */
	if( grid == LINE ) { 	/* lines */
		NTlinetype( "0", 0.3, 0 );
		NTm( DXlo, f ); 
		NTl( DXhi, f ); 
		NTnormline();
		}
	if( grid == WLINE ) ab_rect( da_x( DXlo ), da_y( f ) - 0.02, da_x( DXhi ), da_y( f )+ 0.02, 1.0, 0 );
	if( grid == SHADE && even && f <= (DYhi-DYtic)+.0001 ) { /* shaded blocks */
		rect( DXlo, f, DXhi, f+DYtic, atof( shade ), 0 );
		} 
	even = !even;
	}
if( stubisrc == FROM_FILE ) fclose( fp );
if( smember( do_y, "left both" ) ) { NTmov( Xlo, Ylo ); NTlin( Xlo, Yhi ); }
if( smember( do_y, "right both" ) ) { NTmov( Xhi, Ylo ); NTlin( Xhi, Yhi ); }



/**** X ****/
/* draw axis line */
BEGIN_X:
gget( do_x, "Xaxis" ); 
if( do_x[0] == 'n' ) goto TITLES; /* dont do any of this */

gget( Buf, "Xstub.ticlen" ); tcl = atof( Buf );
gget( Buf, "Xstub.ticlen.minor" ); mtcl = atof( Buf );

/* Figure out where stub text will come from.. either
 * plain numeric, from a data field, from a file, or literally specified.
 * Also available for x axis only is month/year, which actually comes from a file. */

gget( Buf, "Xstub" ); 

if( strcmp( Buf, "num" )==0 ) stubisrc = NUMERIC;
else if( Buf[0] == '@' ) { 
	stubisrc = VAR; 
	varfield = atoi( &Buf[1] ); 
	if( varfield < 1 || varfield > N_d_fields ) { fprintf( stderr, "bad stub var field\n" ); gdp_exit(); }
	}
else if( strcmp( Buf, "month" )==0 ) { 
	int start;
	if( Scale_discipline_x == YYMM ) {
		gget( Buf, "Xmin" );
		sprintf( month, "%02d", atoi( Buf ) % 100 );
		sprintf( year, "%02d", atoi( Buf ) / 100 );
		}
	else	{
		gget( month, "Xstub.startmonth" );
		gget( year, "Xstub.startyear" );
		}
	if( month[0] == '\0' || year[0] == '\0' ) {
		fprintf( stderr, "Warning, Xstub.startmonth (1-12) or Xstub.startyear (70-90) are missing.\n" );
		}
	start = (((atoi(year)%100)*12) + atoi( month )) - (70*12);
	fp = fopen( MONTHSTUB_PATH, "r" );
	if( fp == NULL ) { fprintf( stderr, "Can't open month stub file.\n" ); gdp_exit(); }
	for( i = 0; i < start; i++ ) fgets( str, 30, fp );
	stubisrc = FROM_FILE;
	}
else 	{
	stubisrc = FROM_FILE;
	fp = fopen( Buf, "r" );
	if( fp != NULL ) {
		gget( Buf, "Xstub.fileline" );
		for( i = 0; i < atoi( Buf ); i++ ) fgets( str, 30, fp );
		}
	else if( fp == NULL ) {
		sprintf( Buf2, "%s/%s", Templatepath, Buf );
		fp = fopen( Buf2, "r" );
		if( fp != NULL ) {
			gget( Buf, "Xstub.fileline" );
			for( i = 0; i < atoi( Buf ); i++ ) fgets( str, 30, fp );
			}

		else if( fp == NULL ) {
			text_tofile( Buf, Tempfile );
			fp = fopen( Tempfile, "r" );
			}
		}
	}


gget( Buf, "Xstub.tics" ); 
if( smember( Buf, "bottom both" )) tl = YES; else tl = NO;
if( smember( Buf, "top both" )) tr = YES; else tr = NO;

gget( Buf, "Xstub.stubs" ); 
if( smember( Buf, "bottom both" )) sl = YES; else sl = NO;
if( smember( Buf, "top both" )) sr = YES; else sr = NO;

gget( Buf, "Xstub.size" ); NTptsize( atoi( Buf ) );
gget( shade, "Xstub.shade" );

gget( Buf, "Xstub.grid" ); 
if( strcmp( Buf, "line" )==0 ) grid = LINE; 
else if( strcmp( Buf, "shade" )==0 ) grid = SHADE;
else if( strcmp( Buf, "wline" )==0 ) grid = WLINE;
else grid = NO;

gget( Buf, "Xstub.minor" ); minor = atoi( Buf );
gget( Buf, "Xstub.nolonetics" ); if( Buf[0] == 'y' ) no_lone_tics = 1; else no_lone_tics = 0;

/**** loop for doing x axis tics and stubs ****/
n = 0;
even = YES;
gget( Buf, "Xstub.yofs" ); xstubyofs = - atof( Buf ); /* note sign change */
gget( Buf, "Xstart.0or1" ); stub0or1 = atoi( Buf );
if( stub0or1 ) { f = DXlo + (stub0or1 * DXtic ); stop = DXhi - DXtic; }
else { f = DXlo; stop = DXhi; }
for( ; f <= stop + .0001; f+= DXtic ) {

	/* get stub text */
	if( stubisrc == NUMERIC )sprintf( str, DXticfmt, f );
	else if( stubisrc == VAR ) {
		if( n < N_d_rows ) strcpy( str, D[ n++ ][ varfield -1 ] );
		else str[0] = '\0';
		}
	else if( stubisrc == FROM_FILE) { 
		if( fgets( str, 30, fp ) == NULL ) str[0] = '\0';
		else str[ strlen( str )-1 ] = '\0'; 
		if( str[0] == '!' ) { str[0] = ' '; sscanf( &str[1], "%lf", &f ); if( f > stop ) break; }
		}

	if( no_lone_tics && strlen( str ) < 1 ) { even = !even; continue; }

	if( tl ) { NTm( f, DYlo ); NTlin( da_x( f ), da_y( DYlo ) - tcl ); }
	if( tr ) { NTm( f, DYhi ); NTlin( da_x( f ), da_y( DYhi ) + tcl ); }
	if( f <= (stop-DXtic)+.0001 ) for( i = 0, g = f; i < minor; i++ ) {  /* minor tics */
		g+= DXtic / (double) minor ;
		if( tl ) { NTm( g, DYlo ); NTlin( da_x( g ), da_y( DYlo ) - mtcl ); }
		if( tr ) { NTm( g, DYhi ); NTlin( da_x( g ), da_y( DYhi ) + mtcl ); }
		}

	if( sl ) {    /* tokens are stacked, max=3 */
		char s[3][30];
		for( i = 0; i < strlen( str ); i++ ) { 
			if( str[i] == ' ' )str[i] = '_';
			else if( str[i] == '~' ) str[i] = '\n' ;
			}
		nrows = sscanf( str, "%s %s %s", s[0], s[1], s[2] ); 
		h = da_y( DYlo ) + xstubyofs;
		for( i = 0; i < nrows; i++ ) {
			for( j = 0; j < strlen( s[i] ); j++ ) if( s[i][j]== '_' ) s[i][j]=' ';
			NTmov( da_x( f ) - 1, h ); NTcentext( s[i], 2 ); 
			h -= Chh;
			}
		}
	if( sr ){ 
		char s[3][30];
		for( i = 0; i < strlen( str ); i++ ) { 
			if( str[i] == ' ' )str[i] = '_';
			else if( str[i] == '~' ) str[i] = '\n' ;
			}
		nrows = sscanf( str, "%s %s %s", s[0], s[1], s[2] ); 
		h = -(xstubyofs) + da_y( DYhi ) + ((nrows-2)*Chh); /* */
		for( i = 0; i < nrows; i++ ) {
			for( j = 0; j < strlen( s[i] ); j++ ) if( s[i][j]== '_' ) s[i][j]=' ';
			NTmov( da_x( f ) - 1, h ); NTcentext( s[i], 2 ); 
			h -= Chh;
			}
		}


	if( grid == LINE ) { 
		NTlinetype( "0", 0.3, 0 );
		NTm( f, DYlo ); 
		NTl( f, DYhi ); 
		NTnormline();
		}
	if( grid == WLINE ) ab_rect( da_x( f ) - 0.02, da_y( DYlo ), da_x( f ) + 0.02, da_y( DYhi ), 1.0, 0 );
		
	if( grid == SHADE && even && f <= (stop-DXtic)+.0001 ) { 
		rect( f, DYlo, f+DXtic, DYhi, atof( shade ), 0 );
		} 
	even = !even;
	}
if( stubisrc == FROM_FILE ) fclose( fp );
if( smember( do_x, "top both" ) ) { NTmov( Xlo, Yhi ); NTlin( Xhi, Yhi ); }
if( smember( do_x, "bottom both" ) ){ NTmov( Xlo, Ylo ); NTlin( Xhi, Ylo ); }

TITLES:


/**** do axis identifiers ****/
	{
	int n, c1, c2, c3;
	double ofs;
	gget( Buf, "Xlabel" );
	if( strlen( Buf ) > 0 ) {
		gget( Buf2, "Xlabel.size" ); NTptsize( atof( Buf2 ) );
		gget( Buf2, "Xlabel.position" ); ofs = atof( Buf2 );
		getln( "" );
		for( i = 0; i < countln( Buf ); i++ ) {
			NTmov( Xlo, Ylo - ofs ); 
			NTcentext( getln( Buf ), (Xhi-Xlo) );
			ofs += Chh; 
			}
		}

	gget( Buf, "Ylabel" );
	if( strlen( Buf ) > 0 ) {
		gget( Buf2, "Ylabel.size" ); NTptsize( atof( Buf2 ) );
		gget( Buf2, "Ylabel.position" ); ofs = atof( Buf2 );
		NTchardir( 90 );
		getln( "" );
		for( i = 0; i < countln( Buf ); i++ ) {
			NTmov( Xlo-ofs, Ylo ); 
			NTcentext( getln( Buf ), (Yhi-Ylo) ); 
			ofs -= Chh;
			}
		NTchardir( 0 );
		}
	}

/**** area title ****/
	{
	int i = 1, c;
	double ofs;
	char just[20];

	gget( Buf, "Subtitle" );
	if( strlen( Buf ) > 0 ) {
		gget( Buf2, "Subtitle.font" ); NTfont( Buf2 );
		gget( Buf2, "Subtitle.size" ); NTptsize( atof( Buf2 ) );
		gget( Buf2, "Subtitle.above" ); ofs = atof( Buf2 );
		gget( Buf2, "Subtitle.justify" ); strcpy( just, Buf2 );

		getln( "" );
		for( i = 0; i < countln( Buf ); i++ ) {
			NTmov( Xlo+0.1, Yhi+ofs );
			if( strcmp( just, "center" )==0 ) NTcentext( getln( Buf ), Xhi-(Xlo+0.1) );
			else if( strcmp( just, "right" )==0 )NTrightjust( getln( Buf ), Xhi-(Xlo+0.1) );
			else NTtext( getln( Buf ) );
			ofs -= Chh;
			}
		}
	}
/* restore standard font */
gget( Buf, "Font" ); NTfont( Buf );
}

SHAR_EOF
############################

cat << SHAR_EOF > src/areas.h
/* # area.coords
# 
#   The following is a list of predefined graphics areas (windows) on the page.
# Some use the whole page; those beginning with '2' are for doing two plots 
# per page, 3 for three plots per page, etc.
#   These names can be used as the Area in Proc Areadef.  If none
# of these is suitable, Area.left, Area.right, etc. can be defined explicitly.
# Coordinates are in inches, with the origin in the lower left.
#
#                 ---portrait----    ---landscape---
# format is: 
# AREA NAME (must be followed by space(s))
#               XLO YLO XHI YHI    XLO YLO XHI YHI
# */

char *Areacoords[30] = {
"standard     1.2 3.5 7.4 8.0   1.5 1.5 9.0 6.2",
"square       1.2 2.0 7.2 8.0   2.2 0.8 8.2 6.8",
"dist1        1.2 6.5 7.2 8.0   2.2 5.3 8.2 6.8",
"whole        1.2 1.0 7.4 9.0   1.5 1.2 9.0 7.0",
"2hi          1.0 6.0 7.6 9.5   1.0 4.5 9.0 7.5",
"2lo          1.0 1.5 7.6 5.0   1.0 0.75 9.0 3.75",
"2left        1.0 1.0 4.0 9.5   1.0 1.0 5.25 6.5",
"2right       5.0 1.0 8.0 9.5   6.25 1.0 10.5 6.5",
"3hi          1.0 7.0 7.6 9.0   1.0 5.5 9.0 7.5",
"3mid         1.0 4.0 7.6 6.0   1.0 3.0 9.0 5.0",
"3lo          1.0 1.0 7.6 3.0   1.0 0.5 9.0 2.5",
"4nw          1.0 6.0 4.0 9.0   1.0 4.0 5.25 7.0",
"4ne          4.5 6.0 7.5 9.0   6.25 4.0 10.5 7.0",
"4sw          1.0 1.5 4.0 4.5   1.0 0.5 5.25 3.5",
"4se          4.5 1.5 7.5 4.5   6.25 0.5 10.5 3.5",
"map          0.4 2.0 6.8 8.4   1.4 0.8 7.8 7.2",
"usamap       .5  5 8 9.5        .5  1 10.5 7",
"lifetab      1.0 1.0 7.0 4.5   1.5 1.0 7.5 4.5",
"nicetab      1.0 0.5 7.5 10    1.5 0.5 9.0 7.0",
"narrowtab    2.0 0.5 6.0 10    3.0 0.5 8.0 7.0",
"narrowleft   1.0 0.4 4.0 10.5  1.0 1.0 5.25 6.5",
"narrowright  5.0 0.4 8.0 10.5  6.25 1.0 10.5 6.5" ,
"tabhi        1.0 5.5 8.0 10.5  1.0 4.3 10.0 8.0",
"tablo        1.0 0.5 8.0 5.5   1.0 0.5 10.0 4.2"
	} ;
int Nareas = 25;
SHAR_EOF
############################

cat << SHAR_EOF > src/arrow.c
#include "ipl.x"

Arrow( )
{
double x1, y1, x2, y2;
gget( Buf, "Points" );
sscanf( Buf, "%lf %lf %lf %lf", &x1, &y1, &x2, &y2 );
arr( x1, y1, x2, y2, 0.3, 0.2, 0.0 );
}


arr( x1, y1, x2, y2, delt_th, r, sh )
double x1, y1, x2, y2, delt_th, r, sh;
{
double vx, vy, ax1, ay1, ax2, ay2, th0, th1, th2, atan();
vx = x2 - x1;
vy = y2 - y1;

th0 = atan( vy / vx );
th1 = th0 + delt_th;
th2 = th0 - delt_th;

if( x2 < x1 ) {
	ax1 = x2 + (r * cos( th1 ));
	ay1 = y2 + (r * sin( th1 ));
	ax2 = x2 + (r * cos( th2 ));
	ay2 = y2 + (r * sin( th2 ));
	}
else 	{
	ax1 = x2 - (r * cos( th1 ));
	ay1 = y2 - (r * sin( th1 ));
	ax2 = x2 - (r * cos( th2 ));
	ay2 = y2 - (r * sin( th2 ));
	}

NTmov( x2, y2 );
NTpath( ax1, ay1 );
NTpath( ax2, ay2 );
NTshade( sh );
NTmov( x1, y1 );
NTlin( x2, y2 );
}
SHAR_EOF
############################

cat << SHAR_EOF > src/bargraph.c
/* horizontal (standard) bar graphs */
#include "ipl.x"
#define STACK	0
#define CLUSTER 1


Bargraph( )
{
int 	k[8], 
	idf[8],
	format,
	label,
	n,
	nc,
	i, j, jj,
	p,
	xfld,
	xset,
	start,
	outline;

double s[8],
	accum,
	zer,
	curx,
	xspace,
	subspace,
	y,
	y2,
	f,
	lblpos,
	sep,
	msep = 0.03;
char str[10];


/* get the data field list */
gget( Buf, "Field" ); 
n = 0;
while( n < 1 ) { 
	n = sscanf( Buf, "%d %d %d %d %d %d %d %d", &k[0], &k[1], &k[2], &k[3], &k[4], &k[5], &k[6], &k[7] );
	if( N_d_fields == 1 ) strcpy( Buf, "1" );
	else if( n < 1 ) { fprintf( stderr, "Field parameter(s) for bar graph are missing.\n" ); gdp_exit(); }
	}
for( i = 0; i < n; i++ ) 
	if( k[i] < 1 || k[i] > N_d_fields ) { fprintf( stderr, "Field is bad\n" ); gdp_exit(); }

/* get the label field list, if any */
gget( Buf, "Idfield" ); 
if( strlen( Buf ) > 0 ) { 
	label = YES;
	sscanf( Buf, "%d %d %d %d %d %d %d %d", &idf[0], &idf[1], &idf[2], &idf[3], &idf[4], &idf[5], &idf[6], &idf[7] );
	for( i = 0; i < n; i++ ) 
		if( idf[i] < 1 || idf[i] > N_d_fields ) { fprintf( stderr, "Idfield is bad\n" ); gdp_exit(); }
	}
else label = NO;

gget( Buf, "Format" );  
if( strcmp( Buf, "stack" )==0 ) format = STACK;
else format = CLUSTER;

DXtic = 1.0;

/* get bar shades */
gget( Buf, "Shade" ); 
sscanf( Buf, "%lf %lf %lf %lf %lf %lf %lf %lf", &s[0], &s[1], &s[2], &s[3], &s[4], &s[5], &s[6], &s[7] );

/* get zero line */
gget( Buf, "Zeroat" ); 
if( goodnum( Buf, &p )) zer = atof( Buf );
else zer = DYlo;

/* get label size */
if( label ) { gget( Buf, "Idfield.size" ); NTptsize( atof( Buf ) ) };

/* distance of label from bar top */
if( label ) { gget( Buf, "Idfield.position" ); lblpos = atof( Buf ); }

/* outline or not */
gget( Buf, "Outlinebars" ); if( Buf[0] == 'y' ) outline = YES; else outline = NO;

/* x distance between major bar spaces */
gget( Buf, "Separation" ); sep = atof( Buf );

gget( Buf, "Separation.sub" ); msep = atof( Buf );

xspace = ( (Xhi-Xlo)/((DXhi-DXlo)+1) ) - (sep*Scale_x);

if( format == CLUSTER ) nc = n; else nc = 1;

gget( Buf, "Killwild" ); /* option for aborting plot if any values out of range */
if( atof( Buf ) != 0 ) {
	for( i = 1; i <= N_d_rows; i++ ) {
		if( atof( D[i-1][ k[0] -1 ] ) > atof( Buf ) ) {
			fprintf( stderr, "Note: This Bargraph terminated due to a value of %s.\n", D[i-1][k[0]-1] );
			return( 0 );
			}
		}
	}

gget( Buf, "Xfield" ); /* allow placement of bars by a data field */
if( strlen( Buf ) > 0 ) {
	xset = 1;
	xfld = atoi( Buf );
	if( xfld < 1 || xfld > N_d_fields ) { fprintf( stderr, "Yfield bad.\n" ); gdp_exit(); }
	}
else xset = 0;

gget( Buf, "Xstart.0or1" ); /* allow starting at 0 or 1 */
if( Buf[0] == '0' ) { start = 0; }
else { start = 1; }

for( i = 1; i <= N_d_rows; i++ ) {
	if( xset ) curx = da_x( atof( D[i-1][xfld-1] ) ) - (xspace/2);
	else curx = da_x((double)(DXlo+i+(start-1))) - (xspace/2);

	subspace = ( xspace / nc );
	for( j = 0; j < nc; j++ ) {
		if( !goodnum( D[i-1][ k[j]-1 ], &p )) {
			fprintf( stderr, "Warning, row %d, field %d, is bad (%s)\n", i, k[j], D[i-1][ k[j]-1] );
			curx += subspace;
			continue;
			}
		y = atof(D[i-1][ k[j]-1 ]);
		if( y != DYlo )
			ab_rect( curx, da_y(zer), curx+(subspace-msep), da_y(y), s[j], (s[j]==1)?1:outline );
		if( label ) {
			if( y < zer || format == STACK ) f = (-lblpos)-Chh; else f = lblpos;
			strcpy( str, D[i-1][ idf[j]-1 ] );
			NTmov( curx, da_y(y)+f );
			NTcentext( str, subspace-msep );
			}
		if( format == STACK ) for( jj = 1; jj < n; jj++ ) {
			if( !goodnum( D[i-1][ k[jj] -1 ], &p ) ) {
				fprintf( stderr, "Warning, row %d, field %d, is bad (%s)\n", i, k[jj], D[i-1][k[jj]-1] );
				continue;
				}
			y2 = y + atof( D[i-1][ k[jj] -1 ] );
			if( y2 != DYlo )
				ab_rect( curx, da_y(y), curx+(subspace-msep), da_y(y2), s[jj], (s[jj]==1)?1:outline );
			if( label ) {
				if( y2 < zer || format == STACK ) f = (-lblpos)-Chh; else f = lblpos;
				NTmov( curx, da_y(y2)+f );
				strcpy( str, D[i-1][ idf[jj]-1 ] );
				NTcentext( str, subspace-msep );
				}
			y = y2;
			}

		curx += subspace;
		}
	}

gget( Buf, "Segment" );
if( Buf[0] == 'y' ) 
	for( f = DYlo+DYtic; f < DYhi; f += DYtic ) 
		rect( DXlo + 0.2, f-(DYhi*0.003), DXhi - 0.2, f+(DYhi*0.004), 1.0, 0 );
}
SHAR_EOF
############################

cat << SHAR_EOF > src/boxplot.c
#include "ipl.x"
Boxplot( )
{
int f[8], row, i, doends;
double val[8];
double w, x;

gget( Buf, "Linethick" );
NTlinetype( "0", atof( Buf ), 1.0 );

gget( Buf, "Label.size" );
if( atoi( Buf ) > 0 ) NTptsize( atoi( Buf ) );

gget( Buf, "Ends" );
if( Buf[0] == 'y' ) doends = 1;
else doends = 0;

gget( Buf, "Fields" );
if( strlen( Buf ) > 0 ) {
	if( sscanf( Buf, "%d %d %d %d %d %d", &f[0], &f[1], &f[2], &f[3], &f[4], &f[5] ) != 6 ) {
		fprintf( stderr, "Fields should specify six data fields (n, and the 5,25,50,75,95 percentiles)\n" );
		gdp_exit();
		}
	}

gget( Buf, "Datarow" );

row = atoi( Buf );
for( i = 0; i < 6; i++ ) {
	if( f[i] < 1 || f[i] > N_d_fields ) { fprintf( stderr, "Pfields bad.\n" ); gdp_exit(); }
	else if( row > 0 && row <= N_d_rows ) val[i] = atof( D[ row - 1 ][ f[i]-1 ] );
	else { fprintf( stderr, "Datarow bad.\n" ); gdp_exit(); }
	}

gget( Buf, "Xloc" ); x = atof( Buf );
gget( Buf, "Width" ); w = atof( Buf );

NTm( x-(w/2), val[2] ); /* lower edge of box */
NTp( x+(w/2), val[2] );
NTp( x+(w/2), val[4] );
NTp( x-(w/2), val[4] );
NTp( x-(w/2), val[2] ); /* upper edge */
NTshade( 1.0 );

NTm( x, val[1] ); /* lower tail */
NTl( x, val[2] );
if( doends ) { NTm( x-(w/2.7), val[1] ); NTl( x+(w/2.7), val[1] ); }

NTm( x-(w/2), val[2] ); /* lower edge of box */
NTl( x+(w/2), val[2] );
NTl( x+(w/2), val[4] );
NTl( x-(w/2), val[4] );
NTl( x-(w/2), val[2] ); /* upper edge */

NTm( x, val[4] );
NTl( x, val[5] ); /* upper tail */
if( doends ) { NTm( x-(w/2.7), val[5] ); NTl( x+(w/2.7), val[5] ); }

NTm( x-(w/2), val[3] ); /* median line */
NTl( x+(w/2), val[3] );

gget( Buf, "Printn" );
if( Buf[0] == 'y' ) {
	NTmov( da_x(x) -1, Ylo-0.15 );  /* print N */
	sprintf( Buf, "N = %d", (int) (val[0]) );
	NTcentext( Buf, 2 );
	}

NTnormline();
}
SHAR_EOF
############################

cat << SHAR_EOF > src/constraint_check.c
/* constraint_check() - checks user parameter value against constraints
   from param. database, if any.  If violated, returns 0, otherwise, returns 1.

   Supported constraint types are:	example:		sample input:
	numeric range			0 to 12			2
	any number			number			3.1415
	set				{center,left,right}	left
	character size			charsize		6
	vector (x,y)			coordpair		3.55 2.00
	character string		token			hello
    *	a list of tokens sep. by space	list			0 0.2 0.4 0.7 1
    *	multi-line text			text			Hello world,
								is there anyone there?
    * No enforcement done here for these types..
*/
#include <stdio.h>
#include "../install.h"

constraint_check( value, constraint )
char value[], constraint[];
{
char token[30], val[30], cn[5][8];
double atof(), fval, high, low;
int i, j, multi, rtnval, nct, ix;

if( strlen( value ) < 1 ) return( 1 ); /* empty */

if( smember( constraint, "list text" )) return( 1 );

/* anything else should be single token (or series of single tokens with like types) */
nct = sscanf( constraint, "%*s %s %s %s %s %s", cn[0], cn[1], cn[2], cn[3], cn[4] );
multi = 0;
for( i = 0; i < nct; i++ ) if( strncmp( &cn[i][1], "list", 4 )==0 ) multi = 1;


/* check members of list.. */
rtnval = 1;
ix = 0;
while( 1 ) {
	strcpy( val, getok( value, &ix ) );
	if( val[0] == '\0' ) break;
	i = 0;

	/* sets */
	if( constraint[i] == '{' ) {
		for( j = i; j < strlen( constraint ); j++ ) if( member( constraint[j], "{,}"  )) constraint[j] = ' ';
		while( 1 ) {
			strcpy( token, getok( constraint, &i ) );
			if( token[0] == '\0' ) { 
				fprintf( stderr, "'%s' illegal.  Legal vals are: { %s }.", val, constraint ); 
				rtnval = 0;
				break;
				}
			if( strcmp( token, val )==0 ) { rtnval = 1; break; }
			}
		}
	
	/* numeric ranges */
	j = i;
	low = atof( getok( constraint, &j ) );
	if( strcmp( getok( constraint, &j ), "to" )==0 ) {
		high = atof( getok( constraint, &j ) );
		fval = atof( val );
		if( fval < low || fval > high ) 
			{ fprintf( stderr, "'%s' out of range. Range is %5.2f to %5.2f.", val, low, high ); rtnval = 0; }
		else rtnval = 1;
		}
	
	/* generic number */
	j = i;
	if( strcmp( getok( constraint, &j ), "number" ) == 0 ) {
		if( ! goodnum( val, &j ) ) 
			{ fprintf( stderr, "'%s' is not a number." , val ); rtnval = 0; }
		else rtnval = 1;
		}
	
	/* coordinate pair */
	j = i;
	if( strcmp( getok( constraint, &j ), "coordpair" ) == 0 ) {
		char val1[12], val2[12];
		sscanf( value, "%s %s", val1, val2 );
		if( !goodnum( val1, &j ) || !goodnum( val2, &j ) )
			{ fprintf( stderr, "'%s' is not a coordinate pair.", value ); rtnval = 0; }
		else rtnval = 1;
		}
	
	/* 2coordpair (rectangle) */
	j = i;
	if( strcmp( getok( constraint, &j ), "2coordpair" ) == 0 ) {
		char val1[12], val2[12], val3[12], val4[12];
		sscanf( value, "%s %s %s %s", val1, val2, val3, val4 );
		if( !goodnum( val1, &j ) || !goodnum( val2, &j ) ||
		    !goodnum( val3, &j ) || !goodnum( val4, &j ) )
			{ fprintf( stderr, "'%s' is not a 2coordpair.", value ); rtnval = 0; }
		else rtnval = 1;
		}
	
	/* char size */
	j = i;
	if( strcmp( getok( constraint, &j ), "charsize" ) == 0 ) {
		fval = atof( val );
		if( fval < 1 || fval > 36.0 ) {
			fprintf( stderr, "'%s' is not a legal char size (1 to 32).", val );
			rtnval = 0;
			}
		else rtnval = 1;
		}

	/* data field */
	j = i;
	if( strcmp( getok( constraint, &j ), "dfield" ) == 0 ) {
		if( atoi( val ) > 0 && atoi( val ) <= MAX_D_COLS ) rtnval = 1;
		else {
			fprintf( stderr, "'%s' is not a legal data field number (1 to %d).", val, MAX_D_COLS );
			rtnval = 0;
			}
		}

	/* font */
	j = i;
	if( strcmp( getok( constraint, &j ), "font" ) == 0 ) {
		if( val[0] != '/' ) {
			fprintf( stderr, "'%s': first character in font name should be '/'.", val );
			rtnval = 0;
			}
		else rtnval = 1;
		}

	/* color */
	j = i;
	if( strcmp( getok( constraint, &j ), "color" ) == 0 ) {
		if( atof( val ) < 0.0 || atof( val ) > 1.0 ) {
			fprintf( stderr, "'%s': color must be a number from 0.0 to 1.0.", val );
			rtnval = 0;
			}
		else rtnval = 1;
		}



	if( rtnval == 0 || !multi ) break;
	}

return( rtnval );
}
SHAR_EOF
############################


-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.



More information about the Comp.sources.unix mailing list