home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c034 / 4.ddi / SOURCE / CHRTDEMO.C$ / CHRTDEMO.bin
Encoding:
Text File  |  1990-01-19  |  32.7 KB  |  1,096 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <conio.h>
  4. #include <string.h>
  5. #include <graph.h>
  6. #include <pgchart.h>
  7. #include "chrtdemo.h"
  8.  
  9. /* Structures for system configuration and chart environment. */
  10. struct videoconfig vc;
  11. chartenv ce;
  12.  
  13. /* Category variables.  */
  14. short cCat;
  15. char _far *aCat[MAXVALUES];
  16.  
  17. /* Series variables.  */
  18. short cSeries;
  19. short _far acSeries[MAXSERIES];
  20. char _far *aSeriesName[MAXSERIES];
  21.  
  22. /* Temporary holding array for all data. Data values for multi-series
  23.  * bar, column, and line charts remain here. Data for other kinds of
  24.  * charts are transferred to the arrays below.
  25.  */
  26. float _far aValue[MAXSERIES][MAXVALUES];
  27.  
  28. /* Data values for single-series charts. First array is used for
  29.  * bar, column, line, and pie. First and second are both used for
  30.  * single-series scatter.
  31.  */
  32. float _far axValue[MAXVALUES];
  33. float _far ayValue[MAXVALUES];
  34.  
  35. /* Data values for multi-series scatter charts.  */
  36. float _far axValueMS[MAXVALUES][MAXVALUES];
  37. float _far ayValueMS[MAXVALUES][MAXVALUES];
  38.  
  39. /* Exploded flags for pie chart.  */
  40. short _far aExplode[MAXVALUES];
  41.  
  42. /* Variable used to track control and screen position.  */
  43. struct SCREENINFO si;
  44.  
  45. /* Colors of menus and prompts. */
  46. struct tagColor co;
  47.  
  48. /* Flags to indicate whether to use imported or default data.  */
  49. BOOL fDefault = TRUE;
  50.  
  51. /* Arrays of strings used by the Menu function. The first string is the
  52.  * menu title. The next non-null strings are the menu selections. A null
  53.  * string indicates the end of the list.
  54.  */
  55. char *pszChartOpt[] =
  56.     { "Options", "Screen Mode", "Windows", "Titles",
  57.       "Axis (X and Y)", "Legend", "Fonts", "Reset", "" };
  58.  
  59. char *pszChartType[] =
  60.     { "Type", "Bar", "Column", "Line", "Scatter", "Pie", "" };
  61.  
  62. char *pszMainMenu[] =
  63.     { "Main Menu", "Demo", "View Chart", "Chart Type", "Options",
  64.       "Show Chart Data", "Quit", "" };
  65.  
  66. /* Sample data.  */
  67. #define O_JUICE 0
  68. #define I_TEA   1
  69. #define H_CHOC  2
  70. #define TEMPERATURE  3
  71.  
  72. char _far *aQuarters[] =
  73.     { "First", "Second", "Third", "Fourth" };
  74.  
  75. char _far *aMonths[] =
  76.     { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  77.       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  78.  
  79. float _far aSales[3][12] =
  80. {
  81.     {  3.6F,  3.2F,  3.3F,  3.4F,  3.1F,  2.9F,
  82.        3.0F,  3.6F,  3.2F,  3.3F,  3.5F,  3.9F },
  83.     {  1.0F,  1.3F,  1.4F,  1.7F,  2.2F,  2.9F,
  84.        2.9F,  3.1F,  2.6F,  1.8F,  1.1F,  1.2F },
  85.     {  2.4F,  2.3F,  2.0F,  1.6F,  1.3F,  1.0F,
  86.        0.9F,  0.8F,  1.1F,  1.4F,  1.9F,  2.5F }
  87. };
  88.   
  89. float _far aTemperature[12] =
  90.     {  2.9F,  3.2F,  3.9F,  4.8F,  6.0F,  6.5F,
  91.        7.0F,  7.2F,  6.0F,  4.7F,  4.1F,  3.0F };
  92.  
  93. char _far *aSalesTitles[] =
  94.     { "Orange Juice Sales", "Iced Tea Sales", "Hot Chocolate Sales" };
  95.  
  96. char *TempTitle = "Average Temperature";
  97.  
  98. int main()
  99. {
  100.     Initialize();
  101.     MainMenu();
  102.  
  103.     /* Reset the video mode and screen colors prior to leaving. */
  104.     _setvideomode( _DEFAULTMODE );
  105.     _settextcolor( co.InfoColor );
  106.     _clearscreen( _GCLEARSCREEN );
  107.  
  108.     return 0;
  109. }
  110.  
  111. /*  ChartOptions - Gets chart options.
  112.  *
  113.  *  Params: None
  114.  */
  115. void ChartOptions()
  116. {
  117.     int iChoice;
  118.  
  119.     PushTitle( pszChartOpt[0] );
  120.     while( (iChoice = Menu( pszChartOpt )) != ESCAPE )
  121.     {
  122.  
  123.         /* Get chart options.  */
  124.         switch( iChoice )
  125.         {
  126.  
  127.             /* Branch to the appropriate menu.  */
  128.             case 1:
  129.                 ScreenMode();
  130.                 break;
  131.  
  132.             case 2:
  133.                 Windows();
  134.                 break;
  135.  
  136.             case 3:
  137.                 Titles();
  138.                 break;
  139.  
  140.             case 4:
  141.                 Axes();
  142.                 break;
  143.  
  144.             case 5:
  145.                 Legend();
  146.                 break;
  147.  
  148.             case 6:
  149.                 FontOptions();
  150.                 break;
  151.  
  152.             case 7:
  153.                 ResetOptions();
  154.                 break;
  155.  
  156.         }
  157.     }
  158.     PopTitle();
  159. }
  160.  
  161. /*  ChartType - Gets chart type.
  162.  *
  163.  *  Params: None
  164.  */
  165. void ChartType()
  166. {
  167.     int iChoice;
  168.  
  169.     /* Get chart type.  */
  170.     PushTitle( pszChartType[0] );
  171.     iChoice = Menu( pszChartType );
  172.  
  173.     if( iChoice != ESCAPE )
  174.     {
  175.         /* Set the chart type, and get the chart style.  */
  176.         ce.charttype = iChoice;
  177.         switch( iChoice )
  178.         {
  179.  
  180.             case 1:
  181.             case 2:
  182.                 iChoice = BlankMenu( "Style", "Plain Bars", "Stacked Bars" );
  183.                 break;
  184.  
  185.             case 3:
  186.             case 4:
  187.                 iChoice = BlankMenu( "Style", "Lines-Points", "Points Only" );
  188.                 break;
  189.  
  190.             case 5:
  191.                 iChoice = BlankMenu( "Style", "Percent", "No Percent" );
  192.         }
  193.  
  194.         if( iChoice != ESCAPE)
  195.             ce.chartstyle = iChoice;
  196.  
  197.         /* Set default data without changing environment defaults.  */
  198.         DefaultData( ce.charttype, ce.chartstyle, FALSE );
  199.         PopTitle();
  200.     }
  201.     PopTitle();
  202. }
  203.  
  204. /*  ClearData - Clears category and value data.
  205.  *
  206.  *  Params: fConfirm - flag specifying whether to query for confirmation
  207.  */
  208. void ClearData( BOOL fConfirm )
  209. {
  210.     char chResponse = 'Y';
  211.     int iCat;
  212.  
  213.     WrtForm( 18 );
  214.  
  215.     /* Query for confirmation.  */
  216.     if( fConfirm )
  217.         chResponse = InputCh( "Are you sure? ", "YN\x1b" );
  218.  
  219.     if( chResponse == 'Y' )
  220.     {
  221.  
  222.         /* Clear all relevant data.  */
  223.         for( iCat = 0; iCat < cCat; iCat++ )
  224.             aCat[iCat] = NULL;
  225.         cCat = 0;
  226.         cSeries = 0;
  227.     }
  228. }
  229.  
  230. /*  DefaultData - Initializes default data for each kind of chart.
  231.  *
  232.  *  Params: iType - Chart type to be initialized
  233.  *          iStyle - Chart style
  234.  *          fClear - Signal to clear all defaults
  235.  */
  236. void DefaultData( short iType, short iStyle, BOOL fClear )
  237. {
  238.     int iCat, iValue, iSubValue, iSeries;
  239.  
  240.     /* Call default chart to clear old values.  */
  241.     if( fClear )
  242.         _pg_defaultchart( &ce, iType, iStyle );
  243.  
  244.     /* Initialize category titles.  */
  245.     cCat = 12;
  246.     for( iCat = 0; iCat < cCat; iCat++ )
  247.         aCat[iCat] = aMonths[iCat];
  248.  
  249.     switch( ce.charttype )
  250.     {
  251.  
  252.         /* Initialize data for each chart type.  */
  253.         case _PG_BARCHART:
  254.         
  255.             strcpy( ce.maintitle.title, "Orange Juice and Iced Tea Sales" );
  256.             cSeries = 2;
  257.             for( iSeries = 0; iSeries < cSeries; iSeries++ )
  258.             {
  259.                 aSeriesName[iSeries] = aSalesTitles[iSeries];
  260.                 acSeries[iSeries] = cCat;
  261.                 for( iValue = 0; iValue < cCat; iValue++ )
  262.                     aValue[iSeries][iValue]  = (float)aSales[iSeries][iValue];
  263.             }
  264.             break;
  265.  
  266.         case _PG_COLUMNCHART:
  267.        
  268.             strcpy( ce.maintitle.title, "Orange Juice Sales" );
  269.             cSeries = 1;
  270.             for( iSeries = 0; iSeries < cSeries; iSeries++ )
  271.             {
  272.                 aSeriesName[iSeries] = aSalesTitles[iSeries];
  273.                 acSeries[iSeries] = cCat;
  274.                 for( iValue = 0; iValue < cCat; iValue++ )
  275.                     aValue[iSeries][iValue]  = (float)aSales[iSeries][iValue];
  276.             }
  277.             break;
  278.  
  279.         case _PG_LINECHART:
  280.  
  281.             strcpy( ce.maintitle.title, "Beverage Sales" );
  282.             cSeries = 3;
  283.             for( iSeries = 0; iSeries < cSeries; iSeries++ )
  284.             {
  285.                 aSeriesName[iSeries] = aSalesTitles[iSeries];
  286.                 acSeries[iSeries] = cCat;
  287.                 for( iValue = 0; iValue < cCat; iValue++ )
  288.                     aValue[iSeries][iValue] = (float)aSales[iSeries][iValue];
  289.             }
  290.             break;
  291.  
  292.         case _PG_SCATTERCHART:
  293.  
  294.             strcpy( ce.maintitle.title,
  295.                     "Average Temperature Compared to Beverage Sales" );
  296.             /* ce.chartstyle = _PG_POINTONLY; */
  297.             cSeries = 4;
  298.  
  299.             aSeriesName[0] = aSalesTitles[I_TEA];
  300.             aSeriesName[2] = aSalesTitles[H_CHOC];
  301.             acSeries[0] = acSeries[1] = acSeries[2] = acSeries[3] = 12;
  302.             for( iValue = 0; iValue < 12; iValue++ )
  303.             {
  304.                 aValue[0][iValue]  = (float)aSales[I_TEA][iValue] ;
  305.                 aValue[1][iValue]  = (float)aSales[TEMPERATURE][iValue] ;
  306.                 aValue[2][iValue]  = (float)aSales[H_CHOC][iValue] ;
  307.                 aValue[3][iValue]  = (float)aSales[TEMPERATURE][iValue] ;
  308.             }
  309.             break;
  310.            
  311.         case _PG_PIECHART:
  312.         default:
  313.  
  314.             strcpy( ce.maintitle.title, "Iced Tea Sales" );
  315.             cCat = 4;
  316.             for( iCat = 0; iCat < cCat; iCat++ )
  317.                 aCat[iCat] = aQuarters[iCat];
  318.  
  319.             cSeries = 1;
  320.             aSeriesName[0] = aSalesTitles[I_TEA];
  321.             acSeries[0] = cCat;
  322.  
  323.             for( iValue = 0; iValue < cCat; iValue++ )
  324.             {
  325.                 aValue[0][iValue] = 0.0;
  326.                 for( iSubValue = 0; iSubValue < 3; iSubValue++ )
  327.                     aValue[0][iValue] += (float)aSales[I_TEA][iSubValue * iValue];
  328.             }
  329.             aExplode[3] = 1;
  330.             break;
  331.     }
  332. }
  333.  
  334. /*  Demo - Displays a series of sample charts.
  335.  *
  336.  *  Params: None
  337.  */
  338. void Demo()
  339. {
  340.     int  cValue;
  341.     palettetype palette_struct;
  342.  
  343.     /* Display the sample data in spreadsheet form. */
  344.     ShowSampleData();
  345.  
  346.     DefaultData( _PG_PIECHART, _PG_NOPERCENT, TRUE );
  347.  
  348.     /* Set video mode and draw charts. For each chart, set default
  349.      * data and modify any desired environment fields. If error,
  350.      * terminate demo.
  351.      */
  352.     _setvideomode( si.mode );
  353.  
  354.     cValue = 4;
  355.     strcpy( ce.subtitle.title, "Default Pie Chart" );
  356.     if( ViewChart() )
  357.         return;
  358.     else
  359.         _clearscreen( _GCLEARSCREEN );
  360.  
  361.     strcpy( ce.subtitle.title, "Customized Pie Chart" );
  362.     ce.chartstyle = _PG_PERCENT;
  363.     ce.legend.place = _PG_BOTTOM;
  364.     if (si.fColor)
  365.     {
  366.         ce.maintitle.titlecolor = ce.subtitle.titlecolor = 0;
  367.         ce.chartwindow.background = 1;
  368.         ce.datawindow.background = ce.legend.legendwindow.background = 6;
  369.         ce.legend.textcolor = 1;
  370.     }
  371.     if( ViewChart() )
  372.         return;
  373.     else
  374.         _clearscreen( _GCLEARSCREEN );
  375.  
  376.     cValue = 12;
  377.     DefaultData( _PG_BARCHART, _PG_PLAINBARS, TRUE );
  378.     strcpy( ce.subtitle.title, "Default Bar Chart" );
  379.     if( ViewChart() )
  380.         return;
  381.     else
  382.         _clearscreen( _GCLEARSCREEN );
  383.  
  384.     strcpy( ce.subtitle.title, "Customized Stacked Bar Chart" );
  385.     strcpy( ce.xaxis.axistitle.title, "Sales in Thousands" );
  386.     strcpy( ce.yaxis.axistitle.title, "Month" );
  387.     ce.chartstyle = _PG_STACKEDBARS;
  388.     ce.legend.place = _PG_RIGHT;
  389.     ce.xaxis.ticdecimals = 2;
  390.     if (si.fColor)
  391.     {
  392.         ce.maintitle.titlecolor = ce.subtitle.titlecolor = 12;
  393.         ce.chartwindow.background = 7;
  394.         ce.datawindow.background = 8;
  395.         ce.legend.textcolor = 0;
  396.         ce.legend.legendwindow.background = 8;
  397.         ce.legend.autosize = FALSE;
  398.         ce.legend.legendwindow.y1 = vc.numypixels - 85;
  399.         ce.legend.legendwindow.y2 = vc.numypixels - 45;
  400.     }
  401.     if( ViewChart() )
  402.         return;
  403.     else
  404.         _clearscreen( _GCLEARSCREEN );
  405.  
  406.     DefaultData( _PG_COLUMNCHART, _PG_PLAINBARS, TRUE );
  407.     strcpy( ce.subtitle.title, "Default Column Chart" );
  408.     if( ViewChart() )
  409.         return;
  410.     else
  411.         _clearscreen( _GCLEARSCREEN );
  412.  
  413.     strcpy( ce.subtitle.title, "Customized Column Chart" );
  414.     strcpy( ce.xaxis.axistitle.title, "Month" );
  415.     strcpy( ce.yaxis.axistitle.title, "Sales in Thousands" );
  416.     ce.legend.place = _PG_BOTTOM;
  417.     if (si.fColor)
  418.     {
  419.         ce.maintitle.titlecolor     = 0;
  420.         ce.subtitle.titlecolor     = 0;
  421.         ce.chartwindow.background = 8;
  422.         ce.datawindow.background = 2;
  423.         ce.legend.legendwindow.background = 10;
  424.     }
  425.     if( ViewChart() )
  426.         return;
  427.     else
  428.         _clearscreen( _GCLEARSCREEN );
  429.  
  430.     DefaultData( _PG_LINECHART, _PG_POINTANDLINE, TRUE );
  431.     strcpy( ce.subtitle.title, "Default Line Chart" );
  432.     if( ViewChart() )
  433.         return;
  434.     else
  435.         _clearscreen( _GCLEARSCREEN );
  436.  
  437.     strcpy( ce.subtitle.title, "Customized Line Chart" );
  438.     strcpy( ce.xaxis.axistitle.title, "Month" );
  439.     strcpy( ce.yaxis.axistitle.title, "Sales in Thousands" );
  440.     ce.legend.place = _PG_RIGHT;
  441.     if (si.fColor)
  442.     {
  443.         ce.maintitle.titlecolor = 1;
  444.         ce.subtitle.titlecolor = 1;
  445.         ce.chartwindow.background = 3;
  446.         ce.datawindow.background = 7;
  447.         ce.legend.legendwindow.background = 7;
  448.         ce.legend.autosize = FALSE;
  449.         ce.legend.legendwindow.y1 = vc.numypixels - 85;
  450.         ce.legend.legendwindow.y2 = vc.numypixels - 45;
  451.     }
  452.     if( ViewChart() )
  453.         return;
  454.     else
  455.         _clearscreen( _GCLEARSCREEN );
  456.  
  457.     DefaultData( _PG_SCATTERCHART, _PG_POINTONLY, TRUE );
  458.     strcpy( ce.subtitle.title, "Default Scatter Chart" );
  459.     if( ViewChart() )
  460.         return;
  461.     else
  462.         _clearscreen( _GCLEARSCREEN );
  463.  
  464.     cSeries = 4;
  465.     strcpy( ce.subtitle.title, "Customized Scatter Chart" );
  466.     strcpy( ce.xaxis.axistitle.title, "Sales in Thousands" );
  467.     strcpy( ce.yaxis.axistitle.title, "Average Temperature" );
  468.     ce.legend.place = _PG_RIGHT;
  469.     if (si.fColor)
  470.     {
  471.         ce.maintitle.titlecolor = 0;
  472.         ce.subtitle.titlecolor = 0;
  473.         ce.chartwindow.background = 4;
  474.         ce.datawindow.background = 8;
  475.         ce.legend.legendwindow.background = 8;
  476.         ce.legend.autosize = FALSE;
  477.         ce.legend.legendwindow.y1 = vc.numypixels - 85;
  478.         ce.legend.legendwindow.y2 = vc.numypixels - 45;
  479.     }
  480.     if( ViewChart() )
  481.         return;
  482.     else
  483.         _clearscreen( _GCLEARSCREEN );
  484.  
  485.     DefaultData( _PG_BARCHART, _PG_PERCENT, TRUE );
  486. }
  487.  
  488. /*  FindVideoMode - Finds the "best" video mode for the adaptor in use.
  489.  *
  490.  *  Params: vc - structure of type struct videoconfig
  491.  *
  492.  *  Returns: Best mode
  493.  */
  494. int FindVideoMode( struct videoconfig vc )
  495. {
  496.     switch( vc.adapter )
  497.     {
  498.         case _CGA:
  499.         case _OCGA:
  500.             return _HRESBW;
  501.         case _EGA:
  502.         case _OEGA:
  503.             return( vc.monitor == _MONO ) ? _ERESNOCOLOR : _ERESCOLOR;
  504.         case _VGA:
  505.         case _OVGA:
  506.         case _MCGA:
  507.             return _VRES16COLOR;
  508.         case _HGC:
  509.             return _HERCMONO;
  510.         default:
  511.             return _DEFAULTMODE;
  512.     }
  513. }
  514.  
  515. /*  Initialize - Does various initialization tasks.
  516.  *
  517.  *  Params: None
  518.  */
  519. void Initialize( void )
  520. {
  521.     int iSeries, iValue;
  522.  
  523.     /* Initialize all value arrays to missing.  */
  524.     for( iSeries = 0; iSeries < MAXSERIES; iSeries++ )
  525.     {
  526.  
  527.         axValue[iSeries] = _PG_MISSINGVALUE;
  528.         ayValue[iSeries] = _PG_MISSINGVALUE;
  529.  
  530.         for( iValue = 0; iValue < MAXVALUES; iValue++ )
  531.             aValue[iSeries][iValue] = _PG_MISSINGVALUE;
  532.  
  533.         for( iValue = 0; iValue < MAXVALUES; iValue++ )
  534.         {
  535.             axValueMS[iSeries][iValue] = _PG_MISSINGVALUE;
  536.             ayValueMS[iSeries][iValue] = _PG_MISSINGVALUE;
  537.         }
  538.     }
  539.  
  540.     /* Initialize zero sets. */
  541.     cSeries = 0;
  542.  
  543.     /* Initialize default chart environment, screen mode, and data.  */
  544.     _pg_initchart();
  545.     _getvideoconfig( &vc );
  546.  
  547.     /* Find the best available mode for display.
  548.      * Don't set 256 color, medium resolution (_MRES256COLOR).
  549.      */
  550.     si.mode = FindVideoMode( vc );
  551.  
  552.     if( si.mode == _TEXTMONO )
  553.     {
  554.         _clearscreen( _GCLEARSCREEN );
  555.         _outtext( "No graphics available.  Can't run chart demo." );
  556.         exit( 1 );
  557.     }
  558.  
  559.     SetDisplayColors();
  560.  
  561.     SetGraphMode( si.mode );
  562.     DefaultData( _PG_BARCHART, _PG_PLAINBARS, TRUE );
  563.  
  564.     _setvideomode( _DEFAULTMODE );
  565.  
  566.  
  567. }
  568.  
  569. /*  MainMenu - Manages the main menu.
  570.  *
  571.  *  Params: None
  572.  */
  573. void MainMenu( void )
  574. {
  575.     int iChoice;
  576.     char chResponse = 'Y';
  577.     char chVerify;
  578.  
  579.     PushTitle( pszMainMenu[0] );
  580.     do
  581.     {
  582.         /* If the user selects Quit, iChoice will contain 6.  If the
  583.          *   user presses ESCAPE, iChoice will be ESCAPE, which is
  584.          *   equal to 27.  In any case, we can test both conditions
  585.          *   by checking to see whether iChoice is less than 6.
  586.          */
  587.         while( (iChoice = Menu( pszMainMenu )) < 6 )
  588.         {
  589.             /* Get main menu selection.  */
  590.             switch( iChoice )
  591.             {
  592.  
  593.                 case 1:
  594.                     /* Display demo charts.  */
  595.                     Demo();
  596.                     _setvideomode( _DEFAULTMODE );
  597.                     break;
  598.  
  599.                 case 2:
  600.                     /* Set graphics video mode, display current chart,
  601.                      * and restore text video mode.
  602.                      */
  603.                     _setvideomode( si.mode );
  604.                     ViewChart();
  605.                     _setvideomode( _DEFAULTMODE );
  606.                     break;
  607.  
  608.                 case 3:
  609.                     /* Get chart type and style.  */
  610.                     ChartType();
  611.                     break;
  612.  
  613.                 case 4:
  614.                     /* Get chart options.  */
  615.                     ChartOptions();
  616.                     break;
  617.                 case 5:
  618.                     /* Show chart data. */
  619.                     ShowChartData();
  620.                     break;
  621.  
  622.             }
  623.  
  624.         }
  625.  
  626.         /* If the user is trying to leave the program using the ESCAPE
  627.          *   key, we must verify the choice.  This is done to prevent
  628.          *   an eager typist from pressing ESCAPE one time too often
  629.          *   and exiting at an unanticipated point.
  630.          */
  631.         if( iChoice == ESCAPE )
  632.         {
  633.             Help( "Press \"Q\" to Actually Quit", co.InputColor );
  634.  
  635.             putchar( BEEP );
  636.             _settextposition( si.help - 1, 32 );
  637.             chVerify = getch();
  638.             if( tolower( chVerify ) != 'q' )
  639.                 iChoice = 0;
  640.             else
  641.                 iChoice = 6;
  642.         }
  643.  
  644.     } while( iChoice != 6 );
  645.     PopTitle();
  646. }
  647.  
  648. /*  ResetOptions - After confirmation, resets chart options to default.
  649.  *
  650.  *  Params: None
  651.  */
  652. void ResetOptions()
  653. {
  654.     char chResponse;
  655.  
  656.     /* Prompt for confirmation before setting default environment.  */
  657.     ClrForm();
  658.     Help( "Type  'Y' to reset all options, 'N' to keep them.", co.InputColor );
  659.     chResponse = InputCh( "Are you sure? ", "YN\x1b" );
  660.     if( chResponse == 'Y' )
  661.         _pg_defaultchart( &ce, 1, 1 );
  662.  
  663. }
  664.  
  665. /*  SetGraphMode - Tests the specified graphics mode and sets the xMax
  666.  *  and yMax values in the si (Screen Information) structure.
  667.  *
  668.  *  Params: mode number
  669.  *
  670.  *  Return: FALSE if mode invalid, TRUE if valid
  671.  */
  672. BOOL SetGraphMode(int mode)
  673. {
  674.     if (!_setvideomode( mode ) )
  675.         return FALSE;
  676.     else
  677.     {
  678.         _getvideoconfig ( &vc );
  679.         if( !vc.numxpixels )
  680.             return FALSE;
  681.         si.xMax = vc.numxpixels;
  682.         si.yMax = vc.numypixels;
  683.         si.mode = mode;
  684.  
  685.         /* Set flag to indicate whether multiple colors are available.  */
  686.         si.fColor = iscolor( mode );
  687.  
  688.         return TRUE;
  689.     }
  690. }
  691.  
  692. /*  ShowChartData - Displays the data in the chart environment.
  693.  *
  694.  *  Params: None
  695.  */
  696. void ShowChartData()
  697. {
  698.     int iRow = 2;
  699.     struct _fontinfo fd;
  700.     static char *szContinue =
  701.         "Press any key to continue, ESC to return to the menu.";
  702.  
  703.     _clearscreen( _GCLEARSCREEN );
  704.     SprintAt( iRow++, 1, "short      charttype =  %d", ce.charttype );
  705.     SprintAt( iRow++, 1, "short      chartstyle = %d", ce.chartstyle );
  706.     SprintAt( iRow++, 1, "windowtype chartwindow =" );
  707.     iRow = ShowWindowType( iRow, 1, ce.chartwindow );
  708.     SprintAt( iRow++, 1, "windowtype datawindow =" );
  709.     iRow = ShowWindowType( iRow, 1, ce.datawindow );
  710.     SprintAt( ++iRow, 1, szContinue );
  711.     if( getch() == ESCAPE )
  712.         return;
  713.  
  714.     iRow = 2;
  715.     _clearscreen( _GCLEARSCREEN );
  716.     SprintAt( iRow++, 1, "titletype  maintitle =" );
  717.     iRow = ShowTitleType( iRow, 1, ce.maintitle );
  718.     SprintAt( iRow++, 1, "titletype   subtitle =" );
  719.     iRow = ShowTitleType( iRow, 1, ce.subtitle );
  720.     SprintAt( ++iRow, 1, szContinue );
  721.     if( getch() == ESCAPE )
  722.         return;
  723.  
  724.     iRow = 2;
  725.     _clearscreen( _GCLEARSCREEN );
  726.     SprintAt( iRow++, 1, "axistype       xaxis =" );
  727.     iRow = ShowAxisType( iRow, 1, ce.xaxis );
  728.     SprintAt( ++iRow, 1, szContinue );
  729.     if( getch() == ESCAPE )
  730.         return;
  731.  
  732.     iRow = 2;
  733.     _clearscreen( _GCLEARSCREEN );
  734.     SprintAt( iRow++, 1, "axistype       yaxis =" );
  735.     iRow = ShowAxisType( iRow, 1, ce.yaxis );
  736.     SprintAt( ++iRow, 1, szContinue );
  737.     if( getch() == ESCAPE )
  738.         return;
  739.  
  740.     iRow = 2;
  741.     _clearscreen( _GCLEARSCREEN );
  742.     SprintAt( iRow++, 1, "legendtype     legend =" );
  743.     iRow = ShowLegendType( iRow, 1, ce.legend );
  744.     SprintAt( ++iRow, 1, szContinue );
  745.     if( getch() == ESCAPE )
  746.         return;
  747.  
  748.     iRow = 2;
  749.     _clearscreen( _GCLEARSCREEN );
  750.     if( _getfontinfo( &fd ) != -1 )
  751.     {
  752.         SprintAt( iRow++, 1, "struct _fontinfo =" );
  753.         iRow = ShowFontInfo( iRow, 1, fd );
  754.         SprintAt( ++iRow, 1, "Press any key to continue . . ." );
  755.         getch();
  756.     }
  757. }
  758.  
  759. /*  ShowAxisType - Displays data in a variable of type "axistype".
  760.  *
  761.  *  Params: iRow - Row at which to start
  762.  *          iCol - Column from which to indent
  763.  *          theAxis - Variable of type "axistype" to display
  764.  *
  765.  *  Return: Next available row
  766.  */
  767. int ShowAxisType( int iRow, int iCol, axistype theAxis )
  768. {
  769.     SprintAt( iRow++, iCol + 5, "short        .grid = %d", theAxis.grid );
  770.     SprintAt( iRow++, iCol + 5, "short   .gridstyle = %d", theAxis.gridstyle );
  771.     SprintAt( iRow++, iCol + 5, "titletype axistitle=" );
  772.     iRow = ShowTitleType( iRow, iCol + 5, theAxis.axistitle );
  773.     SprintAt( iRow++, iCol + 5, "short   .axiscolor = %d", theAxis.axiscolor );
  774.     SprintAt( iRow++, iCol + 5, "short     .labeled = %s",
  775.         (theAxis.labeled) ? "TRUE" : "FALSE" );
  776.     SprintAt( iRow++, iCol + 5, "short   .rangetype = %d", theAxis.rangetype );
  777.     SprintAt( iRow++, iCol + 5, "float     .logbase = %f", theAxis.logbase );
  778.     SprintAt( iRow++, iCol + 5, "short   .autoscale = %s",
  779.         (theAxis.autoscale) ? "TRUE" : "FALSE" );
  780.     SprintAt( iRow++, iCol + 5, "float    .scalemin = %f", theAxis.scalemin );
  781.     SprintAt( iRow++, iCol + 5, "float    .scalemax = %f", theAxis.scalemax );
  782.     SprintAt( iRow++, iCol + 5, "float .scalefactor = %f", theAxis.scalefactor );
  783.     iRow = ShowTitleType( iRow, iCol + 5, theAxis.scaletitle );
  784.     SprintAt( iRow++, iCol + 5, "float  .ticinterval = %f", theAxis.ticinterval );
  785.     SprintAt( iRow++, iCol + 5, "short    .ticformat = %d", theAxis.ticformat );
  786.     SprintAt( iRow++, iCol + 5, "short  .ticdecimals = %d", theAxis.ticdecimals );
  787.  
  788.     return iRow;
  789. }
  790.  
  791. /*  ShowFontInfo - Displays data in a variable of type "_fontinfo".
  792.  *
  793.  *  Params: iRow - Row at which to start
  794.  *          iCol - Column from which to indent
  795.  *          theFont - Variable of type "_fontinfo" to display
  796.  *
  797.  *  Return: Next available row
  798.  */
  799. int ShowFontInfo( int iRow, int iCol, struct _fontinfo theFont )
  800. {
  801.     SprintAt( iRow++, iCol + 5, "int          .type = %d", theFont.type );
  802.     SprintAt( iRow++, iCol + 5, "int        .ascent = %d", theFont.ascent );
  803.     SprintAt( iRow++, iCol + 5, "int      .pixwidth = %d", theFont.pixwidth );
  804.     SprintAt( iRow++, iCol + 5, "int     .pixheight = %d", theFont.pixheight );
  805.     SprintAt( iRow++, iCol + 5, "int      .avgwidth = %d", theFont.avgwidth );
  806.     SprintAt( iRow++, iCol + 5, "char     .filename = %s", theFont.filename );
  807.     SprintAt( iRow++, iCol + 5, "char     .facename = %s", theFont.facename );
  808.  
  809.     return iRow;
  810. }
  811.  
  812. /*  ShowLegendType - Displays data in a variable of type "legendtype".
  813.  *
  814.  *  Params: iRow - Row at which to start
  815.  *          iCol - Column from which to indent
  816.  *          theLegend - Variable of type "legendtype" to display
  817.  *
  818.  *  Return: Next available row
  819.  */
  820. int ShowLegendType( int iRow, int iCol, legendtype theLegend )
  821. {
  822.     SprintAt( iRow++, iCol + 5, "short      .legend = %s",
  823.               (theLegend.legend) ? "TRUE" : "FALSE" );
  824.     SprintAt( iRow++, iCol + 5, "short       .place = %d", theLegend.place );
  825.     SprintAt( iRow++, iCol + 5, "short   .textcolor = %d", theLegend.textcolor );
  826.     SprintAt( iRow++, iCol + 5, "short    .autosize = %d", theLegend.autosize );
  827.     SprintAt( iRow++, iCol + 5, "windowtype legendwindow =" );
  828.     iRow = ShowWindowType( iRow, iCol + 5, theLegend.legendwindow );
  829.  
  830.     return iRow;
  831. }
  832.  
  833. /*  ShowSampleData - Displays the sample data for the demo.
  834.  *
  835.  *  Params: None
  836.  */
  837. void ShowSampleData()
  838. {
  839.     int  iCat, y, iSeries, iValue;
  840.     char szTmp[80];
  841.  
  842.     /* Display data in table format. */
  843.     _clearscreen( _GCLEARSCREEN );
  844.     PrintAt( 1, 40 - strlen(szTmp) / 2, "Data in Table Format", -1 );
  845.  
  846.     /* Write titles and draw separator line. */
  847.     y = 3;
  848.     for( iCat = 1; iCat <= 12; iCat++ )
  849.     PrintAt( y, iCat * 6, aMonths[iCat - 1], -1 );
  850.  
  851.     memset( szTmp, '-', 69 );
  852.     szTmp[69] = 0;
  853.     PrintAt( ++y, 6, szTmp, -1 );
  854.  
  855.     /* Write data. */
  856.     for( iSeries = 1; iSeries <= 3; iSeries++ )
  857.     {
  858.         PrintAt( y += 2, 4, aSalesTitles[iSeries - 1], -1 );
  859.         y += 2;
  860.         for( iValue = 1; iValue <= 12; iValue++ )
  861.         {
  862.             sprintf( szTmp, "%#3.2f", aSales[iSeries - 1][iValue - 1] );
  863.             PrintAt( y, iValue * 6, (char _far *)szTmp, -1 );
  864.         }
  865.     }
  866.     PrintAt( y += 2, 4, TempTitle, -1 );
  867.     y += 2;
  868.     for( iValue = 1; iValue <= 12; iValue++ )
  869.     {
  870.         sprintf( szTmp, "%#3.1f", aTemperature[iValue - 1] );
  871.         PrintAt( y, iValue * 6, szTmp, -1 );
  872.     }
  873.  
  874.     PrintAt( y += 2, 1, "Press any key to continue . . .", -1 );
  875.     getche();
  876. }
  877.  
  878. /*  ShowTitleType - Displays data in a variable of type "titletype".
  879.  *
  880.  *  Params: iRow - Row at which to start
  881.  *          iCol - Column from which to indent
  882.  *          theTitle - Variable of type "titletype" to display
  883.  *
  884.  *  Return: Next available row
  885.  */
  886. int ShowTitleType( int iRow, int iCol, titletype theTitle )
  887. {
  888.     SprintAt( iRow++, iCol + 5, "char    .title[%d] = \"%s\"", _PG_TITLELEN,
  889.                  theTitle.title );
  890.     SprintAt( iRow++, iCol + 5, "short  .titlecolor = %d", theTitle.titlecolor );
  891.     SprintAt( iRow++, iCol + 5, "short     .justify = %d", theTitle.justify );
  892.  
  893.     return iRow;
  894. }
  895.  
  896. /*  ShowWindowType - Displays data in a variable of type "windowtype".
  897.  *
  898.  *  Params: iRow - Row at which to start
  899.  *          iCol - Column from which to indent
  900.  *          theWindow - Variable of type "windowtype" to display
  901.  *
  902.  *  Return: Next available row
  903.  */
  904. int ShowWindowType( int iRow, int iCol, windowtype theWindow )
  905. {
  906.     SprintAt( iRow++, iCol + 5, "short          .x1 = %d", theWindow.x1 );
  907.     SprintAt( iRow++, iCol + 5, "short          .y1 = %d", theWindow.y1 );
  908.     SprintAt( iRow++, iCol + 5, "short          .x2 = %d", theWindow.x2 );
  909.     SprintAt( iRow++, iCol + 5, "short          .y2 = %d", theWindow.y2 );
  910.     SprintAt( iRow++, iCol + 5, "short      .border = %d", theWindow.border );
  911.     SprintAt( iRow++, iCol + 5, "short  .background = %d", theWindow.background );
  912.     SprintAt( iRow++, iCol + 5, "short .borderstyle = %d", theWindow.borderstyle );
  913.     SprintAt( iRow++, iCol + 5, "short .bordercolor = %d", theWindow.bordercolor );
  914.  
  915.     return iRow;
  916. }
  917.  
  918. /*  ShowError - Displays error message for one of the chart library
  919.  *  errors.
  920.  *
  921.  *  Params: iErr - Error number
  922.  */
  923. void ShowError( int iErr )
  924. {
  925.     char szTmp[50];
  926.  
  927.     /* Change to text screen.  */
  928.     _setvideomode( _DEFAULTMODE );
  929.  
  930.     /* Select the error text.  */
  931.     switch( iErr )
  932.     {
  933.         case _PG_NOTINITIALIZED:
  934.             strcpy( szTmp, "Chart Library Not Initialized" );
  935.             break;
  936.         case _PG_BADSCREENMODE:
  937.             strcpy( szTmp, "Invalid Screen Mode" );
  938.             break;
  939.         case _PG_BADCHARTTYPE:
  940.             strcpy( szTmp, "Invalid Chart Type" );
  941.             break;
  942.         case _PG_BADCHARTSTYLE:
  943.             strcpy( szTmp, "Invalid Chart Style" );
  944.             break;
  945.         case _PG_BADLEGENDWINDOW:
  946.             strcpy( szTmp, "Invalid Legend Window" );
  947.             break;
  948.         case _PG_BADDATAWINDOW:
  949.             strcpy( szTmp, "No Room for Data window" );
  950.             break;
  951.         case _PG_BADCHARTWINDOW:
  952.             strcpy( szTmp, "Invalid Chart window coordinates" );
  953.             break;
  954.         case _PG_NOMEMORY:
  955.             strcpy( szTmp, "Not Enough Memory for Data Arrays" );
  956.             break;
  957.         case _PG_BADLOGBASE:
  958.             strcpy( szTmp, "X or Y log base <= 0" );
  959.             break;
  960.         case _PG_BADSCALEFACTOR:
  961.             strcpy( szTmp, "X or Y scale factor = 0" );
  962.             break;
  963.         case _PG_TOOSMALLN:
  964.             strcpy( szTmp, "Too few data values" );
  965.             break;
  966.         case _PG_TOOFEWSERIES:
  967.             strcpy( szTmp, "No data series specified" );
  968.             break;
  969.         default:
  970.             strcpy( szTmp, "Unknown error" );
  971.     }
  972.  
  973.     ErrorMsg( szTmp );
  974. }
  975.  
  976. /*  ViewChart - Draws the current chart.
  977.  *
  978.  *  Params: None
  979.  */
  980. int ViewChart()
  981. {
  982.     int cValue, iValue, iSeries, iErr;
  983.  
  984.     /* Make sure some data exists.  */
  985.     if( cSeries <= 0 )
  986.     {
  987.         fDefault = TRUE;
  988.         DefaultData( ce.charttype, ce.chartstyle, FALSE );
  989.     }
  990.  
  991.     /* Find the longest series.  */
  992.     cValue = 0;
  993.     for( iSeries = 0; iSeries < cSeries; iSeries++ )
  994.         if( acSeries[iSeries] > cValue )
  995.             cValue = acSeries[iSeries];
  996.  
  997.     _setvideomode( si.mode );
  998.  
  999.  
  1000.     /* Process depending on the type of chart.  */
  1001.     switch( ce.charttype )
  1002.     {
  1003.  
  1004.         case _PG_PIECHART:
  1005.         case _PG_BARCHART:
  1006.         case _PG_COLUMNCHART:
  1007.         case _PG_LINECHART:
  1008.  
  1009.             /* Initialize data and draw pie chart or single-series bar,
  1010.              * column, or line chart.
  1011.              */
  1012.             if( (cSeries == 1) ||( ce.charttype == _PG_PIECHART) )
  1013.             {
  1014.  
  1015.                 /* Transfer data into a single-dimension array.  */
  1016.                 for( iValue = 0; iValue < cValue; iValue++ )
  1017.                    axValue[iValue] = aValue[0][iValue];
  1018.  
  1019.                 /* Draw chart.  */
  1020.                 if( ce.charttype == _PG_PIECHART )
  1021.                     iErr = _pg_chartpie( &ce, aCat, axValue,
  1022.                                          aExplode, cValue );
  1023.                 else
  1024.                     iErr = _pg_chart( &ce, aCat, axValue, cValue );
  1025.             }
  1026.             /* If multiple-series, then data is OK. Just draw chart.  */
  1027.             else
  1028.                 iErr = _pg_chartms( &ce, aCat, (float _far *)aValue,
  1029.                                     cSeries, cValue, cValue, aSeriesName );
  1030.             break;
  1031.  
  1032.         case _PG_SCATTERCHART:
  1033.  
  1034.             /* Make sure there are enough data sets.  */
  1035.             if( cSeries == 1 )
  1036.             {
  1037.                 _setvideomode( _DEFAULTMODE );
  1038.                 si.help = 10;
  1039.                 ErrorMsg( "Too few value data columns for scatter chart." );
  1040.                 return 1;
  1041.  
  1042.             }
  1043.             /* If it's a single-series scatter, transfer data to one-
  1044.              * dimensional arrays and make chart call.
  1045.              */
  1046.             else if( cSeries == 2 )
  1047.             {
  1048.                 for( iValue = 0; iValue < cValue; iValue++ )
  1049.                 {
  1050.                     axValue[iValue] = aValue[0][iValue];
  1051.                     ayValue[iValue] = aValue[1][iValue];
  1052.                 }
  1053.                 cSeries = 1;
  1054.                 iErr = _pg_chartscatter( &ce, axValue, ayValue, cValue );
  1055.  
  1056.             }
  1057.             /* If it's a multiple-series scatter, transfer odd columns to
  1058.              * X-axis data array and even columns to Y-axis array and make
  1059.              * chart call.
  1060.              */
  1061.             else
  1062.             {
  1063.  
  1064.                 for( iSeries = 1; iSeries < cSeries; iSeries += 2 )
  1065.                 {
  1066.                     aSeriesName[iSeries / 2] = aSeriesName[iSeries - 1];
  1067.                     for( iValue = 0; iValue < cValue; iValue++ )
  1068.                     {
  1069.                         axValueMS[iSeries / 2][iValue] =
  1070.                             aValue[iSeries - 1][iValue];
  1071.                         ayValueMS[iSeries / 2][iValue] =
  1072.                             aValue[iSeries][iValue];
  1073.                     }
  1074.                 }
  1075.                 cSeries /= 2;
  1076.  
  1077.                 iErr = _pg_chartscatterms( &ce, (float _far *)axValueMS,
  1078.                                            (float _far *)ayValueMS,
  1079.                                            cSeries, cValue, cValue,
  1080.                                            aSeriesName );
  1081.             }
  1082.     }
  1083.  
  1084.     if( !fDefault )
  1085.         ClearData( FALSE );
  1086.  
  1087.     /* If error, show it, else wait for keypress with chart on screen.  */
  1088.     if( iErr )
  1089.     {
  1090.         ShowError( iErr );
  1091.         return iErr;
  1092.     }
  1093.     else
  1094.         return ( getch() == ESCAPE );   /* ESCAPE means stop demo */
  1095. }
  1096.