Difference between revisions of "Green-screen Chart/Graph"

From MidrangeWiki
Jump to: navigation, search
(Created page with "=Green-screen Chart/Graph ==Background== It is sometimes useful to display a graph of values on the AS400 green-screen. Although there are commercial products available for...")
 
(GENCHART#D - Source code)
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
=Green-screen Chart/Graph
+
=Green-screen Chart/Graph=
  
 
==Background==
 
==Background==
Line 9: Line 9:
 
==Screen Layout==
 
==Screen Layout==
  
a. This is the header as passed to the program
+
 
b. This is the Y-label, as passed to the program
+
[[File:GenChart_-_Overview.png]]
c. The Y-axis values will be build based on the chart type or the chart calc function
+
 
d. If the number of data points exceed the screen width, the program will create additional pages.  Page Up/Down will show the rest of the entries.  If you want to jump to the 1st page, press F17, or last page press F18.
+
:a. This is the header as passed to the program
e. If you position your cursor on any data item/column, and press F1, the program  will display information about the data point
+
:b. This is the Y-label, as passed to the program
 +
:c. The Y-axis values will be build based on the chart type or the chart calc function
 +
:d. If the number of data points exceed the screen width, the program will create additional pages.  Page Up/Down will show the rest of the entries.  If you want to jump to the 1st page, press F17, or last page press F18.
 +
:e. If you position your cursor on any data item/column, and press F1, the program  will display information about the data point
 +
 
 +
[[File:GenChart_-_Item_Information.png]]
  
 
==Objects==
 
==Objects==
  
 
The following objects will be used by the program:
 
The following objects will be used by the program:
a. GENCHART#D Display File
+
:a. GENCHART#D - Display File
b. GENCHART#R – RPG Program
+
:b. GENCHART#R – RPG Program
  
  
 
==GenChart Program Parameters==
 
==GenChart Program Parameters==
 +
 
The GENCHART#R program requires the following parameters:
 
The GENCHART#R program requires the following parameters:
a. Data structure (see point 4):   
+
:a. Data structure (see point 4):   
The data structure will be passed from your program, to the GENCHART#R program, by using pointers.  When you call the program, the variable has to use %ADDR(DSNAME).
+
::- The data structure will be passed from your program, to the GENCHART#R program, by using pointers.  When you call the program, the variable has to use %ADDR(DSNAME).
b. Heading:   
+
:b. Heading:   
Char (100).  
+
::- Char (100).  
The heading you need for your chart
+
::- The heading you need for your chart
c. Y-Axis Label:   
+
:c. Y-Axis Label:   
Char(30)
+
::- Char(30)
Here you can specify a label for the Y-Axis.  
+
::- Here you can specify a label for the Y-Axis.  
Label will be affected by the Chart Type variable
+
::- Label will be affected by the Chart Type variable
d. Total Items:
+
:d. Total Items:
Int(10)
+
::- Int(10)
Specify the number of values to be passed via the DataStructure
+
::- Specify the number of values to be passed via the DataStructure
e. Max Value:
+
:e. Max Value:
Packed(31:2)
+
::- Packed(31:2)
Specify the Maximum value.  This is needed to determine the sizing of the bars
+
::- Specify the Maximum value.  This is needed to determine the sizing of the bars
f. Chart Type
+
:f. Chart Type
Char(10)
+
::- Char(10)
Allows for two types of charts.  Can be either  
+
::- Allows for two types of charts.  Can be either  
i. *PCT:  Determine %, betwee max value and actual value
+
:::* *PCT:  Determine %, betwee max value and actual value
ii. *NORMAL:  Display the values on the screen as they are
+
:::* *NORMAL:  Display the values on the screen as they are
g. Chart Calc:
+
:g. Chart Calc:
Char(10)
+
::- Char(10)
If the values are too big, the program can scale them.  Allowed values are:
+
::- If the values are too big, the program can scale them.  Allowed values are:
i. *NONE – Keep the values as is
+
:::* *NONE – Keep the values as is
ii. *TB – Scale the values in Terrabytes
+
:::* *TB – Scale the values in Terrabytes
iii. *GB – Scale the values in Gigabytes
+
:::* *GB – Scale the values in Gigabytes
iv. *KB – Scale the values in Megabytes
+
:::* *KB – Scale the values in Megabytes
v. *KB – Scale the values in Kilobytes
+
:::* *KB – Scale the values in Kilobytes
 +
 
 +
==RPG Program Usage==
 +
 
 +
In order to use the GENCHART functionality inside your RPG program, the following is needed:
 +
 
 +
:a. '''Data structure''':  A datastructure has to be passed onto the calling program.  This data structure HAS to use the following definitions:
 +
::- The DataStructure must be limited to 9999 entries.
 +
::- Field 1 is a description field, 30 chars long.  It will be used for the X-Axis
 +
::- Field 2 is a numeric field, packed 31:2.
 +
 
 +
    *====================================================================*   
 +
      dcl-ds TestDS                      qualified dim(9999);               
 +
          wDescription                    char(30);                         
 +
          wDataItem                      packed(31:2);                     
 +
      end-ds;                                                               
 +
    *====================================================================*   
 +
 
 +
:b. '''GenChart Prototype''':  Add the prototype for the external program:
 +
 
 +
 
 +
    *====================================================================*   
 +
      dcl-pr GenChart                    extpgm('GENCHART#R');             
 +
          p_InputDS                      pointer const;                     
 +
          p_Heading                      char(100) const;                   
 +
          p_Ylabel                        char(30) const;                   
 +
          p_TotalItems                    like(TInt) const;                 
 +
          p_MaxValue                      packed(31:2) const;               
 +
          p_ChartType                    char(10) const;                   
 +
          p_YCalc                        char(10) const;                   
 +
      End-pr;                                                               
 +
    *====================================================================*
 +
 
 +
:c.  '''Clear the data structure''':  You have to clear the data structure before you use it, to ensure it does not contain null values.
 +
 
 +
    *====================================================================*
 +
      clear TestDS;
 +
    *====================================================================*
 +
 
 +
:d.  '''Build up your SQL String''': 
 +
::- Limit your data to 9999 entries, either in the SQL String or in the fetch statement
 +
::- Use casting in SQL to ensure the data match the data structure
 +
 
 +
    *====================================================================*
 +
      SQLString =                                                           
 +
          'SELECT cast( ADATE as char(30)) as "WorkDate", cast(aspsizusd as '+
 +
          'decimal(31,2)) as "Value" FROM aspinf#p order by aDate';         
 +
    *====================================================================*
 +
                                                                               
 +
 
 +
:e.  '''Prepare the SQL cursor now''':
 +
::- Use SQL diagnostics to determine the number of records returned
 +
 
 +
    *====================================================================*
 +
        exec sql Prepare SQLGET1 from :SqlString;                         
 +
        exec sql declare IntCursor1 insensitive cursor for SQLGet1;       
 +
        exec sql Open IntCursor1;                                         
 +
        exec sql get diagnostics :wRecCount = DB2_NUMBER_ROWS;             
 +
    *====================================================================*
 +
 
 +
:f.  '''Fetch the data''':
 +
 
 +
    *====================================================================*
 +
            exec sql fetch IntCursor1  for 9999 rows into :TestDs;             
 +
            // Cose the Cursor                       
 +
            exec sql close Intcursor1;                                         
 +
    *====================================================================*
 +
 
 +
:g.  '''Determine the maximum size for the range''':
 +
 
 +
    *====================================================================*
 +
            exec sql select max(aspsiztot) into :wMaxValue from ASPINF#P;     
 +
    *====================================================================*
 +
 
 +
:h.  '''Generate the chart now''':
 +
 
 +
    *====================================================================*
 +
            GenChart(%addr(TestDs):'ASP Information - % Usage':'% Storage':   
 +
                wRecCount:wMaxValue:'*PCT':'*NONE');                           
 +
            GenChart(%addr(TestDs):'ASP Information':'Size in GB':wRecCount:   
 +
              wMaxValue:'*NORMAL':'*NONE');
 +
 
 +
==Example program==
 +
 
 +
'''''THIS SOURCE CODE IS PROVIDED AS IS, USE IT AT YOUR OWN RISK!''''
 +
 
 +
        CTL-OPT COPYRIGHT('Pieter Henrico')                         
 +
                DATFMT(*ISO) TIMFMT(*HMS:)                           
 +
                DFTACTGRP(*NO)                                       
 +
                OPTIMIZE(*NONE)                                     
 +
                OPTION(*NODEBUGIO)                                   
 +
                USRPRF(*USER)                                       
 +
                TEXT(*SRCMBRTXT)                                     
 +
                CopyNest(128)                                       
 +
                BndDir('QC2LE')                                     
 +
                Thread(*Serialize);                                 
 +
                                                                     
 +
      *================================================================
 +
      *    Declare files here                                         
 +
      *================================================================
 +
      // File Description here                                        0
 +
      *================================================================
 +
      *    Copy Programs                                             
 +
      *================================================================
 +
    *    Setup *Entry Parameters                                             
 +
    *================================================================       
 +
        dcl-pr TESTCHART#              extpgm('TESTCHART# ');               
 +
        end-pr;                                                               
 +
        dcl-pi TESTCHART# ;                                                   
 +
        end-pi;                                                               
 +
    * ------------------------------------------------------------------------
 +
      dcl-s wRecCount                    int(10) inz(0);                 
 +
      dcl-s SqlString                    char(5000);                       
 +
      dcl-s wCur                          int(10) inz(1);                 
 +
      dcl-s wMaxValue                    packed(31:2) inz(0);               
 +
    *====================================================================*   
 +
      dcl-ds TestDS                      qualified dim(9999);               
 +
          wDescription                    char(30);                         
 +
          wDataItem                      packed(31:2);                     
 +
      end-ds;                                                               
 +
    *====================================================================*   
 +
      dcl-pr GenChart                    extpgm('GENCHART#R');             
 +
          p_InputDS                      pointer const;                     
 +
          p_Heading                      char(100) const;                   
 +
          p_Ylabel                        char(30) const;                   
 +
          p_TotalItems                    int(10) const;                 
 +
          p_MaxValue                      packed(31:2) const;               
 +
          p_ChartType                    char(10) const;                   
 +
          p_YCalc                        char(10) const;                   
 +
      End-pr;                                                               
 +
                                                                             
 +
    *====================================================================*   
 +
    *  Mainline                                                          *   
 +
    *====================================================================*   
 +
    *================================================================       
 +
    * Check if the data files are available                                 
 +
    *================================================================       
 +
                                                                             
 +
      Clear TestDS;                                                         
 +
      //  Build up the SQL String                                             
 +
      Exec SQL Set Option DatFmt = *ISO;                                     
 +
      SQLString =                                                           
 +
          'SELECT cast( ADATE as char(30)) as "WorkDate", cast(aspsizusd as '+
 +
          'decimal(31,2)) as "Value" FROM aspinf#p order by aDate';         
 +
                                                                               
 +
      // ================================================================     
 +
      //  Prepare the SQL here                                               
 +
      // ================================================================     
 +
            exec sql Prepare SQLGET1 from :SqlString;                         
 +
            exec sql declare IntCursor1 insensitive cursor for SQLGet1;       
 +
            exec sql Open IntCursor1;                                         
 +
            exec sql get diagnostics :wRecCount = DB2_NUMBER_ROWS;             
 +
                                                                               
 +
      // ================================================================     
 +
      //  Fill the datastructure                                             
 +
      // ================================================================     
 +
            exec sql fetch IntCursor1  for 9999 rows into :TestDs;             
 +
            // Cose the Cursor, as it will be recreated                       
 +
            exec sql close Intcursor1;                                         
 +
            exec sql select max(aspsiztot) into :wMaxValue from ASPINF#P;     
 +
            SndstsMsg('Loading Chart 1...');                                   
 +
            GenChart(%addr(TestDs):'ASP Information - % Usage':'% Storage':   
 +
                wRecCount:wMaxValue:'*PCT':'*NONE');                           
 +
            GenChart(%addr(TestDs):'ASP Information':'Size in GB':wRecCount:   
 +
              wMaxValue:'*NORMAL':'*NONE');                                 
 +
                                                                             
 +
                                                                             
 +
      // ================================================================     
 +
      //  Program ends here                                                   
 +
      // ================================================================     
 +
                                                                             
 +
                                                                             
 +
        *InLR = *On;                                                         
 +
        return;                                                               
 +
                                                                             
 +
 
 +
 
 +
==GENCHART#D - Source code==
 +
 
 +
'''''THIS SOURCE CODE IS PROVIDED AS IS, USE IT AT YOUR OWN RISK!'''''
 +
 
 +
    A*%%TS  SD  20210608  135832  REKA        REL-V7R3M0  5770-WDS
 +
    A*%%EC
 +
    A                                      DSPSIZ(27 132 *DS4                -
 +
    A                                            24 80 *DS3)
 +
    A                                      INDARA
 +
    A          R MAIN
 +
    A*%%TS  SD  20210607  181701  REKA        REL-V7R3M0  5770-WDS
 +
    A                                      CF03(03 'Exit')
 +
    A                                      PAGEDOWN(40 'PageDown')
 +
    A                                      PAGEUP(41 'PageUP')
 +
    A                                      CF01(01 'Info')
 +
    A                                      CF18(18 'Last Page')
 +
    A                                      CF17(17 'First Page')
 +
    A                                      RTNCSRLOC(*RECNAME &CSRREC &CSRFLD)
 +
    A                                      RTNCSRLOC(*MOUSE &CSRROW &CSRCOL)
 +
    A                                      CSRLOC(ROWPOS    COLPOS)
 +
    A                                      OVERLAY
 +
    A                                      PRINT
 +
    A            CSRFLD        10A  H
 +
    A            CSRREC        10A  H
 +
    A            COLPOS        3S 0H
 +
    A            ROWPOS        3S 0H
 +
    A            CSRROW        3S 0H
 +
    A            CSRCOL        3S 0H
 +
    A            HLINE        120  O  1  7DSPATR(HI)
 +
    A            DLINE01      131A  O  3  1
 +
    A            DLINE02      131A  O  4  1
 +
    A            DLINE03      131A  O  5  1
 +
    A            DLINE04      131A  O  6  1
 +
    A            DLINE05      131A  O  7  1
 +
    A            DLINE06      131A  O  8  1
 +
    A            DLINE07      131A  O  9  1
 +
    A            DLINE08      131A  O 10  1
 +
    A            DLINE09      131A  O 11  1
 +
    A            DLINE10      131A  O 12  1
 +
    A            DLINE11      131A  O 13  1
 +
    A            DLINE12      131A  O 14  1
 +
    A            DLINE13      131A  O 15  1
 +
    A            DLINE14      131A  O 16  1
 +
    A            DLINE15      131A  O 17  1
 +
    A            DLINE16      131A  O 18  1
 +
    A            DLINE17      131A  O 19  1
 +
    A            DLINE18      131A  O 20  1
 +
    A            DLINE19      131A  O 21  1
 +
    A            DLINE20      131A  O 22  1
 +
    A            DLINE21      131A  O 23  1
 +
    A            DLINE22      131A  O 24  1
 +
    A            DLINE23      131A  O 25  1
 +
    A            DLINE24      131A  O 26  1
 +
    A            YDESC        40  O  2  1COLOR(BLU)
 +
    A            FLINE1        50A  O 27 82DSPATR(HI)
 +
    A                                27  1'F1=Item Info'
 +
    A                                      COLOR(BLU)
 +
    A                                27 16'F3=Exit'
 +
    A                                      COLOR(BLU)
 +
    A                                27 26'F17=First Page'
 +
    A                                      COLOR(BLU)
 +
    A                                27 43'F18=Last Page'
 +
    A                                      COLOR(BLU)
 +
    A          R INFO
 +
    A*%%TS  SD  20210608  134900  REKA        REL-V7R3M0  5770-WDS
 +
    A                                      CF03(03 'Exit')
 +
    A  *DS4                                WINDOW(7 34 11 60 *NOMSGLIN)
 +
    A  *DS3                                WINDOW(7 10 11 60 *NOMSGLIN)
 +
    A                                  1 23'Item Information'
 +
    A                                      DSPATR(HI)
 +
    A                                  3  3'Page..............:'
 +
    A                                  4  3'Values............:'
 +
    A                                  5  5'-'
 +
    A            WSDETAIL1    52A  O  5  7DSPATR(HI)
 +
    A                                  6  5'-'
 +
    A            WSDETAIL2    52A  O  6  7DSPATR(HI)
 +
    A                                  7  5'-'
 +
    A            WSDETAIL3    52A  O  7  7DSPATR(HI)
 +
    A                                  8  5'-'
 +
    A            WSDETAIL4    52A  O  8  7DSPATR(HI)
 +
    A*                                9  5'-'
 +
    A*          WSDETAIL5    52A  O  9  7DSPATR(HI)
 +
    A            WSPAGE        35A  O  3 24DSPATR(HI)
 +
    A                                  9  5'-'
 +
    A            WSDETAIL5    52A  O  9  7DSPATR(HI)
 +
    A                                11  4'F3=Exit'
 +
    A                                      COLOR(BLU)
 +
    A          R MAIN2
 +
    A*%%TS  SD  20210608  093006  REKA        REL-V7R3M0  5770-WDS
 +
    A                                      CF03(03 'Exit')
 +
    A                                      PAGEDOWN(40 'PageDown')
 +
    A                                      PAGEUP(41 'PageUP')
 +
    A                                      CF01(01 'Info')
 +
    A                                      CF18(18 'Last Page')
 +
    A                                      CF17(17 'First Page')
 +
    A                                      RTNCSRLOC(*RECNAME &CSRREC &CSRFLD)
 +
    A                                      RTNCSRLOC(*MOUSE &CSRROW &CSRCOL)
 +
    A                                      DSPMOD(*DS3)
 +
    A                                      CSRLOC(ROWPOS    COLPOS)
 +
    A                                      OVERLAY
 +
    A                                      PRINT
 +
    A            CSRFLD        10A  H
 +
    A            CSRREC        10A  H
 +
    A            COLPOS        3S 0H
 +
    A            ROWPOS        3S 0H
 +
    A            CSRROW        3S 0H
 +
    A            CSRCOL        3S 0H
 +
    A            H2LINE        70A  O  1  7DSPATR(HI)
 +
    A            D2LINE01      78A  O  3  1
 +
    A            D2LINE02      78A  O  4  1
 +
    A            D2LINE03      78A  O  5  1
 +
    A            D2LINE04      78A  O  6  1
 +
    A            D2LINE05      78A  O  7  1
 +
    A            D2LINE06      78A  O  8  1
 +
    A            D2LINE07      78A  O  9  1
 +
    A            D2LINE08      78A  O 10  1
 +
    A            D2LINE09      78A  O 11  1
 +
    A            D2LINE10      78A  O 12  1
 +
    A            D2LINE11      78A  O 13  1
 +
    A            D2LINE12      78A  O 14  1
 +
    A            D2LINE13      78A  O 15  1
 +
    A            D2LINE14      78A  O 16  1
 +
    A            D2LINE15      78A  O 17  1
 +
    A            D2LINE16      78A  O 18  1
 +
    A            D2LINE17      78A  O 19  1
 +
    A            D2LINE18      78A  O 20  1
 +
    A            D2LINE19      78A  O 21  1
 +
    A            D2LINE20      78A  O 22  1
 +
    A            D2LINE21      78A  O 23  1
 +
    A            Y2DESC        40A  O  2  1COLOR(BLU)
 +
    A            F2LINE1      27A  O 24 52DSPATR(HI)
 +
    A                                24  1'F1=Item Info'
 +
    A                                      COLOR(BLU)
 +
    A                                24 15'F3=Exit'
 +
    A                                      COLOR(BLU)
 +
    A                                24 24'F17=1st Page'
 +
    A                                      COLOR(BLU)
 +
    A                                24 38'F18=Last Page'
 +
    A                                      COLOR(BLU)
 +
    A          R ERRSCREEN
 +
    A*%%TS  SD  20210608  135832  REKA        REL-V7R3M0  5770-WDS
 +
    A                                      CF03(03 'Exit')
 +
    A  *DS4                                WINDOW(10 46 4 40 *NOMSGLIN)
 +
    A  *DS3                                WINDOW(10 20 5 40 *NOMSGLIN *NORSTC-
 +
    A                                      SR)
 +
    A                                  1 15'  ERROR!  '
 +
    A                                      COLOR(RED)
 +
    A                                      DSPATR(RI)
 +
    A                                  3  4'  There is no data to display!  '
 +
    A                                      DSPATR(HI)
 +
    A                                      DSPATR(RI)
 +
 
 +
==GENCHART#R - Source Code==
 +
 
 +
 
 +
      *================================================================
 +
      *šProgram Name:‚GENCHART#R
 +
      *šAuthor      :‚REKA      - Pieter Henrico
 +
      *šDate        :‚2021-06-02
 +
      *================================================================
 +
      *šPurpose of program:‚
 +
      *
 +
      * 
 +
      *
 +
      * Before compile:
 +
      *
 +
      *'''''THIS SOURCE CODE IS PROVIDED AS IS, USE IT AT YOUR OWN RISK!'''''
 +
      *
 +
      *================================================================
 +
      //==  A M E N D M E N T S                                              ==
 +
      //=======================================================================
 +
      //== DD.MM.YYYY  Name            Description
 +
      //==
 +
      //==
 +
      //==
 +
      //==
 +
      *================================================================
 +
        CTL-OPT COPYRIGHT('Pieter Henrico')
 +
                DATFMT(*ISO) TIMFMT(*HMS:)
 +
                DFTACTGRP(*NO)
 +
                OPTIMIZE(*NONE)
 +
                OPTION(*NODEBUGIO)
 +
                USRPRF(*USER)
 +
                TEXT(*SRCMBRTXT)
 +
                ALWNULL(*USRCTL)
 +
                CopyNest(128)
 +
                Thread(*Serialize);
 +
      *================================================================
 +
      *š  Declare files here
 +
      *================================================================
 +
      // File Description here
 +
      dcl-f  GENCHART#D      workstn indds(Indicators1);
 +
      *================================================================
 +
      *š  Copy Programs
 +
      *================================================================
 +
      *======================== *ENTRY ================================
 +
      *š  Setup *Entry Parameters
 +
      *================================================================
 +
        dcl-pr GENCHART#R              extpgm('GENCHART#R ');
 +
            p_InputDS                      pointer;
 +
            p_Heading                      char(100);
 +
            p_YLabel                        char(30);
 +
            p_TotalItems                    int(10);
 +
            p_MaxVal                        packed(31:2);
 +
            p_ChartType                    char(10);
 +
            p_YCalc                        char(10);
 +
        end-pr;
 +
        dcl-pi GENCHART#R ;
 +
            p_InputDS                      pointer;
 +
            p_Heading                      char(100);
 +
            p_YLabel                        char(30);
 +
            p_TotalItems                    int(10);
 +
            p_MaxVal                        packed(31:2);
 +
            p_ChartType                    char(10);
 +
            p_YCalc                        char(10);
 +
        end-pi;
 +
      *================================================================
 +
      *š  Declare data structures and variables here
 +
      *================================================================
 +
      * ------------------------------------------------------------------------
 +
        /if not defined(#INDICATORS)
 +
        /define #INDICATORS
 +
        dcl-ds Indicators1;
 +
            InfoRequest        ind pos(1) ;
 +
            ExitPgm            ind pos(3) ;
 +
            FirstPage          ind pos(17);
 +
            LastPage            ind pos(18);
 +
            PageDown            ind  pos(40) ;
 +
            PageUp              ind  pos(41) ;
 +
        end-ds ;
 +
      /Endif
 +
        dcl-s wDetailLine                  char(130) dim(24);
 +
        dcl-s wLine                        int(10);
 +
        dcl-s wTempLine                    char(130);
 +
        dcl-s wColumn                      int(10);
 +
        dcl-s wPage                        int(10);
 +
        dcl-s wDetailX                      char(30) dim(140);
 +
        dcl-s wDetailValue                  packed(15:2) dim(140);
 +
        dcl-ds dsData    qualified based(wPointer) dim(9999);
 +
            wXData                          char(30);
 +
            wDataItem                      packed(31:2);
 +
        end-ds;
 +
        dcl-s wPointer                      pointer;
 +
        dcl-s wMax                          packed(31:2);
 +
        dcl-s wCount                        int(10) inz(0);
 +
        dcl-s wStrCol                      int(10) inz(0);
 +
        dcl-s wDeterminePages              ind inz('0');
 +
        dcl-s wTotalPages                  int(10) inz(0);
 +
        dcl-ds dsPage                      qualified dim(200);
 +
            Start                          int(10);
 +
            End                            int(10);
 +
            Entries                        int(10);
 +
        End-Ds;
 +
        dcl-s wLineStr                      int(10) inz(0);
 +
        dcl-s wLastCol                      int(10) inz(0);
 +
        dcl-s wScreenLarge                  ind inz('0');
 +
        dcl-c wCol_White                    const(X'22');
 +
        //==============================================================
 +
        Dcl-PR QsnQryModSup                Int(10:0) extProc('QsnQryModSup');
 +
          mode                            Char(1) const;
 +
          modeAllowed                      Char(1) options(*OMIT);
 +
          llhandle                        Int(10:0) const options(*OMIT);
 +
          error                            Char(16) options(*varsize:*OMIT);
 +
        End-PR;
 +
        Dcl-C DS4_MODE                      '4';
 +
        Dcl-C MODE_ALLOWED                  1;
 +
      *====================================================================*
 +
      *  Mainline                                                          *
 +
      *====================================================================*
 +
        wPointer = p_InputDS;
 +
        wPage = 1;
 +
        wMax = p_MaxVal;
 +
        ROWPOS = 0;
 +
        COLPOS = 0;
 +
        wScreenLarge = ScreenSizeIs132();
 +
        DoU ExitPgm = *On;
 +
            Reset wDetailLine;
 +
            Reset wDetailValue;
 +
            Reset wDetailX;
 +
            BuildScreen(wPage:wMax:p_TotalItems:p_YLabel:p_ChartType:p_YCalc);
 +
            If wScreenLarge = *On;
 +
                hLine = CenterText(%trim(p_Heading):%len(hLine));
 +
                If p_TotalItems > 0;
 +
                    exfmt main;
 +
                Else;
 +
                    write main;
 +
                    exfmt ErrScreen;
 +
                    ExitPgm = *On;
 +
                EndIf;
 +
            Else;
 +
                h2Line = CenterText(%trim(p_Heading):%len(h2Line));
 +
                If p_TotalItems > 0;
 +
                    exfmt main2;
 +
                Else;
 +
                    write main2;
 +
                    exfmt ErrScreen;
 +
                    ExitPgm = *On;
 +
                EndIf;
 +
            EndIf;
 +
            If ExitPgm = *Off;
 +
                If wScreenLarge = *On;
 +
                    wLastCol = wPage*(130-wLineStr);
 +
                Else;
 +
                    wLastCol = wPage*(78-wLineStr);
 +
                EndIf;
 +
                select;
 +
                when PageUp = *On and wPage > 1;
 +
                    wPage = wPage - 1;
 +
                When PageDown = *On and wPage < wTotalPages;
 +
                    wPage = wPage + 1;
 +
                When FirstPage = *On;
 +
                    wPage = 1;
 +
                    FirstPage = *Off;
 +
                When LastPage = *On;
 +
                    wPage = wTotalPages;
 +
                    LastPage = *Off;
 +
                When InfoRequest = *On and CSRCOL >= wLineStr+1 and
 +
                    CSRCol - wLineStr <= dsPage(wPage).Entries;
 +
                    InfoRequest = *Off;
 +
                    If wScreenLarge = *On;
 +
                        wsPage = %trim(FLine1);
 +
                    Else;
 +
                        wsPage = %trim(F2Line1);
 +
                    EndIf;
 +
                    wsDetail1 = 'Heading:      ' + %trim(p_Heading);
 +
                    wsDetail2 = 'X-Axis Label:  ' + %trim(wDetailX(csrcol):'1');
 +
                    wsDetail3 = 'X-Value:      ' +
 +
                        %trim(%editc(wDetailValue(csrcol)  :'1'));
 +
                    wsDetail4 = 'Max Value:    ' +
 +
                        %trim(%editc(wMax:'1'));
 +
                    If wPage > 1;
 +
                        wsDetail5 = 'Data point:    ' +
 +
                            %trim(%editc(dsPage(wPage-1).End+
 +
                            csrcol-wLineStr:'1'));
 +
                    Else;
 +
                        wsDetail5 = 'Data point:    ' +
 +
                            %trim(%editc(csrcol-wLineStr:'1'));
 +
                    EndIf;
 +
                    exfmt info;
 +
                    ROWPOS = CSRROW;
 +
                    COLPOS = CSRCOL;
 +
                    ExitPgm = *Off;
 +
                EndSl;
 +
            EndIf;
 +
        EndDo;
 +
      // ================================================================
 +
      //  Program ends here
 +
      // ================================================================
 +
        *InLR = *On;
 +
        return;
 +
      // ================================================================
 +
        dcl-proc BuildColumn;
 +
        dcl-pi BuildColumn;
 +
            pColumn                        int(10) value;
 +
            pMaxValue                      int(20) value;
 +
            pValue                          int(20) value;
 +
            pXValue                        char(30) value;
 +
        end-pi;
 +
        dcl-s wLoopCount                    int(10) inz(0);
 +
        dcl-s wChartValue                  int(10) inz(0);
 +
        dcl-s wMaxRows                      int(10) inz(0);
 +
        //
 +
        If wScreenLarge = *On;
 +
            wMaxRows = 23;
 +
        Else;
 +
            wMaxRows = 20;
 +
        EndIf;
 +
        wChartValue = %int((pValue/pMaxValue)*wMaxRows);
 +
        wDetailValue(pColumn) = %dec(pValue:31:2);
 +
        wDetailX(pColumn) = pXValue;
 +
        If wChartValue > 0;
 +
            For wLoopCount = wMaxRows downto (wMaxRows - wChartValue);
 +
                If wLoopCount > 0;
 +
                  %subst(wDetailLine(wLoopCount):pColumn:1) = '|';
 +
                EndIf;
 +
            EndFor;
 +
            If wChartValue < wMaxRows;
 +
              %Subst(wDetailLine(wMaxRows-wChartValue):pColumn:1) = '_';
 +
            Else;
 +
              %Subst(wDetailLine(1):pColumn:1) = '_';
 +
            EndIf;
 +
        EndIf;
 +
        End-proc;
 +
      // ================================================================
 +
        dcl-proc BuildYLines;
 +
        dcl-pi BuildYLines                  int(10);
 +
            pMaxValue                      int(20) value;
 +
            pYType                          char(10) value;
 +
            pYLabel                        char(30) value;
 +
            pYCalc                          char(10) value;
 +
        end-pi;
 +
        dcl-s wLoopCount                    int(10) inz(0);
 +
        dcl-s wDivisor                      int(10) inz(0);
 +
        dcl-s wTempValue                    packed(15:2) inz(0);
 +
        dcl-s wUnderLine                    char(130) inz(*all'-');
 +
        dcl-s wUnderLine2                  char(130) inz(*all'_');
 +
        dcl-s wUnderLine3                  char(130) inz(*all'=');
 +
        dcl-s wLength                      int(10) inz(0);
 +
        dcl-s wEndOfDesc                    int(10) inz(0);
 +
        //
 +
        yDesc = pYLabel;
 +
        y2Desc = pYLabel;
 +
        Select;
 +
        When pYType = '*PCT' and wScreenLarge = *On;  // Y-bar will be percentage
 +
            wDetailLine(1)  = '100%  :' + wCol_White + %trim(wUnderLine);
 +
            wDetailLine(6)  = ' 75%  :' + wCol_White + %trim(wUnderLine);
 +
            wDetailLine(12) = ' 50%  :' + wCol_White + %trim(wUnderLine);
 +
            wDetailLine(17) = ' 25%  :' + wCol_White + %trim(wUnderLine);
 +
            wDetailLine(23) = '  0%  :' + wCol_White + %trim(wUnderLine2);
 +
            wDetailLine(24) = '        ' +
 +
                %trim(wUnderLine3);
 +
            For wLine = 1 to 23;
 +
                %subst(wDetailLine(wLine):7:2) = ':' + wCol_White;
 +
            Endfor;
 +
            wEndOfDesc = 8;
 +
        When pYType = '*NORMAL' and wScreenLarge = *On;  // Determine Min/Max/25%/50%/75%
 +
            select;        //1234567890123
 +
            when pMaxValue >= 1000000000000 and pYCalc = '*TB';
 +
                wDivisor = 1024*1024*1024*1024;
 +
                yDesc = 'Size in TB';
 +
            when pMaxValue >= 1000000000 and pYCalc = '*GB';
 +
                wDivisor = 1024*1024*1024;
 +
                yDesc = 'Size in GB';
 +
            when pMaxValue >= 1000000 and pYCalc = '*MB';
 +
                yDesc = 'Size in MB';
 +
                wDivisor = 1024*1024;
 +
            when pMaxValue >= 1000 and pYCalc = '*KB';
 +
                yDesc = 'Size in KB';
 +
                wDivisor = 1024;
 +
            Other;
 +
                wDivisor = 1;
 +
            EndSl;
 +
            wLength = %len(%trim(FormatNumber(%dec(pMaxValue/wDivisor:31:2))));
 +
            wEndOfDesc = wLength + 4;
 +
            wDetailLine(1) =
 +
                %trim(FormatNumber(%dec(pMaxValue/wDivisor:31:2)));
 +
            %subst(wDetailLine(1):wEndOfDesc+1:131-wEndOfDesc-1) =
 +
                %trim(wUnderLine);
 +
            wDetailLine(6) =
 +
                %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.75:31:2)));
 +
            %subst(wDetailLine(6):wEndOfDesc+1:131-wEndOfDesc-1) =
 +
                %trim(wUnderLine);
 +
            wDetailLine(12) =
 +
                %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.50:31:2)));
 +
            %subst(wDetailLine(12):wEndOfDesc+1:131-wEndOfDesc-1) =
 +
                %trim(wUnderLine);
 +
            wDetailLine(17) =
 +
                %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.25:31:2)));
 +
            %subst(wDetailLine(17):wEndOfDesc+1:131-wEndOfDesc-1) =
 +
                %trim(wUnderLine);
 +
            wDetailLine(23) = '0';
 +
            %subst(wDetailLine(23):wEndOfDesc+1:131-wEndOfDesc-1) =
 +
                %trim(wUnderLine2);
 +
            %Subst(wDetailLine(24):wEndOfDesc+1:131-wEndOfDesc-1)=
 +
                %trim(wUnderLine3);
 +
            For wLine = 1 to 23;
 +
                %subst(wDetailLine(wLine):wEndOfDesc-1:2) = ':' +
 +
                    wCol_White;
 +
            Endfor;
 +
        When pYType = '*PCT' and wScreenLarge = *Off;  // Y-bar will be percentage
 +
            wDetailLine(1)  = '100%  : ' + %trim(wUnderLine);
 +
            wDetailLine(5)  = ' 75%  : ' + %trim(wUnderLine);
 +
            wDetailLine(10) = ' 50%  : ' + %trim(wUnderLine);
 +
            wDetailLine(15) = ' 25%  : ' + %trim(wUnderLine);
 +
            wDetailLine(20) = '  0%  : ' + %trim(wUnderLine2);
 +
            wDetailLine(21) = '        ' +
 +
                %trim(wUnderLine3);
 +
            For wLine = 1 to 20;
 +
                %subst(wDetailLine(wLine):7:2) = ':' + wCol_White;
 +
            Endfor;
 +
            wEndOfDesc = 8;
 +
        When pYType = '*NORMAL' and wScreenLarge = *Off;  // Determine Min/Max/25%/50%/75%
 +
            select;        //1234567890123
 +
            when pMaxValue >= 1000000000000 and pYCalc = '*TB';
 +
                wDivisor = 1024*1024*1024*1024;
 +
                y2Desc = 'Size in TB';
 +
            when pMaxValue >= 1000000000 and pYCalc = '*GB';
 +
                wDivisor = 1024*1024*1024;
 +
                y2Desc = 'Size in GB';
 +
            when pMaxValue >= 1000000 and pYCalc = '*MB';
 +
                y2Desc = 'Size in MB';
 +
                wDivisor = 1024*1024;
 +
            when pMaxValue >= 1000 and pYCalc = '*KB';
 +
                y2Desc = 'Size in KB';
 +
                wDivisor = 1024;
 +
            Other;
 +
                wDivisor = 1;
 +
            EndSl;
 +
            wLength = %len(%trim(FormatNumber(%dec(pMaxValue/wDivisor:31:2))));
 +
            wEndOfDesc = wLength + 4;
 +
            wDetailLine(1) =
 +
                %trim(FormatNumber(%dec(pMaxValue/wDivisor:31:2)));
 +
            %subst(wDetailLine(1):wEndOfDesc+1:79-wEndOfDesc-1) =
 +
                %trim(wUnderLine);
 +
            wDetailLine(5) =
 +
                %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.75:31:2)));
 +
            %subst(wDetailLine(5):wEndOfDesc+1:79-wEndOfDesc-1) =
 +
                %trim(wUnderLine);
 +
            wDetailLine(10) =
 +
                %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.50:31:2)));
 +
            %subst(wDetailLine(10):wEndOfDesc+1:79-wEndOfDesc-1) =
 +
                %trim(wUnderLine);
 +
            wDetailLine(15) =
 +
                %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.25:31:2)));
 +
            %subst(wDetailLine(15):wEndOfDesc+1:79-wEndOfDesc-1) =
 +
                %trim(wUnderLine);
 +
            wDetailLine(20) = '0';
 +
            %subst(wDetailLine(20):wEndOfDesc+1:79-wEndOfDesc-1) =
 +
                %trim(wUnderLine2);
 +
            %Subst(wDetailLine(21):wEndOfDesc+1:79-wEndOfDesc-1)=
 +
                %trim(wUnderLine3);
 +
            For wLine = 1 to 20;
 +
                %subst(wDetailLine(wLine):wEndOfDesc-1:2) = ':' + wCol_White;
 +
            Endfor;
 +
        EndSl;
 +
        Return wEndOfDesc;
 +
        End-proc;
 +
      // ================================================================
 +
        dcl-proc FormatNumber;
 +
        dcl-pi FormatNumber                char(20);
 +
            pInputValue                    packed(15:2) value;
 +
        end-pi;
 +
        dcl-s wTempValue                    char(20) inz(' ');
 +
        //
 +
        If pInputValue < 1 and pInputValue > 0;
 +
            wTempValue = '0' + %trim(%editc(pInputValue:'J'));
 +
        Else;
 +
            wTempValue = %trim(%editC(pInputValue:'J'));
 +
        EndIf;
 +
        Return wTempValue;
 +
        End-proc;
 +
      // ================================================================
 +
        dcl-proc BuildScreen;
 +
        dcl-pi BuildScreen;
 +
            pPage                          int(10) value;
 +
            pMaxValue                      packed(31:2) value;
 +
            pTotalItems                    int(10)  value;
 +
            pYLabel                        char(30) value;
 +
            pChartType                      char(10) value;
 +
            pYCalc                          char(10) value;
 +
        end-pi;
 +
        dcl-s wLineCount                    int(10) inz(0);
 +
        dcl-s wTotalColumns                int(10) inz(0);
 +
        dcl-s wPageCount                    int(10) inz(0);
 +
        dcl-s wStrCol                      int(10) inz(0);
 +
        dcl-s wEndCol                      int(10) inz(0);
 +
        dcl-s wTempNum                      packed(31:2) inz(0);
 +
        dcl-s wMaxCol                      int(10) inz(0);
 +
            If wScreenLarge = *On;
 +
                wMaxCol = 130;
 +
            Else;
 +
                wMaxCol = 78;
 +
            EndIf;
 +
            wLineStr = BuildyLines(pMaxValue:pChartType:pYLabel:pYCalc);
 +
            If wDeterminePages = *Off;
 +
                wDeterminePages = *On;
 +
                wTotalColumns = wMaxCol - wLineStr;
 +
                wTotalPages = %inth(pTotalItems/wTotalColumns);
 +
                wStrCol = 1;
 +
                If wTotalPages = 0;
 +
                    wTotalPages = 1;
 +
                EndIf;
 +
                For wPageCount = 1 to wTotalPages;
 +
                    dsPage(wPageCount).Start = wStrCol;
 +
                    wEndCol = wStrCol + wTotalColumns - 1;
 +
                    If wEndCol > pTotalItems;
 +
                        wEndCol = pTotalItems;
 +
                    EndIf;
 +
                    dsPage(wPageCount).End = wEndCol;
 +
                    dsPage(wPageCount).Entries = wEndCol - wStrCol + 1;
 +
                    wStrCol = wEndCol + 1;
 +
                EndFor;
 +
            EndIf;
 +
            wStrCol = dsPage(pPage).Start;
 +
            wEndCol = dsPage(pPage).End;
 +
            For wLineCount = 0 to (wMaxCol - wLineStr - 1);
 +
                If dsData(wLineCount+wStrCol).wDataItem  < 0;
 +
                    wTempNum = 0;
 +
                Else;
 +
                    wTempNum = dsData(wLineCount+wStrCol).wDataItem;
 +
                EndIf;
 +
                BuildColumn(wLineStr+wLineCount+1:pMaxValue:
 +
                    wTempNum:
 +
                    dsData(wLineCount+wStrCol).wxData);
 +
            EndFor;
 +
            BuildDLines();
 +
            If wScreenLarge = *On;
 +
                EvalR FLine1 = 'Page ' + %trim(%editc(wPage:'1')) + ' of ' +
 +
                %trim(%editc(wTotalPages:'1')) + ' page(s)';
 +
            Else;
 +
                EvalR F2LIne1= 'Page ' + %trim(%editc(wPage:'1')) + ' of ' +
 +
                %trim(%editc(wTotalPages:'1')) + ' page(s)';
 +
            EndIf;
 +
        End-proc;
 +
      // ================================================================
 +
      // ================================================================
 +
        dcl-proc BuildDlines;
 +
        If wScreenLarge = *On;
 +
            dline01 = wDetailLine(1);
 +
            dline02 = wDetailLine(2);
 +
            dline03 = wDetailLine(3);
 +
            dline04 = wDetailLine(4);
 +
            dline05 = wDetailLine(5);
 +
            dline06 = wDetailLine(6);
 +
            dline07 = wDetailLine(7);
 +
            dline08 = wDetailLine(8);
 +
            dline09 = wDetailLine(9);
 +
            dline10 = wDetailLine(10);
 +
            dline11 = wDetailLine(11);
 +
            dline12 = wDetailLine(12);
 +
            dline13 = wDetailLine(13);
 +
            dline14 = wDetailLine(14);
 +
            dline15 = wDetailLine(15);
 +
            dline16 = wDetailLine(16);
 +
            dline17 = wDetailLine(17);
 +
            dline18 = wDetailLine(18);
 +
            dline19 = wDetailLine(19);
 +
            dline20 = wDetailLine(20);
 +
            dline21 = wDetailLine(21);
 +
            dline22 = wDetailLine(22);
 +
            dline23 = wDetailLine(23);
 +
            dline24 = wDetailLine(24);
 +
        Else;
 +
            d2line01 = wDetailLine(1);
 +
            d2line02 = wDetailLine(2);
 +
            d2line03 = wDetailLine(3);
 +
            d2line04 = wDetailLine(4);
 +
            d2line05 = wDetailLine(5);
 +
            d2line06 = wDetailLine(6);
 +
            d2line07 = wDetailLine(7);
 +
            d2line08 = wDetailLine(8);
 +
            d2line09 = wDetailLine(9);
 +
            d2line10 = wDetailLine(10);
 +
            d2line11 = wDetailLine(11);
 +
            d2line12 = wDetailLine(12);
 +
            d2line13 = wDetailLine(13);
 +
            d2line14 = wDetailLine(14);
 +
            d2line15 = wDetailLine(15);
 +
            d2line16 = wDetailLine(16);
 +
            d2line17 = wDetailLine(17);
 +
            d2line18 = wDetailLine(18);
 +
            d2line19 = wDetailLine(19);
 +
            d2line20 = wDetailLine(20);
 +
            d2line21 = wDetailLine(21);
 +
        EndIf;
 +
        End-proc;
 +
      // ====================================================================*
 +
      //  Subroutine.... ScreenSizeIs132                                    *
 +
      //  Description... Check if the screen is configured for 132 Chars    *
 +
      //
 +
      //  Parameters:
 +
      //
 +
      // ‚Example:
 +
      //
 +
      // šIf ScreenSizeIs132() = *Off;
 +
      //      SndCompMsg('Screen is NOT configured for 132 chars');
 +
      // šElse;
 +
      //      SndCompMsg('Object is configured for 132 chars');
 +
      // šEndIf;
 +
      // ====================================================================*
 +
        Dcl-Proc ScreenSizeIs132            export;
 +
        Dcl-PI ScreenSizeIs132              ind;// Return Variable
 +
        End-PI;
 +
        // Check the screen size now
 +
              If (QsnQryModSup(DS4_MODE:*OMIT:*OMIT:*OMIT) <> MODE_ALLOWED);
 +
                  Return *Off;
 +
              Else;
 +
                  Return *On;
 +
              EndIf;
 +
        End-Proc;
 +
      //********************************************************************
 +
      //  ===================================================================================
 +
      //  Center Text in a string
 +
      //    Parm:    Input String varchar(32767)
 +
      //              String Length (untrimmed)
 +
      //    Returns: Output String varchar(32000)
 +
      //  ===================================================================================
 +
      //  EXAMPLE:
 +
      //              wTestString = CenterText(wTestString):%len(wTestString));
 +
      //
 +
      //  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 +
        dcl-proc CenterText              export;
 +
            dcl-pi CenterText            char(32767);
 +
              p_InputString              char(32767) const OPTIONS(*VARSIZE);
 +
              p_Stringlength            int(10) value;
 +
            end-pi;
 +
      //
 +
            dcl-s wStrPos                int(10) inz(0);
 +
            dcl-s wTempLen                int(10) inz(0);
 +
            dcl-s wOutputString          char(32767) inz(' ');
 +
              wTempLen = %len(%trim(%subst(p_InputString:1:p_StringLength)));
 +
              wStrPos = ((p_StringLength - wTempLen)/2) + 1;
 +
                %Subst(wOutputString:wStrPos:wTempLen) =
 +
                    %trim(%subst(p_InputString:1:p_StringLength));
 +
                Return wOutputString;
 +
        end-proc;

