Skip to Content
Author's profile photo Felipe de Mello Rodrigues

Create KPIs with data points and criticality calculation in a SAP Fiori Overview Page

Nowadays, most part of the organizations make use of Key Performance Indicators (a.k.a KPIs) to evaluate their success in different activities relevant with their business. A KPI is a measurable value that demonstrates how effectively a company is achieving its objectives.

When we relate KPIs with the SAP Fiori experience the first thing that comes to our minds is the use of SAP Smart Business Applications and the KPI Modeller (more information available here), but what most part of the developers don’t know is that this is not the only path available to publish KPIs in an SAP Fiori application.

We know already that Fiori Elements can generate UIs at runtime based on metadata annotations and predefined templates, but one of the most interesting functionalities (and not so widespread) is the ability to publish KPIs using the @UI.dataPoint annotation.

With a measurable field (number, price, quantity or percentage) you can define a threshold and evaluate how the indicator has been performing and display the result in a range of different colors and symbols. This concept is defined as Trend-Criticality Calculation and you can check the official documentation here.

The focus of this post is to explain only the Criticality calculation inside an Overview Page application, but since there are different Fiori Elements providing support to the annotation @UI.dataPoint is possible to adapt the same concepts for different kind of developments (e.g. KPI in the header of an Object Page).

This post covers not only Fiori and UI5 concepts but also ABAP CDS, if you are not familiar with these concepts I advise you to check my previous posts or to have a look in SAP official documentation.

 

What do I need to know about Criticality?

In a criticality calculation we need to provide the following data:

  • Improvement direction
  • Threshold (low and high values)

Depending on the selected direction we must define multiple low and high values, let’s check in details the available directions and the expected threshold values:

  • #TARGET: Your key figure must stay inside a specific target in the center of your threshold, deviations in any directions will reflect a bad performance of the indicator.
    • Example of an use case: Headcount.

 

  • #MINIMIZE: Your key figure must stay in the lowest part of the threshold to indicate a good performance, deviation in the opposite direction will reflect as bad performance.
    • Example of an use case: Work Incidents.

 

  • #MAXIMIZE: Your key figure must stay in the highest part of the threshold to indicate a good performance, deviation in the opposite direction will reflect as bad performance.
    • Example of an use case: Sales.

 

 

Now that you are able to identify the available scenarios we can start the development of our demo. To construct our application we will use data from SFLIGHTS standard view and create a KPI to check the seating occupancy for each one of the scheduled flights in the system. Comparing the number of occupied seats against the maximum seats available in the plane is possible to generate a percentage value and evaluate the position with a criticality calculation.

The improvement direction in this case must be #MAXIMIZE because the airline wants to sell all the seats available in the plane, if the indicator is showing entries with red color it basically means they need to focus sales in those particular flights with a low occupancy.

The UI5 application will be based on an Overview Page template with a List card with progress bar. When we combine a data point annotation with this card template the framework populates automatically the colors and completion of the bar.

As usual, I’m splitting this post in 3 sections:

  1. ABAP CDS
  2. OData Project
  3. UI5 Project (Web IDE)

 

ABAP CDS

Create the view ZDEMO_CRITICALITY_OVP and select data from the view SFLIGHTS. The following fields are expected as the result:

  • FlightCode: The union of the airline code (CARRID) and the connection number (CONNID). This field should be available inside the list card and in the global filter of the Overview Page.
  • FlightDate: Date of the flight, configured as a secondary data point in the list card.
  • Destination: The arrival city, expected in the result of the card as well.
  • Occupancy: A percentage result based on the calculation of the maximum seats (SEATSMAX) against the occupied seats (SEATSOCC). This field should be configured as a data point to become a KPI about seating occupancy. Extra configurations determine only 2 fractional digits, expected values between 0 and 100, and a criticality calculation with a maximize direction with the following range of colors:
    • RED from 0 to 25.
    • YELLOW from 26 to 60.
    • GREEN from 61 to 100.
  • Percentage: Just a unit of measure to associate directly with the occupancy field.
@AbapCatalog.sqlViewName: 'ZDEMOCRITOVP'
@AbapCatalog.compiler.compareFilter: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Criticality OVP'

@OData.publish: true

