I have a new goal in life. Well at least I have a new goal as it relates to my job. I am a firm believer in RPG's ability to meet current day business needs. This also means I am a firm believer in not jumping ship to platforms like Microsoft/.NET just because they have more out-of-the-box glitter. After all, most shops have invested millions in hardware, software and personnel in and around the iSeries -- it would make sense to expend a reasonable amount of effort to not only make the platform survive, but also thrive.
Some would say that they're skeptical of RPG's ability to do much outside of a green screen. But I say there is very little RPG can't do. To back up my statement, I am going to show how to create graphical pie, bar and line charts with RPG. Now, I could create the necessary code from scratch, but that just wouldn't make sense because there are free code-sets out there that allow me to completely bypass that portion. I will be making use of JFreeChart to build the charts and simply put an RPG facade over their API's to make the creation of charts seamless.
Now you might say "why is Java OK and Microsoft/.NET gets a bad rap?" Good question. It is because I am a proponent of using Java around the fringe edges of your main RPG application suite. Also, because .NET doesn't natively run on the iSeries, I rule it out pretty fast. I have found that a healthy balance of RPG and Java on the iSeries provides me with many opportunities to retain investment in the platform. IMO, a healthy balance of Java for an RPG shop would be a ratio of around 1% to 99%. Ok, enough preaching to the choir.
The tool I am describing in this text is called the "RPG Chart Engine" and is used to produce charts like the following shown in Figure 1. RPG Chart Engine is a free and open source tool I wrote and make available via my personal website, www.mowyourlawn.com.
By simply making some straightforward calls to the RPG Chart Engine service program you can accomplish charts like the above and more (see notes at bottom for links to more examples). Below is the RPG code to produce the pie chart in Figure 1. Yes, that's right, only three easy-to-use API calls are required! Of course the values in this example program are hard coded for brevity sake and normally data would be pulled from your DB2 files.
H dftactgrp(*no) bnddir('RCEBND')
D uid s 15p 0
*on: *on: *on: '/home/aaron/pie123.jpg': 700: 300);
RCE_addPieChartData(uid: 'January': 3100.50);
RCE_addPieChartData(uid: 'February': 5100.50);
RCE_addPieChartData(uid: 'March': 7100.50);
RCE_addPieChartData(uid: 'April': 1100.50);
*inlr = *on;
Let me explain the above code a little so it is understood what's happening. Starting at the top you can see a binding directory of RCEBND used to aid in finding the RCESV service program at compile time. Next RCECp is copied in which contains the necessary prototypes and variables to accomplish the various calls to the RPG Chart Engine. It should be noted there are two DB2 tables that receive data from the RPG Chart Engine sub procedures behind the scenes and they are called RCEHDRPF and RCEDTAPF. Each of these tables have their records made unique by specifying an integer column with a number that is pulled from a data area. A unique integer is returned when RCE_newPieChart is called and is stored in variable UID. The variable UID then needs to be specified on all subsequent calls to RCE_addPieChartData so the pie chart data can be matched up with the record in RCEHDRPF. Next make multiple calls to RCE_addPieChartData specifying the UID of this chart along with the actual data this chart should be based on (e.g. Janauary, 3100.50). A question I get asked a lot at this point is "could I wrap a DOW loop around the call to RCE_addPieChartData so that I can specify DB columns as parameters?" The answer is yes!
There are three types of charts that can currently be created with RPG Chart Engine -- pie, bar and x/y line charts. Above the pie chart creation process was described, and the bar and x/y line charts are pretty much the same, just a few different parameters. Take a look at program T_RCE (Test RPG Chart Engine) to see an example of creating all three types of charts.
Once you have executed RCE_newPieChart to set header level data and executed RCE_addPieChartData to enter all detail level data you are ready to execute the RCE_run sub procedure. This does a whole bunch of work behind the scenes. Basically, the RCE_run sub procedure is going to send a message to keyed data queue DQRCE. Listening for input entries on DQRCE is the Java side of RPG Chart Engine. When the Java receives an entry it uses the unique id of the DB2 records to obtain access to all the necessary information used to build the graphical chart. After it has created the jpg file it will write a data queue entry back into DQRCE that the RPG Chart Engine service program is listening/waiting for, and once received will return control to your calling program.
The "big picture" of how all the pieces fit together is detailed in Figure 2.
The numbered steps in Figure 2 are:
- Make calls to RCE_* sub procedures which in turn do WRITE's to RCEHDRPF and RCEDTAPF.
- Execute RCE_run which in turn writes a record with a unique key to data queue DQRCE. The RCE RPG program immediately goes to wait for a response on the same data queue for the same unique key.
- Java program RPGChartEngine.java is listening for new entries on data queue DQRCE.
- Java uses unique key from data queue entry to do an SQL select out to tables RCEHDRPF and RCEDTAPF to obtain the information necessary to produce the appropriate graph.
- Using the information in RCEHDRPF the Java program knows which type of chart to create and uses data from RCEDTAPF to produce the data detail aspect of the chart. The result is placed in the IFS at the location your RPG program specified. If debugging is turned on the Java program will also trickle statements into that file during processing.
- Java program completes and writes the result of the chart creation back to the data queue.
- RPG program receives response and continues processing based on the result.
Crazy! That process may seem kind of complicated, but the best part about it is that you don't need to care about those details. Instead you just need to install RPG Chart Engine and run a prompt-able command to start the Java that waits for messages on the data queue! Note the below STRRCE only needs to be started once and will service all users/jobs on your iSeries. In this way each user will not incur the JVM startup costs of invoking Java.
Here is a sample of the necessary information to specify on the STRRCE (Start RPG Chart Engine) command:
Start RPG Chart Engine (STRRCE)
Type choices, press Enter.
Host . . . . . . . . . . . . . . > LOCALHOST
User . . . . . . . . . . . . . . > *CURRENT Character value
Password . . . . . . . . . . . . > *CURRENT Character value
Data Library . . . . . . . . . . > MYLIB Character value
Data Queue Library . . . . . . . > MYLIB Character value
Data Queue Name . . . . . . . . > DQRCE Character value
Data Queue Wait . . . . . . . . > -1 Character value
Debug Mode . . . . . . . . . . . > TRUE TRUE, FALSE
Debug Folder . . . . . . . . . . > '/java/rce/
Here is the result:
STRRCE HOST(LOCALHOST) USER(*CURRENT) PW(*CURRENT) DTALIB(MYLIB)
DQLIB(MYLIB) DQNAM(DQRCE) DQWAIT(-1) DBG(TRUE) DBGFLR('/java/rce/')
Command STRRCE calls CL program STRRCEC which submits a RUNJVA job to QBATCH. This initializes the Java process and starts it waiting on data queue DQRCE. For an example of how this is done:
PARM(&HOST &USER &PW &DTALIB &DQLIB &DQNAM &DQWAIT
&DBG &DBGFLR) +
JOB(RCERUNJVA) PROP((java.version 1.4)(java.awt.headless true))
Now that you know how the tool works the next step would be to install it on your iSeries. This is a two part process as there is both RPG and Java included in the zip download. Detailed instructions are included in the download readme.txt, but in general what needs to happen is upload a *SAVF to QGPL/RCE.SAVF and then upload the Java jar files to /java/rce in the IFS. Go here and click on the RPG Chart Engine link to download.
The RPG Chart Engine is in it's first version and as mentioned earlier it only supports three charts -- RCE_newPieChart, RCE_newBarChart, RCE_newXYLineChart. New charts can be added fairly easily by adding a new sub procedure to the RCEFN program and modifying the RPGChartEngine.java source file (included in download). I built the underlying DB2 tables, RCEHDRPF and RCEDTAPF, to facilitate holding data for any of the other charts supported (in theory). The vast array of other charts can be seen at www.jfree.org -- select the "JFreeChartDemo (web start)" link to get the full picture of different charts. Please feel free to contact me if you have a particular chart need and would like help creating it.
That's it for now. Stay tuned for more open source tooling from www.mowyourlawn.com before years end!
ABOUT THE AUTHOR: Aaron Bartell is a RPG and Java developer for Krengeltech.com. He is also the lead developer of the popular RPG-XML Suite, which aids RPG programmers in getting up to speed fast with xml web services on the iSeries with zero Java involved. Aaron can be contacted at firstname.lastname@example.org.
This was first published in June 2008