Latest revision as of 07:45, 9 June 2021

Green-screen Chart/Graph

Background

It is sometimes useful to display a graph of values on the AS400 green-screen. Although there are commercial products available for the AS400, these are often difficult to use and not available everywhere. This product was designed to allow for a simple text-based line-graph to be displayed on the screen. It will take a data-structure from another program, and build up the screen accordingly.

The program has been written to work correctly on either a wide screen (27x132) or a normal screen(24x80).

Screen Layout

GenChart - Overview.png

a. This is the header as passed to the program
b. This is the Y-label, as passed to the program
c. The Y-axis values will be build based on the chart type or the chart calc function
d. If the number of data points exceed the screen width, the program will create additional pages. Page Up/Down will show the rest of the entries. If you want to jump to the 1st page, press F17, or last page press F18.
e. If you position your cursor on any data item/column, and press F1, the program will display information about the data point

GenChart - Item Information.png

Objects

The following objects will be used by the program:

a. GENCHART#D - Display File
b. GENCHART#R – RPG Program


GenChart Program Parameters

The GENCHART#R program requires the following parameters:

a. Data structure (see point 4):
- The data structure will be passed from your program, to the GENCHART#R program, by using pointers. When you call the program, the variable has to use %ADDR(DSNAME).
b. Heading:
- Char (100).
- The heading you need for your chart
c. Y-Axis Label:
- Char(30)
- Here you can specify a label for the Y-Axis.
- Label will be affected by the Chart Type variable
d. Total Items:
- Int(10)
- Specify the number of values to be passed via the DataStructure
e. Max Value:
- Packed(31:2)
- Specify the Maximum value. This is needed to determine the sizing of the bars
f. Chart Type
- Char(10)
- Allows for two types of charts. Can be either
  • *PCT: Determine %, betwee max value and actual value
  • *NORMAL: Display the values on the screen as they are
