Creating a Map driven by server-side code

 

Overview

This page provides a step-by-step example on how to use an RPG program to populate data for a map widget in a Rich Display File.

To follow the instructions you will need access to an installation of Profound UI with Visual Designer. Also, you should know how to create and compile an RPG source member in a library. Finally, you should know how to create a database file from which you will pull map data. In this tutorial, we provide sample RPG program code for populating the file.

Create the Rich Display File

In this section, we will create a new Rich Display file and add some content.

First, create a new Display File from Profound's Visual Designer. Next, name the screen MAPRF. Optionally, provide a description and title.

Add a Map

We will add a map widget by finding it in the Widgets toolbox and dragging it onto the designer canvas. Find the Map widget:

Click and drag the map onto the canvas.

 

In this tutorial we will use data for US States, so we need to set the map type to "usa":

Hint: to use another map type, you can find a complete list on the FusionMaps page; also read the section in the Maps page about map type.

 

Next, we need to specify from where the map gets its data. We will use an RPG program to read from a database and generate the map data in XML format, so find the property called, "chart xml", and click on it to make the Binding button appear:

Click on the Binding button indicated in the above image to get the binding panel. In this panel you can specify the name of an RPG variable that will contain the XML text for the chart. Enter "MAPXML" as the Field Name, and enter "10000" as the Length:

Press OK, and you'll see that the chart xml property is bound to a variable named MAPXML, indicated by the green text.

Note: the variable MAPXML is defined in the Display File; so later in the RPG, we will reference it but not define it.

Add and Bind Buttons

The next step in Visual Designer is to add some control buttons and bind them to variables.

In this example, we used the "Secondary" and "Cancel" button from the Blueprint Widget Set. Look in the "Widget Sets" tab and open the Blueprint Widget Set. Here, you should see a "Secondary" and a "Cancel" button. We'll use the "Cancel" button to exit the page, closing the RPG program. And we'll use the "Secondary" button to refresh the page.

To add the buttons, click and drag each onto the canvas. You can rename a button by double-clicking on it and typing a new label:

After we place and label the buttons, we'll need to bind the response to a variable. That is, when the user clicks on a button, an indicator in RPG will be set. We will code the RPG program to respond according to the user's action.

Click on the Refresh button to view its properties in the lower-right section of the screen. Look for a property named, response, which is found under the Identification group at the top of the property list.

Click on the Binding button, as indicated in the above image. When the binding panel appears, enter "BTNREFRESH" as the Field Name, then press OK.

Now do the same for the Exit button, and use "BTNEXIT" as the Field Name.

 

Save the Member

Next, save the Display file as a source member somewhere, such as MYLIB/QDDSSRC. Name the member, "RPGDBMAPD". We will refer to this name in our RPG code later.

Now we are ready to compile the display file. Click on the "Compile..." button located near the top of the screen:

You are prompted to confirm you are creating a Rich Display File having the name and library you specified:

Click Compile, and after a moment you should see a message indicated the file compiled successfully.

Create Sample Data

In this tutorial section you can use the IBM tool you feel comfortable with; e.g. SEU or Rational Developer.

Create a physical file named, USINCOMEP, in a library of your choice. Define the data to have a 2-character column named, "statecodes", and a 5 character column named, "statedata".

After that, copy the following sample RPG code into a RPGLE source file.