define view ZDEMO_CRITICALITY_OVP
  as select from sflights as Flight
{
      @EndUserText.label: 'Flight Code'
      @UI: {
          selectionField.position: 10,
          lineItem.position: 10
      }
  key concat(carrid, connid)                as FlightCode,

      @UI: {
          lineItem: {
              type: #AS_DATAPOINT,
              importance: #HIGH,
              position: 20
          },
          dataPoint: {
              title: 'Flight Date'
          }
      }
  key fldate                                as FlightDate,

      @UI.lineItem.position: 20
      cityto                                as Destination,

      @UI: {
          lineItem: {
              type: #AS_DATAPOINT,
              importance: #HIGH,
              position: 10
          },
          dataPoint: {
              title: 'Flight Date',
              valueFormat.numberOfFractionalDigits: 2,
              minimumValue: 0,
              maximumValue: 100,
              criticalityCalculation: {
                  improvementDirection: #MAXIMIZE,
                  deviationRangeLowValue: 25,
                  toleranceRangeLowValue: 60
              }
          }
      }
      @Semantics.quantity.unitOfMeasure: 'Percentage'
      division(seatsocc * 100, seatsmax, 2) as Occupancy,

      @Semantics.unitOfMeasure: true
      cast(' % ' as abap.unit(3))           as Percentage
} 

Important points about the annotations used in this CDS view:

  • @OData.publish: Used to publish the OData service automatically without the need to create an OData project through transaction SEGW.
  • @EndUserText.label: This annotation provides a label to the field.
  • @UI.selectionField: This annotation determines the position of the field in the global filter of the Overview Page.
  • @UI.lineItem: This annotation determines the position of the fied inside the cell of our list card.
  • @UI.dataPoint: This annotation holds the criticality calculation of our KPI. Notice that we use #MAXIMIZE as the improvement direction, so we just need to fill deviationRangeLowValue and toleranceRangeLowValue to determine the threshold (as described by SAP documentation). Also, there is a configuration for decimal places and the minimum and maximum values expected for the field.
  • @Semantics.quantity and @Semantics.unitOfMeasure: These annotations define a relation between a quantity field and its respective unit.

This is the expected outcome:

 

OData Project

There are 2 ways to create your OData project consuming ABAP CDS views:

  • Create a new project through SEGW transaction and include your CDS views by Reference. Just right click on the Data Model folder and select Reference -> Data Source.

  • Include the @OData.publish annotation in the header of your CDS view, the system will create your OData project automatically based on the field structure and annotations.
@OData.publish: true

define view ZDEMO_CRITICALITY_OVP
  as select from sflights as Flight
{
  ...
}

Remember always to activate the OData service in the Front-end server (SAP Gateway server) through the transaction /IWFND/MAINT_SERVICE.

 

UI5 Project (Web IDE)

The process to create an UI5 application through Web IDE is pretty simple and straightforward, just follow the steps below to create an Overview Page with a list card with progress bar.

Right click in your Workspace folder and click New -> Project from Template.

 

Template Selection: Create a new project based on a Overview Page.

 

Basic Information: Define the project name as zdemo_criticality_ovp.

 

Data Connection: Select your system and OData project.

 

Annotation Selection: Select the remote annotation provided by the ABAP CDS exposure.

Note #1: All the annotations published in our ABAP CDS view will flow to the UI5 application through this remote source ZDEMO_CRITICALITY_OVP_CDS_VAN. Later on you can see the same annotations inside the XML file inside the localService folder.

 

Template Customization: Define a namespace, data source, entity type, app title and description. The rest of the configuration doesn’t affect this demo.

Finish the wizard and conclude the creation of your Overview Page.

 

Now we need to configure a List card inside of our application, right click in the main folder of your project, click New -> Card.

 

Configure Datasource: Select the existing data source and continue.

 

Select a Card: Select a List card template, no need to mark the extra configuration in the bottom.

 

Template Customization: Select the entity set, provide a title and fill the card properties with the following data:

  • List Type: Extended
  • List Flavor: Bar
  • Sort By: Flight Date
  • Sort Order: Descending

Finish the wizard and conclude the creation of your new card.

Note #2: The list flavor must be set as Bar to allow the use of progress bar and provide support to data points with criticality calculation.