g. Chart Calc:
- Char(10)
- If the values are too big, the program can scale them. Allowed values are:
  • *NONE – Keep the values as is
  • *TB – Scale the values in Terrabytes
  • *GB – Scale the values in Gigabytes
  • *KB – Scale the values in Megabytes
  • *KB – Scale the values in Kilobytes

RPG Program Usage

In order to use the GENCHART functionality inside your RPG program, the following is needed:

a. Data structure: A datastructure has to be passed onto the calling program. This data structure HAS to use the following definitions:
- The DataStructure must be limited to 9999 entries.
- Field 1 is a description field, 30 chars long. It will be used for the X-Axis
- Field 2 is a numeric field, packed 31:2.
    *====================================================================*    
      dcl-ds TestDS                       qualified dim(9999);                
          wDescription                    char(30);                           
          wDataItem                       packed(31:2);                       
      end-ds;                                                                 
    *====================================================================*    
b. GenChart Prototype: Add the prototype for the external program:


    *====================================================================*    
      dcl-pr GenChart                     extpgm('GENCHART#R');               
          p_InputDS                       pointer const;                      
          p_Heading                       char(100) const;                    
          p_Ylabel                        char(30) const;                     
          p_TotalItems                    like(TInt) const;                   
          p_MaxValue                      packed(31:2) const;                 
          p_ChartType                     char(10) const;                     
          p_YCalc                         char(10) const;                     
      End-pr;                                                                 
    *====================================================================*
