/*******************************************************/ /* Linux GNU C++ Compiler */ /* Name : fastpictex.cc */ /* Autor: Harald Stauss */ /*******************************************************/ #include <iostream> #include <fstream> #include <float.h> #include <string.h> #include <stdlib.h> #include <math.h> #include "fastpictex.h" #ifdef DUMA #include <new> #include "../../duma/duma.h" #include "../../duma/dumapp.h" #endif /* ----------------------------- */ /* Implementation der Funktionen */ /* ----------------------------- */ FASTPICTEX::FASTPICTEX() { /* Constructor */ width=6.0; height=6.0; // default 6x6 cm; nofseries=0; nofbar=0; linenoxmax=-1; xgrid=0; ygrid=0; noftline=0; series=(SERIES *)malloc(sizeof(SERIES)); need_errorbarmacros=0; xlabel =(char*)malloc(2*sizeof(char)); strcpy(xlabel, "\0"); ylabel =(char*)malloc(2*sizeof(char)); strcpy(ylabel, "\0"); heading=(char*)malloc(2*sizeof(char)); strcpy(heading, "\0"); nxticlabels=0; xticlabels=new char* [1]; nofrawpictex=0; rawpictex=(char **)malloc(sizeof(char *)); strcpy(plotsym[0], "$\\bullet$"); strcpy(plotsym[1], "$\\circ$"); strcpy(plotsym[2], "$\\diamond$"); strcpy(plotsym[3], "$\\star$"); strcpy(plotsym[4], "$\\ast$"); strcpy(plotsym[5], "$\\oplus$"); strcpy(plotsym[6], "$\\odot$"); strcpy(plotsym[7], "$\\oslash$"); strcpy(plotsym[8], "$\\otimes$"); strcpy(plotsym[9], "$\\times$"); strcpy(linesym[0], "\\setsolid"); strcpy(linesym[1], "\\setdots"); strcpy(linesym[2], "\\setdashes"); strcpy(linesym[3], "\\setdashpattern <3mm,1mm,1mm,1mm>"); strcpy(linesym[4], "\\setdashpattern <3mm,1mm,0.5mm,0.5mm,0.5mm,1mm>"); strcpy(linesym[5], "\\setsolid"); strcpy(linesym[6], "\\setdots"); strcpy(linesym[7], "\\setdashes"); strcpy(linesym[8], "\\setdashpattern <3mm,1mm,1mm,1mm>"); strcpy(linesym[9], "\\setdashpattern <3mm,1mm,0.5mm,0.5mm,0.5mm,1mm>"); } 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); } /* allocate memory */ s = (char *)malloc(MAX_FIELD_LENGTH*sizeof(char)); fpt_command = (char *)malloc(MAX_FIELD_LENGTH*sizeof(char)); hchar = (char *)malloc(MAX_FIELD_LENGTH*sizeof(char)); data = (float *)malloc(nallocdata*sizeof(float)); nx=0; ny=0; ndx=0; ndy=0; ntype=0; nlegend=0; is_multiword=0; /* 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); }