Skip to Content
Author's profile photo Steve Rumsby

Using SAPUI5 charts in Personas Flavours

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.

Assigned Tags

      25 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Manu Kapur
      Manu Kapur

      Thats impressive. 🙂

      Thanks for sharing.

      Author's profile photo Clemens Gantert
      Clemens Gantert

      Steve did it again! Very nice!

      Author's profile photo Sylvia Barnard
      Sylvia Barnard

      Thanks, Steve! What else can be expected from you? Simply the best! 😉

      Author's profile photo Simon Kemp
      Simon Kemp

      Nice one Steve. I think the use cases would not be that dissimilar to those for NWBC Side Panels, basically you are augmenting the SAPGUI screen. I wonder if you can use the scripting in Personas 3.0 to pass data to the NWBC side panel?

      Author's profile photo Steve Rumsby
      Steve Rumsby
      Blog Post Author

      You could in Personas 2. I'm not sure that functionality has made it to Personas 3 yet.

      Steve.

      Author's profile photo Juergen Jakowski
      Juergen Jakowski

      That's pretty cool..!

      Author's profile photo Neil Ward
      Neil Ward

      thats so cool ... more please

      Author's profile photo Krishna Kishor Kammaje
      Krishna Kishor Kammaje

      Thanks Steve for the complete code. I could get it to working with the help of that.

      Otherwise it is so tough to get pass the script escaping.

      Author's profile photo Steve Rumsby
      Steve Rumsby
      Blog Post Author

      Happy to help. If you do anything interesting with this technique, please share... 🙂

      Steve.

      Author's profile photo Former Member
      Former Member

      Nice one Steve !!

      Has anyone tried to convert Table data into a scroll container using Ui5 ?

      If any of you have tried or trying , do let me know the basic approach.

      Thanks

      Author's profile photo Steve Rumsby
      Steve Rumsby
      Blog Post Author

      Oh yes. Keep a look out for my next blog... 🙂

      Author's profile photo Former Member
      Former Member

      That was quick!! 😆

      Waiting 😈

      Author's profile photo Steve Rumsby
      Steve Rumsby
      Blog Post Author

      Actually, it turns out I'd already posted the blog I was talking about - Custom tables in Personas (take 2). This takes data from an ALV grid an puts it into an UI5 table, but you could of course use the same technique to display in a table data from any course, including stuff you calculate in Javascript.

      Is that what you were looking for?

      Author's profile photo Michael Olijnyk
      Michael Olijnyk

      Steve, I am trying to implement something similar, but keep running into the non-whitelist URL error when sending the HTML to the HTML viewer control. Did you have this issue, and if so, how did you resolve? Thanks

      Author's profile photo Clemens Gantert
      Clemens Gantert

      Hi,

      did you create a whitelist entry for "local" URLs like "/.*"  ?

      Cheers,

      Clemens

      Author's profile photo Michael Olijnyk
      Michael Olijnyk

      Thanks that worked!

      Author's profile photo Michael Olijnyk
      Michael Olijnyk

      Steve, do you need to additionally install sapui5? I cannot get past the "failed to preload sap.viz.library error message. Thanks

      Author's profile photo Steve Rumsby
      Steve Rumsby
      Blog Post Author

      I do have the SAP_UI package installed, yes. It was in my system already, so I guess I forgot to mention the need for it. Sorry for the confusion.

      Personas itself is built on UI5 and comes with its own version, which you can access at "/sap/bc/personas3/ui5/resources/sap-ui.core.js" instead of "/ui5/1/resources/sap-ui-core.js", but it doesn't seem to include sap.viz.

      Author's profile photo Michael Olijnyk
      Michael Olijnyk

      Thank you!

      Author's profile photo Ramakrishnan Subramaniam
      Ramakrishnan Subramaniam

      @Steve - sap.viz.ui5.StackedColumn is deprecated as of 1.32.  I am looking for an alternative for this context.  Could you please guide on the same?

      Regards,

      Author's profile photo Steve Rumsby
      Steve Rumsby
      Blog Post Author

      The same principle applies to the replacement VizFrame. Create an object of type sap.viz.ui5.controls.VizFrame instead of a sap.viz.ui5.StackedColumn. The usage is a little different, but not drastically so. You still used the FlattenedDataset construction, for example. A little googling should get you there.

      I've been meaning to publish an updated blog post about this for ages now, but I just don't have the time at the moment. Sorry.

      Steve.

      Author's profile photo Ramakrishnan Subramaniam
      Ramakrishnan Subramaniam

      Thanks Steve!!!

      Author's profile photo Luis zapata
      Luis zapata

      hi,

      I have a problem in the call to rfc, I have migrated from screen personas 3.0 service pack 3 to screen personas 3.0 service pack 9. In the scripts I have calls to rfc using the XMLHttpReques method, as follows

      var random = Math.random ();

      var server = location.protocol + '//' + location.host;

      var webrfcURL = "" + server + "/ sap (bD1lcyZjPTIwMQ ==) / bc / webrfc? _FUNCTION = Z_xxxx & _Name =" + v_pernr + "& _ random =" + random + "";

      var request = new XMLHttpRequest ();

      request.open ("GET", webrfcURL, false);

      request.send ();

      var results = request.responseText;

      var arr = JSON.parse (results);

      var arr_length = parseInt (arr.results.length);

      but with the new service pack, it does not recognize the instructions

      var server = location.protocol + '//' + location.host;

      as well as neither

      var request = new XMLHttpRequest ();

      How can i solve this problem?

      from already very grateful

      Greetings.

      Author's profile photo Steve Rumsby
      Steve Rumsby
      Blog Post Author

      You should probably be using the built-in RFC functionality now available in Personas. It makes these things much easier. See this Wiki page for more detail and some examples:

      https://wiki.scn.sap.com/wiki/display/Img/How+to+call+Remote+Enabled+ABAP+Function+Modules+in+Personas+3.0

      This is a little old now and the editor has acquired a tool for automatically creating the necessary code. See the RFC Tool tab on the right hand side of the script editor:

       

      Steve.

      Author's profile photo Luis zapata
      Luis zapata

      Steve,

      thanks for the reply.

       

      Regards.