c. Clear the data structure: You have to clear the data structure before you use it, to ensure it does not contain null values.
    *====================================================================*
      clear TestDS;
    *====================================================================*
d. Build up your SQL String:
- Limit your data to 9999 entries, either in the SQL String or in the fetch statement
- Use casting in SQL to ensure the data match the data structure
    *====================================================================*
      SQLString =                                                             
          'SELECT cast( ADATE as char(30)) as "WorkDate", cast(aspsizusd as '+
          'decimal(31,2)) as "Value" FROM aspinf#p order by aDate';           
    *====================================================================*
                                                                               
e. Prepare the SQL cursor now:
- Use SQL diagnostics to determine the number of records returned
    *====================================================================*
        exec sql Prepare SQLGET1 from :SqlString;                           
        exec sql declare IntCursor1 insensitive cursor for SQLGet1;         
        exec sql Open IntCursor1;                                           
        exec sql get diagnostics :wRecCount = DB2_NUMBER_ROWS;              
    *====================================================================*
f. Fetch the data:
    *====================================================================*
           exec sql fetch IntCursor1  for 9999 rows into :TestDs;              
           // Cose the Cursor                        
           exec sql close Intcursor1;                                          
    *====================================================================*
g. Determine the maximum size for the range:
    *====================================================================*
           exec sql select max(aspsiztot) into :wMaxValue from ASPINF#P;       
    *====================================================================*
