home *** CD-ROM | disk | FTP | other *** search
/ pc.louisiana.edu/pub/unix/ / Louisiana_UNIX.tar / Louisiana_UNIX / xspread3.0.zoo / graphic_main.c < prev    next >
C/C++ Source or Header  |  1994-04-26  |  45KB  |  1,346 lines

  1. /*
  2.  * Copyright (C) 1992  Board of Regents of the University of Wisconsin
  3.  * on behalf of the Department of Electrical Engineering and Computer
  4.  * Science, University of Wisconsin-Milwaukee, Milwaukee, WI 53201.
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * The programs in this directory were developed by software engineering
  21.  * teams as part of the course "Introduction to Software Engineering"
  22.  * under the supervision of Professor G. Davida.
  23.  *
  24.  * Please send all changes, enhancements, and other comments about this
  25.  * software to
  26.  *
  27.  *             soft-eng@cs.uwm.edu
  28.  *
  29.  *            or
  30.  *        
  31.  *        Software Engineering Coordinator
  32.  *        Computer Science
  33.  *           Department of EECS
  34.  *        University of Wisconsin - Milwaukee
  35.  *        Milwaukee, WI  53201
  36.  *        414-229-4677
  37.  */
  38.  
  39. /* Modified by Dan Gruber to run Line, Bar, XY, Stack Bar and
  40.    Pie graphs.  Mike Frey modified the Graph Menu so that if
  41.    <ESC> is pressed, it will bounce up one.  December 1991 */
  42.  
  43. /* B. Backman 7-29-91.  Appended other graphic calls to this
  44.  * file instead of (ugh) #include-ing (choke, choke) them.
  45.  * Also, fixed the atrocious spelling and grammar of Tuan Tang! */
  46.  
  47. /* Modified by Dan Coppersmith 5/94 to include ability to save graphic
  48.  * definitions, ability to run a sample graph, improve user friendliness
  49.  * of graph error functions, and improve user interface of 
  50.  * Graphic/Options/Format section                 ****/
  51.  
  52. /* ************************************************** */
  53. /* Programer: <Tuan Tang>    Date: July 24, 1990      */
  54. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  55. /* This is the main function of graphics program.     */
  56. /* This function will display  the main graphic menu, */
  57. /* and branch to the appropriate function once the    */
  58. /* item in the menu is selected, It also include a    */
  59. /* list of      */
  60. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  61.  
  62. /* modified 7-24-91, B.Backman.  Commented out curses
  63.    calls and replaced them with X equivalents and 
  64.    functions defined in scXstuff.c */
  65. /* 7-31-91 B. Backman -- Removed illegal comparisons of char-pointers to 
  66.    chars */
  67.  
  68. #include <signal.h>
  69. #include "config.h"
  70.  
  71.  
  72. #ifdef BSD42
  73. #include <strings.h>
  74. #else
  75. #ifndef SYSIII
  76. #include <string.h>
  77. #endif
  78. #endif
  79.  
  80. #include <X11/Xlib.h>
  81. #include <X11/Xutil.h>
  82.  
  83. #include <stdio.h>
  84. #include <ctype.h> 
  85. #include "sc.h"  
  86. #include "scXstuff.h" 
  87. #include "graphic_gvar.h"
  88.  
  89. extern plot_XY();
  90. extern plot_bar();
  91. extern plot_line();
  92. extern plot_pie();
  93. extern plot_stacked_bar();
  94.  
  95. Graph_Menu()
  96. {
  97.      static  char *mainmenu[] =
  98.                    {
  99.                     "Type",
  100.                     "X","A","B","C","D","E","F",
  101.                     "Reset",
  102.                     "View",
  103.                     "Options",
  104.             "Sample",
  105.                    };
  106.  
  107.      static  char *help[] =
  108.                    {
  109. /* Type */          "Type of the graph",
  110. /* X */             "Set data range for X",
  111. /* A */             "Set data range for A",
  112. /* B */             "Set data range for B",
  113. /* C */             "Set data range for C",
  114. /* D */             "Set data range for D",
  115. /* E */             "Set data range for E",
  116. /* F */             "Set data range for F",
  117. /* Reset */         "Cancel graph or range settings",
  118. /* View */          "View the graph on the monitor",
  119. /* Options */       "Graph output options",
  120. /* Sample */        "Make a sample graph",
  121.                    };
  122.  
  123. /* auto. */  unsigned int  choice=0;
  124. /* auto. */  char msg[100];
  125.  
  126.     do {     /* do until ESC is selected */
  127.        choice = menu(GRAPHITEMS,mainmenu,help); 
  128.        switch(choice) {    
  129.                       case  0: Main_Menu();
  130.                    break; /* exit */
  131.        /* Type */     case  1: graphic_typefn();
  132.                                break;
  133.        /* X */        case  2: 
  134.        /* A */        case  3:
  135.        /* B */        case  4: 
  136.        /* C */        case  5:
  137.        /* D */        case  6: 
  138.        /* E */        case  7:
  139.        /* F */        case  8: graphic_grangefn(choice,mainmenu); 
  140.                                break;
  141.        /* Reset */    case  9: graphic_resetfn();
  142.                                break;
  143.        /* View */     case 10: graphic_view();                              
  144.                                break;
  145.        /* Options */  case 11: graphic_optionsfn(); 
  146.                                break;
  147.        /* Sample */   case 12: graphic_sample();
  148.                       default: sprintf(msg,"Invalid data arrived here !");
  149.                                (void) message(msg);
  150.                                break;
  151.                       } /* end of switch */
  152.       } while ( choice != NULL );  /* end of do */
  153. }
  154.  
  155.  
  156. /* =============================================== */
  157. /* This function displays the input data or message*/
  158. /* at the first line of the spread sheet screen    */
  159. /* for approximately one second.                   */
  160. /* =============================================== */
  161.  
  162. message(x)  
  163.  
  164. char *x;        /* string for display */
  165. {
  166.    clearlines(0,0);
  167.    XDrawImageString(dpy, mainwin, maingc,
  168.             textcol(0), textrow(0),
  169.             x, strlen(x));
  170.    XFlush(dpy);      /* force it onto the screen */
  171.    sleep(1);         /* delay 1 second */
  172.    clearlines(0,0);
  173. } /* end of message */
  174.  
  175. /* ******************************************************* */
  176. /* Programer: <Tuan Tang>  Date: August 05, 1990           */
  177. /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
  178. /* This function sets the numeric scales for the X axis    */
  179. /* and Y axis, Automatic is the default scale while manual */
  180. /* allows the user specified output data range.            */
  181. /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
  182.  
  183. graphic_XYscalefn(c,m) 
  184.  
  185. unsigned int  c;    /* 1 for X scale, 2 for Y scale */
  186.          char *m[]; /* array of itmes from graphic_scalefn */
  187. {
  188.      static char *submenu[] =
  189.                  {
  190.                   "Automatic",
  191.                   "Manual", 
  192.                   "Lower",
  193.           "Upper",
  194.                  };
  195.  
  196.      static char *help[] =
  197.                  {
  198. /* Automatic */  "Use the max. and min. values of data ranges to set the scale",
  199. /* Manual */     "Allow the user to specify the range of data for display",
  200. /* Lower */      "Set lower limit",                        
  201. /* Upper */      "Set upper limit",
  202.                  };
  203.  
  204. /* auto. */ unsigned int  choice;
  205. /* auto. */ char msg[100];
  206.  
  207.    while ( (choice = menu(GRAPHXYSCALES,submenu,help)) != NULL )
  208.          switch(choice) {
  209.             case  0: graphic_optionsfn();
  210.                  break;
  211.             case  1: g_auto_man[c-1] = 'A';
  212.                                  sprintf(msg,"Graph scale is Automatic"); 
  213.                                  (void) message(msg);
  214.                  break;
  215.             case  2: g_auto_man[c-1] = 'M';
  216.                                  sprintf(msg,"Graph scale is Manual");
  217.                                  (void) message(msg);
  218.                  break;
  219.                         case  3: 
  220.                         case  4: graphic_srangefn(c,m,choice);
  221.                  break;
  222.                         default: sprintf(msg,"Invalid data arrived here!");
  223.                                  (void) message(msg);
  224.                  break;
  225.                         }  /* end of switch */
  226. } /* end of function */
  227.  
  228.  
  229. double gatofn(s)    /* convert string s to double */
  230. /* *********************************** */
  231. /* This was copied from system library */
  232. /* *********************************** */
  233.  
  234. char  s[];
  235. {
  236.     double val, power;
  237.     int i, sign;
  238.  
  239.     for (i=0; s[i]==' ' || s[i]=='\n' || s[i]=='\t'; i++)
  240.         ;           /* skip white space */
  241.     sign = 1;
  242.     if (s[i] == '+' || s[i] == '-')   /* sign */
  243.          sign = (s[i++]=='+') ? 1 : -1;
  244.     for (val = 0; s[i] >= '0' && s[i] <= '9'; i++)
  245.          val = 10 * val + s[i] - '0';
  246.     if (s[i] == '.')
  247.        i++;
  248.     for (power = 1; s[i] >= '0' && s[i] <= '9'; i++) {
  249.          val = 10 * val + s[i] - '0';
  250.          power *= 10;
  251.         }
  252.     return(sign * val / power);
  253. }
  254.  
  255.  
  256. /* ************************************************** */
  257. /* Programer: <Tuan Tang>    Date: August 04, 1990    */
  258. /* -------------------------------------------------- */
  259. /* Funtion graphic_formatfn sets the output format    */
  260. /* of XY & line graphs. The format can be set for     */
  261. /* each data range or for all data ranges.            */
  262. /* To set one data range at a time select A,B,...,    */
  263. /* or F.  And of all data ranges select Graph.        */
  264. /* -------------------------------------------------- */
  265.  
  266. graphic_formatfn()
  267.  
  268. {
  269.  
  270.    static char *submenu[] =
  271.                 {
  272.                  "Graph",
  273.                  "A","B","C","D","E","F",
  274.                 };
  275.  
  276.    static char *help[] =
  277.                 {
  278. /* Graph */      "Change the format of the entire graph",
  279. /* A */          "Change the format of A range",                     
  280. /* B */          "Change the format of B range",                     
  281. /* C */          "Change the format of C range",                     
  282. /* D */          "Change the format of D range",                     
  283. /* E */          "Change the format of E range",                     
  284. /* F */          "Change the format of F range",                     
  285.                  };
  286.  
  287.    unsigned int   choice;
  288.         char  msg[100];
  289.  
  290.    while ( (choice = menu(GRAPHFORMATS,submenu,help) ) != NULL )
  291.          {            
  292.            if ( choice > GRAPHFORMATS )
  293.           {
  294.                sprintf(msg,"0 <= Input Data < %1d ",GRAPHFORMATS);
  295.            (void) message(msg);
  296.           }
  297.            else
  298.               graphic_formatst(choice-1);   /* index of array */
  299.           } /* end of while */
  300.  
  301. }  /* end of function */
  302. /* ************************************************ */
  303. /* Programer: <Tuan Tang>    Date: August 04, 1990  */
  304. /* ------------------------------------------------ */
  305. /* Funtion graphic_formatst sets the output format  */
  306. /* of line & XY graphs. There are four options.     */
  307. /*    1. Lines  :this option connects each data     */
  308. /*                point with a straight line.       */
  309. /*    2. Symbol :display each range data point with */
  310. /*               the same symbol.  There is a       */
  311. /*               different symbol for each range.   */
  312. /*    3. Both   :select both Lines and Symbols.     */
  313. /*    4. Neither:Will allow you to select the label */
  314. /*               for data range.                    */
  315. /* ------------------------------------------------ */
  316.  
  317. graphic_formatst(idx)
  318.  
  319. unsigned int  idx;    /* type of data range(s) */
  320.  
  321. {
  322.  
  323.    static char *submenu[] =
  324.                 {
  325.                  "Lines",
  326.                  "Symbols",
  327.                  "Both",
  328.                  "Neither",
  329.                 };
  330.  
  331.     char *help[4];
  332.  
  333.    unsigned int   choice;
  334.             char  msg[100];
  335.         char *range;
  336.             int   i;
  337.  
  338.    /* This is to create a more user friendly help message (-DC) */
  339.    switch(idx) {
  340.     case 0:    help[0] = "Connect all range data points with a straight line";
  341.         help[1] = "Display all range data points with a symbol only";
  342.         help[2] = "Display all ranges with both lines and symbols";
  343.         help[3] = "Use neither lines nor symbols for display of ranges";
  344.         range = "Graph";    break;
  345.     case 1: help[0] = "Connect A range data points with a straight line";
  346.         help[1] = "Display A range data points with a symbol only";
  347.         help[2] = "Display A range with both lines and symbols";
  348.         help[3] = "Use neither lines nor symbols to display A range";
  349.         range = "A";        break;
  350.      case 2:    help[0] = "Connect B range data points with a straight line";
  351.         help[1] = "Display B range data points with a symbol only";
  352.         help[2] = "Display B range with both lines and symbols";
  353.         help[3] = "Use neither lines nor symbols to display B range";
  354.         range = "B";        break;
  355.     case 3:    help[0] = "Connect C range data points with a straight line";
  356.         help[1] = "Display C range data points with a symbol only";
  357.         help[2] = "Display C range with both lines and symbols";
  358.         help[3] = "Use neither lines nor symbols to display C range";
  359.         range = "C";        break;
  360.     case 4: help[0] = "Connect D range data points with a straight line";
  361.         help[1] = "Display D range data points with a symbol only";
  362.         help[2] = "Display D range with both lines and symbols";
  363.         help[3] = "Use neither lines nor symbols to display D range";
  364.         range = "D";        break;
  365.     case 5: help[0] = "Connect E range data points with a straight line";
  366.         help[1] = "Display E range data points with a symbol only";
  367.         help[2] = "Display E range with both lines and symbols";
  368.         help[3] = "Use neither lines nor symbols to display E range";
  369.         range = "E";        break;
  370.     case 6: help[0] = "Connect F range data points with a straight line";
  371.         help[1] = "Display F range data points with a symbol only";
  372.         help[2] = "Display F range with both lines and symbols";
  373.         help[3] = "Use neither lines nor symbols to display F range";
  374.         range = "F";        break;
  375.     default:   sprintf(msg, "parameter error idx graphic_formatst()");
  376.            message(msg);    break;
  377.     }    /* end of switch(idx) */
  378.  
  379.  
  380.    choice = menu(GRAPHSYMBOLS,submenu,help);
  381.          switch(choice) {
  382.             case  0: graphic_optionsfn();
  383.                  break;
  384.                         case  1: graphic_format[idx] = 'L';
  385.                                  break;
  386.                         case  2: graphic_format[idx] = 'S';
  387.                                  break;
  388.                         case  3: graphic_format[idx] = 'B';
  389.                                  break;
  390.                         case  4: graphic_format[idx] = 'N';
  391.                                  break;
  392.                         default: sprintf(msg,"Input error for format!");  
  393.                  message(msg);
  394.                                  break;
  395.                         }    /* end switch */
  396.    if ( 1 <= choice && choice <= GRAPHSYMBOLS )  /* print message */
  397.       {
  398.     sprintf(msg,"The %s format is %s",range, submenu[choice-1]);
  399.     (void) message(msg);
  400.        }     
  401.     
  402.    /* set the format for the entire graph by setting each */
  403.    /* data range to the same type of graph format         */
  404.    if ( idx == 0 )   
  405.       for (i=1; i< GRAPHFORMATS; i++){
  406.           graphic_format[i] = graphic_format[idx];
  407.       }
  408.   
  409. }  /* end of function */
  410.  
  411.  
  412. /* *************************************************** */
  413. /* Programmer: <Dan Coppersmith>  Date: May 2, 1994    */
  414. /* ``````````````````````````````````````````````````` */
  415. /* Reads in the graph definitions from the input file. */
  416. /* =================================================== */
  417.  
  418. void graphic_read_defn(FILE *f)
  419. {
  420.     int c, i, j;
  421.     FILE *z;    /* erase this after test! */
  422.     char *testDir;
  423.  
  424. /* this is a test */
  425. /*    if (*testDir == NULL)
  426.     {*/    testDir = getenv("HOME");
  427.     if (*testDir == NULL)
  428.         testDir = "/";
  429. /*    }*/
  430.     z = fopen("test_file", "w");
  431.     fprintf(z, "testDir = %s\n", testDir);
  432.     fclose(z);
  433. /* end of test */
  434.  
  435.  
  436.     while ((c = getc(f)) != '=')  ;    /* move beyond = sign */
  437.     graphic_type = getc(f);                /* graphic_type */
  438.  
  439.     for (i = 0; i < GRAPHLEGENDS; i++) {        /* graphic_legend */
  440.         while ((c = getc(f)) != '=')  ;
  441.     c = getc(f);
  442.     for (j = 0; ((j < 99)&&(c != NULL)&&(c != '\n')); j++) {
  443.         graphic_legend[i][j] = c;        
  444.         c = getc(f);
  445.     }
  446.     graphic_legend[i][j] = NULL;
  447.     }
  448.  
  449.     while ((c = getc(f)) != '=')  ;            /* graphic_format */
  450.     for (i = 0; i < GRAPHFORMATS; i++) 
  451.     graphic_format[i] = getc(f);            
  452.  
  453.     for (i = 0; i < GRAPHTITLES; i++) {            /* graphic_title */
  454.     while ((c = getc(f)) != '=') ;
  455.     c = getc(f);
  456.     for (j = 0; ((j < 49)&&(c != NULL)&&(c != '\n')); j++) {
  457.         graphic_title[i][j] = c;
  458.         c = getc(f);
  459.     }
  460.     graphic_title[i][j] = NULL;
  461.     }
  462.  
  463.     while ((c = getc(f)) != '=') ;            /* graphic_grid */
  464.     graphic_grid = getc(f);
  465.  
  466.     while ((c = getc(f)) != '=') ;            /* g_auto_man[] */
  467.     g_auto_man[0] = getc(f);
  468.     g_auto_man[1] = getc(f);
  469.  
  470.     while ((c = getc(f)) != '=') ;            /* graphic_skip */
  471.     fscanf(f, "%d", &graphic_skip);
  472.  
  473.     fscanf(f, " curves_n=%d", &curves_n);        /* curves_n */
  474.  
  475.     fscanf(f, " graphic_scale[0][]=%lf %lf", 
  476.         &graphic_scale[0][0], &graphic_scale[0][1]);
  477.     fscanf(f, " graphic_scale[1][]=%lf %lf",
  478.         &graphic_scale[1][0], &graphic_scale[1][1]);
  479.  
  480.     for (i = 0; i < GRAPHRANGES; i++) {            /* graphic_range */
  481.     while ((c = getc(f)) != '=') ;
  482.     for (j = 0; j < 3; j++) {
  483.         if ((c = getc(f)) == '~')
  484.         graphic_range[i].col[j] = NULL;
  485.         else 
  486.         graphic_range[i].col[j] = c;
  487.     }
  488.     fscanf(f, " %d", &graphic_range[i].r1);
  489.     fscanf(f, " %d", &graphic_range[i].r2);
  490.     fscanf(f, " %d", &graphic_range[i].c);
  491.     }
  492. }
  493.  
  494.  
  495. /* *************************************************** */
  496. /* Programer: <Tuan Tang>     Date: July 24, 1990      */
  497. /* ``````````````````````````````````````````````````` */
  498. /* Sets the range for a particular data range. There   */
  499. /* are seven different data ranges allowed.  They are  */
  500. /* labeled as X, A, B, C, D, E, and F.                 */
  501. /* ``````````````````````````````````````````````````` */
  502.  
  503. #define  CLIM 3   /* characters allow for column address */
  504. #define  RLIM 4   /* digits allow to enter for row # */
  505.  
  506. graphic_grangefn(c,m)
  507.  
  508.  int    c;    /* an integer, index to a data set */
  509.  char   *m[]; /* array of items */
  510.  
  511. {
  512.   char s[100];   /* stored number to be converted */
  513.   char msg[100]; /* message for display */
  514.   int  ierr;     /* 1 = No error on input */
  515.   int  colm;     /* column number from label entered */
  516.   int  i;        /* miscellaneous index */
  517.   
  518.       /* accept column address for graph range */
  519.       do {
  520.           ierr = 1;
  521.           sprintf(s,"Input column label for range %s-- 2 character max.: ",m[c-1]);
  522.           strcpy(graphic_range[c-2].col,get_str(s,CLIM));
  523.  
  524.       /* convert label in "base 26" to column number */
  525.       /* set ierr=0 if an error occurs */
  526.       for(i=colm=0; (i<CLIM) && (s[i] != '\0') && ierr ; i++){
  527.         if ( !isalpha(s[i]) && !isspace(s[i])) {
  528.           ierr = 0;
  529.           continue;
  530.             }
  531.         if (isspace(s[i])) continue;
  532.         if ( islower(s[i]))
  533.           s[i] = toupper(s[i]);
  534.         colm = (colm * 26) + (s[i] - 'A' + 1);
  535.       }
  536.       if (colm == 0)
  537.         ierr = 0;  /* input was all spaces */
  538.           else
  539.         colm--;    /* adjust to zero-based system */
  540.  
  541.           if (ierr == 0 )
  542.             {
  543.              sprintf(msg,"Input must be character(s)");
  544.              (void) message(msg);
  545.              graphic_range[c-2].col[0] = '\0';
  546.             }
  547.          } while ( ierr == 0 );
  548.       graphic_range[c-2].c = colm;
  549.      
  550.       do {           
  551.      clearlines(0,0);  /* clear from row 0 to row 0 */
  552.          ierr = 1;
  553.          sprintf(s,"Input starting row number, 200 max., for range %s : ",m[c-1]);
  554.          graphic_range[c-2].r1 = atoi( get_str(s,RLIM) );
  555.          if ( (isdigit(s[0]) == NULL) || (graphic_range[c-2].r1 > 200) )     
  556.            {
  557.             sprintf(msg,"Input error !");
  558.             (void) message(msg);
  559.             ierr = NULL;
  560.            } /* end if */
  561.          } while ( ierr  == NULL );  /* end do */
  562.  
  563.       do {
  564.          ierr = 1;   /* No input error */
  565.          sprintf(s,"Input ending row number >= %2d for range %s ",
  566.                     graphic_range[c-2].r1,m[c-1]);
  567.          graphic_range[c-2].r2 = atoi( get_str(s,RLIM) );
  568.          if ( (isdigit(s[0]) == NULL) || (graphic_range[c-2].r2 < 
  569.                graphic_range[c-2].r1) )
  570.            {
  571.             sprintf(msg,"Input error !");
  572.             (void) message(msg);
  573.             ierr = NULL;
  574.            } /* end if */
  575.          } while ( ierr == NULL );  /* end do */
  576.    /* B. Backman 7-31-91  The following won't work if user enters a 
  577.       capital letter or a double-letter column such as 'aa'.  It will 
  578.       need to be fixed if we have time */
  579. }
  580.   
  581.  
  582. /* ********************************************* */
  583. /* Programer: <Tuan Tang>  Date: August 04, 1990 */
  584. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  585. /* Function graphic_gridfn adds or removes grid  */
  586. /* lines on the graph display.  Grid lines can   */
  587. /* not be used for pie charts.                   */
  588. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  589.  
  590. #define  GRIDS   4
  591.  
  592. graphic_gridfn()
  593. {
  594.      static  char *submenu[] =  /* stored reset options */
  595.                    {
  596.                     "Horizontal",
  597.                     "Vertical",                 
  598.                     "Both",
  599.                     "Clear",
  600.                    };
  601.                    
  602.      static  char *help[] = /* help menu for reset options */
  603.                    {
  604. /* Horizontal */    "Horizontal grid lines appear across the graph",
  605. /* Vertical */      "Vertical grid lines appear across the graph",
  606. /* Both */          "Both horizontal and vertical lines appear",
  607. /* Clear */         "Erases all the grid lines"
  608.                    };
  609.  
  610.     unsigned int  choice;
  611.              char msg[100];
  612.  
  613.     choice = menu(GRIDS,submenu,help);
  614.     switch(choice) {
  615. /* Exit */       case  0: graphic_optionsfn();
  616.                 break;
  617. /* Horizontal */   case  1: graphic_grid = 'H';
  618.                             sprintf(msg,"Add Horizontal grids on the graph");
  619.                             (void) message(msg);
  620.                             break;
  621. /* Vertical */     case  2: graphic_grid = 'V';
  622.                             sprintf(msg,"Add Vertical grids on the graph");
  623.                             (void) message(msg);
  624.                             break;
  625. /* Both */         case  3: graphic_grid = 'B';
  626.                             sprintf(msg,"Add grids on X & Y axes");
  627.                             (void) message(msg);
  628.                             break;
  629. /* Clear */        case  4: graphic_grid = 'C';
  630.                             sprintf(msg,"Remove grids on the graph");
  631.                             (void) message(msg);
  632.                             break;
  633.                    default: sprintf(msg,"0 <= Input Data <= %1d ",GRIDS);
  634.                             (void) message(msg);
  635.                             break;
  636.                    } /* end of switch */
  637. } /* end of function */
  638.  
  639.  
  640. /* ********************************************** */
  641. /* Programer: <Tuan Tang>   Date: August 09, 1990 */
  642. /* ---------------------------------------------- */
  643. /* Function graphic_init initializes the          */
  644. /* global variables use by the graphic functions  */
  645. /* These variable could be found in graphic**.h   */
  646. /* ********************************************** */
  647.  
  648. graphic_init()
  649.  
  650. {
  651.   int i,j;
  652.  
  653.   graphic_type = 'L';  /* graph format is line initialy */
  654.   graphic_grid = 'C';  /* clear grid line */
  655.   graphic_skip = 0;    /* do not skip points */
  656.    
  657.   for (i=0; i < GRAPHLEGENDS; i++)
  658.       graphic_legend[i][0] = '\0';   /* no legend assign to them yet */
  659.  
  660.   for (i=0; i < GRAPHFORMATS; i++)   /* Line & Symbol */
  661.       graphic_format[i] = 'B';
  662.   
  663.   for (i=0; i < GRAPHTITLES; i++)    /* no title been assigned to them */
  664.       graphic_title[i][0] = '\0';
  665.  
  666.   g_auto_man[0] = 'A';  /* Scaling is automatic */
  667.   g_auto_man[1] = 'A';
  668.  
  669.   for (i=0; i< (GRAPHSCALES-1); i++) /* none */
  670.       for (j=0; j < 2; j++)
  671.           graphic_scale[i][j] = (double) 0.0;
  672.  
  673.   for (i=0; i<GRAPHRANGES; i++)
  674.     graphic_range[i].col[0] = '\0';
  675. }   
  676.  
  677.  
  678. /* ***************************************************** */
  679. /* Programer: <Tuan Tang>  Date: August 01, 1990         */
  680. /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
  681. /* This function allows you to enter the label for each  */
  682. /* graph. The label is used to identify what each symbol */
  683. /* color, or crosshatching represents in the graph.      */
  684. /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
  685.  
  686. #define  MAXLEN  40 
  687.  
  688. graphic_legendfn()
  689.  
  690. {
  691.      static char *submenu[] =
  692.                  {
  693.                    "A","B","C","D","E","F", 
  694.                  };
  695.  
  696.      static char *help[] =
  697.                  {
  698.                   "Set legend for A",
  699.                   "Set legend for B",
  700.                   "Set legend for C",
  701.                   "Set legend for D", 
  702.                   "Set legend for E",
  703.                   "Set legend for F",
  704.                  };
  705.  
  706. /* auto. */ unsigned int  choice;
  707. /* auto. */          char msg[100];
  708.     
  709.    while ( (choice = menu(GRAPHLEGENDS,submenu,help)) != NULL ) 
  710.      {
  711.        (void) sprintf (msg,"Enter the legend for %s : ",submenu[choice-1]);
  712.        strcpy(graphic_legend[choice-1],get_str(msg, MAXLEN)); 
  713.        sprintf(msg,"The legend for %s  is:  %s ",submenu[choice-1],
  714.                graphic_legend[choice-1]); 
  715.        (void) message(msg); 
  716.      }
  717. }
  718. /* ******************************************************* */
  719. /* Programer: <Tuan Tang>     Date: August 01, 1990        */
  720. /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
  721. /* Sets the options for graphs.  There are eight options   */
  722. /* and they are Legend, Format, Titles, Grid, Scale, Color */
  723. /* B&W and Data-Labels.                                    */
  724. /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
  725.  
  726. graphic_optionsfn()
  727. {
  728.      static char *submenu[] =
  729.                   {
  730.                    "Legend",
  731.                    "Format",
  732.                    "Titles",
  733.                    "Grid",
  734.                    "Scale",
  735.                   };
  736.  
  737.      static char *help[] =
  738.                   {
  739. /* Legend */       "Label to identify what each symbol represents",
  740. /* Format */       "Use to change the appearance of line and XY graphs",
  741. /* Title */        "Assigns a title to each axis or to an entire graph",
  742. /* Grid */         "Adds or removes grid lines on the graph display",
  743. /* Scale */        "Set numeric scales for X axis and Y axis",
  744.                   };
  745.  
  746. /* auto. */ unsigned int  choice;
  747. /* auto. */          char msg[100];
  748.  
  749.     do {  /* do until escape is selected */
  750.         choice = menu(GRAPHOPTIONS,submenu,help);
  751.         switch(choice) {
  752. /* Legend */           case  1: graphic_legendfn();
  753.                                 break;
  754. /* Format */           case  2: graphic_formatfn(); 
  755.                                 break;
  756. /* Title */            case  3: graphic_titlesfn(); 
  757.                                 break;
  758. /* Grid */             case  4: graphic_gridfn(); 
  759.                                 break;
  760. /* Scale */            case  5: graphic_scalefn();
  761.                                 break;
  762. /* Quit */             case  0: break;    /* exit do loop */
  763.                        default: sprintf(msg,"Invalid data arrived here!");
  764.                                 (void) message(msg);
  765.                                 break;
  766.                       }
  767.        } while ( choice != 0 ); 
  768.  }
  769.  
  770.  
  771. /* ********************************************* */
  772. /* Programer: <Tuan Tang>  Date: July 25, 1990   */
  773. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  774. /* This function sets the range  for the graph.  */
  775. /* The range  can be set for the entire graph    */
  776. /* or for each individual set of value.          */
  777. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  778.  
  779. graphic_resetfn()
  780. {
  781.      static  char *submenu[] =  /* stored reset options */
  782.                    {
  783.                     "Graph",
  784.                     "X","A","B","C","D","E","F",
  785.                    };
  786.                    
  787.      static  char *help[] = /* help menu for reset options */
  788.                    {
  789. /* Graph */         "Cancel the range settings for current graph",
  790. /* X */             "Reset the range for X",
  791. /* A */             "Reset the range for A",
  792. /* B */             "Reset the range for B",
  793. /* C */             "Reset the range for C",
  794. /* D */             "Reset the range for D",
  795. /* E */             "Reset the range for E",
  796. /* F */             "Reset the range for F",
  797.                    };
  798.  
  799. /* auto. */  unsigned int  choice;
  800. /* auto. */           char msg[100];
  801. /* auto. */           int  i;
  802.  
  803.     do {
  804.        choice = menu(GRAPHRESETS,submenu,help);
  805.        if ( choice > GRAPHRESETS )
  806.           {
  807.           sprintf(msg,"Invalid data arrived here !");
  808.           (void) message(msg);
  809.           }
  810.        else if ( choice != 0 )
  811.           {
  812.           if ( choice == 1 ) {
  813.             for (i=1; i < GRAPHRANGES; i++)
  814.                 graphic_range[i].col[0] = '\0'; /* set all ranges to NULL */
  815.             sprintf(msg,"Clear the ranges for entire graph !");
  816.           }
  817.           else {
  818.             graphic_range[choice-2].col[0] = '\0'; /* set data range to NULL */
  819.             sprintf(msg,"Clear %s data range ",submenu[choice-1]); 
  820.       }
  821.           (void) message(msg);
  822.          }
  823.       } while ( choice != NULL );
  824. }
  825.  
  826.  
  827. /* ********************************************** */
  828. /* Programer: Dan Coppersmith   Date: May 2, 1994 */
  829. /* ---------------------------------------------- */
  830. /* graphic_sample allows the user to select a     */
  831. /* sample graph without affecting the global      */
  832. /* graph definitions.                      */
  833. /* ********************************************** */
  834.  
  835. graphic_sample()
  836.  
  837. {
  838.      int i, j;
  839.      static  char *samplemenu[] =
  840.                    {
  841.                     "Type",
  842.                     "X","A","B","C","D","E","F",
  843.                     "View",
  844.                     "Options",
  845.                    };
  846.  
  847.      static  char *help[] =
  848.                    {
  849. /* Type */          "Type of sample graph",
  850. /* X */             "Set sample data range for X",
  851. /* A */             "Set sample data range for A",
  852. /* B */             "Set sample data range for B",
  853. /* C */             "Set sample data range for C",
  854. /* D */             "Set sample data range for D",
  855. /* E */             "Set sample data range for E",
  856. /* F */             "Set sample data range for F",
  857. /* View */          "View the sample graph on the monitor",
  858. /* Options */       "Sample graph output options",
  859.                    };
  860.  
  861. /* auto. */  unsigned int  choice=0;
  862. /* auto. */  char msg[100];                 
  863.  
  864.   /* These variables temporarily store current graph definitions */
  865.   char tmp_type, tmp_legend[GRAPHLEGENDS][100],
  866.     tmp_format[GRAPHFORMATS], tmp_title[GRAPHTITLES][50],
  867.     tmp_grid, t_auto_man[2];
  868.   unsigned int tmp_skip, tmp_curves_n;
  869.   double tmp_scale[GRAPHSCALES-1][2];
  870.   struct g_range tmp_range[GRAPHRANGES];
  871.  
  872.   tmp_type = graphic_type;    /* store all original graph definitions */
  873.   tmp_grid = graphic_grid;    /* in tmp variables.            */
  874.   tmp_skip = graphic_skip;
  875.   tmp_curves_n = curves_n;
  876.  
  877.   for (i=0; i < GRAPHLEGENDS; i++) 
  878.     strcpy(tmp_legend[i], graphic_legend[i]);
  879.  
  880.   for (i=0; i < GRAPHFORMATS; i++)   
  881.     tmp_format[i] = graphic_format[i];
  882.  
  883.   for (i=0; i < GRAPHTITLES; i++) 
  884.     strcpy(tmp_title[i], graphic_title[i]);
  885.  
  886.   t_auto_man[0] = g_auto_man[0];
  887.   t_auto_man[1] = g_auto_man[1];
  888.  
  889.   for (i=0; i< (GRAPHSCALES-1); i++)
  890.       for (j=0; j < 2; j++)
  891.           tmp_scale[i][j] = graphic_scale[i][j];
  892.  
  893.   for (i=0; i<GRAPHRANGES; i++) {
  894.     tmp_range[i].col[0] = graphic_range[i].col[0];
  895.     tmp_range[i].col[1] = graphic_range[i].col[1];
  896.     tmp_range[i].col[2] = graphic_range[i].col[2];
  897.     tmp_range[i].r1 = graphic_range[i].r1;
  898.     tmp_range[i].r2 = graphic_range[i].r2;
  899.     tmp_range[i].c = graphic_range[i].c;
  900.   }
  901.  
  902.      graphic_init();    /* reset all global graph definitions */
  903.  
  904.     do {     /* do until ESC is selected */
  905.        choice = menu(GRAPHSAMPLES,samplemenu,help);
  906.        switch(choice) {
  907.                       case  0: /* before exiting, must restore 
  908.                   previous graph definitions  */
  909.           graphic_type = tmp_type;
  910.           graphic_grid = tmp_grid;
  911.           graphic_skip = tmp_skip;
  912.            curves_n = tmp_curves_n;
  913.  
  914.           for (i=0; i < GRAPHLEGENDS; i++) 
  915.         strcpy(graphic_legend[i], tmp_legend[i]);
  916.  
  917.           for (i=0; i < GRAPHFORMATS; i++)
  918.             graphic_format[i] = tmp_format[i];
  919.  
  920.           for (i=0; i < GRAPHTITLES; i++) 
  921.         strcpy(graphic_title[i], tmp_title[i]);
  922.  
  923.           g_auto_man[0] = t_auto_man[0];
  924.           g_auto_man[1] = t_auto_man[1];
  925.  
  926.           for (i=0; i< (GRAPHSCALES-1); i++)
  927.               for (j=0; j < 2; j++)
  928.                   graphic_scale[i][j] = tmp_scale[i][j];
  929.  
  930.           for (i=0; i<GRAPHRANGES; i++) {
  931.                 graphic_range[i].col[0] = tmp_range[i].col[0];
  932.                 graphic_range[i].col[1] = tmp_range[i].col[1];
  933.                 graphic_range[i].col[2] = tmp_range[i].col[2];
  934.                 graphic_range[i].r1 = tmp_range[i].r1;
  935.                 graphic_range[i].r2 = tmp_range[i].r2;
  936.                 graphic_range[i].c = tmp_range[i].c;
  937.         }
  938.  
  939.                    Main_Menu();
  940.                                break; /* exit */
  941.        /* Type */     case  1: graphic_typefn();
  942.                                break;
  943.        /* X */        case  2:
  944.        /* A */        case  3:
  945.        /* B */        case  4:
  946.        /* C */        case  5:
  947.        /* D */        case  6:
  948.        /* E */        case  7:
  949.        /* F */        case  8: graphic_grangefn(choice,samplemenu);
  950.                                break;
  951.        /* View */     case  9: graphic_view();
  952.                                break;
  953.        /* Options */  case 10: graphic_optionsfn();
  954.                                break;
  955.                       default: sprintf(msg,"Invalid data arrived here !");
  956.                                (void) message(msg);
  957.                                break;
  958.                       } /* end of switch */
  959.       } while ( choice != NULL );  /* end of do */
  960. }
  961.  
  962.  
  963. /* ******************************************************* */
  964. /* Programer: <Tuan Tang>  Date: August 05, 1990           */
  965. /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
  966. /* This function sets the numeric scales for the X axis    */
  967. /* and Y axis, and specifies the skip factor for X axis    */
  968. /* labels.  The skip factor n is the number of points skip */
  969. /* for every point appears on the graph.                   */
  970. /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
  971.  
  972. graphic_scalefn()
  973.  
  974. {
  975.      static char *submenu[] =
  976.                  {
  977.                   "X scale",
  978.                   "Y Scale",
  979.                   "Skip",
  980.                  };
  981.  
  982.      static char *help[] =
  983.                  {
  984. /* X scale */     "Alter the scale of X axis",                        
  985. /* Y scale */     "Alter the scale of Y axis",
  986. /* Skip */        "Skip n points for every point plotted",
  987.                  };
  988.  
  989. /* auto. */ unsigned int  choice;
  990. /* auto. */          char msg[100];
  991.  
  992.    while ( (choice = menu(GRAPHSCALES,submenu,help)) != NULL )
  993.          switch(choice) {
  994.          case  0: graphic_optionsfn();
  995.               break;
  996.              case  1: 
  997.          case  2: graphic_XYscalefn(choice,submenu);
  998.                   break;
  999.                  case  3: graphic_skipscale();
  1000.                   break;
  1001.                  default: sprintf(msg,"0<= Input Value <=%1d",GRAPHSCALES);
  1002.                           (void) message(msg);
  1003.               break;
  1004.                         }  /* end of switch */
  1005. } /* end of function */
  1006.  
  1007. /* ************************************************ */
  1008. /* Programer: <Tuan Tang>   Date: August 05, 1990   */
  1009. /* ================================================ */
  1010. /* This function accepts a number.  This is the     */
  1011. /* number of points will be skip between the two    */
  1012. /* points that are plotted.                         */
  1013. /* ================================================ */
  1014.  
  1015.  
  1016. graphic_skipscale()
  1017.  
  1018. {
  1019.   char msg[100];
  1020.   int  ierr = 1;
  1021.   while ( ierr == NULL )
  1022.   {
  1023.    ierr = 1;
  1024.    sprintf(msg,"Input skip factor ##, positive integer only : ");
  1025.    get_str(msg,3);
  1026.    if ( isdigit(msg[0]) == NULL )
  1027.       {
  1028.         message("Input Error!");
  1029.         ierr = NULL;
  1030.        }
  1031.    else
  1032.       graphic_skip = atoi(get_str(msg,3));
  1033.   }
  1034.   sprintf(msg," %2d ",graphic_skip);
  1035.   message(msg);
  1036.  
  1037. }
  1038.  
  1039.  
  1040. /* *************************************************** */
  1041. /* Programer: <Tuan Tang>     Date: July 24, 1990      */
  1042. /* ``````````````````````````````````````````````````` */
  1043. /* Sets the range of X scale or Y scale.  It is being  */
  1044. /* called from graphic_scalefn().                      */
  1045. /* ``````````````````````````````````````````````````` */
  1046.  
  1047. #define  GMAXLEN  40
  1048.  
  1049. graphic_srangefn(c1,m,c2)
  1050.  
  1051. int    c1;    /* indicate whether it is X scale or Y scale */
  1052. char   *m[];  /* array of items: X, Y scale and Skip */
  1053. int    c2;    /* indicate whether it is Lower or Upper limit */
  1054.  
  1055. {
  1056.   double gatofn();
  1057.   char s[GMAXLEN];   /* stored number to be convert */
  1058.  
  1059.   if ( c2 == 3 )   /* Lower limit */
  1060.      {
  1061.      sprintf(s,"Input Lower limit for %s ",m[c1-1]);
  1062.      get_str(s,GMAXLEN);
  1063.      graphic_scale[c1-1][0] = gatofn(s);
  1064.      }
  1065.   else if ( c2 == 4 ) /* Upper limit */
  1066.      {
  1067.      sprintf(s,"Input Upper limit for %s ",m[c1-1]);
  1068.      get_str(s,GMAXLEN);
  1069.      graphic_scale[c1-1][1] = gatofn(s);
  1070.      }
  1071. }
  1072.   
  1073.  
  1074. /* ******************************************************* */
  1075. /* Programer: <Tuan Tang>  Date: August 04, 1990           */
  1076. /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
  1077. /* This function allows you to enter four different titles */
  1078. /* for the graph.  The First(main) title and Second(sub)   */
  1079. /* title will appear on the top of the graph. The X-Axis   */
  1080. /* title will appear on the x-axis and Y-Axis title on     */
  1081. /* the y-axis of the graph.                                */
  1082. /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
  1083.  
  1084. #define  MAXLEN  40 
  1085.  
  1086. graphic_titlesfn()
  1087.  
  1088. {
  1089.      static char *submenu[] =
  1090.                  {
  1091.                   "First",
  1092.                   "Second",
  1093.                   "X-Axis",
  1094.                   "Y-Axis",
  1095.                  };
  1096.  
  1097.      static char *help[] =
  1098.                  {
  1099. /* First */       "Main title, will show up on the top of the graph",
  1100. /* Second */      "Subtitle, will appear below the Main title",
  1101. /* X-Axis */      "Label for x-axis",
  1102. /* Y-Axis */      "Label for y-axis",
  1103.                  };
  1104.  
  1105. /* auto. */ unsigned int  choice;
  1106. /* auto. */          char s[MAXLEN];
  1107. /* auto. */          char msg[100];
  1108.  
  1109.    while ( (choice = menu(GRAPHTITLES,submenu,help)) != NULL )
  1110.      {
  1111.       if ( choice > GRAPHTITLES )
  1112.         {
  1113.          sprintf(msg,"0 <= Input Value < %1d ",GRAPHTITLES);
  1114.          (void) message(msg);
  1115.          }
  1116.       else {
  1117.            sprintf(s,"Enter %s  title: ",submenu[choice-1]);
  1118.            strcpy(graphic_title[choice-1],get_str(s,MAXLEN));
  1119.            }  /* end of else */
  1120.       }  /* end of while */
  1121. } /* end of function */
  1122.  
  1123.  
  1124. /* ************************************************** */
  1125. /* Programer: <Tuan Tang>     Date: July 24, 1990     */
  1126. /* -------------------------------------------------- */
  1127. /* This header file declares and initializes the type */
  1128. /* of the graph and it is executed only during the    */
  1129. /* compilation of the program                         */
  1130. /* -------------------------------------------------- */
  1131.  
  1132. graphic_typefn()
  1133. {
  1134.      static  char *submenu[] = 
  1135.                   {
  1136.                    "Line",
  1137.                    "Bar",
  1138.                    "XY",
  1139.                    "Stack Bar",
  1140.                    "Pie",
  1141.                   };
  1142.  
  1143.  
  1144.     static   char *help[] = 
  1145.                   {
  1146.                    "Represents each value with a point",
  1147.                    "Represents each value with a bar of varying height",
  1148.                    "Plot a pair of xy values with a point",
  1149.                    "The value of one data range stack on the top of the other",
  1150.                    "The pie chart compares parts to the whole--a circle shape",
  1151.                   };
  1152.  
  1153. /* auto. */  unsigned int choice;
  1154. /* auto. */           char msg[100];
  1155.  
  1156.    choice = menu(GRAPHTYPES,submenu,help);
  1157. /* the following ifdef is to "comment out" something w/ comments in it */
  1158. #ifdef NEVER_DEFINED
  1159.    switch(choice){
  1160.                  case  0: break; /* exit */
  1161.                  case  1: graphic_type = 'L'; 
  1162.                           break;
  1163.                  case  2: graphic_type = 'B'; 
  1164.                           break;
  1165.                  case  3: graphic_type = 'X';
  1166.                           break;
  1167.                  case  4: graphic_type = 'S';
  1168.                           break;
  1169.                  case  5: graphic_type = 'P';
  1170.                           break;
  1171.                  default: sprintf(msg,"Invalid data arrived here!");
  1172.                           (void) message(msg);
  1173.                           break;
  1174.                  }
  1175. #endif /* NEVER_DEFINED */
  1176. /* now the replacement for the ifdef'ed code: */
  1177.    switch(choice){
  1178.          case 1: graphic_type = 'L';     break;
  1179.          case 2: graphic_type = 'B';     break;
  1180.          case 3: graphic_type = 'X';    break;
  1181.          case 4: graphic_type = 'S';    break;
  1182.                  case 5: graphic_type = 'P';    break;
  1183.          case 0:                  break;
  1184.          default: sprintf(msg,"Sorry, %s is not implemented yet",
  1185.                   submenu[choice-1]);
  1186.               (void) message(msg);
  1187.               choice = 0;
  1188.               break;
  1189.              }
  1190.     if ( NULL < choice && choice <= GRAPHTYPES )
  1191.        {
  1192.        sprintf(msg,"You have selected %s graph ",submenu[choice-1]);
  1193.        (void) message(msg);
  1194.        }
  1195. }
  1196.  
  1197. graphic_view()
  1198. {
  1199.    unsigned int getout, i, j;
  1200.    double       x;
  1201.    struct ent *p;
  1202.  
  1203.    getout = 0;
  1204.    if (*(graphic_range[0].col) == '\0') { 
  1205.       fprintf(stderr,"\007");
  1206.       message("X range not defined yet.");
  1207.       getout = 1;  
  1208.    }
  1209.  
  1210.    curves_n = 0;
  1211.    for (i = 1; i < GRAPHRANGES; i++) {
  1212.       int cells = 0; /* valid numeric cells in this range */
  1213.  
  1214.       if (*(graphic_range[i].col) == '\0')
  1215.     continue;
  1216.       for (j=graphic_range[i].r1; j<=graphic_range[i].r2; j++){
  1217.     if ((lookat(j, graphic_range[i].c))->flags & is_valid)
  1218.       cells++;
  1219.         else {
  1220.       sprintf(stringbuf,"Invalid numeric cell in range %c\n",'A'+i);
  1221.       fprintf(stderr,"\007");
  1222.       message(stringbuf);
  1223.     }
  1224.       }
  1225.       if (cells < 1){
  1226.     sprintf(stringbuf,"Range %c ignored.\007\n",'A'+i);
  1227.     fprintf(stderr,"\007");
  1228.     message(stringbuf);
  1229.     graphic_range[i].col[0] = '\0';
  1230.       } else 
  1231.         curves_n ++;
  1232.    }  
  1233.    if (curves_n < 1) {
  1234.       getout = 1;
  1235.       message("Not enough valid ranges defined.");
  1236.    }
  1237.  
  1238.    if (graphic_scale[0][0] > graphic_scale[0][1]) {
  1239.       x = graphic_scale[0][0]; 
  1240.       graphic_scale[0][0] = graphic_scale[0][1]; 
  1241.       graphic_scale[0][1] = x; 
  1242.    }
  1243.  
  1244.    if (graphic_scale[1][0] > graphic_scale[1][1]) {
  1245.       x = graphic_scale[1][0]; 
  1246.       graphic_scale[1][0] = graphic_scale[1][1]; 
  1247.       graphic_scale[1][1] = x; 
  1248.    }
  1249.    
  1250.    if (!getout) {
  1251.       switch(graphic_type) {
  1252.       
  1253.       case 'L':
  1254.          plot_line();
  1255.          break; 
  1256.       case 'B':
  1257.          plot_bar();
  1258.          break; 
  1259.       case 'X':
  1260.          plot_XY();
  1261.          break;
  1262.       case 'S':
  1263.          plot_stacked_bar();
  1264.          break;
  1265.       case 'P':
  1266.          plot_pie();
  1267.          break;
  1268.       }
  1269.    }
  1270.    FullUpdate++; /* in case window becomes obscured */
  1271.    update(FALSE);
  1272. }
  1273.  
  1274.  
  1275. /* *************************************************** */
  1276. /* Programmer: <Dan Coppersmith>  Date: May 2, 1994    */
  1277. /* ``````````````````````````````````````````````````` */
  1278. /* Writes in the graph definitions to the input file.  */
  1279. /* =================================================== */
  1280.                                     
  1281. void graphic_write_defn(FILE *f)
  1282. {
  1283.     int i, j, save;
  1284.  
  1285.     /* should first check to see if there is anything to save */
  1286.     save = 0;
  1287.     for (i = 0; i < GRAPHLEGENDS; i++)
  1288.     if (graphic_legend[i][0] != NULL)
  1289.         save = 1;
  1290.     for (i = 0; i < GRAPHTITLES; i++)
  1291.     if (graphic_title[i][0] != NULL)
  1292.         save = 1;
  1293.     for (i = 0; i < GRAPHRANGES; i++)
  1294.     if (graphic_range[i].col[0] != NULL)
  1295.         save = 1;
  1296.     for (i = 0; i < GRAPHFORMATS; i++)
  1297.     if (graphic_format[i] != 'B')
  1298.         save = 1;
  1299.     if ((save == 0)&&(graphic_type == 'L')&&(graphic_grid == 'C')&&
  1300.     (g_auto_man[0] == 'A')&&(g_auto_man[1] == 'A')&&
  1301.     (graphic_skip == 0)&&(curves_n == 0))    /* nothing to save */
  1302.     return;
  1303.     
  1304.     /* if here, then start saving graph definitions */
  1305.     fprintf(f, "Graph Definitions:\n");
  1306.     fprintf(f, "graphic_type=%c\n", graphic_type);
  1307.     
  1308.     for (i = 0; i < GRAPHLEGENDS; i++) {
  1309.     fprintf(f, "graphic_legend[%d]=", i);
  1310.     for (j = 0; ((j < 100)&&(graphic_legend[i][j] != NULL)); j++)
  1311.         fprintf(f, "%c", graphic_legend[i][j]);
  1312.     fprintf(f, "\n");
  1313.     }
  1314.     fprintf(f, "graphic_format=");
  1315.     for (i = 0; i < GRAPHFORMATS; i++)
  1316.     fprintf(f, "%c", graphic_format[i]);
  1317.     fprintf(f, "\n");
  1318.  
  1319.     for (i = 0; i < GRAPHTITLES; i++) {
  1320.     fprintf(f, "graphic_title[%d]=", i);
  1321.         for (j = 0; ((j < 50)&&(graphic_title[i][j] != NULL)); j++)  
  1322.         fprintf(f, "%c", graphic_title[i][j]);
  1323.     fprintf(f, "\n");
  1324.     }
  1325.     fprintf(f, "graphic_grid=%c\n", graphic_grid);
  1326.     fprintf(f, "g_auto_man[]=%c%c\n", g_auto_man[0],g_auto_man[1]);
  1327.     fprintf(f, "graphic_skip=%u\n", graphic_skip);
  1328.     fprintf(f, "curves_n=%u\n", curves_n);
  1329.  
  1330.     for(i = 0; i < GRAPHSCALES-1; i++) {
  1331.      fprintf(f, "graphic_scale[%d][]=%f %f\n", i,
  1332.             graphic_scale[i][0], graphic_scale[i][1]);
  1333.     }
  1334.     for ( i = 0; i < GRAPHRANGES; i++) {
  1335.     fprintf(f, "graphic_range[%d]=", i);
  1336.     for (j = 0; j < 3; j++)
  1337.         if (graphic_range[i].col[j] == NULL)
  1338.         fprintf(f, "~");
  1339.         else
  1340.         fprintf(f, "%c",graphic_range[i].col[j]);
  1341.     fprintf(f, " %d %d %d\n", graphic_range[i].r1,
  1342.         graphic_range[i].r2, graphic_range[i].c);
  1343.     }
  1344. }
  1345.  
  1346.