59 #define NUMOUTPTS 1001 81 static void draw(
struct gplot*,
int,
double,
double);
83 static void set_scale(
double,
double,
double*,
double*,
int*);
84 static void set_scale_4(
double,
double,
double*,
double*);
85 static void writef(
double,
int,
int);
86 static void writeg(
double,
int,
int,
char);
87 static char *
ecvt12(
double);
92 static int ymap(
struct gplot*,
double*,
int,
int,
int,
int);
105 static void ebox(
int,
int,
int,
int);
106 static void xbox(
int,
int,
int,
int);
107 static void pbox(
int,
int,
int,
int);
154 static char *
errmsg_scale =
"Error: scale not monotonically increasing\n";
156 static char *
errmsg_newvp =
"Error: can't open viewport for graphics\n";
165 struct dvec *
d, *lv, *scale;
185 fprintf(
cp_err,
"Error: no vectors given\n");
203 for (dl = dl0; dl; dl = dl->
dl_next) {
205 fprintf(
cp_err,
"Error: %s: too few points to plot\n",
229 for (dl = dl0; dl; dl = dl->
dl_next) {
238 fprintf(
cp_err,
"Error: more than %d traces\n",
PNUM);
250 for (dl = dl0, i = 0; dl; dl = dl->
dl_next) {
328 if (v->v_numdims > 1)
329 len = v->
v_dims[v->v_numdims - 1];
334 inc = v->v_realdata[0] < v->v_realdata[1];
337 for (i = 2; i < len; i++) {
338 if (inc != (v->v_realdata[i-1] < v->v_realdata[i]))
346 for (i = 2; i < len; i++) {
347 if (inc != (
realpart(&v->v_compdata[i-1]) <
365 while (graf->
numtr--)
372 for (dl = graf->
dlist; dl; dl = graf->
dlist) {
390 struct gplot *newgraf;
401 size = graf->
numpt*
sizeof(float);
405 for (i = 0; i < graf->
numtr; i++) {
421 int fwidth, fheight, edge;
422 int oldXL, oldYL, oldX, oldY;
441 scr->H3 = scr->H + scr->H2;
442 scr->XL = 14*fwidth + edge;
443 scr->YL = 3*fheight + edge;
446 scr->X = scr->XS - scr->XL - 2*fwidth - edge;
447 scr->Y = scr->YS - scr->YL - 3*fheight - edge;
448 scr->XC = scr->XL + scr->X/2;
449 scr->YC = scr->YL + scr->Y/2;
450 scr->XU = scr->XL + scr->X;
451 scr->YU = scr->YL + scr->Y;
455 k->x = (k->x - oldXL)*((
double)scr->X)/oldX + scr->XL;
456 k->y = (k->y - oldYL)*((double)scr->Y)/oldY + scr->YL;
467 struct gplot *graf = (
struct gplot *)graph->plotdata;
506 for (k = graph->keyed; k; k = k->next) {
526 if (!isalpha(*s))
return 0;
554 for (dl = dl0, i = 0; dl; dl = dl->
dl_next, i++) {
610 double *ah, *al, xx, xl, yy, dy, amx, amn;
632 for (dl = graf->
dlist; dl; dl = dl0) {
639 DevText(
"Monotonicity error, partial plot",graf->
scr.
XU,
651 for (dl = dl0, i = 0; dl; dl = dl->
dl_next, i++) {
671 for (dl = dl0, i = 0; dl; dl = dl->
dl_next, i++) {
674 amx = ((ah[i]+al[i])+(ah[i]-al[i])*(2*i+1))/2;
675 amn = ((ah[i]+al[i])-(ah[i]-al[i])*(2*(n-i)-1))/2;
684 l = (int) (.5 + graf->
scr.
Y*(yy - amn)/(amx - amn));
697 for (dl = dl0, i = 0; dl; dl = dl->
dl_next, i++) {
726 for (dl = dl0, i = 0; dl; dl = dl->
dl_next, i++) {
732 for (dl = dl0; dl; dl = dl0) {
748 if (i == 0 && *q ==
'\0')
break;
760 int x0,y0,x1,y1,xr0,xr1;
781 DevText(
"What now? (h for help) :",x0,y0);
808 struct gplot *graf, *oldgraf;
809 double dxl, dxh, dxt;
897 int xt,
swap =
false;
908 if (xl < graf->
scr.
XL)
910 if (xh > graf->
scr.
XU)
945 struct dvec *xs = graf->plot->pl_scale;
955 dx = (xu - xl)/(graf->numpt-1);
960 dx = (xu - xl)/(graf->numpt-1);
962 txfree((
char*)graf->xdata);
963 graf->xdata = (
float *)
tmalloc(graf->numpt*
sizeof(
float));
965 for (i = 0; i < graf->numpt; i++) {
969 graf->scale->xfull.beg = *graf->xdata;
970 graf->scale->xfull.end = *(graf->xdata + graf->numpt - 1);
971 if (graf->scale->lflg) {
972 graf->scale->xfull.beg = log10(graf->scale->xfull.beg);
973 graf->scale->xfull.end = log10(graf->scale->xfull.end);
974 graf->scale->xfull.min = floor(graf->scale->xfull.beg);
975 graf->scale->xfull.max = ceil(graf->scale->xfull.end);
976 graf->scale->ncells = graf->scale->xfull.max -
977 graf->scale->xfull.min;
980 set_scale(graf->scale->xfull.beg,graf->scale->xfull.end,
981 &graf->scale->xfull.min,&graf->scale->xfull.max,
982 &graf->scale->ncells);
984 graf->scale->xcurr = graf->scale->xfull;
996 double xl, xu, ymax, ymin, dx, xi, xj, yi, yj, xl0;
1000 int i, j, len, cy, extra, ird, irs;
1001 struct dvec *xs = graf->plot->pl_scale;
1011 dx = (xu - xl)/(graf->numpt-1);
1016 dx = (xu - xl)/(graf->numpt-1);
1019 && xl > 0 && fabs(xu/xl) >
LOGTST) {
1022 dx = (xu - xl)/(graf->numpt-1);
1023 graf->scale->lflg = 1;
1029 for (j = 1, i = 0; i < d->
v_numdims - 1; i++)
1032 graf->tdata[ind].cycles = j;
1035 (graf->tdata[ind].cycles)++;
1037 graf->tdata[ind].extra = 0;
1040 graf->tdata[ind].cycles = 1;
1042 graf->tdata[ind].extra = 0;
1045 txfree((
char*)graf->tdata[ind].data);
1046 graf->tdata[ind].data =
1047 (
float *)
tmalloc(graf->numpt*graf->tdata[ind].cycles*
sizeof(
float));
1048 v = graf->tdata[ind].data;
1057 ymin = ymax = ird ? *yd :
realpart(&yc[0]);
1058 cy = graf->tdata[ind].cycles;
1067 for (i = 1; i < len; i++) {
1068 xj = irs ? *(xd + i) :
realpart(&xc[i]);
1069 if (graf->scale->lflg) {
1073 yj = ird ? *(yd + i) :
realpart(&yc[i]);
1074 if (yj > ymax) ymax = yj;
1075 if (yj < ymin) ymin = yj;
1078 while (xl < xj && j < graf->numpt) {
1085 while (xl < xj && j < graf->numpt) {
1087 (
float) (yi + (yj - yi)*(xl - xi)/(xj - xi));
1096 graf->tdata[ind].extra = j;
1099 while (j < graf->numpt) {
1100 *(v++) = (
float) yj;
1114 graf->tdata[ind].scale+1);
1127 if (strchr(q,
'q')) {
1131 if (strchr(q,
'P')) graf->opt |=
OPT_hcpy;
1132 if (strchr(q,
'a')) graf->opt |=
OPT_add;
1133 if (strchr(q,
'c')) graf->opt |=
OPT_mark;
1135 if (strchr(q,
'n')) {
1137 graf->opt &= ~
OPT_N;
1139 if (strchr(q,
'N')) {
1141 graf->opt &= ~
OPT_n;
1143 if (strchr(q,
'y')) graf->opt &= ~(
OPT_n|
OPT_N);
1146 if (strchr(q,
'x')) {
1148 graf->opt &= ~
OPT_X;
1151 if (strchr(q,
'X')) {
1153 graf->opt &= ~
OPT_x;
1158 if (graf->numtr > 1) {
1159 if (strchr(q,
'b')) graf->opt ^=
OPT_b;
1160 if (strchr(q,
't')) graf->opt ^=
OPT_t;
1162 if (strchr(q,
'p')) graf->opt ^=
OPT_p;
1173 double fl, fh, *al, *ah, full_scale[2];
1181 al = graf->scale->ymin;
1182 ah = graf->scale->ymax;
1184 graf->scale->numpts =
1185 (int) (m*(graf->scale->xcurr.end - graf->scale->xcurr.beg)/
1186 (graf->scale->xfull.end - graf->scale->xfull.beg) + .5);
1187 graf->scale->strtpt =
1188 (int) (m*(graf->scale->xcurr.beg - graf->scale->xfull.beg)/
1189 (graf->scale->xfull.end - graf->scale->xfull.beg) + .5);
1191 if (graf->opt &
OPT_x) {
1193 for (i = 0; i < n; i++)
1197 cflgs[0] = cflgs[1] = cflgs[2] = 0;
1198 al[n] = al[n+1] = al[n+2] = al[n+3] = 1;
1199 ah[n] = ah[n+1] = ah[n+2] = ah[n+3] = -1;
1200 for (i = 0; i < n; i++) {
1201 al[i] = fl = *graf->tdata[i].scale;
1202 ah[i] = fh = *(graf->tdata[i].scale + 1);
1203 if (al[n] > ah[n]) {
1208 if (fl < al[n]) al[n] = fl;
1209 if (fh > ah[n]) ah[n] = fh;
1211 switch (graf->tdata[i].type) {
1213 if (al[n+1] > ah[n+1]) {
1218 if (fl < al[n+1]) al[n+1] = fl;
1219 if (fh > ah[n+1]) ah[n+1] = fh;
1224 if (al[n+2] > ah[n+2]) {
1229 if (fl < al[n+2]) al[n+2] = fl;
1230 if (fh > ah[n+2]) ah[n+2] = fh;
1235 if (al[n+3] > ah[n+3]) {
1240 if (fl < al[n+3]) al[n+3] = fl;
1241 if (fh > ah[n+3]) ah[n+3] = fh;
1248 if (graf->opt &
OPT_b) {
1253 if (cflgs[0]) {
set_scale_4(al[n+1],ah[n+1],al+n+1,ah+n+1); }
1254 if (cflgs[1]) {
set_scale_4(al[n+2],ah[n+2],al+n+2,ah+n+2); }
1255 if (cflgs[2]) {
set_scale_4(al[n+3],ah[n+3],al+n+3,ah+n+3); }
1258 axes(graf,graf->scale->ncells, ((graf->opt &
OPT_t) && n > 1) ? n : ny);
1259 dely = 3*graf->scr.H + graf->scr.H2;
1260 if (graf->opt &
OPT_t) {
1262 spa = graf->scr.Y/n;
1270 dely -= graf->scr.H2/2;
1271 for (i = 0; i < n; i++) {
1274 int scrx = graf->scr.XL - 13*graf->scr.W - graf->scr.W2;
1277 DevText(graf->tdata[i].name,scrx,
1278 graf->scr.YU - i*spa - graf->scr.H - 2);
1279 if (graf->opt &
OPT_N)
1281 else if (graf->opt &
OPT_n) {
1282 if (graf->tdata[i].type ==
GRAF_V)
1284 else if (graf->tdata[i].type ==
GRAF_I)
1292 if (!(graf->opt &
OPT_N) || i == 0) {
1294 graf->scr.YU - i*spa - 2*graf->scr.H - 2);
1296 graf->scr.YU - i*spa - 3*graf->scr.H - 2);
1299 amx = ((graf->opt &
OPT_t) && n > 1) ?
1300 ((ah[ix]+al[ix])+(ah[ix]-al[ix])*(2*i+1))/2 : ah[ix];
1301 amn = ((graf->opt &
OPT_t) && n > 1) ?
1302 ((ah[ix]+al[ix])-(ah[ix]-al[ix])*(2*(n-i)-1))/2 : al[ix];
1305 !(graf->opt &
OPT_t))
1307 ebox(scrx - graf->scr.W2, graf->scr.YU - i*spa - dely,
1308 scrx - graf->scr.W2 + 13*graf->scr.W, graf->scr.YU - i*spa);
1309 draw(graf,i,amn,amx);
1311 !(graf->opt &
OPT_t))
1317 graf->scr.XL,graf->scr.YU + graf->scr.H3);
1319 if (graf->scale->lflg) strcat(
INBUF,
" (log)");
1321 graf->scr.YL - graf->scr.H3);
1322 writeg(graf->scale->xcurr.min,
1323 graf->scr.XL,graf->scr.YL - graf->scr.H - 1,
'l');
1324 writeg(graf->scale->xcurr.max,
1325 graf->scr.XU,graf->scr.YL - graf->scr.H - 1,
'r');
1327 if (!graf->iniplot) {
1328 DevText(graf->plot->pl_name,graf->scr.XL,graf->scr.YU + graf->scr.H2);
1329 if (graf->scr.X > ((
int)strlen(graf->plot->pl_name) +
1330 (
int)strlen(graf->plot->pl_date))*graf->scr.W)
1332 graf->scr.XU - (
int)strlen(graf->plot->pl_date)*graf->scr.W,
1333 graf->scr.YU + graf->scr.H2);
1348 strcpy(s,graf->plot->pl_scale->v_name);
1349 if (graf->scale->lflg) strcat(s,
" (log)");
1351 sprintf(
INBUF,
"Scale type: %s",s);
1354 sprintf(
INBUF,
"The full range of x is: %s %s",
1355 ecvt12(graf->scale->xfull.beg),
ecvt12(graf->scale->xfull.end));
1357 sprintf(
INBUF,
"Currently, the range is: %s %s",
1358 ecvt12(graf->scale->xcurr.beg),
ecvt12(graf->scale->xcurr.end));
1361 sprintf(
INBUF,
"Enter new range min max or <CR> for full scale : ");
1367 graf->scr.Y - 5*graf->scr.H,graf->scr.XU,
1368 graf->scr.Y - 4*graf->scr.H);
1370 graf->scr.Y - 5*graf->scr.H,11,1,13);
1374 graf->scale->xcurr.end = graf->scale->xfull.end;
1375 graf->scale->xcurr.beg = graf->scale->xfull.beg;
1381 if ((j == 1) && (*c ==
' '))
break;
1382 if (sscanf(c,
"%le %le",
1383 &graf->scale->xcurr.beg,&graf->scale->xcurr.end) == 1) {
1384 graf->scale->xcurr.end = graf->scale->xcurr.beg;
1385 graf->scale->xcurr.beg = graf->scale->xfull.beg;
1387 if (graf->scale->xcurr.end > graf->scale->xfull.end)
1388 graf->scale->xcurr.end = graf->scale->xfull.end;
1389 if (graf->scale->xcurr.beg < graf->scale->xfull.beg)
1390 graf->scale->xcurr.beg = graf->scale->xfull.beg;
1391 if (graf->scale->xcurr.beg >= graf->scale->xfull.beg &&
1392 graf->scale->xcurr.end <= graf->scale->xfull.end &&
1393 graf->scale->xcurr.beg < graf->scale->xcurr.end)
break;
1395 DevBox(0,graf->scr.Y - 5*graf->scr.H,graf->scr.XU,
1396 graf->scr.Y - 4*graf->scr.H);
1397 sprintf(
INBUF,
"Error: Please reenter the new range min max : ");
1401 if (graf->scale->lflg) {
1402 graf->scale->xcurr.min = floor(graf->scale->xcurr.beg);
1403 graf->scale->xcurr.max = ceil(graf->scale->xcurr.end);
1404 graf->scale->ncells = graf->scale->xcurr.max - graf->scale->xcurr.min;
1407 set_scale(graf->scale->xcurr.beg,graf->scale->xcurr.end,
1408 &graf->scale->xcurr.min,&graf->scale->xcurr.max,
1409 &graf->scale->ncells);
1422 double xi, xx, yi, yx;
1423 int i, j, k, num, spa, scrx, cy;
1424 int ix, iy, ixo, iyo, len, extra;
1427 if (graf->numtr < 2)
return;
1429 scrx = graf->scr.XL - 13*graf->scr.W - graf->scr.W2;
1430 num = (graf->numtr >> 1) << 1;
1431 spa = (num*graf->scr.H) >> 1;
1433 DevText(
"X",scrx,graf->scr.YC + spa);
1434 DevText(
"Y",scrx,graf->scr.YC + spa - graf->scr.H);
1435 for (i = 0; i < num; i += 2) {
1437 xi = graf->scale->ymin[i];
1438 xx = graf->scale->ymax[i];
1439 yi = graf->scale->ymin[i+1];
1440 yx = graf->scale->ymax[i+1];
1442 scrx,graf->scr.YC + spa - (i+2)*graf->scr.H);
1443 DevText(graf->tdata[i+1].name,
1444 scrx,graf->scr.YC + spa - (i+3)*graf->scr.H);
1446 writef(yx,scrx,graf->scr.YU - graf->scr.H*(i/2+1));
1447 writef(yi,scrx,graf->scr.YL + spa - graf->scr.H*(i/2 + 1));
1449 writef(xi,graf->scr.XL,graf->scr.YL - graf->scr.H*(i/2+1));
1451 graf->scr.YL - graf->scr.H*(i/2+1));
1455 graf->scr.YL - graf->scr.H*(i/2-1));
1457 graf->scr.YL - graf->scr.H*(i/2-1));
1460 writef(xi,graf->scr.XL,graf->scr.YL - graf->scr.H*(i/2+1));
1462 graf->scr.YL - graf->scr.H*(i/2+1));
1468 cy = graf->tdata[i].cycles;
1469 if (cy > graf->tdata[i+1].cycles)
1470 cy = graf->tdata[i+1].cycles;
1471 extra = graf->tdata[i].extra;
1472 if (extra > graf->tdata[i+1].extra)
1473 extra = graf->tdata[i+1].extra;
1475 px = graf->tdata[i].data + graf->scale->strtpt;
1476 py = graf->tdata[i+1].data + graf->scale->strtpt;
1477 len = graf->scale->numpts;
1480 if (graf->scale->strtpt > extra)
1482 if (len + graf->scale->strtpt > extra)
1483 len = extra - graf->scale->strtpt;
1485 for (j = 0; j < len; j++) {
1487 (.5 + graf->scr.X*(*(px+j) - xi)/(xx - xi));
1489 (.5 + graf->scr.Y*(*(py+j) - yi)/(yx - yi));
1490 if (graf->opt &
OPT_p)
1503 DevText(graf->plot->pl_title,graf->scr.XL,graf->scr.YU + graf->scr.H3);
1505 DevText(graf->plot->pl_name,graf->scr.XL,graf->scr.YU + graf->scr.H2);
1506 if (graf->scr.X > ((
int)strlen(graf->plot->pl_name) +
1507 (
int)strlen(graf->plot->pl_date))*graf->scr.W)
1509 graf->scr.XU - (
int)strlen(graf->plot->pl_date)*graf->scr.W,
1510 graf->scr.YU + graf->scr.H2);
1525 int i, j, n, cy, numpts;
1526 double f, atof(), *al, *ah;
1528 c[0] = c[1] = c[2] = 0;
1529 al = graf->scale->ymin;
1530 ah = graf->scale->ymax;
1532 al[n] = al[n+1] = al[n+2] = al[n+3] = 1;
1533 ah[n] = ah[n+1] = ah[n+2] = ah[n+3] = -1;
1534 for (i = 0; i < n; i++) {
1537 cy = graf->tdata[i].cycles;
1538 dp = graf->tdata[i].data + graf->scale->strtpt;
1539 numpts = graf->scale->numpts;
1541 if (!cy && graf->tdata[i].extra) {
1542 if (graf->scale->strtpt > graf->tdata[i].extra)
1544 if (numpts + graf->scale->strtpt > graf->tdata[i].extra)
1545 numpts = graf->tdata[i].extra - graf->scale->strtpt;
1548 for (j = 0; j < numpts; j++) {
1550 f = (double) *(dp + j);
1551 if (al[i] > ah[i]) {
1556 if (f < al[i]) al[i] = f;
1557 if (f > ah[i]) ah[i] = f;
1559 switch (graf->tdata[i].type) {
1561 if (al[n+1] > ah[n+1]) {
1566 if (f < al[n+1]) al[n+1] = f;
1567 if (f > ah[n+1]) ah[n+1] = f;
1572 if (al[n+2] > ah[n+2]) {
1577 if (f < al[n+2]) al[n+2] = f;
1578 if (f > ah[n+2]) ah[n+2] = f;
1583 if (al[n+3] > ah[n+3]) {
1588 if (f < al[n+3]) al[n+3] = f;
1589 if (f > ah[n+3]) ah[n+3] = f;
1597 if (al[n] > ah[n]) {
1602 if (al[i] < al[n]) al[n] = al[i];
1603 if (ah[i] > ah[n]) ah[n] = ah[i];
1620 int i, k,
l, ok, ol, cy, numpts;
1621 double atof(),
s,
o;
1625 s = (graf->scale->xcurr.end - graf->scale->xcurr.beg) /
1626 (graf->scale->xcurr.max - graf->scale->xcurr.min);
1627 o = (graf->scale->xcurr.beg - graf->scale->xcurr.min) /
1628 (graf->scale->xcurr.max - graf->scale->xcurr.min);
1630 cy = graf->tdata[trace].cycles;
1631 dp = graf->tdata[trace].data + graf->scale->strtpt;
1632 numpts = graf->scale->numpts;
1635 if (!cy && graf->tdata[trace].extra) {
1636 if (graf->scale->strtpt > graf->tdata[trace].extra)
1638 if (numpts + graf->scale->strtpt > graf->tdata[trace].extra)
1639 numpts = graf->tdata[trace].extra - graf->scale->strtpt;
1641 k = graf->scr.XL + (int) (.5 + o*graf->scr.X);
1642 l = graf->scr.YL + (int) (.5 + graf->scr.Y*(*dp - fl)/(fh - fl));
1643 if (graf->opt &
OPT_p)
1647 for (i = 1; i < numpts; i++) {
1649 (int) (.5 + o*graf->scr.X +
1650 s*graf->scr.X*i/(graf->scale->numpts - 1));
1652 (int) (.5 + graf->scr.Y*(*(dp + i) - fl)/(fh - fl));
1653 if (graf->opt &
OPT_p)
1664 graf->tdata[trace].lasty = l;
1678 graf->
scr.
X = (graf->scr.X/nx)*nx;
1679 graf->scr.Y = (graf->scr.Y/ny)*ny;
1680 graf->scr.XC = graf->scr.XL + graf->scr.X/2;
1681 graf->scr.YC = graf->scr.YL + graf->scr.Y/2;
1682 graf->scr.XU = graf->scr.XL + graf->scr.X;
1683 graf->scr.YU = graf->scr.YL + graf->scr.Y;
1688 ebox(graf->scr.XL,graf->scr.YL,graf->scr.XU,graf->scr.YU);
1691 for (x = graf->scr.X/nx; x <= graf->scr.X - graf->scr.X/nx;
1692 x += graf->scr.X/nx)
1693 DevLine(x + graf->scr.XL,graf->scr.YL,x + graf->scr.XL,graf->scr.YU);
1694 for (y = graf->scr.Y/ny; y <= graf->scr.Y - graf->scr.Y/ny;
1695 y += graf->scr.Y/ny)
1696 DevLine(graf->scr.XL,y + graf->scr.YL,graf->scr.XU,y + graf->scr.YL);
1705 double
l, u, *lnew, *unew;
1708 double x,
e,
m, del,
s;
1709 double fabs(), log10(), pow(), floor();
1712 if (u < l) { x = l; l = u; u = x; }
1713 if (u == l) { l -= 0.1*fabs(l); u += 0.1*fabs(u); }
1714 if (u == l) { *lnew = -0.5; *unew = 0.5;
return; }
1719 e = floor(log10(x));
1720 m = x / pow(10.0,e);
1723 else if (m <= 4) j = 2;
1724 else if (m <= 8) j = 4;
1727 if (m > j*1.75) *n = 8;
1728 else if (m > j*1.5) *n = 7;
1729 else if (m > j*1.25) *n = 6;
1730 else if (m > j*1.0) *n = 5;
1733 s = *n * j * pow(10.0, e) / 4.0;
1734 if (*n == 8) *n = 4;
1737 while (s + del*floor(x) < u) {
1740 if (*n == 8) *n = 4;
1744 *lnew = del * floor(x);
1753 double
l, u, *lnew, *unew;
1755 double x,
e,
m, del,
s;
1756 double fabs(), log10(), pow(), floor();
1758 if (u < l) { x = l; l = u; u = x; }
1759 if (u == l) { l -= 0.1*fabs(l); u += 0.1*fabs(u); }
1760 if (u == l) { *lnew = -0.5; *unew = 0.5;
return; }
1765 e = floor(log10(x));
1766 m = x / pow(10.0,e);
1769 else if (m <= 4) j = 2;
1770 else if (m <= 8) j = 4;
1773 if (m > j*1.75) n = 8;
1774 else if (m > j*1.5) n = 7;
1775 else if (m > j*1.25) n = 6;
1776 else if (m > j*1.0) n = 5;
1779 s = n * j * pow(10.0, e) / 4.0;
1783 while (n != 4 || s + del*floor(x) < u) {
1790 *lnew = del * floor(x);
1818 if ((tt = strchr(t,
'e')) !=
NULL) {
1837 sprintf(tt,
"%02d",xp);
1854 static char s[10][20];
1862 sprintf(s[num],
"%+.5e",d);
1863 ss = strchr(s[num],
'e');
1874 strcpy(s[num],
" 0.00000e+00");
1880 if (ss - s[num] == 2)
1882 while (ss - s[num] < 8)
1889 *ss++ =
'0' + (xp/10);
1890 *ss++ =
'0' + (xp%10);
1907 x = graf->scr.XL - 10*graf->scr.W;
1908 y = graf->scr.YS - 2*graf->scr.H;
1912 DevText(
"Display mode options are as follows :",x,y);
1914 DevText(
"a Append current plot to file \"plotdt\".",
1916 DevText(
"b Plot data in X-Y mode, taking 2 traces at a time.",
1918 DevText(
"c Enable the marker. The marker prints the trace",
1920 DevText(
" coordinates, and is retired when ENTER is struck.",
1922 DevText(
"n Use similar scales for three classes of traces: those",
1924 DevText(
" with names beginning with V,I, and otherwise.",
1926 DevText(
"N Plot all traces on the same vertical scale",
1928 DevText(
"p Plot data as points.",
1930 DevText(
"P Generate a hardcopy.",
1934 DevText(
"t Display each trace on a separate axis, no overlap.",
1936 DevText(
"x Change the horizontal scale, thus display a portion of the graph.",
1938 DevText(
"X Same as \"x\" but use the whole curve to generate the y scales.",
1940 DevText(
"y Use separate scales for each trace.",
1942 DevText(
"Options p and t toggle, therefore enter a second time to return to the",
1944 DevText(
"original display mode. Options can also be input from the command line.",
1946 DevText(
"When using the x option, ENTER as response to the scale min max prompt",
1948 DevText(
"will reset to full scale values, and a space followed by ENTER will leave",
1950 DevText(
"the previous values unchanged.",
1952 DevText(
"Options may be entered after each plot is displayed.",
1958 ebox(x - graf->scr.W,y - graf->scr.H2,
1959 x + maxline*graf->scr.W,graf->scr.YS - graf->scr.H2);
1971 struct gplot *graf = (
struct gplot *)graph->plotdata;
1972 int i, spa, dely, scrx;
1986 num = (graf->
numtr >> 1);
1987 spa = num*graf->
scr.
H;
1990 scrx + fw,graf->
scr.
YU);
1992 scrx + fw,graf->
scr.
YL + spa);
1994 for (i = 0; i < num; i++) {
2034 for (i = 0; i < graf->
numtr; i++) {
2036 scrx + fw, graf->
scr.
YU - i*spa - graf->
scr.
H - 1);
2059 int i, spa, dely, scrx, fw;
2063 nmin = graf->
scr.
XL + (int)
2064 ((graf->scale->xcurr.beg - graf->scale->xcurr.min)*graf->scr.X/
2065 (graf->scale->xcurr.max - graf->scale->xcurr.min)+.5);
2066 nmax = graf->scr.XL + (int)
2067 ((graf->scale->xcurr.end - graf->scale->xcurr.min)*graf->scr.X/
2068 (graf->scale->xcurr.max - graf->scale->xcurr.min)+.5);
2069 if (x < nmin || x > nmax)
2073 scrx = graf->scr.XL - 13*graf->scr.W - graf->scr.W2;
2074 fw =
FIELD*graf->scr.W;
2075 dely = 3*graf->scr.H + graf->scr.H2;
2076 if (graf->opt &
OPT_t) {
2078 spa = graf->scr.Y/graf->numtr;
2086 for (i = 0; i < graf->numtr; i++) {
2087 DevBox(scrx,graf->scr.YU - i*spa - 3*graf->scr.H - 2,
2088 scrx + fw, graf->scr.YU - i*spa - graf->scr.H - 1);
2090 DevBox(graf->scr.XL, graf->scr.YL - 3*graf->scr.H,
2091 graf->scr.XS-1, graf->scr.YL - 2*graf->scr.H);
2093 graf->ref.set =
true;
2103 int x, y, refx, refy;
2106 int i, num, scrx, spa, dely;
2109 double xx, x0, yy, y0;
2124 num = (graf->
numtr >> 1) << 1;
2125 for (i = 0; i < num; i += 2) {
2127 fy = graf->
scr.
H*i/2;
2154 nmin = graf->
scr.
XL + (int)
2157 nmax = graf->
scr.
XL + (int)
2161 if (x < nmin || x > nmax)
2178 for (i = 0; i < graf->
numtr; i++) {
2179 ymap(graf,&yy,x,nmin,nmax,i);
2181 ymap(graf,&y0,graf->
ref.
x,nmin,nmax,i);
2210 int m, nmin, nmax, j;
2212 double mm, mf, maxy, miny;
2216 mm *= (graf->scale->numpts-1);
2217 mm /= (nmax - nmin);
2218 mm += graf->scale->strtpt;
2221 *y = graf->tdata[j].data[mi] +
2222 mf*(graf->tdata[j].data[mi+1]-graf->tdata[j].data[mi]);
2223 if (graf->opt &
OPT_t) {
2224 ys = graf->scr.Y/graf->numtr;
2225 yo = graf->scr.YL + (graf->numtr-j-1)*ys;
2231 if (graf->opt &
OPT_N) {
2232 miny = graf->scale->ymin[graf->numtr];
2233 maxy = graf->scale->ymax[graf->numtr];
2235 else if (graf->opt &
OPT_n) {
2236 switch (graf->tdata[j].type) {
2238 miny = graf->scale->ymin[graf->numtr+1];
2239 maxy = graf->scale->ymax[graf->numtr+1];
2242 miny = graf->scale->ymin[graf->numtr+2];
2243 maxy = graf->scale->ymax[graf->numtr+2];
2246 miny = graf->scale->ymin[graf->numtr+3];
2247 maxy = graf->scale->ymax[graf->numtr+3];
2251 miny = graf->scale->ymin[j];
2252 maxy = graf->scale->ymax[j];
2254 return yo + (int) ((*y-miny)*ys/(maxy-miny)+.5);
2265 int i, j,
m, n, rem;
2268 fptr = fopen(
"plotdt",
"a");
2272 fprintf(fptr,
"%s\n%d %s %s\n",graf->plot->pl_title,n,
"27.0",
2273 graf->plot->pl_date);
2274 for (i = 0; i < n; i++)
2275 fprintf(fptr,
"%d\n%s\n",1,graf->tdata[i].name);
2276 fprintf(fptr,
"%s\n%d\n",graf->plot->pl_scale->v_name,m);
2279 for (i = 0; i < n; i++) {
2280 fprintf(fptr,
"%s%s\n",
ecvt12(*graf->tdata[i].scale),
2281 ecvt12(*(graf->tdata[i].scale + 1)));
2283 dp = graf->tdata[i].data;
2284 for (j = 0; j <
m; j++, dp += 10)
2286 fprintf(fptr,
"%s%s%s%s%s%s%s%s%s%s\n",
2291 for (j = 0; j < rem; j++, dp++)
2292 fprintf(fptr,
"%s",
ecvt12(*dp));
2297 for (j = 0; j <
m; j++, dp += 10)
2299 fprintf(fptr,
"%s%s%s%s%s%s%s%s%s%s\n",
2304 for (j = 0; j < rem; j++, dp++)
2305 fprintf(fptr,
"%s",
ecvt12(*dp));
2339 fp = fopen(buf,
"r");
2341 fp = fopen(
"check.dat",
"r");
2343 fprintf(
cp_err,
"Error: No margin analysis data file found\n");
2349 for (ww = wl; ww; ww = ww->
wl_next) {
2357 fprintf(
cp_out,
"Will display plot during margin analysis.\n");
2363 fprintf(
cp_out,
"Will not display plot during margin analysis.\n");
2369 "Error: Margin analysis data file \"%s\" not found\n",
2379 fprintf(
cp_err,
"Error: Nothing in file to plot.\n");
2384 for (p = p0;
p; p = p0) {
2417 DevText(
"Hit any key to continue, 'p' for hardcopy",
2441 int i, j, x, y, d1, d2;
2442 double v1, v2, maxv1, minv1, maxv2, minv2;
2447 while (fgets(buf,80,fp)) {
2448 if (strchr(buf,
'p') || strchr(buf,
'f')) i++;
2461 sscanf(buf,
"%d %d %le %le",&d1,&d2,&v1,&v2);
2467 while (fgets(buf,80,fp)) {
2469 sscanf(buf,
"%d %d %le %le",&d1,&d2,&v1,&v2);
2471 if (v1 > maxv1) maxv1 =
v1;
2472 if (v1 < minv1) minv1 =
v1;
2473 if (v2 > maxv2) maxv2 =
v2;
2474 if (v2 < minv2) minv2 =
v2;
2477 else if (strchr(buf,
'p')) {
2483 else if (strchr(buf,
'f')) {
2497 for (q = *p0; q->
next; q = q->
next) ;
2511 int i, o1, o2, o3, o4;
2514 d1 = (p0->maxv1 - p0->minv1)/(p0->delta1 - 1);
2515 d2 = (p0->maxv2 - p0->minv2)/(p0->delta2 - 1);
2516 for (p = p0->
next; p; p = q) {
2519 if (fabs((d1-maxv1)/(d1+
maxv1)) + fabs((d2-maxv2)/(d2+maxv2)) > 1
e-6) {
2520 fprintf(
cp_err,
"Error: can't combine, incompatible data.\n");
2526 maxv1 = (p0->maxv1 > p->
maxv1 ? p0->maxv1 : p->
maxv1);
2527 minv1 = (p0->minv1 < p->
minv1 ? p0->minv1 : p->
minv1);
2528 maxv2 = (p0->maxv2 > p->
maxv2 ? p0->maxv2 : p->
maxv2);
2529 minv2 = (p0->minv2 < p->
minv2 ? p0->minv2 : p->
minv2);
2531 if (temp > 0) temp += .5;
2537 if (temp > 0) temp += .5;
2542 temp = -(maxv1 +
minv1)/d1 + 2*p0->minv1/d1 + p0->delta1 - 1;
2543 if (temp > 0) temp += .5;
2548 temp = -(maxv2 +
minv2)/d2 + 2*p0->minv2/d2 + p0->delta2 - 1;
2549 if (temp > 0) temp += .5;
2554 p0->delta1 = (maxv1 -
minv1)/d1 + 1.5;
2555 p0->delta2 = (maxv2 -
minv2)/d2 + 1.5;
2556 for (i = 0; i < p0->size; i++) {
2563 p1 = p0->v1 + p0->size;
2564 p2 = p0->v2 + p0->size;
2565 p3 = p0->pf + p0->size;
2566 p0->size += p->
size;
2567 for (i = 0; i < p->
size; i++) {
2568 *p1++ = p->
v1[i] + o1;
2569 *p2++ = p->
v2[i] + o2;
2594 for (j = 0; j < p->
size; j++) {
2603 x = p->
xc + p->
v1[j]*p->
d;
2604 y = p->
yc + p->
v2[j]*p->
d;
2605 box(x+1,y+1,x+p->
d-1,y+p->
d-1);
2616 struct mdata *md = (
struct mdata *)graph->plotdata;
2622 for (k = graph->keyed; k; k = k->next) {
2666 *
new->pts = *md->
pts;
2668 new->pts->v2 =
tmalloc(new->pts->size);
2669 new->pts->pf =
tmalloc(new->pts->size);
2670 memcpy(new->pts->v1,md->
pts->
v1,new->pts->size);
2671 memcpy(new->pts->v2,md->
pts->
v2,new->pts->size);
2672 memcpy(new->pts->pf,md->
pts->
pf,new->pts->size);
2681 mp_init(delta1,delta2, v1min, v1max, v2min, v2max)
2687 double v1min, v1max, v2min, v2max;
2689 int d, dd1, dd2, xc, yc, x1, y1;
2691 char *msg =
"Operating Range Analysis";
2745 if (!
DOIPLOT || !
id)
return (1);
2769 if (!
DOIPLOT || !
id)
return (1);
2783 x = p->
xc + p->
d1*p->
d;
2784 y = p->
yc + p->
d2*p->
d;
2785 box(x+1,y+1,x+p->
d-1,y+p->
d-1);
2800 struct gpoint *graf;
2803 if (!
DOIPLOT || !
id)
return (1);
2814 DevText(
"Hit any key to continue, 'p' for hardcopy",
2837 int d, dd1, dd2,
xc,
yc, x1, y1;
2840 char *msg =
"Operating Range Analysis";
2844 xx = md->scr.XS - 10*md->scr.W;
2845 yy = md->scr.YS - 9*md->scr.H;
2846 dx = (1.0 + (double)p->
delta1)/xx;
2847 dy = (1.0 + (double)p->
delta2)/yy;
2854 dd1 = ((p->
delta1-1)*d) >> 1;
2855 dd2 = ((p->
delta2-1)*d) >> 1;
2857 p->
xc = xc = 8*md->scr.W + xx/2;
2858 p->
yc = yc = 6*md->scr.H + yy/2;
2859 if (!(p->
delta1 & 1)) p->
xc += d/2;
2867 ebox(x1,y1,xc+dd1+d+spa,yc+dd2+d+spa);
2869 yy = y1 - md->scr.H3;
2875 yy = y1 - 3*md->scr.H;
2878 pbox(xx,yy,xx + md->scr.H,yy + md->scr.H);
2880 DevText(
"pass",xx + md->scr.H3,yy);
2882 xx += md->scr.H3 + 7*md->scr.W;
2885 xbox(xx,yy,xx + md->scr.H,yy + md->scr.H);
2887 DevText(
"fail",xx + md->scr.H3,yy);
2889 yy = y1 - 3*md->scr.H - md->scr.H3;
2897 sprintf(s,
"Incr1 = %g, Incr2 = %g",(p->
maxv1-p->
minv1)/
2907 writeg(p->
maxv2,x1-md->scr.W,yc+dd2+d/2-md->scr.H2,
'r');
2909 writeg(p->
minv2,x1-md->scr.W,yc-dd2+d/2-md->scr.H2,
'r');
2914 writeg(p->
maxv1,xc+dd1+d,yc+dd2+d+md->scr.H2,
'l');
2916 writeg(p->
maxv1,xc+dd1+d,yc+dd2+d+md->scr.H2,
'r');
2920 x1-8*md->scr.W-md->scr.W2,yc+d/2-(dd2 ? md->scr.H2 : md->scr.H3));
2921 DevText(
"Param 1",xc+d/2-3*md->scr.W-md->scr.W2,yc+dd2+d+md->scr.H3);
2940 if (p->size > p->rsize) {
2946 p->v1[p->size] = (char) v1;
2947 p->v2[p->size] = (char) v2;
2948 p->pf[p->size] =
pf;
2982 DevLine(xl+(xu-xl)/4,yl+(yu-yl)/2,xu-(xu-xl)/4,yl+(yu-yl)/2);
2983 DevLine(xl+(xu-xl)/2,yl+(yu-yl)/4,xl+(xu-xl)/2,yu-(yu-yl)/4);
3004 if (wlist &&
eq(wlist->wl_word,
"-n")) {
3005 wlist = wlist->wl_next;
3010 ss = s =
copy(wlist->wl_word);
3015 if (wlist->wl_next && (i <
BSIZE_SP-3))
3017 wlist = wlist->wl_next;
static char buf[MAXPROMPT]
struct gtrace tdata[PNUM]
static char * errmsg_gralloc
bool cp_getvar(char *n, int t, char *r)
static void interpolateX()
struct graph::@2 absolute
static void interpolateY()
void graf_slopelocation()
int mp_init(int delta1, int delta2, double v1min, double v1max, double v2min, double v2max)
struct dvlist * ft_dvlist()
struct pnode * ft_getpnames()
int iplot_begin(struct dvlist *dl0, struct plot *pl)
void DevDefineLinestyle()
static char * errmsg_newvp
void com_mplot(wordlist *wl)
int mp_mark(int id, char pf)
int mp_where(int id, int d1, int d2)
struct wordlist * wl_prev
void com_graf(wordlist *wl)
static bool is_monotonic()
char * KbEdit(char *s, int x, int y, int bg, int fg, int cc)
static void proc_option()
struct graph::_keyed * keyed
static void set_scale_4()
static char * errmsg_scale
void com_echo(wordlist *wlist)
static void graf_setmark()
struct wordlist * wl_next
static void init_viewport()
void ShowPrompt(char *str)
static void graf_display()
static void chkpts_free()