h. Generate the chart now:
    *====================================================================*
           GenChart(%addr(TestDs):'ASP Information - % Usage':'% Storage':     
               wRecCount:wMaxValue:'*PCT':'*NONE');                            
           GenChart(%addr(TestDs):'ASP Information':'Size in GB':wRecCount:    
              wMaxValue:'*NORMAL':'*NONE');

Example program

THIS SOURCE CODE IS PROVIDED AS IS, USE IT AT YOUR OWN RISK!'

        CTL-OPT COPYRIGHT('Pieter Henrico')                           
                DATFMT(*ISO) TIMFMT(*HMS:)                            
                DFTACTGRP(*NO)                                        
                OPTIMIZE(*NONE)                                       
                OPTION(*NODEBUGIO)                                    
                USRPRF(*USER)                                         
                TEXT(*SRCMBRTXT)                                      
                CopyNest(128)                                         
                BndDir('QC2LE')                                       
                Thread(*Serialize);                                   
                                                                      
     *================================================================
     *    Declare files here                                          
     *================================================================
     // File Description here                                         0
     *================================================================
     *    Copy Programs                                               
     *================================================================
    *    Setup *Entry Parameters                                              
    *================================================================         
       dcl-pr TESTCHART#               extpgm('TESTCHART# ');                 
       end-pr;                                                                
       dcl-pi TESTCHART# ;                                                    
       end-pi;                                                                
    * ------------------------------------------------------------------------
      dcl-s wRecCount                     int(10) inz(0);                  
      dcl-s SqlString                     char(5000);                         
      dcl-s wCur                          int(10) inz(1);                  
      dcl-s wMaxValue                     packed(31:2) inz(0);                
    *====================================================================*    
      dcl-ds TestDS                       qualified dim(9999);                
          wDescription                    char(30);                           
          wDataItem                       packed(31:2);                       
      end-ds;                                                                 
    *====================================================================*    
      dcl-pr GenChart                     extpgm('GENCHART#R');               
          p_InputDS                       pointer const;                      
          p_Heading                       char(100) const;                    
          p_Ylabel                        char(30) const;                     
          p_TotalItems                    int(10) const;                   
          p_MaxValue                      packed(31:2) const;                 
          p_ChartType                     char(10) const;                     
          p_YCalc                         char(10) const;                     
      End-pr;                                                                 
                                                                              
    *====================================================================*    
    *  Mainline                                                          *    
    *====================================================================*    
    *================================================================         
    * Check if the data files are available                                   
    *================================================================         
                                                                              
      Clear TestDS;                                                           
     //  Build up the SQL String                                              
      Exec SQL Set Option DatFmt = *ISO;                                      
      SQLString =                                                             
          'SELECT cast( ADATE as char(30)) as "WorkDate", cast(aspsizusd as '+
          'decimal(31,2)) as "Value" FROM aspinf#p order by aDate';           
                                                                               
      // ================================================================      
      //  Prepare the SQL here                                                 
      // ================================================================      
           exec sql Prepare SQLGET1 from :SqlString;                           
           exec sql declare IntCursor1 insensitive cursor for SQLGet1;         
           exec sql Open IntCursor1;                                           
           exec sql get diagnostics :wRecCount = DB2_NUMBER_ROWS;              
                                                                               
      // ================================================================      
      //  Fill the datastructure                                               
      // ================================================================      
           exec sql fetch IntCursor1  for 9999 rows into :TestDs;              
           // Cose the Cursor, as it will be recreated                         
           exec sql close Intcursor1;                                          
           exec sql select max(aspsiztot) into :wMaxValue from ASPINF#P;       
           SndstsMsg('Loading Chart 1...');                                    
           GenChart(%addr(TestDs):'ASP Information - % Usage':'% Storage':     
               wRecCount:wMaxValue:'*PCT':'*NONE');                            
           GenChart(%addr(TestDs):'ASP Information':'Size in GB':wRecCount:    
              wMaxValue:'*NORMAL':'*NONE');                                   
                                                                              
                                                                              
     // ================================================================      
     //  Program ends here                                                    
     // ================================================================      
                                                                              
                                                                              
       *InLR = *On;                                                           
       return;                                                                
                                                                              