Note #3: The list type must be set as Extended to provide extra space for all of our fields.

Note #4: The sort order was just configured like this to increase our chances to find flights with low occupancy during the tests.

 

Now the application is concluded and we can start the tests, just filter by Flight Code to navigate across different KPI results. Since we configured a sort by Flight Date the chances to find flights with low occupancy are higher. Check some examples below:

SQ0015 (Singapore)

AZ0555 (Frankfurt)

LH0402 (New York)

LH2402 (Berlin)

Assigned Tags

      13 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Former Member
      Former Member

      The blog was very subjective and it clears the idea about SAP.

       

      Author's profile photo Jocelyn Dart
      Jocelyn Dart

      Great work Felipe! I've added your blog to our SAP Fiori elements wiki

      https://wiki.scn.sap.com/wiki/display/Fiori/Fiori+elements

      I'd love to see more blogs from you on Fiori elements topics ... as you are interested in analytics you might like to do something on the Analytical List Page perhaps?

       

      Author's profile photo Felipe de Mello Rodrigues
      Felipe de Mello Rodrigues
      Blog Post Author

      Hi Jocelyn,

      Thanks for the feedback!

      I'm actually with this idea in mind since the release of version 1.48. I've been planning to deliver two new posts for the next months, first one focused only in ABAP CDS development for analytical purposes (dimensions, texts, cubes and queries) and the second post about Analytical List Page (probably consuming the data model created in the first article).

      I think it would be good to explain how to generate a proper data model for an Analytical application before we discuss how to configure the front-end application.

      Best Regards,

      Felipe

      Author's profile photo Felipe de Mello Rodrigues
      Felipe de Mello Rodrigues
      Blog Post Author

      Hi Jocelyn Dart,

      Hope you're well.

      As we discussed previously, I've been working with those two articles about ABAP CDS analytical views and the Analytical List Page during the last months.

      I just released the last article about ALP a few minutes ago, so I would like to share with you and see if they are aligned with your expectations. These are the links:

      Hope you like it.

      Cheers,

      Felipe

      Author's profile photo Jocelyn Dart
      Jocelyn Dart

      Fantastic work Felipe!!! I'm adding them to the Fiori Elements Wiki

      They will be much appreciated by many of our readers I know!

      https://wiki.scn.sap.com/wiki/display/Fiori/Fiori+elements

      Author's profile photo Former Member
      Former Member

      Hi Felipe,

      I don't find the annotation.

      Note #1: All the annotations published in our ABAP CDS view will flow to the UI5 application through this remote source ZDEMO_CRITICALITY_OVP_CDS_VAN. Later on you can see the same annotations inside the XML file inside the localService folder.

      Can you tell me how to build this?

      kind regards,

      Cesar

      Author's profile photo Felipe de Mello Rodrigues
      Felipe de Mello Rodrigues
      Blog Post Author

      Hi Cesar,

      There is an OData Service which controls the annotations catalogues, I advise you to check if this service is active in your front-end server, access the transaction SICF and check the following node:

      • /sap/opu/odata/IWFND/CATALOGSERVICE

      If the service is already active, I recommend to use transaction /IWFND/GW_CLIENT to read all the catalogues and confirm if your ABAP CDS view is available in the list.

      Let me know how it goes.

      Cheers,

      Felipe

      Author's profile photo Smriti Gupta
      Smriti Gupta

      Hello Felipe,

       

      Many thanks for the wonderful blog with end to end developemet. Not only the developement part,

      but explaination of annotations, use case makes this blog my favorite one to learn Cds views and

      Fiori Elements.

      Also thanks Jocelyn Dart for posting it on wiki else I would have missed this precious info. You and your team  are organising and updating the contents so well.

       

      Best Regards,

      Smriti

      Author's profile photo Felipe de Mello Rodrigues
      Felipe de Mello Rodrigues
      Blog Post Author

      Hi Smriti,

      Thank you for the feedback.

      Cheers,

      Felipe

      Author's profile photo Sebastian Freilinger-Huber
      Sebastian Freilinger-Huber

      Hi Felipe,

      I am currently trying to get deeper into the ALP and Overview Page, so first of all thanks a lot for your Blog (series). They content is arranged very nice and well explained. Great work.

      As I always try to understand also the idea behind an implementation (and not just the implementation itself), I would like to ask you a few things about your example. It would be nice, if you find the time to answer.

      Just to make sure: My questions should rather be understood as criticism or something into this direction, but they should provide some constructive feedback.

      • I assume, you did not do anything with the local annotations in the WebIDE, so basically the whole annotations are coming from CDS. I am a little wondering about the visualization of the date - in the CDS View you select the raw date and the card sets this into relevance to today's date and displays the date on a monthly base (e.g. next month or 4 month ago). Do you know, if this is the standard behaviour and/or if it is possible to define this, maybe also be annotations?
      • I assume you added the UI.lineItem.position annotations, to steer, where the data is displayed on the card. However, for the four fields, which are displayed you defined two times the value 10 and two times the value 20. I am pretty confused here, because when I compare the locations in the card to the defined values, I don't see how the logic behind it works. Could you help me out here?
      • You are writing that you implemented a sorting based on the flight date for the following reason ". Since we configured a sort by Flight Date the chances to find flights with low occupancy are higher" - Was the main purpose behind it to show how to define a 2nd data point? I am just curious, if an ascending sorting on the occupancy itself wouldn't do a better job?

      Best regards and thanks one more time for the blog series, look forward to read the other blogs,

      Sebastian

      Author's profile photo Felipe de Mello Rodrigues
      Felipe de Mello Rodrigues
      Blog Post Author

      Hi Sebastian,

      Thank you for the feedback, I'm glad when people start to explore these subjects in a deeper level. Regarding your questions here it goes the explanation:

      • I assume, you did not do anything with the local annotations in the WebIDE, so basically the whole annotations are coming from CDS. I am a little wondering about the visualization of the date – in the CDS View you select the raw date and the card sets this into relevance to today’s date and displays the date on a monthly base (e.g. next month or 4 month ago). Do you know, if this is the standard behaviour and/or if it is possible to define this, maybe also be annotations?
        • Actually, this is the standard behaviour of Overview Pages and it's not related with annotations. The OVP always display dates as relative dates but there is a simple technique to change this functionality based on a configuration in the manifest.json. I discussed this subject in one of my first blogs, have a look in the following link: Replace relative dates by real dates in your SAP Fiori Overview Page.
      • I assume you added the UI.lineItem.position annotations, to steer, where the data is displayed on the card. However, for the four fields, which are displayed you defined two times the value 10 and two times the value 20. I am pretty confused here, because when I compare the locations in the card to the defined values, I don’t see how the logic behind it works. Could you help me out here?
        • If you are using only UI.LineItem you can populate all the fields in the card with this annotation, the difference in my example is that I configured two fields with UI.LineItem and UI.DataPoint at the same time (flight date and occupancy), in this case the system places the line items in the left side while the data points are included in the right side of the card. I decided to reuse 10 and 20 to exemplify this difference, but I think you're one of the few who noticed that. Also, since I used the Extended card with a Bar the value in the first data point is associated with the bar automatically.
      • You are writing that you implemented a sorting based on the flight date for the following reason “. Since we configured a sort by Flight Date the chances to find flights with low occupancy are higher” – Was the main purpose behind it to show how to define a 2nd data point? I am just curious, if an ascending sorting on the occupancy itself wouldn’t do a better job?
        • Since I wanted to demonstrate the usage of multiple data points in the the CDS view I tried to create a meaningful role for Flight Date in the application, for this reason I used this field for the sorting. I agree with you, the occupancy would provide the answer straight forward.

      Hope this information helps.

      Cheers,

      Felipe

      Author's profile photo Sebastian Freilinger-Huber
      Sebastian Freilinger-Huber

      Hi Felipe,

      thanks a lot for your time - especially the thing with the positions is very interessting (and shame on me that I missed your blog about the dates - I think it is the only one).

      Looking forward to hopefully see new content provided by you in the future.

      Bye,

      Sebastian

      Author's profile photo Peter Widmer
      Peter Widmer

      Great block, thanks a lot!

      Error

       

      I am facing a weird error.. somehow my bars are all empty, even though the “Percentage” part works fine. The bars are just grayed out, as if the value is 0 for all entries.

       

      Error