/*******************************************************/
/* Linux GNU C++ Compiler */
/* Name : fastpictex.cc */
/* Autor: Harald Stauss */
/*******************************************************/
FASTPICTEX::~FASTPICTEX() { /* Destructor */
int i;
unsigned long j;
for (i=0; i<nofseries; i++) {
free(series[i].x);
free(series[i].y);
free(series[i].dx);
free(series[i].dy);
for (j=0; j<series[i].ny; j++)
delete[]series[i].sig[j];
free(series[i].sig);
free(series[i].legend);
}
for (j=0; j<nxticlabels; j++)
delete[]xticlabels[j];
delete[]xticlabels;
free(series);
free(xlabel);
free(ylabel);
free(heading);
for (i=0; i<nofrawpictex; i++) free(rawpictex[i]);
free(rawpictex);
}
/* function to read input file */
int FASTPICTEX::Read(char *fname) {
std::ifstream fptin;
int i, j, rc=0;
int nx, ny, ndx, ndy, ntype, nsize, nlegend;
short is_newcommand;
char *s, *fpt_command, *token, *hchar;
unsigned long n, ndata, nallocdata=100;
float *data, wert;
short is_multiword;
extern int myatof(char *s, float *f);
extern char *getsig(char *s);
/* open input file */
fptin.open(fname);
if (!fptin) {
rc=1;
std::cout << "Cannot open input file! \n";
return(rc);
}
/* Hauptschleife */
fptin.getline(hchar,MAX_FIELD_LENGTH);
strcpy(s,hchar);
while (fptin.fail() && !fptin.eof()) {
fptin.clear();
fptin.getline(hchar,MAX_FIELD_LENGTH);
s=(char *)realloc(s, strlen(s)+strlen(hchar)+1);
strcat(s, hchar);
}
while(!fptin.eof()) {
/* new command or continue with old command */
if (strchr(WHITE_SPACE, s[0])) {
fpt_command=(char *)realloc(fpt_command, strlen(fpt_command)+strlen(s)+1);
s=(char *)realloc(s, strlen(fpt_command)+strlen(s)+1);
strcat(fpt_command, s);
strcpy(s, fpt_command);
is_newcommand=0;
}
else {
is_newcommand=1;
}
/* get first token */
token=strtok(s, WHITE_SPACE);
strcpy(fpt_command, token);
/* work on commands */
/* comment */
if (!strcmp(fpt_command, "%")) {
/* do nothing */
}
/* size */
else if (!strcmp(fpt_command, "size")) {
token=fpt_command;
if (is_newcommand) {
nsize=0;
}
while (token) {
token=strtok(NULL, WHITE_SPACE);
if (token) {
if (nsize==0) {
if (myatof(token, &wert)) {
width=wert;
nsize++;
}
}
else if (nsize==1) {
if (myatof(token, &wert)) {
height=wert;
nsize++;
}
}
} /* endif */
} /* endwhile */
}
/* xlabel */
else if (!strcmp(fpt_command, "xlabel")) {
token=fpt_command;
if (is_newcommand) strcpy(xlabel, "");
else strcat(xlabel, " ");
while (token) {
token=strtok(NULL, WHITE_SPACE);
if (token) {
xlabel=(char *)realloc(xlabel, strlen(xlabel)+strlen(token)+2);
strcat(xlabel, token); strcat(xlabel, " ");
} /* endif */
} /* endwhile */
xlabel[strlen(xlabel)-1]='\0';
}
/* ylabel */
else if (!strcmp(fpt_command, "ylabel")) {
token=fpt_command;
if (is_newcommand) strcpy(ylabel, "");
else strcat(ylabel, " ");
while (token) {
token=strtok(NULL, WHITE_SPACE);
if (token) {
ylabel=(char *)realloc(ylabel, strlen(ylabel)+strlen(token)+2);
strcat(ylabel, token); strcat(ylabel, " ");
} /* endif */
} /* endwhile */
ylabel[strlen(ylabel)-1]='\0';
}
/* heading */
else if (!strcmp(fpt_command, "heading")) {
token=fpt_command;
if (is_newcommand) strcpy(heading, "");
else strcat(heading, " ");
while (token) {
token=strtok(NULL, WHITE_SPACE);
if (token) {
heading=(char *)realloc(heading, strlen(heading)+strlen(token)+2);
strcat(heading, token); strcat(heading, " ");
} /* endif */
} /* endwhile */
heading[strlen(heading)-1]='\0';
}
/* graph type */
else if (!strcmp(fpt_command, "type")) {
if (is_newcommand) {
ntype++;
if (ntype>nofseries) {
AddSeries();
}
}
token=fpt_command;
token=strtok(NULL, WHITE_SPACE);
if (!token) {
series[ntype-1].type=0;
}
if (!strcmp(token, "xy")) {
series[ntype-1].type=1;
}
else if (!strcmp(token, "line")) {
series[ntype-1].type=2;
}
else if (!strcmp(token, "bar")) {
series[ntype-1].type=3;
nofbar++;
}
else {
series[ntype-1].type=0;
}
}
/* trendline */
else if (!strcmp(fpt_command, "tline")) {
if (is_newcommand) {
noftline++;
if (noftline>nofseries) {
AddSeries();
}
}
//series[noftline-1].tline=1;
token=fpt_command;
/* read one more token */
token=strtok(NULL, WHITE_SPACE);
if (token) series[noftline-1].tline=atoi(token);
/* read remaining tokens to go to end of line */
while (token) {
token=strtok(NULL, WHITE_SPACE);
}
}
/* legend */
else if (!strcmp(fpt_command, "legend")) {
if (is_newcommand) {
nlegend++;
if (nlegend>nofseries) {
AddSeries();
}
}
token=fpt_command;
if (is_newcommand) {
series[nlegend-1].legend=(char *)realloc(series[nlegend-1].legend, sizeof(char));
strcpy(series[nlegend-1].legend, "");
}
else {
series[nlegend-1].legend=(char *)realloc(series[nlegend-1].legend,
(strlen(series[nlegend-1].legend)+2)*sizeof(char));
strcat(series[nlegend-1].legend, " ");
}
while (token) {
token=strtok(NULL, WHITE_SPACE);
if (token) {
series[nlegend-1].legend=(char *)realloc(series[nlegend-1].legend,
(strlen(series[nlegend-1].legend)+strlen(token)+2)*sizeof(char));
strcat(series[nlegend-1].legend, token);
strcat(series[nlegend-1].legend, " ");
} /* endif */
} /* endwhile */
series[nlegend-1].legend[strlen(series[nlegend-1].legend)-1]='\0';
}
/* pictex commands */
else if (!strcmp(fpt_command, "pictex")) {
token=fpt_command;
if (is_newcommand) {
nofrawpictex++;
rawpictex=(char **)realloc(rawpictex, nofrawpictex*sizeof(char *));
rawpictex[nofrawpictex-1]=(char *)malloc(sizeof(char));
strcpy(rawpictex[nofrawpictex-1], "");
}
else {
rawpictex[nofrawpictex-1]=(char *)realloc(rawpictex[nofrawpictex-1],
(strlen(rawpictex[nofrawpictex-1])+2)*sizeof(char));
strcat(rawpictex[nofrawpictex-1], " ");
}
while (token) {
token=strtok(NULL, WHITE_SPACE);
if (token) {
rawpictex[nofrawpictex-1]=(char *)realloc(rawpictex[nofrawpictex-1],
(strlen(rawpictex[nofrawpictex-1])+strlen(token)+2)*sizeof(char));
strcat(rawpictex[nofrawpictex-1], token);
strcat(rawpictex[nofrawpictex-1], " ");
} /* endif */
} /* endwhile */
rawpictex[nofrawpictex-1][strlen(rawpictex[nofrawpictex-1])-1]='\0';
}
/* x coordinates */
else if (!strcmp(fpt_command, "x")) {
if (is_newcommand) {
ndata=0;
nx++;
if (nx>nofseries) {
AddSeries();
}
}
token=fpt_command;
while (token) {
token=strtok(NULL, WHITE_SPACE);
if (token) {
if (ndata>=nallocdata) {
nallocdata+=100;
data=(float *)realloc(data, nallocdata*sizeof(float));
} /* endif */
data[ndata]=atof(token);
ndata++;
} /* endif */
} /* endwhile */
series[nx-1].nx=ndata;
series[nx-1].x=(float *)realloc(series[nx-1].x, ndata*sizeof(float));
for (n=0; n<ndata; n++) {
series[nx-1].x[n]=data[n];
}
}
/* y coordinates */
else if (!strcmp(fpt_command, "y")) {
if (is_newcommand) {
ndata=0;
ny++;
if (ny>nofseries) {
AddSeries();
}
}
token=fpt_command;
while (token) {
token=strtok(NULL, WHITE_SPACE);
if (token) {
if (ndata>=nallocdata) {
nallocdata+=100;
data=(float *)realloc(data, nallocdata*sizeof(float));
} /* endif */
series[ny-1].sig=(char **)realloc(series[ny-1].sig, (ndata+1)*sizeof(char *));
series[ny-1].sig[ndata]=getsig(token);
data[ndata]=atof(token);
ndata++;
} /* endif */
} /* endwhile */
series[ny-1].ny=ndata;
series[ny-1].y=(float *)realloc(series[ny-1].y, ndata*sizeof(float));
for (n=0; n<ndata; n++) {
series[ny-1].y[n]=data[n];
}
}
/* dx coordinates */
else if (!strcmp(fpt_command, "dx")) {
if (is_newcommand) {
need_errorbarmacros=1;
ndata=0;
ndx++;
if (ndx>nofseries) {
AddSeries();
}
}
token=fpt_command;
while (token) {
token=strtok(NULL, WHITE_SPACE);
if (token) {
if (ndata>=nallocdata) {
nallocdata+=100;
data=(float *)realloc(data, nallocdata*sizeof(float));
} /* endif */
data[ndata]=atof(token);
ndata++;
} /* endif */
} /* endwhile */
series[ndx-1].ndx=ndata;
series[ndx-1].dx=(float *)realloc(series[ndx-1].dx, ndata*sizeof(float));
for (n=0; n<ndata; n++) {
series[ndx-1].dx[n]=data[n];
}
}
/* dy coordinates */
else if (!strcmp(fpt_command, "dy")) {
if (is_newcommand) {
need_errorbarmacros=1;
ndata=0;
ndy++;
if (ndy>nofseries) {
AddSeries();
}
}
token=fpt_command;
while (token) {
token=strtok(NULL, WHITE_SPACE);
if (token) {
if (ndata>=nallocdata) {
nallocdata+=100;
data=(float *)realloc(data, nallocdata*sizeof(float));
} /* endif */
data[ndata]=atof(token);
ndata++;
} /* endif */
} /* endwhile */
series[ndy-1].ndy=ndata;
series[ndy-1].dy=(float *)realloc(series[ndy-1].dy, ndata*sizeof(float));
for (n=0; n<ndata; n++) {
series[ndy-1].dy[n]=data[n];
}
}
/* xticlabels */
else if (!strcmp(fpt_command, "xticlabels")) {
is_multiword=0; nxticlabels=0;
token=fpt_command;
while (token) {
token=strtok(NULL, WHITE_SPACE);
if (token) {
if (is_multiword) {
xticlabels[nxticlabels-1]=(char *)realloc(xticlabels[nxticlabels-1],
strlen(xticlabels[nxticlabels-1])+1
+strlen(token)+1);
strcat(xticlabels[nxticlabels-1], " ");
strcat(xticlabels[nxticlabels-1], token);
if (token[strlen(token)-1]=='"') {
xticlabels[nxticlabels-1][strlen(xticlabels[nxticlabels-1])-1]='\0';
is_multiword=0;
}
}
else {
if (token[0]=='"') {
is_multiword=1;
token++;
}
nxticlabels++;
xticlabels=(char **)realloc(xticlabels, nxticlabels * sizeof(char *));
xticlabels[nxticlabels-1]=new char [strlen(token)+1];
strcpy(xticlabels[nxticlabels-1], token);
if (token[strlen(token)-1]=='"') {
xticlabels[nxticlabels-1][strlen(xticlabels[nxticlabels-1])-1]='\0';
is_multiword=0;
}
}
} /* endif */
} /* endwhile */
}
/* xgrid lines */
else if (!strcmp(fpt_command, "xgrid")) {
xgrid=1;
}
/* ygrid lines */
else if (!strcmp(fpt_command, "ygrid")) {
ygrid=1;
}
/* unknown command */
else {
token=fpt_command;
while (token) {
token=strtok(NULL, WHITE_SPACE);
}
}
/* read new line */
fptin.getline(hchar,MAX_FIELD_LENGTH);
s=(char *)realloc(s, strlen(hchar)+1);
strcpy(s,hchar);
while (fptin.fail() && !fptin.eof()) {
fptin.clear();
fptin.getline(hchar,MAX_FIELD_LENGTH);
s=(char *)realloc(s, strlen(s)+strlen(hchar)+1);
strcat(s, hchar);
}
} /* endwhile */
/* set x coordinates for bar charts if number of x coords different from number of y coords */
for (i=0; i<nofseries; i++) {
if (series[i].type==3) {
if (series[i].ny>0 && (series[i].nx!=series[i].ny)) {
series[i].nx=series[i].ny;
series[i].x=(float *)realloc(series[i].x, series[i].nx*sizeof(float));
for (n=0; n<series[i].nx; n++) {
series[i].x[n]=n+1;
}
}
}
}
/* set x coordinates for line and xy series without x-values */
linenoxmax=-1; j=0;
for (i=0; i<nofseries; i++) {
if ((series[i].type==2 || series[i].type==1) && series[i].nx==0) {
if (series[i].ny>0) {
if (series[i].ny>j) {j=series[i].ny; linenoxmax=i;}
series[i].nx=series[i].ny;
series[i].x=(float *)realloc(series[i].x, series[i].nx*sizeof(float));
for (n=0; n<series[i].nx; n++) {
series[i].x[n]=n+1;
}
}
}
}
/* close input file */
free(s); free(hchar); free(fpt_command);
free(data);
fptin.close();
return(rc);
}
/* function to write PicTeX file */
int FASTPICTEX::Write(char *fname) {
std::ofstream pictex;
int rc=0, i, j, is_fault;
short is_valid, is_first;
short nxy=0, nline=0, nbar=0;
unsigned long n;
float xmin=0, xmax=10, xstep=1, ymin=0, ymax=10, ystep=1;
float xlmin, xlmax;
float valmin=0, valmax=10, step=1;
float xunit, yunit;
float ypos;
unsigned long nreg;
float sx, sy, sx2, sy2, sxy, qx, qy, qxy;
float ax, bx, ay, by, r, s2xy, s2yx, pwert;
float rxmin, rxmax;
extern float prho(int n, float is, int *ifault);
extern int scale(float fmn, float fmx, int n, float *valmin, float *step, float *valmax);
/* open output file */
pictex.open(fname);
if (!pictex) {
rc=1;
std::cout << "Cannot open output file! \n";
return(rc);
}
/* write header of pictex file */
pictex << "% ...... start of pictex file generated by FastPicTeX ...... \n";
pictex << "\\beginpicture \n";
/* need errorbar macros ? */
if (need_errorbarmacros) {
pictex << "% ...... macros for errorbars ...... \n";
pictex << "\\newcommand{\\putxerrorbar}[3]{% \n";
pictex << "\\dimen0=\\Xdistance{#1} \\dimen1=\\Ydistance{#2} \\dimen2=\\Xdistance{#3} \n";
pictex << "\\unitlength=1pt \\setdimensionmode \n";
pictex << "\\dimen3=\\dimen0 \\advance \\dimen3 by -\\dimen2 \n";
pictex << "\\dimen4=\\dimen0 \\advance \\dimen4 by \\dimen2 \n";
pictex << "\\dimen5=\\dimen1 \\advance \\dimen5 by -1mm \n";
pictex << "\\dimen6=\\dimen1 \\advance \\dimen6 by 1mm \n";
pictex << "\\putrule from {\\dimen3} {\\dimen1} to {\\dimen4} {\\dimen1} \n";
pictex << "\\putrule from {\\dimen3} {\\dimen5} to {\\dimen3} {\\dimen6} \n";
pictex << "\\putrule from {\\dimen4} {\\dimen5} to {\\dimen4} {\\dimen6} \n";
pictex << "\\setcoordinatemode } \n";
pictex << "\\newcommand{\\putyerrorbar}[3]{% \n";
pictex << "\\dimen0=\\Xdistance{#1} \\dimen1=\\Ydistance{#2} \\dimen2=\\Ydistance{#3} \n";
pictex << "\\unitlength=1pt \\setdimensionmode \n";
pictex << "\\dimen3=\\dimen1 \\advance \\dimen3 by -\\dimen2 \n";
pictex << "\\dimen4=\\dimen1 \\advance \\dimen4 by \\dimen2 \n";
pictex << "\\dimen5=\\dimen0 \\advance \\dimen5 by -1mm \n";
pictex << "\\dimen6=\\dimen0 \\advance \\dimen6 by 1mm \n";
pictex << "\\putrule from {\\dimen0} {\\dimen3} to {\\dimen0} {\\dimen4} \n";
pictex << "\\putrule from {\\dimen5} {\\dimen3} to {\\dimen6} {\\dimen3} \n";
pictex << "\\putrule from {\\dimen5} {\\dimen4} to {\\dimen6} {\\dimen4} \n";
pictex << "\\setcoordinatemode } \n";
}
/* get extrema */
GetExtrema(0,0.0,0.0,&xmin, &xmax, &ymin, &ymax);
/* write coordinate-system and axis */
/* number of x-tics depend on xticlabels first */
xlmin=FLT_MIN; xlmax=FLT_MAX;
if (nxticlabels>0) {
xlmin=1.0; xlmax=(float)nxticlabels;
GetExtrema(1, xlmin, xlmax, &xmin, &xmax, &ymin, &ymax);
xmin=1.0; xmax=(float)nxticlabels;
scale(xmin-1, xmax+1, nxticlabels+2, &valmin, &step, &valmax);
}
/* number of x-tics depend on bar-graphs second */
else if (nofbar>0) {
j=0;
for (i=0; i<nofseries; i++) {
if (series[i].type==3)
if (series[i].nx>j) j=series[i].nx;
}
scale(xmin-1, xmax+1, j+2, &valmin, &step, &valmax);
}
/* number of x-tics depend on line- and xy-series without x-values third */
else if (linenoxmax>=0)
scale(xmin-1, xmax+1, series[linenoxmax].nx+2, &valmin, &step, &valmax);
/* finally default */
else
scale(xmin, xmax, N_XTICKS, &valmin, &step, &valmax);
xstep=floor(step*10000.0+0.5)/10000.0;
if (xmin>valmin) xmin=floor(valmin*10000.0+0.5)/10000.0;
else xmin=floor((valmin-xstep)*10000.0+0.5)/10000.0;
if (xmax<valmax) xmax=floor(valmax*10000.0+0.5)/10000.0;
else xmax=floor((valmax+xstep)*10000.0+0.5)/10000.0;
scale(ymin, ymax, N_YTICKS, &valmin, &step, &valmax);
ystep=floor(step*10000.0+0.5)/10000.0;
if (ymin>valmin) ymin=floor(valmin*10000.0+0.5)/10000.0;
else ymin=floor((valmin-ystep)*10000.0+0.5)/10000.0;
if (ymax<valmax) ymax=floor(valmax*10000.0+0.5)/10000.0;
else ymax=floor((valmax+ystep)*10000.0+0.5)/10000.0;
xunit=width/(xmax-xmin);
yunit=height/(ymax-ymin);
pictex << "\\setcoordinatesystem units <" << xunit << "cm,"
<< yunit << "cm> point at 0 0 \n";
pictex << "\\setplotarea x from " << xmin << " to " << xmax
<< ", y from " << ymin << " to " << ymax << " \n";
/* plot axis */
pictex << "% .......... axis ............ \n";
pictex << "\\axis bottom ";
if (xlabel) pictex << "label {" << xlabel << "} ";
pictex << "ticks ";
if (xgrid) pictex << "andacross ";
if (nxticlabels==0) {
pictex << "numbered from "
<< xmin << " to " << xmax << " by " << xstep << " / \n";
}
else {
pictex << "withvalues {} ";
for (n=0; n<nxticlabels; n++) pictex << "{" << xticlabels[n] << "}" << " ";
pictex << "{} / \n";
pictex << "quantity " << nxticlabels+2 << " / \n";
}
pictex << "\\axis left ";
if (ylabel) pictex << "label {" << ylabel << "} ";
pictex << "ticks ";
if (ygrid) pictex << "andacross ";
pictex << "numbered from "
<< ymin << " to " << ymax << " by " << ystep << " / \n";
/* plot heading */
pictex << "% .......... heading ............ \n";
if (heading) pictex << "\\plotheading {" << heading << "} \n";
/* plot series */
pictex.setf(std::ios::fixed);
pictex << "% .......... series ............. \n";
for (i=0; i<nofseries; i++) {
switch (series[i].type) {
case 1: // xy plot;
/* write dots and calculate regression line */
sx2=0; sy2=0; sx=0; sy=0; sxy=0; nreg=0;
for (n=0; n<series[i].nx; n++) {
if (series[i].x[n]>=xlmin && series[i].x[n]<=xlmax) {
pictex << "\\put {" << plotsym[(int)fmod(nxy,10)] << "} at "
<< series[i].x[n] << " " << series[i].y[n] << " \n";
sx2+=(series[i].x[n]*series[i].x[n]); sy2+=(series[i].y[n]*series[i].y[n]);
sxy+=(series[i].x[n]*series[i].y[n]);
sx+=series[i].x[n]; sy+=series[i].y[n];
nreg++;
if (series[i].ndx>n) {
pictex << "\\putxerrorbar{" << series[i].x[n] << "}{"
<< series[i].y[n] << "}{" << series[i].dx[n] << "} \n";
}
if (series[i].ndy>n) {
pictex << "\\putyerrorbar{" << series[i].x[n] << "}{"
<< series[i].y[n] << "}{" << series[i].dy[n] << "} \n";
}
/* plot significance signs */
if (series[i].sig[n]) {
ypos=series[i].y[n];
if (series[i].ndy>n) ypos+=series[i].dy[n];
pictex << "\\put {" << series[i].sig[n] << "} [b] <0mm,0.5\\baselineskip> at "
<< series[i].x[n] << " " << ypos << "\n";
}
}
}
/* calculate regression line */
if (nreg>2) {
qx=sx2-(sx*sx/nreg); qy=sy2-(sy*sy/nreg); qxy=sxy-(sx*sy/nreg);
r=qxy/sqrt(qx*qy);
by=qxy/qx; bx=qxy/qy;
ay=(sy-by*sx)/nreg; ax=(sx-bx*sy)/nreg;
s2yx=(qy-(qxy*qxy/qx))/(nreg-2);
s2xy=(qx-(qxy*qxy/qy))/(nreg-2);
pwert=2.0*(1.0-prho(nreg, (nreg*nreg*nreg-nreg)*(1.0-fabs(r))/6.0, &is_fault));
series[i].m1=by; series[i].m2=bx; series[i].b=ay; series[i].nreg=nreg;
if (pwert>1.0) pwert=1.0;
if (pwert<0.0) pwert=0.0;
/* plot regression line */
rxmin=xmin; rxmax=xmax;
if (series[i].tline>0) {
if (ymin>xmin*by+ay) rxmin=(ymin-ay)/by;
if (ymax<xmin*by+ay) rxmin=(ymax-ay)/by;
if (ymin>xmax*by+ay) rxmax=(ymin-ay)/by;
if (ymax<xmax*by+ay) rxmax=(ymax-ay)/by;
pictex << "\\setlinear \n";
pictex << linesym[(int)fmod(nxy,10)] << " \n";
/* set formatting */
pictex << "\\plot " << rxmin << " " << rxmin*by+ay << " "
<< rxmax << " " << rxmax*by+ay << " /\n";
}
} /* endif nreg>2 */
else series[i].tline=0;
/* clean up */
nxy++;
break;
case 2: // line graph;
/* write lines */
pictex << "\\setlinear \n";
pictex << linesym[(int)fmod(nline,10)] << " \n";
is_first=1;
for (n=0; n<series[i].nx; n++) {
if (series[i].x[n]>=xlmin && series[i].x[n]<=xlmax) {
if (is_first) {pictex << "\\plot "; is_first=0;}
pictex << series[i].x[n] << " " << series[i].y[n] << " ";
}
}
pictex << "/ \n";
pictex << "\\setsolid \n";
for (n=0; n<series[i].nx; n++) {
if (series[i].x[n]>=xlmin && series[i].x[n]<=xlmax) {
if (series[i].ndx>n) {
pictex << "\\putxerrorbar{" << series[i].x[n] << "}{"
<< series[i].y[n] << "}{" << series[i].dx[n] << "} \n";
}
if (series[i].ndy>n) {
pictex << "\\putyerrorbar{" << series[i].x[n] << "}{"
<< series[i].y[n] << "}{" << series[i].dy[n] << "} \n";
}
/* plot significance signs */
if (series[i].sig[n]) {
ypos=series[i].y[n];
if (series[i].ndy>n) ypos+=series[i].dy[n];
pictex << "\\put {" << series[i].sig[n] << "} [b] <0mm,0.5\\baselineskip> at "
<< series[i].x[n] << " " << ypos << "\n";
}
}
}
nline++;
break;
case 3: // bar graph;
/* write bars */
if (nbar==0) {
pictex << "\\shaderectanglesoff \n";
}
if (nbar>0 && nbar<nofbar-1) {
pictex << "\\shaderectangleson \n";
pictex << "\\setshadegrid span <" << 1.0-(float)(nbar-1)/(float)(nofbar-2) << "mm> \n";
}
if (nbar!=0 && nbar==nofbar-1) {
pictex << "\\shaderectanglesoff%\n";
pictex << "\\dimen0=\\linethickness%\n";
pictex << "%look here\n";
pictex << "\\setlength{\\linethickness}{" << (BARWIDTH*xunit)/(float)nofbar << "cm}%\n";
//pictex << "\\setlength{\\linethickness}{\\Xdistance{" << BARWIDTH/(float)nofbar << "}}%\n";
}
if (nbar==0 || nbar<nofbar-1) {
for (n=0; n<series[i].nx; n++) {
if (series[i].x[n]>=xlmin && series[i].x[n]<=xlmax) {
pictex << "\\putrectangle corners at ";
pictex << (series[i].x[n]-BARWIDTH/2.0)+(BARWIDTH*(float)nbar/(float)nofbar) << " " << ymin << " and ";
pictex << (series[i].x[n]-BARWIDTH/2.0)+(BARWIDTH*(float)(nbar+1)/(float)nofbar) << " "
<< series[i].y[n] << " \n";
}
}
}
if (nbar!=0 && nbar==nofbar-1) {
for (n=0; n<series[i].nx; n++) {
if (series[i].x[n]>=xlmin && series[i].x[n]<=xlmax) {
pictex << "\\putrule from "
<< (series[i].x[n]-BARWIDTH/2)+BARWIDTH/(float)(2*nofbar)+(BARWIDTH*(float)(nbar)/(float)nofbar) << " "
<< ymin << " to "
<< (series[i].x[n]-BARWIDTH/2)+BARWIDTH/(float)(2*nofbar)+(BARWIDTH*(float)(nbar)/(float)nofbar) << " "
<< series[i].y[n] << " \n";
}
}
pictex << "\\setlength{\\linethickness}{\\dimen0}%\n";
}
for (n=0; n<series[i].nx; n++) {
if (series[i].x[n]>=xlmin && series[i].x[n]<=xlmax) {
/* plot errorbars */
if (series[i].ndy>n) {
pictex << "\\putyerrorbar{"
<< (series[i].x[n]-BARWIDTH/2)+BARWIDTH/(float)(2*nofbar)+(BARWIDTH*(float)(nbar)/(float)nofbar)
<< "}{"
<< series[i].y[n] << "}{" << series[i].dy[n] << "} \n";
}
/* plot significance signs */
if (series[i].sig[n]) {
ypos=series[i].y[n];
if (series[i].ndy>n) ypos+=series[i].dy[n];
pictex << "\\put {" << series[i].sig[n] << "} [b] <0mm,0.5\\baselineskip> at "
<< (series[i].x[n]-BARWIDTH/2)+BARWIDTH/(float)(2*nofbar)+(BARWIDTH*(float)(nbar)/(float)nofbar)
<< " " << ypos << "\n";
}
}
}
nbar++;
break;
} /* endswitch */
} /* endfor */
/* legend */
is_valid=0;
for (i=0; i<nofseries; i++) {
if ((strlen(series[i].legend)>0) ||
(series[i].type==1 && series[i].tline>0 && series[i].nreg>2))
is_valid=1;
}
if (is_valid) {
pictex << "% .......... legends ............. \n";
j=0; nxy=0; nbar=0, nline=0;
for (i=0; i<nofseries; i++) {
if ((strlen(series[i].legend)>0) ||
(series[i].type==1 && series[i].tline>0 && series[i].nreg>2)) {
/* first symbols */
if (series[i].type==1) { /* xy */
if (series[i].tline>0 && series[i].nreg>2) {
pictex << "\\put {" << plotsym[(int)fmod(nxy,10)] << "} [cc] <0.2cm,-" << 2.5*j+1 << "ex> at " << xmax << " " << ymax << "\n";
pictex << "\\setlinear \n";
pictex << linesym[(int)fmod(nxy,10)] << " \n";
pictex << "\\put {\\frame{\\hspace*{8mm}}} [lc] <0.4cm,-" << 2.5*j+1 << "ex> at " << xmax << " " << ymax << "\n";
}
else
pictex << "\\put {" << plotsym[(int)fmod(nxy,10)] << "} [cc] <0.8cm,-" << 2.5*j+1 << "ex> at " << xmax << " " << ymax << "\n";
}
if (series[i].type==2) { /* line */
pictex << linesym[(int)fmod(nline,10)] << " \n";
pictex << "\\putrule <0.4cm,-" << 2.5*j+1 << "ex> from " <<
xmax << " " << ymax << " to " << xmax+0.8/xunit << " " << ymax << "\n";
}
if (series[i].type==3) { /* bar */
if (nbar==0) {
pictex << "\\shaderectanglesoff \n";
pictex << "\\putrectangle <5mm,-" << 2.5*j << "ex> corners at " <<
xmax << " " << ymax << " and " << xmax+0.6/xunit << " " << ymax-0.3/yunit << "\n";
}
if (nbar>0 && nbar<nofbar-1) {
pictex << "\\shaderectangleson \n";
pictex << "\\setshadegrid span <" << 1.0-(float)(nbar-1)/(float)(nofbar-2) << "mm> \n";
pictex << "\\putrectangle <5mm,-" << 2.5*j << "ex> corners at " <<
xmax << " " << ymax << " and " << xmax+0.6/xunit << " " << ymax-0.3/yunit << "\n";
}
if (nbar!=0 && nbar==nofbar-1) {
pictex << "\\shaderectanglesoff%\n";
pictex << "\\dimen0=\\linethickness%\n";
pictex << "\\setlength{\\linethickness}{6mm}%\n";
pictex << "\\putrule <8mm,-" << 2.5*j << "ex> from " <<
xmax << " " << ymax << " to " << xmax << " " << ymax-0.3/yunit << "\n";
pictex << "\\setlength{\\linethickness}{\\dimen0}%\n";
}
}
/* then labels */
pictex << "\\put {" << series[i].legend;
if (series[i].type==1 && series[i].tline>0 && series[i].nreg>2) {
if (strlen(series[i].legend)>0) pictex << ", n=" << series[i].nreg;
else pictex << "n=" << series[i].nreg;
}
pictex << "} [lc] <1.4cm,-" << 2.5*j+1 << "ex> at " << xmax << " " << ymax << "\n";
j++;
if (series[i].type==1 && series[i].tline==2 && series[i].nreg>2) {
pictex << "\\put ";
by=series[i].m1; ay=series[i].b; bx=series[i].m2;
pictex.precision(3);
if (ay>0)
pictex << "{\\footnotesize $(y=" << by << "x+" << ay << ", r^2=" << by*bx << ")$}";
else pictex << "{\\footnotesize $(y=" << by << "x-" << (-1)*ay << ", r^2=" << by*bx << ")$}";
pictex.precision(6);
pictex << " [lc] <1.4cm,-" << 2.5*j+1 << "ex> at " << xmax << " " << ymax << "\n";
j++;
}
}
if (series[i].type==1) nxy++;
if (series[i].type==2) nline++;
if (series[i].type==3) nbar++;
} /* endfor i */
} /* endif is_valid */
/* pictex commands */
if (nofrawpictex>0) pictex << "% .......... rawpictex ............. \n";
for (i=0; i<nofrawpictex; i++) pictex << rawpictex[i] << " \n";
/* close pictex file */
pictex << "\\endpicture \n";
pictex << "% ...... end of pictex file generated by FastPicTeX ...... \n";
pictex.close();
return(rc);
}
/* function to add a new series */
int FASTPICTEX::AddSeries() {
nofseries++;
series=(SERIES *)realloc(series, nofseries*sizeof(SERIES));
series[nofseries-1].type=0; /* graph type not defined (0) */
series[nofseries-1].ndata=0;
series[nofseries-1].nx=0; series[nofseries-1].ny=0;
series[nofseries-1].ndx=0; series[nofseries-1].ndy=0;
series[nofseries-1].tline=0; /* no trendline */
series[nofseries-1].x=(float *)malloc(sizeof(float));
series[nofseries-1].y=(float *)malloc(sizeof(float));
series[nofseries-1].dx=(float *)malloc(sizeof(float));
series[nofseries-1].dy=(float *)malloc(sizeof(float));
series[nofseries-1].sig=(char **)malloc(sizeof(char *));
series[nofseries-1].legend=(char *)malloc(sizeof(char));
strcpy(series[nofseries-1].legend, "\0");
}
/* Get Extrema */
int FASTPICTEX::GetExtrema(short is_limit, float x1, float x2, float *xmin, float *xmax, float *ymin, float *ymax) {
int rc=0, i;
unsigned long n;
float wert1, wert2;
float mxmin, mxmax, mymin, mymax;
if (nofseries>0) {
/* start values */
mxmin=FLT_MAX; mymin=FLT_MAX;
mxmax=FLT_MIN; mymax=FLT_MIN;
for (i=0; i<nofseries; i++) {
for (n=0; n<series[i].nx; n++) {
if (!is_limit || (is_limit && series[i].x[n]<=x2 && series[i].x[n]>=x1)) {
if (series[i].ndx>n) {
wert1=series[i].x[n]-series[i].dx[n];
wert2=series[i].x[n]+series[i].dx[n];
}
else {
wert1=series[i].x[n];
wert2=series[i].x[n];
}
if (mxmin>wert1) mxmin=wert1;
if (mxmax<wert2) mxmax=wert2;
if (series[i].ndy>n) {
wert1=series[i].y[n]-series[i].dy[n];
wert2=series[i].y[n]+series[i].dy[n];
}
else {
wert1=series[i].y[n];
wert2=series[i].y[n];
}
if (mymin>wert1) mymin=wert1;
if (mymax<wert2) mymax=wert2;
} /* endif limit */
} /* endfor */
} /* endfor */
*xmin=mxmin; *xmax=mxmax;
*ymin=mymin; *ymax=mymax;
}
else rc=-1;
return(rc);
}