GENCHART#D - Source code

THIS SOURCE CODE IS PROVIDED AS IS, USE IT AT YOUR OWN RISK!

    A*%%TS  SD  20210608  135832  REKA        REL-V7R3M0  5770-WDS
    A*%%EC
    A                                      DSPSIZ(27 132 *DS4                 -
    A                                             24 80 *DS3)
    A                                      INDARA
    A          R MAIN
    A*%%TS  SD  20210607  181701  REKA        REL-V7R3M0  5770-WDS
    A                                      CF03(03 'Exit')
    A                                      PAGEDOWN(40 'PageDown')
    A                                      PAGEUP(41 'PageUP')
    A                                      CF01(01 'Info')
    A                                      CF18(18 'Last Page')
    A                                      CF17(17 'First Page')
    A                                      RTNCSRLOC(*RECNAME &CSRREC &CSRFLD)
    A                                      RTNCSRLOC(*MOUSE &CSRROW &CSRCOL)
    A                                      CSRLOC(ROWPOS     COLPOS)
    A                                      OVERLAY
    A                                      PRINT
    A            CSRFLD        10A  H
    A            CSRREC        10A  H
    A            COLPOS         3S 0H
    A            ROWPOS         3S 0H
    A            CSRROW         3S 0H
    A            CSRCOL         3S 0H
    A            HLINE        120   O  1  7DSPATR(HI)
    A            DLINE01      131A  O  3  1
    A            DLINE02      131A  O  4  1
    A            DLINE03      131A  O  5  1
    A            DLINE04      131A  O  6  1
    A            DLINE05      131A  O  7  1
    A            DLINE06      131A  O  8  1
    A            DLINE07      131A  O  9  1
    A            DLINE08      131A  O 10  1
    A            DLINE09      131A  O 11  1
    A            DLINE10      131A  O 12  1
    A            DLINE11      131A  O 13  1
    A            DLINE12      131A  O 14  1
    A            DLINE13      131A  O 15  1
    A            DLINE14      131A  O 16  1
    A            DLINE15      131A  O 17  1
    A            DLINE16      131A  O 18  1
    A            DLINE17      131A  O 19  1
    A            DLINE18      131A  O 20  1
    A            DLINE19      131A  O 21  1
    A            DLINE20      131A  O 22  1
    A            DLINE21      131A  O 23  1
    A            DLINE22      131A  O 24  1
    A            DLINE23      131A  O 25  1
    A            DLINE24      131A  O 26  1
    A            YDESC         40   O  2  1COLOR(BLU)
    A            FLINE1        50A  O 27 82DSPATR(HI)
    A                                 27  1'F1=Item Info'
    A                                      COLOR(BLU)
    A                                 27 16'F3=Exit'
    A                                      COLOR(BLU)
    A                                 27 26'F17=First Page'
    A                                      COLOR(BLU)
    A                                 27 43'F18=Last Page'
    A                                      COLOR(BLU)
    A          R INFO
    A*%%TS  SD  20210608  134900  REKA        REL-V7R3M0  5770-WDS
    A                                      CF03(03 'Exit')
    A  *DS4                                WINDOW(7 34 11 60 *NOMSGLIN)
    A  *DS3                                WINDOW(7 10 11 60 *NOMSGLIN)
    A                                  1 23'Item Information'
    A                                      DSPATR(HI)
    A                                  3  3'Page..............:'
    A                                  4  3'Values............:'
    A                                  5  5'-'
    A            WSDETAIL1     52A  O  5  7DSPATR(HI)
    A                                  6  5'-'
    A            WSDETAIL2     52A  O  6  7DSPATR(HI)
    A                                  7  5'-'
    A            WSDETAIL3     52A  O  7  7DSPATR(HI)
    A                                  8  5'-'
    A            WSDETAIL4     52A  O  8  7DSPATR(HI)
    A*                                 9  5'-'
    A*           WSDETAIL5     52A  O  9  7DSPATR(HI)
    A            WSPAGE        35A  O  3 24DSPATR(HI)
    A                                  9  5'-'
    A            WSDETAIL5     52A  O  9  7DSPATR(HI)
    A                                 11  4'F3=Exit'
    A                                      COLOR(BLU)
    A          R MAIN2
    A*%%TS  SD  20210608  093006  REKA        REL-V7R3M0  5770-WDS
    A                                      CF03(03 'Exit')
    A                                      PAGEDOWN(40 'PageDown')
    A                                      PAGEUP(41 'PageUP')
    A                                      CF01(01 'Info')
    A                                      CF18(18 'Last Page')
    A                                      CF17(17 'First Page')
    A                                      RTNCSRLOC(*RECNAME &CSRREC &CSRFLD)
    A                                      RTNCSRLOC(*MOUSE &CSRROW &CSRCOL)
    A                                      DSPMOD(*DS3)
    A                                      CSRLOC(ROWPOS     COLPOS)
    A                                      OVERLAY
    A                                      PRINT
    A            CSRFLD        10A  H
    A            CSRREC        10A  H
    A            COLPOS         3S 0H
    A            ROWPOS         3S 0H
    A            CSRROW         3S 0H
    A            CSRCOL         3S 0H
    A            H2LINE        70A  O  1  7DSPATR(HI)
    A            D2LINE01      78A  O  3  1
    A            D2LINE02      78A  O  4  1
    A            D2LINE03      78A  O  5  1
    A            D2LINE04      78A  O  6  1
    A            D2LINE05      78A  O  7  1
    A            D2LINE06      78A  O  8  1
    A            D2LINE07      78A  O  9  1
    A            D2LINE08      78A  O 10  1
    A            D2LINE09      78A  O 11  1
    A            D2LINE10      78A  O 12  1
    A            D2LINE11      78A  O 13  1
    A            D2LINE12      78A  O 14  1
    A            D2LINE13      78A  O 15  1
    A            D2LINE14      78A  O 16  1
    A            D2LINE15      78A  O 17  1
    A            D2LINE16      78A  O 18  1
    A            D2LINE17      78A  O 19  1
    A            D2LINE18      78A  O 20  1
    A            D2LINE19      78A  O 21  1
    A            D2LINE20      78A  O 22  1
    A            D2LINE21      78A  O 23  1
    A            Y2DESC        40A  O  2  1COLOR(BLU)
    A            F2LINE1       27A  O 24 52DSPATR(HI)
    A                                 24  1'F1=Item Info'
    A                                      COLOR(BLU)
    A                                 24 15'F3=Exit'
    A                                      COLOR(BLU)
    A                                 24 24'F17=1st Page'
    A                                      COLOR(BLU)
    A                                 24 38'F18=Last Page'
    A                                      COLOR(BLU)
    A          R ERRSCREEN
    A*%%TS  SD  20210608  135832  REKA        REL-V7R3M0  5770-WDS
    A                                      CF03(03 'Exit')
    A  *DS4                                WINDOW(10 46 4 40 *NOMSGLIN)
    A  *DS3                                WINDOW(10 20 5 40 *NOMSGLIN *NORSTC-
    A                                      SR)
    A                                  1 15'  ERROR!  '
    A                                      COLOR(RED)
    A                                      DSPATR(RI)
    A                                  3  4'  There is no data to display!  '
    A                                      DSPATR(HI)
    A                                      DSPATR(RI)