FILLUSDBR.RPGLE
* Fill a database record of US state income with values from an array. * H DFTACTGRP(*NO) FUSINCOMEP UF A E K DISK Dstatecodes S 2A DIM(52) Dstatedata S 5A DIM(52) Di S 3i 0 statecodes(1) = 'AL'; statecodes(2) = 'AK'; statecodes(3) = 'AZ'; statecodes(4) = 'AR'; statecodes(5) = 'CA'; statecodes(6) = 'CO'; statecodes(7) = 'CT'; statecodes(8) = 'DE'; statecodes(9) = 'DC'; statecodes(10) = 'FL'; statecodes(11) = 'GA'; statecodes(12) = 'HI'; statecodes(13) = 'ID'; statecodes(14) = 'IL'; statecodes(15) = 'IN'; statecodes(16) = 'IA'; statecodes(17) = 'KS'; statecodes(18) = 'KY'; statecodes(19) = 'LA'; statecodes(20) = 'ME'; statecodes(21) = 'MD'; statecodes(22) = 'MA'; statecodes(23) = 'MI'; statecodes(24) = 'MN'; statecodes(25) = 'MS'; statecodes(26) = 'MO'; statecodes(27) = 'MT'; statecodes(28) = 'NE'; statecodes(29) = 'NV'; statecodes(30) = 'NH'; statecodes(31) = 'NJ'; statecodes(32) = 'NM'; statecodes(33) = 'NY'; statecodes(34) = 'NC'; statecodes(35) = 'ND'; statecodes(36) = 'OH'; statecodes(37) = 'OK'; statecodes(38) = 'OR'; statecodes(39) = 'PA'; statecodes(40) = 'RI'; statecodes(41) = 'SC'; statecodes(42) = 'SD'; statecodes(43) = 'TN'; statecodes(44) = 'TX'; statecodes(45) = 'UT'; statecodes(46) = 'VT'; statecodes(47) = 'VA'; statecodes(48) = 'WA'; statecodes(49) = 'WV'; statecodes(50) = 'WI'; statecodes(51) = 'WY'; statecodes(52) = 'PR'; statedata(1) = '22.8'; statedata(2) = '47.5'; statedata(3) = '50.6'; statedata(4) = '51.9'; statedata(5) = '53.6'; statedata(6) = '54'; statedata(7) = '54'; statedata(8) = '54'; statedata(9) = '54.5'; statedata(10) = '55.3'; statedata(11) = '55.4'; statedata(12) = '55.8'; statedata(13) = '56'; statedata(14) = '56'; statedata(15) = '57.3'; statedata(16) = '57.4'; statedata(17) = '58.6'; statedata(18) = '58.8'; statedata(19) = '59.3'; statedata(20) = '59.5'; statedata(21) = '60.2'; statedata(22) = '60.4'; statedata(23) = '60.7'; statedata(24) = '60.9'; statedata(25) = '61'; statedata(26) = '62.6'; statedata(27) = '64.3'; statedata(28) = '64.9'; statedata(29) = '65.6'; statedata(30) = '65.9'; statedata(31) = '66.1'; statedata(32) = '66.3'; statedata(33) = '67.7'; statedata(34) = '68'; statedata(35) = '69.1'; statedata(36) = '69.8'; statedata(37) = '70.5'; statedata(38) = '70.7'; statedata(39) = '71.1'; statedata(40) = '71.8'; statedata(41) = '71.9'; statedata(42) = '72.2'; statedata(43) = '74.4'; statedata(44) = '75.8'; statedata(45) = '78.5'; statedata(46) = '78.9'; statedata(47) = '79.5'; statedata(48) = '81.7'; statedata(49) = '83.9'; statedata(50) = '85.6'; statedata(51) = '86.4'; statedata(52) = '87.1'; FOR i = 1 to 52; USSTATECD = statecodes(i); USINCOME = %dec(statedata(i):3:1); Write USINCOMER; ENDFOR; *InLr = *On;   return;

 

Edit your library list, if necessary, to include the library containing the file you just created. Then compile the RPG program, and run it.

Verify that the DB file was populated. For example, run the STRSQL command, and enter this query: SELECT * FROM USINCOMEP

You should see something like this image:

Now we are ready for the RPG program.

Create an RPG program

In this section we will create the RPG program to read from the database, generate the XML, and respond to user button clicks.

Create a new RPG source member, named "XMLDBMAPR", and place it in the library object of your choice. A good choice is "QRPGLESRC".

Copy the code below, and paste it into your source member:

XMLDBMAPR
************************************************************************* * Program Name: XMLDBMAPR ************************************************************************* ctl-opt DFTACTGRP(*NO); dcl-f RPGDBMAPD WORKSTN Handler('PROFOUNDUI(HANDLER)'); dcl-f USINCOMEP Disk(*Ext) keyed usage(*input); dcl-s MAPDATA varchar(10000); // Initialize bound properties. BTNEXIT = *Off; // Loop until the user clicks Exit button. DoU BTNEXIT = *On; // Clear the XML data each iteration. MAPDATA = ''; // Read each record from the file. SetLL *loval USINCOMER; Read USINCOMER; DoW not %eof(USINCOMEP); // Add the record's data to the "entity" XML tag. MAPDATA += '<entity id="' + USSTATECD + '" value="'; MAPDATA += %char(USINCOME) + '" />'; Read USINCOMER; EndDo; // Create an XML document for the map. MAPXML = '<map caption="Median Family Income - 2011-2013"' + ' legendPosition="BOTTOM" showlabels="1" showToolTip="1" >' + '<colorRange> ' + '<color minValue="0" maxValue="50" ' + ' displayValue="Under $50K" color="AA3939"/>' + '<color minValue="50.001" maxValue="65" ' + ' displayValue="$50K to $65K" color="AAA539" />' + '<color minValue="65.001" maxValue="75" ' + ' displayValue="$65K to $75K" color="522B72" /> ' + '<color minValue="75.001" maxValue="1000" ' + ' displayValue="$Over $75K" color="2D882D" /> ' + '</colorRange>' + '<data>' + MAPDATA + '</data></map>'; // Output the XML data to webserver. ExFmt MAPRF; EndDo; //end loop until Exit clicked. *InLr = *On; return;

 

Alternately, here is the program with fixed-form H, F, and D specs:

