home *** CD-ROM | disk | FTP | other *** search
- /*+
- * File: line.c
- *
- * Description: Produce a line graph using pic and troff.
- *
- * This module is the property of McCaw Cellular Communications, Inc
- * Copyright 1990, all rights reserved
- *
- * Audit Trail:
- * Original Author and Date: Dan Flak - 13 Jul 1990.
- *
- -*/
- #ifdef VERSION
- static char *SCCS = "%Z% %M% %I% %G% %U%"
- #endif
-
- /* #includes */
- #include <stdio.h>
-
- /* #defines */
- #define SAY printf
- #define BACKSLASH '\134'
-
- /* external variables */
- extern char *optarg;
- extern int optind;
- extern int opterr;
- extern int optopt;
-
- /* referenced external functions */
- float atof();
-
- /* internal functions */
- int basemonth();
-
-
- /* global variables */
-
- struct record
- {
- char mdate[5];
- float f;
- char m[8];
- } rec[12];
-
- float data_x;
- float data_x2;
- float data_y;
- float data_y2;
- float data_xy;
-
- float newx, newy, oldx, oldy;
- float factor1, factor2, factor3;
- float m, b, bmonth;
-
- float lower = 0, upper = 100, lineat = 10, hbar, eachmo;
- char title[80];
- int nrecs = 0; int npts = 0;
-
- char *month[12] =
- {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- };
-
- FILE *fin, *fopen();
-
-
- /* static variables */
-
-
- /*<
- * Function: main
- *
- * Description: Parse the data and make a pic file
- *
- * Data Type: int
- *
- * Arguments:
- * argv[] = input file name
- *
- * Flags
- * -l lower limit
- * -u upper limit
- * -i increment
- * -t title string
- *
- * Returns:
- *
- * Side Effects:
- *
- * Calls:
- *
- * PDL
- *
- >*/
-
- int
- main (argc, argv)
- int argc;
- char *argv[];
- {
- int i, k, nfound;
- int c;
- float range, perinch;
- char linebuf[1000];
- *title = '\0';
-
- while ((c = getopt (argc, argv, "i:l:u:t:")) != EOF)
- {
- switch (c)
- {
- case 'i':
- lineat = atof (optarg);
- break;
- case 'l':
- lower = atof (optarg);
- break;
- case 'u':
- upper = atof (optarg);
- break;
- case 't':
- sprintf (title, "%s", optarg);
- break;
- default:
- ;
- break;
- }
- }
-
- if (argc < 2)
- {
- fprintf (stderr,
- "syntax: %s [-i increment] [-l lower limit] [-u upper limit] [-t title]\n",
- argv[0]);
- fprintf (stderr, " <data file>\n");
- exit (0);
- }
-
- /* Read data file */
- if ((fin = fopen (argv[optind], "r")) == NULL)
- {
- fprintf (stderr, "%s: can't open %s\n", argv[0], argv[1]);
- exit (-1);
- }
-
-
- while (fgets (linebuf, 1000, fin) != NULL)
- {
- nfound = sscanf (linebuf, "%[^|]|%[^'\n']",
- rec[nrecs].mdate, rec[nrecs].m);
- /* SAY ("nfound = %d / %2d - %s | %s\n",
- nfound, nrecs, rec[nrecs].mdate, rec[nrecs].m); */
- if (nfound == 2)
- {
- if (strcmp (rec[nrecs].m, "ND"))
- {
- rec[nrecs].f = atof (rec[nrecs].m);
- }
- else
- {
- rec[nrecs].f = -1;
- }
- nrecs++;
- if (nrecs > 12 )
- {
- fprintf (stderr,
- "%s: Can only accomodate a maximum of 12 data points\n",
- argv[0]);
- exit (-1);
- }
- }
- }
-
- fclose (fin);
-
- /* Check upper and lower bounds */
-
- for (i = 0; i < nrecs; i++)
- {
- if (rec[i].f < lower && rec[i].f != -1)
- {
- fprintf (stderr, "Warning: lower limit exceeded %s\n",
- rec[i].mdate);
- }
-
- if (rec[i].f > upper)
- {
- fprintf (stderr, "Warning: upper limit exceeded %s\n",
- rec[i].mdate);
- }
- }
-
-
- /* Build the file that will plot the graph */
-
- printf (".de )k\n..\n");
- printf (".PH\n");
- printf (".ps 12\n");
- printf (".vs 12\n");
- data_x = 0; data_x2 = 0; data_y = 0; data_y2 = 0; data_xy = 0;
- printf (".ce 3\n");
- printf ("%cs+4%cfB%s%cfP%cs0\n",
- BACKSLASH, BACKSLASH, title, BACKSLASH, BACKSLASH);
- printf (".br\n");
- printf (".DS CB\n");
- printf (".PS\n");
- printf ("\n# set invisible refernece box\n");
- printf ("boxht = 3.45; boxwid = 4.65\n");
- printf ("move to (0, -2.5); OB: box invis\n");
- printf ("\n# workaround for bug in 'old' pic\n");
- printf ("%c %c at OB.nw + (0, .2)\n", '"', '"');
- printf ("%c %c at OB.sw\n", '"', '"');
- printf ("\n# Print horizontal axis\n");
- printf ("HA: line from OB.sw to OB.se\n");
- printf ("\n# Print vertical axis\n");
- printf ("VA: line from OB.nw to OB.sw\n");
- range = upper - lower;
- if (range == 0)
- {
- fprintf (stderr,
- "Warning: range = 0. Sorry, Dave, I can't do that\n");
- exit (-1);
- }
- perinch = 3.45 / range;
- SAY ("# range = %f, perinch = %f\n", range, perinch);
- printf ("\n# put in horizontal scale marks\n");
- printf ("%c%4.1f%c rjust at OB.sw + (-.1, 0)\n", '"', lower, '"');
- hbar = lower + lineat;
- eachmo = 4.65 / 11;
- while (hbar <= upper)
- {
- printf ("line right 4.65 at OB.sw + (0, %f) dashed; ",
- (hbar - lower) * perinch);
- printf ("%c%4.1f%c rjust at OB.sw + (-.1, %f)\n",
- '"', hbar, '"', (hbar - lower) * perinch);
- hbar += lineat;
- }
- printf ("\n# Put in vertical scale marks\n");
- for (i = 0; i < nrecs; i++)
- {
- k = atoi (rec[i].mdate + 2) - 1;
- printf ("%c%s%c at OB.sw + (%f, -.1); ",
- '"', month[k], '"', i * eachmo);
- printf ("%c%s%c at OB.sw + (%f, 3.60)\n",
- '"', rec[i].m, '"', i * eachmo);
- }
- putchar ('\n');
- for (i = 1; i < nrecs; i++)
- {
- if (lineat == 0)
- {
- lineat = 1;
- }
- printf ("line from OB.sw + (%f, 0) to OB.sw + (%f, 3.45) dotted %f\n",
- i * eachmo, i * eachmo, perinch * lineat / 10);
- }
- printf ("\n# Drawing Actual lines\n");
- oldx = -1; oldy = -1;
- for (i = 0; i < nrecs; i++)
- {
- if (rec[i].f != -1)
- {
- newx = i * eachmo;
- newy = (rec[i].f - lower) * perinch;
- if (oldx != -1)
- {
- printf ("line from OB.sw + (%f, %f) to OB.sw + (%f, %f)\n",
- oldx, oldy, newx, newy);
- }
- oldx = newx; oldy = newy;
- }
- }
- printf ("\n# Drawing trend lines\n");
- npts = 0;
- for (i = 0; i < nrecs; i++)
- {
- if (rec[i].f != -1)
- {
- bmonth = basemonth (rec[i].mdate);
- /* SAY ("%s = %d\n", rec[i].mdate, bmonth); */
- data_x += bmonth;
- data_x2 += bmonth * bmonth;
- data_y += rec[i].f;
- data_y2 += rec[i].f * rec[i].f;
- data_xy += bmonth * rec[i].f;
- npts++;
- }
- }
- factor1 = npts * data_x2 - data_x * data_x;
- factor2 = npts * data_y2 - data_y * data_y;
- factor3 = npts * data_xy - data_x * data_y;
- if (factor1 != 0)
- {
- m = factor3 / factor1;
- }
- else
- {
- fprintf (stderr, "Warning: slope not calcualted for %d\n");
- m = 0;
- }
-
- if (npts != 0)
- {
- b = (data_y - m * data_x) / npts;
- }
- else
- {
- fprintf (stderr, "Warning: intercept not calculated\n");
- b = (upper - lower) / 2;
- }
- printf ("\n# Slope = %f, Intercept = %f\n", m, b);
- printf ("line from OB.sw + (0, %f) to OB.sw + (4.65, %f) dotted\n",
- (m * basemonth (rec[0].mdate) + b - lower) * perinch,
- (m * basemonth (rec[nrecs - 1].mdate) + b -lower) * perinch);
-
- printf ("\n# Put in ledgend\n");
- printf ("line right 1.0 at HA.start + (0.5, -.333)\n %c Actual%c ljust\n",
- '"', '"');
- printf ("move right 1.0\n");
- printf ("line right 1.0 dotted\n %c Trend%c ljust\n", '"', '"');
- printf (".PE\n");
- printf (".DE\n");
- printf (".bp\n");
- }
-
- /*<
- * Function: basemonth (yymm)
- *
- * Description: Feed it a YYMM and it will give you number of months
- * since 8901.
- *
- * Data Type: int
- *
- * Arguments:
- * yymm = the date to convert
- *
- * Returns:
- * The number of months since 8901
- *
- * Side Effects:
- *
- * Calls:
- *
- * PDL:
- *
- >*/
-
- int
- basemonth (yymm)
- char *yymm;
- {
- int zzzz;
- zzzz = atoi (yymm);
- return (12 * ((zzzz - 8901) / 100) + (zzzz - 8901) % 100) ;
- }
-