GENCHART#R - Source Code

     *================================================================
     *šProgram Name:‚GENCHART#R
     *šAuthor      :‚REKA       - Pieter Henrico
     *šDate        :‚2021-06-02
     *================================================================
     *šPurpose of program:‚
     *
     *  
     *
     * Before compile:
     *
     *THIS SOURCE CODE IS PROVIDED AS IS, USE IT AT YOUR OWN RISK!
     *
     *================================================================
     //==  A M E N D M E N T S                                              ==
     //=======================================================================
     //== DD.MM.YYYY   Name             Description
     //==
     //==
     //==
     //==
     *================================================================
        CTL-OPT COPYRIGHT('Pieter Henrico')
                DATFMT(*ISO) TIMFMT(*HMS:)
                DFTACTGRP(*NO)
                OPTIMIZE(*NONE)
                OPTION(*NODEBUGIO)
                USRPRF(*USER)
                TEXT(*SRCMBRTXT)
                ALWNULL(*USRCTL)
                CopyNest(128)
                Thread(*Serialize);
     *================================================================
     *š   Declare files here
     *================================================================
     // File Description here
      dcl-f  GENCHART#D      workstn indds(Indicators1);
     *================================================================
     *š   Copy Programs
     *================================================================
     *======================== *ENTRY ================================
     *š   Setup *Entry Parameters
     *================================================================
        dcl-pr GENCHART#R               extpgm('GENCHART#R ');
           p_InputDS                       pointer;
           p_Heading                       char(100);
           p_YLabel                        char(30);
           p_TotalItems                    int(10);
           p_MaxVal                        packed(31:2);
           p_ChartType                     char(10);
           p_YCalc                         char(10);
        end-pr;
        dcl-pi GENCHART#R ;
           p_InputDS                       pointer;
           p_Heading                       char(100);
           p_YLabel                        char(30);
           p_TotalItems                    int(10);
           p_MaxVal                        packed(31:2);
           p_ChartType                     char(10);
           p_YCalc                         char(10);
        end-pi;
     *================================================================
     *š   Declare data structures and variables here
     *================================================================
     * ------------------------------------------------------------------------
       /if not defined(#INDICATORS)
       /define #INDICATORS
       dcl-ds Indicators1;
           InfoRequest         ind pos(1) ;
           ExitPgm             ind pos(3) ;
           FirstPage           ind pos(17);
           LastPage            ind pos(18);
           PageDown            ind  pos(40) ;
           PageUp              ind  pos(41) ;
       end-ds ;
     /Endif
       dcl-s wDetailLine                   char(130) dim(24);
       dcl-s wLine                         int(10);
       dcl-s wTempLine                     char(130);
       dcl-s wColumn                       int(10);
       dcl-s wPage                         int(10);
       dcl-s wDetailX                      char(30) dim(140);
       dcl-s wDetailValue                  packed(15:2) dim(140);
       dcl-ds dsData    qualified based(wPointer) dim(9999);
           wXData                          char(30);
           wDataItem                       packed(31:2);
       end-ds;
       dcl-s wPointer                      pointer;
       dcl-s wMax                          packed(31:2);
       dcl-s wCount                        int(10) inz(0);
       dcl-s wStrCol                       int(10) inz(0);
       dcl-s wDeterminePages               ind inz('0');
       dcl-s wTotalPages                   int(10) inz(0);
       dcl-ds dsPage                       qualified dim(200);
           Start                           int(10);
           End                             int(10);
           Entries                         int(10);
       End-Ds;
       dcl-s wLineStr                      int(10) inz(0);
       dcl-s wLastCol                      int(10) inz(0);
       dcl-s wScreenLarge                  ind inz('0');
       dcl-c wCol_White                    const(X'22');
       //==============================================================
       Dcl-PR QsnQryModSup                 Int(10:0) extProc('QsnQryModSup');
          mode                             Char(1) const;
          modeAllowed                      Char(1) options(*OMIT);
          llhandle                         Int(10:0) const options(*OMIT);
          error                            Char(16) options(*varsize:*OMIT);
       End-PR;
       Dcl-C DS4_MODE                      '4';
       Dcl-C MODE_ALLOWED                  1;
     *====================================================================*
     *  Mainline                                                          *
     *====================================================================*
       wPointer = p_InputDS;
       wPage = 1;
       wMax = p_MaxVal;
       ROWPOS = 0;
       COLPOS = 0;
       wScreenLarge = ScreenSizeIs132();
       DoU ExitPgm = *On;
           Reset wDetailLine;
           Reset wDetailValue;
           Reset wDetailX;
           BuildScreen(wPage:wMax:p_TotalItems:p_YLabel:p_ChartType:p_YCalc);
           If wScreenLarge = *On;
               hLine = CenterText(%trim(p_Heading):%len(hLine));
               If p_TotalItems > 0;
                   exfmt main;
               Else;
                   write main;
                   exfmt ErrScreen;
                   ExitPgm = *On;
               EndIf;
           Else;
               h2Line = CenterText(%trim(p_Heading):%len(h2Line));
               If p_TotalItems > 0;
                   exfmt main2;
               Else;
                   write main2;
                   exfmt ErrScreen;
                   ExitPgm = *On;
               EndIf;
           EndIf;
           If ExitPgm = *Off;
               If wScreenLarge = *On;
                   wLastCol = wPage*(130-wLineStr);
               Else;
                   wLastCol = wPage*(78-wLineStr);
               EndIf;
               select;
               when PageUp = *On and wPage > 1;
                   wPage = wPage - 1;
               When PageDown = *On and wPage < wTotalPages;
                   wPage = wPage + 1;
               When FirstPage = *On;
                   wPage = 1;
                   FirstPage = *Off;
               When LastPage = *On;
                   wPage = wTotalPages;
                   LastPage = *Off;
               When InfoRequest = *On and CSRCOL >= wLineStr+1 and
                   CSRCol - wLineStr <= dsPage(wPage).Entries;
                   InfoRequest = *Off;
                   If wScreenLarge = *On;
                       wsPage = %trim(FLine1);
                   Else;
                       wsPage = %trim(F2Line1);
                   EndIf;
                   wsDetail1 = 'Heading:       ' + %trim(p_Heading);
                   wsDetail2 = 'X-Axis Label:  ' + %trim(wDetailX(csrcol):'1');
                   wsDetail3 = 'X-Value:       ' +
                       %trim(%editc(wDetailValue(csrcol)  :'1'));
                   wsDetail4 = 'Max Value:     ' +
                       %trim(%editc(wMax:'1'));
                   If wPage > 1;
                       wsDetail5 = 'Data point:    ' +
                           %trim(%editc(dsPage(wPage-1).End+
                           csrcol-wLineStr:'1'));
                   Else;
                       wsDetail5 = 'Data point:    ' +
                           %trim(%editc(csrcol-wLineStr:'1'));
                   EndIf;
                   exfmt info;
                   ROWPOS = CSRROW;
                   COLPOS = CSRCOL;
                   ExitPgm = *Off;
               EndSl;
           EndIf;
       EndDo;
      // ================================================================
      //  Program ends here
      // ================================================================
        *InLR = *On;
        return;
      // ================================================================
       dcl-proc BuildColumn;
       dcl-pi BuildColumn;
           pColumn                         int(10) value;
           pMaxValue                       int(20) value;
           pValue                          int(20) value;
           pXValue                         char(30) value;
       end-pi;
       dcl-s wLoopCount                    int(10) inz(0);
       dcl-s wChartValue                   int(10) inz(0);
       dcl-s wMaxRows                      int(10) inz(0);
       //
       If wScreenLarge = *On;
           wMaxRows = 23;
       Else;
           wMaxRows = 20;
       EndIf;
       wChartValue = %int((pValue/pMaxValue)*wMaxRows);
       wDetailValue(pColumn) = %dec(pValue:31:2);
       wDetailX(pColumn) = pXValue;
       If wChartValue > 0;
           For wLoopCount = wMaxRows downto (wMaxRows - wChartValue);
               If wLoopCount > 0;
                  %subst(wDetailLine(wLoopCount):pColumn:1) = '|';
               EndIf;
           EndFor;
           If wChartValue < wMaxRows;
              %Subst(wDetailLine(wMaxRows-wChartValue):pColumn:1) = '_';
           Else;
              %Subst(wDetailLine(1):pColumn:1) = '_';
           EndIf;
       EndIf;
       End-proc;
      // ================================================================
       dcl-proc BuildYLines;
       dcl-pi BuildYLines                  int(10);
           pMaxValue                       int(20) value;
           pYType                          char(10) value;
           pYLabel                         char(30) value;
           pYCalc                          char(10) value;
       end-pi;
       dcl-s wLoopCount                    int(10) inz(0);
       dcl-s wDivisor                      int(10) inz(0);
       dcl-s wTempValue                    packed(15:2) inz(0);
       dcl-s wUnderLine                    char(130) inz(*all'-');
       dcl-s wUnderLine2                   char(130) inz(*all'_');
       dcl-s wUnderLine3                   char(130) inz(*all'=');
       dcl-s wLength                       int(10) inz(0);
       dcl-s wEndOfDesc                    int(10) inz(0);
       //
       yDesc = pYLabel;
       y2Desc = pYLabel;
       Select;
       When pYType = '*PCT' and wScreenLarge = *On;  // Y-bar will be percentage
           wDetailLine(1)  = '100%  :' + wCol_White + %trim(wUnderLine);
           wDetailLine(6)  = ' 75%  :' + wCol_White + %trim(wUnderLine);
           wDetailLine(12) = ' 50%  :' + wCol_White + %trim(wUnderLine);
           wDetailLine(17) = ' 25%  :' + wCol_White + %trim(wUnderLine);
           wDetailLine(23) = '  0%  :' + wCol_White + %trim(wUnderLine2);
           wDetailLine(24) = '        ' +
               %trim(wUnderLine3);
           For wLine = 1 to 23;
               %subst(wDetailLine(wLine):7:2) = ':' + wCol_White;
           Endfor;
           wEndOfDesc = 8;
       When pYType = '*NORMAL' and wScreenLarge = *On;  // Determine Min/Max/25%/50%/75%
           select;         //1234567890123
           when pMaxValue >= 1000000000000 and pYCalc = '*TB';
               wDivisor = 1024*1024*1024*1024;
               yDesc = 'Size in TB';
           when pMaxValue >= 1000000000 and pYCalc = '*GB';
               wDivisor = 1024*1024*1024;
               yDesc = 'Size in GB';
           when pMaxValue >= 1000000 and pYCalc = '*MB';
               yDesc = 'Size in MB';
               wDivisor = 1024*1024;
           when pMaxValue >= 1000 and pYCalc = '*KB';
               yDesc = 'Size in KB';
               wDivisor = 1024;
           Other;
               wDivisor = 1;
           EndSl;
           wLength = %len(%trim(FormatNumber(%dec(pMaxValue/wDivisor:31:2))));
           wEndOfDesc = wLength + 4;
           wDetailLine(1) =
               %trim(FormatNumber(%dec(pMaxValue/wDivisor:31:2)));
           %subst(wDetailLine(1):wEndOfDesc+1:131-wEndOfDesc-1) =
               %trim(wUnderLine);
           wDetailLine(6) =
               %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.75:31:2)));
           %subst(wDetailLine(6):wEndOfDesc+1:131-wEndOfDesc-1) =
               %trim(wUnderLine);
           wDetailLine(12) =
               %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.50:31:2)));
           %subst(wDetailLine(12):wEndOfDesc+1:131-wEndOfDesc-1) =
               %trim(wUnderLine);
           wDetailLine(17) =
               %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.25:31:2)));
           %subst(wDetailLine(17):wEndOfDesc+1:131-wEndOfDesc-1) =
               %trim(wUnderLine);
           wDetailLine(23) = '0';
           %subst(wDetailLine(23):wEndOfDesc+1:131-wEndOfDesc-1) =
               %trim(wUnderLine2);
           %Subst(wDetailLine(24):wEndOfDesc+1:131-wEndOfDesc-1)=
               %trim(wUnderLine3);
           For wLine = 1 to 23;
               %subst(wDetailLine(wLine):wEndOfDesc-1:2) = ':' +
                   wCol_White;
           Endfor;
       When pYType = '*PCT' and wScreenLarge = *Off;  // Y-bar will be percentage
           wDetailLine(1)  = '100%  : ' + %trim(wUnderLine);
           wDetailLine(5)  = ' 75%  : ' + %trim(wUnderLine);
           wDetailLine(10) = ' 50%  : ' + %trim(wUnderLine);
           wDetailLine(15) = ' 25%  : ' + %trim(wUnderLine);
           wDetailLine(20) = '  0%  : ' + %trim(wUnderLine2);
           wDetailLine(21) = '        ' +
               %trim(wUnderLine3);
           For wLine = 1 to 20;
               %subst(wDetailLine(wLine):7:2) = ':' + wCol_White;
           Endfor;
           wEndOfDesc = 8;
       When pYType = '*NORMAL' and wScreenLarge = *Off;  // Determine Min/Max/25%/50%/75%
           select;         //1234567890123
           when pMaxValue >= 1000000000000 and pYCalc = '*TB';
               wDivisor = 1024*1024*1024*1024;
               y2Desc = 'Size in TB';
           when pMaxValue >= 1000000000 and pYCalc = '*GB';
               wDivisor = 1024*1024*1024;
               y2Desc = 'Size in GB';
           when pMaxValue >= 1000000 and pYCalc = '*MB';
               y2Desc = 'Size in MB';
               wDivisor = 1024*1024;
           when pMaxValue >= 1000 and pYCalc = '*KB';
               y2Desc = 'Size in KB';
               wDivisor = 1024;
           Other;
               wDivisor = 1;
           EndSl;
           wLength = %len(%trim(FormatNumber(%dec(pMaxValue/wDivisor:31:2))));
           wEndOfDesc = wLength + 4;
           wDetailLine(1) =
               %trim(FormatNumber(%dec(pMaxValue/wDivisor:31:2)));
           %subst(wDetailLine(1):wEndOfDesc+1:79-wEndOfDesc-1) =
               %trim(wUnderLine);
           wDetailLine(5) =
               %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.75:31:2)));
           %subst(wDetailLine(5):wEndOfDesc+1:79-wEndOfDesc-1) =
               %trim(wUnderLine);
            wDetailLine(10) =
               %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.50:31:2)));
           %subst(wDetailLine(10):wEndOfDesc+1:79-wEndOfDesc-1) =
               %trim(wUnderLine);
           wDetailLine(15) =
               %trim(FormatNumber(%dec(pMaxValue/wDivisor*0.25:31:2)));
           %subst(wDetailLine(15):wEndOfDesc+1:79-wEndOfDesc-1) =
               %trim(wUnderLine);
           wDetailLine(20) = '0';
           %subst(wDetailLine(20):wEndOfDesc+1:79-wEndOfDesc-1) =
               %trim(wUnderLine2);
           %Subst(wDetailLine(21):wEndOfDesc+1:79-wEndOfDesc-1)=
               %trim(wUnderLine3);
           For wLine = 1 to 20;
               %subst(wDetailLine(wLine):wEndOfDesc-1:2) = ':' + wCol_White;
           Endfor;
       EndSl;
       Return wEndOfDesc;
       End-proc;
      // ================================================================
       dcl-proc FormatNumber;
       dcl-pi FormatNumber                 char(20);
           pInputValue                     packed(15:2) value;
       end-pi;
       dcl-s wTempValue                    char(20) inz(' ');
       //
       If pInputValue < 1 and pInputValue > 0;
           wTempValue = '0' + %trim(%editc(pInputValue:'J'));
       Else;
           wTempValue = %trim(%editC(pInputValue:'J'));
       EndIf;
       Return wTempValue;
       End-proc;
      // ================================================================
       dcl-proc BuildScreen;
       dcl-pi BuildScreen;
           pPage                           int(10) value;
           pMaxValue                       packed(31:2) value;
           pTotalItems                     int(10)  value;
           pYLabel                         char(30) value;
           pChartType                      char(10) value;
           pYCalc                          char(10) value;
       end-pi;
       dcl-s wLineCount                    int(10) inz(0);
       dcl-s wTotalColumns                 int(10) inz(0);
       dcl-s wPageCount                    int(10) inz(0);
       dcl-s wStrCol                       int(10) inz(0);
       dcl-s wEndCol                       int(10) inz(0);
       dcl-s wTempNum                      packed(31:2) inz(0);
       dcl-s wMaxCol                       int(10) inz(0);
           If wScreenLarge = *On;
               wMaxCol = 130;
           Else;
               wMaxCol = 78;
           EndIf;
           wLineStr = BuildyLines(pMaxValue:pChartType:pYLabel:pYCalc);
           If wDeterminePages = *Off;
               wDeterminePages = *On;
               wTotalColumns = wMaxCol - wLineStr;
               wTotalPages = %inth(pTotalItems/wTotalColumns);
               wStrCol = 1;
               If wTotalPages = 0;
                   wTotalPages = 1;
               EndIf;
               For wPageCount = 1 to wTotalPages;
                   dsPage(wPageCount).Start = wStrCol;
                   wEndCol = wStrCol + wTotalColumns - 1;
                   If wEndCol > pTotalItems;
                       wEndCol = pTotalItems;
                   EndIf;
                   dsPage(wPageCount).End = wEndCol;
                   dsPage(wPageCount).Entries = wEndCol - wStrCol + 1;
                   wStrCol = wEndCol + 1;
               EndFor;
           EndIf;
           wStrCol = dsPage(pPage).Start;
           wEndCol = dsPage(pPage).End;
           For wLineCount = 0 to (wMaxCol - wLineStr - 1);
               If dsData(wLineCount+wStrCol).wDataItem  < 0;
                   wTempNum = 0;
               Else;
                   wTempNum = dsData(wLineCount+wStrCol).wDataItem;
               EndIf;
               BuildColumn(wLineStr+wLineCount+1:pMaxValue:
                   wTempNum:
                   dsData(wLineCount+wStrCol).wxData);
           EndFor;
           BuildDLines();
           If wScreenLarge = *On;
               EvalR FLine1 = 'Page ' + %trim(%editc(wPage:'1')) + ' of ' +
               %trim(%editc(wTotalPages:'1')) + ' page(s)';
           Else;
               EvalR F2LIne1= 'Page ' + %trim(%editc(wPage:'1')) + ' of ' +
               %trim(%editc(wTotalPages:'1')) + ' page(s)';
           EndIf;
       End-proc;
      // ================================================================
      // ================================================================
       dcl-proc BuildDlines;
       If wScreenLarge = *On;
           dline01 = wDetailLine(1);
           dline02 = wDetailLine(2);
           dline03 = wDetailLine(3);
           dline04 = wDetailLine(4);
           dline05 = wDetailLine(5);
           dline06 = wDetailLine(6);
           dline07 = wDetailLine(7);
           dline08 = wDetailLine(8);
           dline09 = wDetailLine(9);
           dline10 = wDetailLine(10);
           dline11 = wDetailLine(11);
           dline12 = wDetailLine(12);
           dline13 = wDetailLine(13);
           dline14 = wDetailLine(14);
           dline15 = wDetailLine(15);
           dline16 = wDetailLine(16);
           dline17 = wDetailLine(17);
           dline18 = wDetailLine(18);
           dline19 = wDetailLine(19);
           dline20 = wDetailLine(20);
           dline21 = wDetailLine(21);
           dline22 = wDetailLine(22);
           dline23 = wDetailLine(23);
           dline24 = wDetailLine(24);
       Else;
           d2line01 = wDetailLine(1);
           d2line02 = wDetailLine(2);
           d2line03 = wDetailLine(3);
           d2line04 = wDetailLine(4);
           d2line05 = wDetailLine(5);
           d2line06 = wDetailLine(6);
           d2line07 = wDetailLine(7);
           d2line08 = wDetailLine(8);
           d2line09 = wDetailLine(9);
           d2line10 = wDetailLine(10);
           d2line11 = wDetailLine(11);
           d2line12 = wDetailLine(12);
           d2line13 = wDetailLine(13);
           d2line14 = wDetailLine(14);
           d2line15 = wDetailLine(15);
           d2line16 = wDetailLine(16);
           d2line17 = wDetailLine(17);
           d2line18 = wDetailLine(18);
           d2line19 = wDetailLine(19);
           d2line20 = wDetailLine(20);
           d2line21 = wDetailLine(21);
       EndIf;
       End-proc;
      // ====================================================================*
      //   Subroutine.... ScreenSizeIs132                                    *
      //   Description... Check if the screen is configured for 132 Chars    *
      //
      //   Parameters:
      //
      // ‚Example:
      //
      // šIf ScreenSizeIs132() = *Off;
      //      SndCompMsg('Screen is NOT configured for 132 chars');
      // šElse;
      //      SndCompMsg('Object is configured for 132 chars');
      // šEndIf;
      // ====================================================================*
       Dcl-Proc ScreenSizeIs132            export;
       Dcl-PI ScreenSizeIs132              ind;// Return Variable
       End-PI;
       // Check the screen size now
              If (QsnQryModSup(DS4_MODE:*OMIT:*OMIT:*OMIT) <> MODE_ALLOWED);
                 Return *Off;
              Else;
                 Return *On;
              EndIf;
       End-Proc;
     //********************************************************************
      //  ===================================================================================
      //   Center Text in a string
      //     Parm:    Input String varchar(32767)
      //              String Length (untrimmed)
      //     Returns: Output String varchar(32000)
      //  ===================================================================================
      //  EXAMPLE:
      //              wTestString = CenterText(wTestString):%len(wTestString));
      //
      //  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        dcl-proc CenterText              export;
           dcl-pi CenterText             char(32767);
              p_InputString              char(32767) const OPTIONS(*VARSIZE);
              p_Stringlength             int(10) value;
           end-pi;
      //
           dcl-s wStrPos                 int(10) inz(0);
           dcl-s wTempLen                int(10) inz(0);
           dcl-s wOutputString           char(32767) inz(' ');
              wTempLen = %len(%trim(%subst(p_InputString:1:p_StringLength)));
              wStrPos = ((p_StringLength - wTempLen)/2) + 1;
               %Subst(wOutputString:wStrPos:wTempLen) =
                   %trim(%subst(p_InputString:1:p_StringLength));
               Return wOutputString;
        end-proc;