int PLP_usedata( ) { char attr[NAMEMAXLEN], val[256]; char *line, *lineval; int nt, lvp; int first; TDH_errprog( "pl proc usedata" ); if( PLD.curds < 0 ) return( Eerr( 2478, "no data have been read yet", "" )); /* get attributes.. */ first = 1; while( 1 ) { line = getnextattr( first, attr, val, &lvp, &nt ); if( line == NULL ) break; first = 0; lineval = &line[lvp]; if( stricmp( attr, "element" )== 0 ) { if( atoi( val ) <= PLD.curds ) PLD.curds = atoi( val ); } else if( stricmp( attr, "pop" )== 0 ) PLD.curds -= atoi( val ); else if( strnicmp( attr, "original", 8 )== 0 ) PLD.curds = 0; else if( stricmp( attr, "fieldnames" )==0 ) definefieldnames( lineval ); else Eerr( 1, "attribute not recognized", attr ); } if( first == 1 ) PLD.curds = 0; /* no attributes specified - (originaldata) */ if( PLD.curds < 0 ) PLD.curds = 0; if( PLS.debug ) fprintf( PLS.diagfp, "using data set %d\n", PLD.curds ); setintvar( "NRECORDS", Nrecords ); setintvar( "NFIELDS", Nfields ); return( 0 ); }
/* DO_PRELIMINARIES - set defaults, read config file, etc. */ int PL_do_preliminaries() { char buf[512]; FILE *fp; char *filename, *getenv(); char attr[80]; char val[512]; char *lineval; int ix; int valused, found; int i, stat, j; int projectrootfound; char pathslash; char uniq[80]; char configfile[MAXPATH]; char cgierrfile[80]; TDH_errprog( "pl" ); /* set pre-config (hard-coded) defaults.. */ PLS.debug = 0; PLS.echolines = 0; PLS.skipout = 0; PLS.eready = 0; PLS.prefabsdir = NULL; strcpy( PLS.outfile, "" ); PLS.winx = 100; PLS.winy = 0; PLS.winw = 8.0; PLS.winh = 8.0; PLS.winsizegiven = 0; PLS.bkcolorgiven = 0; PLS.clickmap = 0; PLS.usingcm = 0; strcpy( PLS.viewer, "" ); strcpy( PLS.mapfile, "" ); PLS.noshell = 0; TDH_prohibit_shell( 0 ); #ifndef WIN32 TDH_reslimits( "cpu", CPULIMIT ); #endif #ifdef LOCALE setlocale(LC_CTYPE, "" ); setlocale(LC_COLLATE, "" ); #endif #ifdef NOX11 PLS.device = 'e'; #else PLS.device = 'x'; #endif PLD.maxrows = MAXDROWS; PLD.maxdf = MAXD; PLL.maxproclines = MAXPROCLINES; PLVsize = MAXDAT; PLG_set_early_defaults(); PLS.errfp = stderr; /* portability? */ PLS.diagfp = stderr; /* portability? */ PLS.bignumspacer = '\0'; /* use standard number notation */ PLS.bignumthres = 4; suppress_convmsg( 1 ); /* suppress unplottable data msgs by default - user can turn on */ DT_checkdatelengths( 0 ); /* don't be strict about the length of date items */ setintvar( "CM_UNITS", 0 ); projectrootfound = 0; strcpy( TDH_tmpdir, TMPDIR ); pathslash = PATH_SLASH; /* set this now, but it might be updated depending on what's in config file.. */ GL_make_unique_string( uniq, 0 ); sprintf( PLS.tmpname, "%s%cplo%s", TDH_tmpdir, pathslash, uniq ); /* make cgierrfile (default /tmp/plcgi_err) for cgi errors */ sprintf( cgierrfile, "%s%cplcgi_err", TDH_tmpdir, PATH_SLASH ); /* reads and process config file, if any.. */ if( PLS.cgiargs != NULL ) { /* determine name of config file.. (can't use PLOTICUS_CONFIG in CGI context) */ char *cgiprogname; strcpy( buf, "file=" ); strcat( buf, CONFIGFILE ); if( strlen( buf ) == 5 ) { /* CONFIGFILE not set.. retrieve prog name from CGI environment and build config file name from that.. */ cgiprogname = getenv( "SCRIPT_FILENAME" ); if( cgiprogname == NULL ) { PLS.errfp = fopen( cgierrfile, "w" ); if( PLS.errfp != NULL ) { fprintf( PLS.errfp, "cgi var SCRIPT_FILENAME not found.\n" ); #ifdef UNIX fchmod( fileno( PLS.errfp ), 00666 ); #endif } TDH_errfile( PLS.errfp ); /* set it for TDH */ return( 1 ); } strcat( buf, cgiprogname ); j = strlen( buf ) -4; if( strcmp( &buf[ j ], ".cgi" )==0 ) buf[ j ] = '\0'; else if( strcmp( &buf[ j ], ".exe" )==0 ) buf[ j ] = '\0'; strcat( buf, ".cnf" ); } strcpy( configfile, buf ); } else { /* command line usage.. check PLOTICUS_CONFIG.. */ filename = getenv( "PLOTICUS_CONFIG" ); if( filename == NULL ) goto SKIPCONFIG; sprintf( configfile, "file=%s", filename ); } if( strlen( configfile ) == 5 ) { if( PLS.cgiargs != NULL ) goto BAD_CGI_CONFIG; else goto SKIPCONFIG; /* no config file given.. */ } stat = TDH_readconfig( configfile ); /* no point in checking return stat.. */ /* do this again because TDH_tmpdir might have been updated.. */ GL_make_unique_string( uniq, 0 ); sprintf( PLS.tmpname, "%s%cplo%s", TDH_tmpdir, pathslash, uniq ); /* now read it again to get pl-specific items.. */ fp = fopen( &configfile[5], "r" ); if( fp == NULL ) { if( PLS.cgiargs != NULL ) { BAD_CGI_CONFIG: PLS.errfp = fopen( cgierrfile, "w" ); if( PLS.errfp != NULL ) { fprintf( PLS.errfp, "cgi mode: cannot open config file (%s).\n", &configfile[5] ); #ifdef UNIX fchmod( fileno( PLS.errfp ), 00666 ); #endif } return( 1 ); } else Eerr( 15060, "Cannot open ploticus config file", &configfile[5] ); return( 0 ); } /* get user settings.. */ while( fgets( buf, 511, fp ) != NULL ) { buf[ strlen( buf ) -1 ] = '\0'; ix = 0; strcpy( attr, GL_getok( buf, &ix ) ); if( attr[0] == '\0' ) continue; if( attr[0] == '#' || attr[0] == '/' ) continue; /* skip comments of various kinds */ while( isspace( (int) buf[ix] ) )ix++; lineval = &buf[ix]; strcpy( val, GL_getok( buf, &ix ) ); if( attr[ strlen( attr ) -1 ] == ':' ) attr[ strlen( attr ) - 1 ] = '\0'; /* attributes that exist in config file, but not proc settings, go here: */ if( strcmp( attr, "projectroot" )==0 ) { stat = chdir( val ); if( stat != 0 ) goto CGI_BAD_CHDIR; projectrootfound = 1; if( PLS.debug ) fprintf( PLS.diagfp, "config: found projectroot.. chdir to %s..\n", val ); } else if( strcmp( attr, "option" )==0 ) { val[0] = '\0'; sscanf( buf, "%*s %s %s", attr, val ); /* check for embedded '=' in attr.. if found indicates prefab parm setting.. send lineval as attr.. */ for( i = 0, found = 0; attr[i] != '\0'; i++ ) if( attr[i] == '=' ) { found = 1; break; } if( found ) { strcpy( attr, lineval ); strcpy( val, "" ); } if( PLS.debug ) fprintf( PLS.diagfp, "config file: got option: %s %s\n", attr, val ); PL_process_arg( attr, val, &valused, &found ); if( !found ) Eerr( 2784, "invalid 'option:' in config file", attr ); } /* shared settings takes care of settings that can be set in config file OR proc settings */ else { stat = PL_sharedsettings( attr, val, lineval ); if( stat == 0 && PLS.debug ) fprintf( PLS.diagfp, "config: setting %s to %s\n", attr, lineval ); } /* don't forget that there are other settings (tmpdir, date-related, etc.) * that were handled by the TDH config file reader !! */ } fclose( fp ); SKIPCONFIG: if( PLS.cgiargs != NULL && !projectrootfound ) { CGI_BAD_CHDIR: PLS.errfp = fopen( cgierrfile, "w" ); if( PLS.errfp != NULL ) { fprintf( PLS.errfp, "cgi mode: no projectroot in config file, or could not chdir to projectroot\n" ); #ifdef UNIX fchmod( fileno( PLS.errfp ), 00666 ); #endif } return( 1 ); } /* get prefabs directory name if available.. */ /* this must come after config file is read, because in cgi mode PLOTICUS_PREFABS is set via config file. */ PLS.prefabsdir = getenv( "PLOTICUS_PREFABS" ); if( PLS.prefabsdir != NULL ) { TDH_setspecialincdir( PLS.prefabsdir ); /* set special include directory (#include $foo) */ /* note: prefabsdir must reference static storage, either via getenv() or constant */ } return( 0 ); }
int PLP_print() { int i, lvp, first; char attr[NAMEMAXLEN], *line, *lineval; char *printstring, *label, *selectex, *outfile, *outmode; char buf[512], tok[80]; int result, dontclose, nrecords; FILE *outfp; TDH_errprog( "pl proc print" ); /* initialize */ printstring = ""; label = ""; selectex = ""; outfile = ""; outmode = "w"; /* get attributes.. */ first = 1; while( 1 ) { line = getnextattr( first, attr, &lvp ); if( line == NULL ) break; first = 0; lineval = &line[lvp]; if( strcmp( attr, "select" )==0 ) selectex = lineval; else if( strcmp( attr, "label" )==0 ) { label = lineval; convertnl( label ); } else if( strcmp( attr, "print" )==0 ) { printstring = lineval; convertnl( printstring ); } else if( strcmp( attr, "outfile" )==0 ) outfile = lineval; else if( strcmp( attr, "outmode" )==0 ) outmode = lineval; else Eerr( 1, "attribute not recognized", attr ); } if( printstring[0] != '\0' && Nrecords < 1 ) return( Eerr( 17, "Warning: no data has been read yet w/ proc getdata", "" ) ); fprintf( PLS.errfp, "Warning, proc print is deprecated in 2.40\n" ); /* now do the work.. */ dontclose = 0; if( outfile[0] != '\0' ) { sprintf( tok, "%c", outmode[0] ); outfp = fopen( outfile, tok ); if( outfp == NULL ) { Eerr( 7259, "cannot open outfile", outfile ); outfp = PLS.diagfp; dontclose = 1; } } else { outfp = PLS.diagfp; dontclose = 1; } if( label[0] != '\0' ) fprintf( outfp, "%s\n", label ); nrecords = 0; for( i = 0; i < Nrecords; i++ ) { do_select( selectex, i, &result ); if( result == 1 ) { if( printstring[0] != '\0' ) { do_subst( buf, printstring, i, NORMAL ); fprintf( outfp, "%s\n", buf ); } nrecords++; } } setintvar( "NSELECTED", nrecords ); if( !dontclose ) fclose( outfp ); return( 0 ); }
int PLP_scatterplot() { int i; char attr[NAMEMAXLEN], val[256]; char *line, *lineval; int nt, lvp; int first; int stat; int align; double adjx, adjy; int xfield, yfield; char symbol[256]; double linelen; char linedetails[256]; double xloc, yloc; int cluster; double radius; char symcode[80]; double x, y; char text[256]; double cx, cy; double hlinelen; char textdetails[256]; int lblfield; char selex[256]; int result; double sizescale; int sizefield; double ox[38], oy[38]; double clusterfact; double oldx, oldy; int dupcount; int subdupcount; int clustevery; int verttext; int nrow; char legendlabel[256]; /* raised (can contain urls for clickmap) scg 4/22/04 */ char xrange[80], yrange[80]; double xlo, xhi, ylo, yhi; char rhi[40], rlo[40]; double clusterdiff; int realrow; int clustermeth; int symfield; int symfield_userange; int dupsleg; char mapurl[MAXPATH], expurl[MAXPATH]; char maplabel[MAXTT], explabel[MAXTT]; int irow; double ptx, pty; double hw, txhi; char linedir, reqlinedir; double rectw, recth; int dorect, rectoutline; int clickmap_on; int flop2; int maxdups; char labelword[80], labeltxt[80]; double vennden; TDH_errprog( "pl proc scatterplot" ); /* initialize */ xfield = -1; yfield = -1; strcpy( symbol, "" ); linelen = -1.0; strcpy( linedetails, "" ); xloc = 0.0; yloc = 0.0; /* cluster = 1; */ cluster = 0; /* changed and added to "breakers" in docs, scg 5/29/06 */ strcpy( text, "" ); strcpy( textdetails, "" ); lblfield = -1; strcpy( selex, "" ); sizefield = -1; sizescale = 0.5/72.0; /* correspond roughly with pt size */ clusterfact = 0.01; verttext = 0; strcpy( legendlabel, "" ); strcpy( xrange, "" ); strcpy( yrange, "" ); clustevery = 0; clusterdiff = 0.001; clustermeth = 0; symfield = -1; dupsleg = 0; symfield_userange = 0; strcpy( mapurl, "" ); strcpy( expurl, "" ); strcpy( maplabel, "" ); strcpy( explabel, "" ); dorect = 0; rectoutline = 0; linedir = reqlinedir = '\0'; /* scg 3/4/03 */ clickmap_on = 0; strcpy( labelword, "@VAL" ); vennden = 0.0; /* get attributes.. */ first = 1; while( 1 ) { line = getnextattr( first, attr, val, &lvp, &nt ); if( line == NULL ) break; first = 0; lineval = &line[lvp]; if( stricmp( attr, "xfield" )==0 ) xfield = fref( val ) -1; else if( stricmp( attr, "yfield" )==0 ) yfield = fref( val ) -1; else if( stricmp( attr, "labelfield" )==0 ) lblfield = fref( val ) -1; else if( stricmp( attr, "symbol" )==0 ) strcpy( symbol, lineval ); else if( stricmp( attr, "text" )==0 ) strcpy( text, val ); else if( stricmp( attr, "textdetails" )==0 ) strcpy( textdetails, lineval ); else if( stricmp( attr, "sizefield" )==0 ) sizefield = fref( val ) -1; else if( stricmp( attr, "sizescale" )==0 ) sizescale = atof( val ) * 0.5/72.0; else if( stricmp( attr, "xrange" )==0 ) strcpy( xrange, lineval ); else if( stricmp( attr, "yrange" )==0 ) strcpy( yrange, lineval ); else if( stricmp( attr, "clickmapurl" )==0 ) { if( PLS.clickmap ) { strcpy( mapurl, val ); clickmap_on = 1; } } else if( stricmp( attr, "clickmaplabel" )==0 ) { if( PLS.clickmap ) { strcpy( maplabel, lineval ); clickmap_on = 1; } } else if( stricmp( attr, "clickmaplabeltext" )==0 ) { if( PLS.clickmap ) { getmultiline( "clickmaplabeltext", lineval, MAXTT, maplabel ); clickmap_on = 1; } } else if( stricmp( attr, "linelen" )==0 ) { if( val[0] == '\0' ) linelen = -1.0; else { linelen = atof( val ); if( PLS.usingcm ) linelen /= 2.54; } } else if( stricmp( attr, "linedir" )==0 ) reqlinedir = tolower( val[0] ); else if( stricmp( attr, "linedetails" )==0 ) strcpy( linedetails, lineval ); else if( stricmp( attr, "xlocation" )==0 ) { Eposex( lineval, X, &xloc ); /* val -> lineval scg 5/3/99 */ if( Econv_error() ) Eerr( 2394, "invalid xlocation", val ); } else if( stricmp( attr, "ylocation" )==0 ) { Eposex( lineval, Y, &yloc ); /* val -> lineval 5/3/99 */ if( Econv_error() ) Eerr( 2395, "invalid ylocation", val ); } else if( stricmp( attr, "select" )==0 ) strcpy( selex, lineval ); else if( stricmp( attr, "legendlabel" )==0 ) strcpy( legendlabel, lineval ); else if( stricmp( attr, "cluster" )==0 ) { if( strnicmp( val, YESANS, 1 )==0 ) cluster = 1; else cluster = 0; } else if( stricmp( attr, "clusterdiff" )==0 ) { cluster = 1; clusterdiff = atof( val ); } else if( stricmp( attr, "clustermethod" )==0 ) { cluster = 1; clustermeth = tolower( val[0] ); /* h, v, 2, u, r, .. */ } else if( stricmp( attr, "clusterfact" )==0 ) { cluster = 1; clusterfact = atof( val ) * .01; } else if( stricmp( attr, "clustevery" )==0 ) { cluster = 1; clustevery = atoi( val ); if( clustevery < 1 ) clustevery = 1; } else if( stricmp( attr, "dupsleg" )==0 ) { if( strnicmp( val, YESANS, 1 )==0 ) { dupsleg = 1; cluster = 1; clustermeth = 'l'; strcpy( symbol, "sym6a" ); /* just to get us into symbol mode */ } else dupsleg = 0; } else if( stricmp( attr, "symfield" )==0 ) { strcpy( symbol, "sym6a" ); /* just to get us into symbol mode */ symfield = fref( val ) -1; symfield_userange = 0; } else if( stricmp( attr, "symrangefield" )==0 ) { strcpy( symbol, "sym6a" ); /* just to get us into symbol mode */ symfield = fref( val ) -1; symfield_userange = 1; } else if( stricmp( attr, "verticaltext" )==0 ) { if( strnicmp( val, YESANS, 1 )==0 ) verttext = 1; else verttext = 0; } else if( stricmp( attr, "rectangle" )==0 ) { nt = sscanf( lineval, "%lf %lf %s", &rectw, &recth, val ); if( nt == 3 ) rectoutline = 1; rectw *= 0.5; recth *= 0.5; rectw = Eax( rectw ) - Eax( 0.0 ); recth = Eay( recth ) - Eay( 0.0 ); dorect = 1; } else if( stricmp( attr, "labelword" ) == 0 ) strcpy( labelword, lineval ); else if( stricmp( attr, "vennden" ) == 0 ) vennden = atof( val ); else Eerr( 1, "attribute not recognized", attr ); } /* overrides and degenerate cases */ /* -------------------------- */ if( Nrecords < 1 ) return( Eerr( 17, "No data has been read yet w/ proc getdata", "" ) ); if( !scalebeenset() ) return( Eerr( 51, "No scaled plotting area has been defined yet w/ proc areadef", "" ) ); if( xfield < 0 && yfield < 0 ) return( Eerr( 2205, "Niether xfield nor yfield defined", "" )); if( lblfield >= 0 ) cluster = 0; /* added scg 12/21/00 */ if( stricmp( legendlabel, "#usexname" )==0 ) getfname( xfield+1, legendlabel ); if( stricmp( legendlabel, "#useyname" )==0 ) getfname( yfield+1, legendlabel ); if( dorect ) strcpy( symbol, "" ); /* now do the plotting work.. */ /* -------------------------- */ if( cluster ) { /* make offsets */ for( i = 0; i < 38; i++ ) { ox[i] = xofst[i] * clusterfact; oy[i] = yofst[i] * clusterfact; } /* determine cluster method */ if( clustermeth == 0 ) { if( yfield < 0 ) clustermeth = 'v'; /* 1-d horizontal - cluster vertically (was 'h'-scg 4/21/05) */ else if( xfield < 0 ) clustermeth = 'h'; /* 1-d vertical - cluster horizontally (was 'v'-scg 4/21/05) */ else clustermeth = '2'; /* 2-d cluster */ } } /* ranges */ xlo = EDXlo; xhi = EDXhi; ylo = EDYlo; yhi = EDYhi; if( xrange[0] != '\0' ) { nt = sscanf( xrange, "%s %s", rlo, rhi ); xlo = Econv( X, rlo ); if( Econv_error() ) { Eerr( 3958, "xrange bad format", rlo ); xlo = EDXlo; } if( nt == 2 ) xhi = Econv( X, rhi ); if( Econv_error() ) { Eerr( 3958, "xrange bad format", rhi ); xhi = EDXhi; } } if( yrange[0] != '\0' ) { nt = sscanf( yrange, "%s %s", rlo, rhi ); ylo = Econv( Y, rlo ); if( Econv_error() ) { Eerr( 3958, "yrange bad format", rlo ); ylo = EDYlo; } if( nt == 2 ) yhi = Econv( Y, rhi ); if( Econv_error() ) { Eerr( 3958, "yrange bad format", rhi ); yhi = EDYhi; } } nrow = 0; for( i = 0; i < Nrecords; i++ ) { if( selex[0] != '\0' ) { /* process against selection condition if any.. */ stat = do_select( selex, i, &result ); if( stat != 0 ) { Eerr( stat, "Select error", selex ); continue; } if( result == 0 ) continue; /* reject */ } /* get x value.. */ if( xfield >= 0 ) { x = fda( i, xfield, 'x' ); if( Econv_error() ) { conv_msg( i, xfield, "xfield" ); continue; } if( x < xlo || x > xhi ) continue; } /* get y value.. */ if( yfield >= 0 ) { y = fda( i, yfield, 'y' ); if( Econv_error() ) { conv_msg( i, yfield, "yfield" ); continue; } if( y < ylo || y > yhi ) continue; } /* go to absolute units.. */ if( xfield < 0 ) x = xloc; else x = Eax(x); if( yfield < 0 ) y = yloc; else y = Eay(y); /* put (x,y) into PLV array so points can be sorted.. */ if( nrow >= PLVthirdsize ) { fprintf( PLS.errfp, "point capacity exceeded, skipping data point (raise using -maxvector)\n" ); continue; } dat3d( nrow, 0 ) = x; dat3d( nrow, 1 ) = y; dat3d( nrow, 2 ) = (double)i; /* added scg 12/21/00 - went from dat2d to dat3d */ /* need to keep track of actual location in data array for labels, sizefield, etc.. */ nrow++; } /* if clustering and not using a label field, sort PLV array */ if( cluster && lblfield < 0 && sizefield < 0 ) { if( PLS.debug ) fprintf( PLS.diagfp, "sorting points for scatterplot\n" ); qsort( PLV, nrow, sizeof(double)*3, ptcompare ); } if( verttext ) Etextdir( 90 ); /* these are used in clustering.. */ oldx = NEGHUGE; oldy = NEGHUGE; dupcount = 0; subdupcount = 0; maxdups = 0; strcpy( symcode, "sym6a" ); radius = 0.04; /* in the following, text must come before symbol.. */ if( text[0] != '\0' || lblfield >= 0 ) { textdet( "textdetails", textdetails, &align, &adjx, &adjy, -3, "R", 1.0 ); } if( symbol[0] != '\0' ) { symdet( "symbol", symbol, symcode, &radius ); } if( linelen > 0.0 || rectoutline ) { linedet( "linedetails", linedetails, 0.5 ); } cx = Ecurtextwidth * 0.3; cy = Ecurtextheight * 0.3; hlinelen = linelen * 0.5; txhi = cy + cy; if( text[0] != '\0' ) hw = strlen( text ) * Ecurtextwidth * 0.5; /* now display points.. */ for( irow = 0; irow < nrow; irow++ ) { x = dat3d( irow, 0 ); y = dat3d( irow, 1 ); realrow = (int)dat3d( irow, 2 ); /* added scg 12/21/00 */ /* in this loop, you MUST USE REALROW, NOT IROW for accessing ancillary data fields!! */ if( cluster ) { if( GL_close_to( x, oldx, clusterdiff ) && GL_close_to( y, oldy, clusterdiff ) ) { subdupcount++; if( subdupcount >= clustevery ) { dupcount++; subdupcount = 0; } if( dupcount % 2 == 0 ) flop2 = 1; else flop2 = -1; if( clustermeth == '2' && dupcount > 37 ) { maxdups = 37; dupcount = 0; /* mod */ } if( clustermeth == 'h' ) x += ((dupcount+1)/2) * clusterfact * 2.0 * flop2; else if( clustermeth == 'v' ) y += ((dupcount+1)/2) * clusterfact * 2.0 * flop2; else if( clustermeth == 'u' ) y += dupcount * clusterfact * 2.0; /* 1D upward */ else if( clustermeth == 'r' ) x += dupcount * clusterfact * 2.0; /* 1D rightward */ else if( clustermeth == 'l' ) ; /* legend lookup, no offset */ else if( clustermeth == '2' ) { x += ox[dupcount%38]; y += oy[dupcount%38]; } /* 2-D */ if( clustermeth == 'l' ) { /* if more duplicate points coming, skip.. */ if( irow < nrow-1 ) { double nextx, nexty; nextx = dat3d( irow+1, 0 ); nexty = dat3d( irow+1, 1 ); if( GL_close_to( x, nextx, clusterdiff ) && GL_close_to( y, nexty, clusterdiff ) ) continue; } } } else { if( dupcount > maxdups ) maxdups = dupcount; oldx = x; oldy = y; dupcount = 0; subdupcount = 0; } } /* allow @field substitutions into url */ if( clickmap_on ) { do_subst( expurl, mapurl, realrow, URL_ENCODED ); do_subst( explabel, maplabel, realrow, NORMAL ); } /* render text, mark or line.. */ /* text can be combined with mark if text and symbol both specified */ /* symbol or rectangle.. */ if( symbol[0] != '\0' || dorect || ( text[0] == '\0' && linelen <= 0.0 && lblfield < 0 ) ) { if( symfield >= 0 ) { /* look it up in legend list.. */ if( symfield_userange ) { stat = PL_get_legent_rg( atof( da( realrow, symfield ) ), symbol, NULL, NULL ); } else stat = PL_get_legent( da( realrow, symfield ), symbol, NULL, NULL ); if( stat ) Eerr( 7429, "warning: symfield: no matching legend entry tag found", da( realrow, symfield ) ); if( !dorect ) symdet( "symfield", symbol, symcode, &radius ); } if( dupsleg ) { /* look it up in legend list.. */ stat = PL_get_legent_rg( (double)dupcount+1, symbol, NULL, NULL ); if( stat ) Eerr( 7692, "warning: dupsleg: no appropriate legend entry tag\n", "" ); if( !dorect ) symdet( "symfield", symbol, symcode, &radius ); /* note: currently all marks will be rendered; the last one will be on "top" */ } if( sizefield >= 0 ) radius = sqrt((atof( da( realrow, sizefield ) ) * sizescale)/3.1415927); /* sizefield scales up the AREA of symbol, not the diameter */ if( dorect ) { char color[ COLORLEN ]; strcpy( color, "" ); /* added scg 9/1/05 - heatmap bug */ if( symfield >=0 || dupsleg ) sscanf( symbol, "%s", color ); /* strip off any trailing space */ Ecblock( x-rectw, y-recth, x+rectw, y+recth, color, rectoutline ); symbol[0] = '\0'; } else if( vennden > 0.0 ) { double urad; for( urad = 0.01; urad < radius; urad += vennden ) Emark( x, y, symcode, urad ); } else Emark( x, y, symcode, radius ); if( clickmap_on ) { if( dorect ) clickmap_entry( 'r', expurl, 0, x-rectw, y-recth, x+rectw, y+recth, 0, 0, explabel ); else clickmap_entry( 'r', expurl, 0, x-radius, y-radius, x+radius, y+radius, 0, 0, explabel ); } } /* text */ if( text[0] != '\0' ) { if( symbol[0] != '\0' ) /* set text color etc... */ textdet( "textdetails", textdetails, &align, &adjx, &adjy, -3, "R", 1.0 ); if( sizefield >= 0 ) Etextsize( (int) (atof( da( realrow, sizefield ) ) * sizescale) ); if( verttext ) { ptx = (x+cy)+adjx; pty = y; } /* cy puts midheight of character on point */ else { ptx = x+adjx; pty = (y-cy)+adjy; } convertnl( text ); Emov( ptx, pty ); if( align == '?' ) Edotext( text, 'C' ); else Edotext( text, align ); if( symbol[0] != '\0' ) /* restore symbol color etc... */ symdet( "symbol", symbol, symcode, &radius ); if( clickmap_on ) clickmap_entry( 'r', expurl, 0, ptx-hw, pty, x+hw, y+txhi, 0, 0, explabel ); } /* label from data */ else if( lblfield >= 0 ) { if( sizefield >= 0 ) Etextsize( (int) (atof( da( realrow, sizefield ) ) * sizescale) ); if( verttext) { ptx = (x+cy)+adjx; pty = y+adjy; } /* cy puts midheight of character on point */ else { ptx = x+adjx; pty = (y-cy)+adjy; } strcpy( labeltxt, labelword ); GL_varsub( labeltxt, "@VAL", da( realrow, lblfield ) ); Emov( ptx, pty ); if( align == '?' ) Edotext( labeltxt, 'C' ); else Edotext( labeltxt, align ); if( clickmap_on ) { hw = strlen( labeltxt ) * Ecurtextwidth * 0.5; if( GL_member( align, "C?" ))clickmap_entry( 'r', expurl, 0, ptx-hw, pty, x+hw, y+txhi, 0, 0, explabel ); else if( align == 'L' ) clickmap_entry( 'r', expurl, 0, ptx, pty, x+(hw*2.0), y+txhi, 0, 0, explabel ); else if( align == 'R' ) clickmap_entry( 'r', expurl, 0, ptx-(hw*2.0), pty, x, y+txhi, 0, 0, explabel ); } } /* line */ /* (no clickmap support) */ /* no legend support either (?) */ else if( linelen > 0.0 ) { if( sizefield >= 0 ) hlinelen = linelen * 0.5 * atof( da( realrow, sizefield ) ); /* sizefield acts as a scale factor to linelen */ if( reqlinedir != '\0' ) linedir = reqlinedir; else if( xfield >= 0 && yfield >= 0 ) linedir = 'h'; /* arbitrary .. scg 5/16/03 */ else if( xfield >= 0 ) linedir = 'v'; else linedir = 'h'; /* scg 3/5/03 */ if( linedir == 'v' ) { Emov( x, y-hlinelen ); Elin( x, y+hlinelen ); } else if( linedir == 'u' ) { Emov( x, y ); Elin( x, y+(hlinelen*2.0) ); } else if( linedir == 'r' ) { Emov( x, y ); Elin( x+(hlinelen*2.0), y ); } else { Emov( x-hlinelen, y ); Elin( x+hlinelen, y ); } } } if( verttext ) Etextdir( 0 ); if( legendlabel[0] != '\0' ) { char s[40]; sprintf( s, "%d", nrow ); GL_varsub( legendlabel, "@NVALUES", s ); if( linelen <= 0.0 && lblfield < 0 && text[0] == '\0' ) PL_add_legent( LEGEND_SYMBOL, legendlabel, "", symbol, "", "" ); else if( symbol[0] != '\0' && text[0] != '\0' ) PL_add_legent( LEGEND_SYMBOL+LEGEND_TEXT, legendlabel, "", text, textdetails, symbol ); else if( linelen > 0.0 ) { char dirstr[8]; sprintf( dirstr, "%c", linedir ); PL_add_legent( LEGEND_LINEMARK, legendlabel, "", linedetails, dirstr, "" ); } } setintvar( "NVALUES", nrow ); maxdups++; setintvar( "MAXDUPS", maxdups ); return( 0 ); }