Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member


One of the things I really (really, really) like about SAP Screen Personas 3 is the much (much, much) improved scripting. It still retains the ability for non-programmers to do basic things easily, via the recorder and object inspector tools, while allowing programmers to do much more advanced things than were possible in Personas 2 scripting. One of the things I've been experimenting with recently is using SAPUI5 controls within Personas flavours. If you saw my talk at TechEd you'll have seen a flavour that incorporated a UI5 table. That will be the subject of a subsequent blog. This blog was inspired by an Expert Networking session given by klaus.keller at TechEd Barcelona last week, where he showed a UI5 chart embedded in a Personas screen. Obviously the first thing I did when I got back to the office was figure out how to do that, and then think about where it might be useful. The example below is the Personas admin transaction, and specifically the migration tool for converting Personas 2 flavours to Personas 3. I've used the chart to give a graphical representation of progress in migrating your flavours. It looks like this:



As you can see, the chart automatically updates as changes are made in the transaction. Initially there are no flavours marked as successfully migrated, but as I do that the chart updates to match. I don't imagine it would be too hard to think of similar examples within business transactions, where a chart could be used to indicate, perhaps, progress through a payment plan, or received vs. outstanding items on a purchase order. Or maybe you could use a bar chart to show a customer's credit exposure vs credit limit when creating a sales order in VA01? I'd love to hear suggestions for other uses - please add them in the comments below!

So how do you do this? As far as the Personas screen editor is concerned the chart lives in an HTMLviewer control, so you need to add that in an appropriate place on the screen. In the above example I made the table narrower to make room and you may well need to make similar layout changes to accommodate your chart. Everything else happens via scripting. There are three parts to the scripting needed for this - first grab the data from wherever it lives, reformat (filtering, totalling, etc.) the data if necessary for the chart and finally create the chart based on that data. Let's look at those steps one by one.

Copying data from a table in Personas 3 is a slightly complex process, but it is well described in this wiki page - Copying Table data into a variable. I just copied the code from there with no changes, so I won't reproduce it here. This code gives me a JavaScript array called "contents" with one object per row of the table, and each object having fields matching the table columns. I need to summarise this data to build the chart - specifically I want totals for each of the possible statuses - so I need some code to iterate through this "contents" array and build a new one I call, imaginatively, "newContents". That code looks like this:
var newContents = [];

for(i = 0; i < contents.length; i++) {
     var status = contents[i]["STATUS"];
    
     for(j = 0; j < newContents.length; j++) {
          if(newContents[j]["Status"] == status) {
               break;
          }
     }
     if(j == newContents.length) {
          newContents[j] = {"Status": status, "Count": 0};
     }
     newContents[j].Count += 1;
}

That gives me an array "newContents" that structured like this:
[
    {"Status": "PROCESS", "Count": 5},
    {"Status": "IGNORED", "Count": 4},
    {"Status": "NONE",    "Count": 3},
    {"Status": "SUCCESS", "Count": 2},
];

Now to build a chart based on this data. We do this by writing HTML that we will ultimately send to the HTMLviewer control. That HTML has to be, essentially, a self-contained HTML page, and has to include all the necessary UI5 libraries we need. We're going to build a single JavaScript string called, imaginatively again, "chartHTML" containing all of this. There's some boilerplate HTML at the top so let's start there:
var chartHTML = '<html> <head>';
chartHTML += '
<script src="/ui5/1/resources/sap-ui-core.js"\
type="text/javascript"\
data-sap-ui-libs="sap.ui.core,sap.ui.commons,sap.viz" \
data-sap-ui-theme="sap_goldreflection"></script>';
chartHTML += '<script>';

For the chart itself we need to turn the array we built earlier first into a "model" and then a "dataset", before connecting it to the chart object and placing the chart on the page. This is, finally, the UI5 stuff:
// some business data
chartHTML += ' var oModel = new sap.ui.model.json.JSONModel({businessData:' + JSON.stringify(newContents) + '});';

// A Dataset defines how the model data is mapped to the chart
chartHTML += ' var oDataset = new sap.viz.ui5.data.FlattenedDataset({\
   dimensions : [ \
       {\
            axis : 1, \
           name : "Status", \
            value : "{Status}"\
       } \
   ],\
   measures : [ \
       {\
            name : "",  \
            value : "{Count}"    \
      }\
   ],\ 
  data : {\
       path : "/businessData"\
  }\
});';

// create a Donut chart
chartHTML += ' var oBarChart = new sap.viz.ui5.Donut({\
  width : "100%",\
  height : "200px",\
  plotArea : {\
  },\
  title : {\
       visible : true,\
       text : "Migration Progress"\
  },\
dataset : oDataset\
  });';

// attach the model to the chart and display it
chartHTML += ' oBarChart.setModel(oModel);\
  oBarChart.placeAt("content");';

Finally we just need to finish off the HTML by closing the head and creating a body with a div to hold the chart, in the usual UI5 way:
chartHTML += '</script>';
chartHTML += '</head>';
chartHTML += '<body class="sapUiBody" supportedthemes="sap_corbu" role="application">';
chartHTML += '<div id="content"></div>'
chartHTML += '</body></html>';

And the last step is to send all of this HTML to the HTMLviewer control:
session.findById("wnd[0]/usr/htmlViewerPersonas_1447866610072").content = chartHTML;

And that's it. This script, when run, will read the data from the table summarise it, and present it in a Donut chart. As a final step, if you go back to the screen editor and add this script as the handler for the screen's "onAfterRefesh" event, the chart will automatically redraw whenever you make changes, as it did in the video above.

(Just in case some of the code got scrambled in the process of including it in this blog, I've attached a full copy, including the table copying, so start with that rather than copying code from here...)

I'd love to hear your thoughts on where this technique, using Donut or other chart types, might be useful in other transactions.

25 Comments