XMLDBMAPR Fixed Form
************************************************************************* * Program Name: XMLDBMAPR ************************************************************************* H DFTACTGRP(*NO) FRPGDBMAPD CF E WORKSTN Handler('PROFOUNDUI(HANDLER)') FUSINCOMEP IF E K DISK DMAPDATA S 10000A VARYING   // Initialize bound properties. BTNEXIT = *Off; // Loop until the user clicks Exit button. DoU BTNEXIT = *On; // Clear the XML data each iteration. MAPDATA = ''; // Read each record from the file. SetLL *loval USINCOMER; Read USINCOMER; DoW not %eof(USINCOMEP); // Add the record's data to the "entity" XML tag. MAPDATA += '<entity id="' + USSTATECD + '" value="'; MAPDATA += %char(USINCOME) + '" />'; Read USINCOMER; EndDo; // Create an XML document for the map. MAPXML = '<map caption="Median Family Income - 2011-2013"' + ' legendPosition="BOTTOM" showlabels="1" showToolTip="1" >' + '<colorRange> ' + '<color minValue="0" maxValue="50" ' + ' displayValue="Under $50K" color="AA3939"/>' + '<color minValue="50.001" maxValue="65" ' + ' displayValue="$50K to $65K" color="AAA539" />' + '<color minValue="65.001" maxValue="75" ' + ' displayValue="$65K to $75K" color="522B72" /> ' + '<color minValue="75.001" maxValue="1000" ' + ' displayValue="$Over $75K" color="2D882D" /> ' + '</colorRange>' + '<data>' + MAPDATA + '</data></map>'; // Output the XML data to webserver. ExFmt MAPRF; EndDo; //end loop until Exit clicked. *InLr = *On; return;

 

The specs explained:

  • DFTACTGRP(*NO) is required for all Profound UI programs.

  • F spec for RPGDBMAPD declares the Rich Display File™.

  • Handler('PROFOUNDUI(HANDLER)') enables RPG Open Access and identifies Profound UI as the RPG OA handler

You may have noticed these same names from the display file:

  • MAPRF is the name we gave the screen.

  • MAPXML is the name of the variable we Bound the map widget to.

  • BTNEXIT is the name of the indicator we bound the Exit button to.

 

Next, compile the RPG program, and continue to the next section.

Run the Program

This section explains two ways to run the program; one requires creation of a CL program. We'll first explain the method that doesn't require a CL program.

Run from Genie Screen

For this option, you will log into the IBM i using a Genie skin, set your library list, and call the program.

Starting at the Profound UI welcome screen on your IBM i, launch a genie skin:

  • Click the plus sign beside "Launch Genie Skin" to expand the list of skins.

  • Click on any skin you prefer to launch the skin in a new browser window or tab.

  • When prompted, sign into the IBM i with your username and password.

Next, add PROFOUNDUI to your library list:

ADDLIBLE LIB(PROFOUNDUI)

Also, add the library containing the RPG program and the display file to your list:

ADDLIBLE LIB(MYLIBRARY)

Finally, call the program:

CALL PGM(XMLDBMAPR)

You should see the map loaded inside of a browser page:

You can click refresh to reload the map from the database. Clicking Exit will close the page and return you to the Genie environment.

Notes:

  • If you change anything in Visual Designer, you'll need to recompile the display file. You won't see the changes until you exit and call the program again.

  • If you log out of the Genie session, then you'll need to set your library list again to run the program.

Run from Rich Display Session

This method requires us to create a CL program, because we can't interact with the library list in a Rich Display environment.

In your preferred code editor, create a CL source member named, XMLDBMAPC, and place it in the QCLLESRC object. Put this code in the member:

XMLDBMAPC

Note: you'll want to replace "MYLIBRARY" with the name of whichever library your RPG program and Display file are found in. This code presumes they are in the same library.

Compile the CL source, and open Profound's Visual Designer in your browser. When a Rich Display session starts, the same program is called each time. We will set our CL program to be the startup program.

Click on the Launch button to view a drop-down menu:

Click on the "Maintain Initial Programs..." option to get a panel for setting the program that loads when you start a Rich Display Session:

If you don't see your username, click on the plus icon to add a new row; enter your username in the first column.

Then, you'll want to set the value in the "Program" column to "XMLDBMAPC", and set the appropriate library. You may want to first write down the original values in case you had a different initial program and want to restore it later.

Click save, and you are ready to start a new session.

Click on the Launch button again, and this time click on "Launch Session". A Profound UI session should start in a new browser window.

Enter your username and password, and click Sign On:

Now you should see your Rich Display program on the page:

Notes:

  • If you change anything in Visual Designer, you'll need to recompile the display file. You won't see the changes until you exit and start the program again.

  • If you click Exit, you are returned to the sign on screen. You can change the URL from /profoundui/start to /profoundui/auth/start to avoid logging in repeatedly.

  • You can load your CL program from a Genie screen with this command: CALL MYLIBRARY/XMLDBMAPC. Replace MYLIBRARY with the appropriate library.

  • Instead of launching a session from withing Visual Designer, you can launch one from the Welcome screen:

 

Adding Links to the Map

Note: The example provided on this page uses an older style of XML that FusionCharts still supports. Maps using this XML will render. However, for a map to support the "chart response" or "onchartclick" properties, Profound UI only supports the newer form of XML. See Maps under the section: "Adding Links to XML and JSON Charts" for the valid XML.

Summary

This tutorial illustrated how to:

  • Create a Rich Display file with a map

  • Generate a sample map data file

  • Create an RPG program to read the data file, and generate XML code for the map.

  • Run the program in Genie.

  • Create a CL program to run the program in a Rich Display session.

Using these instructions, you should be able to use different map types and data. For different map types and options, read further in the Maps article.