Skip to Content

On Premise Fiori Launchpad is coming with standard dynamic tile which is numeric content tile. It is there for you to use, but it has a limitation. With little knowledge of Fiori, ABAP an Gateway you can overcome a limitation and reveal more analytical insight.

Lets understand what standard dynamic tile (numeric content) has to offer and what it is lacking. As name suggests is shows numeric content value that can be semantically color coded (neutral, good, critical and error) and can indicate deviation (up, down and none). It all works fine as long as target value is constant and user know that value is. For example, user knows that target is 90% and if he sees that Numeric Content Value is 80% he can quickly calculate by how much the value is off. But what if target is variable? Then Standard Dynamic Tile can not reveal complete analytical insight.

Below are two standard dynamic tiles (numeric content):

From the left tile user can tell that Fastest Jet airline did not meet Dec 2017 Seats Occupancy rate target, but problem is that user does not know by how much it is off(Seats Occupancy rate varies by month) .

From the right tile user can tell that Fastest Jet airline Dec 2017 Payments received exceeded Dec 2016 Payments received (there is no target for Payments received.That is why this year Payments received is compared with last year Payments received). Again user can not tell by how much Payments received exceeded last year number.

I created two custom tiles to address the above issue with variable target values with Microchart visualizations:

So now Custom Content Tiles are more informative and reveal more analytical insight:

Below is a list of steps to create a Custom Fiori Launchpad Tile:

  1. Create Custom Tile Web IDE project;
  2. Deploy Custom Tile Web IDE project to back-end system;
  3. Register Custom Tile.

To use custom tile you need:

  1. Create Data Service that feeds Custom Tile with data;
  2. Configure Tile in Fiori Launchpad Designer.

The above steps are explained in following 2 blogs:

How-To: Create Custom Tile types for OnPremise Fiori Launchpad

Create and use custom tile type

I am not going to repeat the same information over again, but rather focus on what requires additional clarification and specific to my Custom Tiles.

This is what I learned from my experience:

  • Custom Tiles deployed to back-end system must have unique custom tile view and controller names (in my case CustomTile and CustomTile1)
  • UI2 cache needs to be cleared to make changes to your custom tile take into effect (execute /UI2/INVALIDATE_CLIENT_CACHES and /UI2/INVALIDATE_GLOBAL_CACHES project)

 

2×1 Numeric Content & Bullet Microchart Custom Tile

 

This is a structure of Numeric Content & Bullet Microchart Custom Tile Fiori project in Web IDE:

You can download the project from here

Since my tile is 2×1 some specific configuration needs to be done in CustomChip.xml file:

 

Below is a portion of CustomTile1.controller.js code that passes additional data to custom tile:

successHandleFn: function(oResult) {
	var oConfig = this.getView().getModel().getProperty("/config");
	this.oDataRequest = undefined;
	var oData = oResult,
		oDataToDisplay;

	oDataToDisplay = sap.ushell.components.tiles.utilsRT.getDataToDisplay(oConfig, oData);
	var aKeys = [
		// Additional data for our KPI Tile //
		"scale", "targetValue", "targetValueLabel", "minValue", "maxValue", "actual", "color", "footer1", "footer2", "unit1", "unit2"
		// End additional data //
	];
	// Prepare emp object:
	oResult.results = {};
	for (var i = 0; i < aKeys.length; i++) {
		//sName = aKeys[i];
		if (i === 1 || i === 3 || i === 4 || i === 5) {
			oResult.results[aKeys[i]] = parseFloat(oResult[aKeys[i]]);
		} else {
			oResult.results[aKeys[i]] = oResult[aKeys[i]];
		}
	}
	// Store the additional results back to emp
	oDataToDisplay.emp = oResult.results;

	// set data to display
	this.getView().getModel().setProperty("/data", oDataToDisplay);

	// rewrite target URL
	this.getView().getModel().setProperty("/nav/navigation_target_url",
		sap.ushell.components.tiles.utilsRT.addParamsToUrl(
			this.navigationTargetUrl,
			oDataToDisplay
		));
}

Note: targetValue, minValue, maxValue and actual are converted to float to have them displayed correctly

Below is a portion of CustomTile1.view.js code that displays the Custom Tile data:

var actual = new sap.suite.ui.microchart.BulletMicroChartData({
	value: '{/data/emp/actual}',
	color: '{/data/emp/color}'
});

return new sap.m.GenericTile({
	header: '{/data/display_title_text}',
	subheader: '{/data/display_subtitle_text}',
	frameType: "TwoByOne", //TwoByOne
	tileContent: [new sap.m.TileContent({
			footer: '{/data/emp/footer1}',
			unit: '{/data/emp/unit1}',
			content: [
				new sap.m.NumericContent({
					scale: '{/data/display_number_factor}',
					value: '{/data/display_number_value}',
					truncateValueTo: 5, //Otherwise, The default value is 4.
					indicator: '{/data/display_state_arrow}',
					valueColor: '{/data/display_number_state}',
					icon: '{/data/display_icon_url}',
					width: '100%'
				})
			]
		}),

		new sap.m.TileContent({
			footer: '{/data/emp/footer2}',
			unit: '{/data/emp/unit2}',
			content: [
				new sap.suite.ui.microchart.BulletMicroChart({
					scale: '{/data/emp/scale}',
					targetValue: '{/data/emp/targetValue}',
					targetValueLabel: '{/data/emp/targetValueLabel}',
					minValue: '{/data/emp/minValue}',
					maxValue: '{/data/emp/maxValue}',
					actual: [actual]
				})
			]
		})
	],
	press: [oController.onPress, oController]
});

This is how Numeric Content & Bullet Microchart Custom Tile is registered

Once registered the tile is available in Fiori Launchpad Designer

ZTILE_NUM_BT_SRV OData Service created to feeds Numeric Content & Bullet Microchart Custom Tile with data

Below is ZTILE_NUM_BT Entity Type of the service

Note: first comes properties of Standard Dynamic Tile followed by properties specific to my Numeric Content & Bullet Microchart Tile (in red rectangle)

ZTILES_NUM_BT Entity Set is defined based on ZTILE_NUM_BT Entity Type

ZTILE_NUM_BT_SRV OData Service has GetEntity (Read) operation implemented for ZTILES_NUM_BT Entity Set

Below is the implementation:

METHOD ztiles_num_bt_get_entity.

  er_entity = zcl_tile_num_bt=>get_entity( io_tech_request_context ).

ENDMETHOD.

Note: ZCL_TILE_NUM_BT=>GET_ENTITY method takes request context as an input and calls method that correspond to entity key

METHOD get_entity.

  DATA(wt_keys) = io_tech_request_context->get_keys( ).
  TRY.
    DATA(w_title) = wt_keys[ name = 'TITLE' ]-value.
    DATA(w_method) = REPLACE( val =  |GET_ENTITY_{ w_title CASE = UPPER }| regex = '\s' WITH = '_' OCC = 0 ).
    CALL METHOD (w_method) RECEIVING rs_entity = rs_entity.
  CATCH cx_sy_itab_line_not_found cx_sy_dyn_call_error.
  ENDTRY.

ENDMETHOD.

Note: this method dynamically calls respective method for each entity key. In case of ‘Flight Occ’ entity key ZCL_TILE_NUM_BT=>GET_ENTITY_FLIGHT_OCC method is called

This is how ZCL_TILE_NUM_BT=>GET_ENTITY_FLIGHT_OCC method is implemented:

METHOD get_entity_flight_occ.

  rs_entity = VALUE #(
    icon             = 'sap-icon://waiver'
    number           = '76.5'
    numberDigits     = '5'
    numberFactor     = ''
    numberState      = 'Error'                           "Positive or Error
    numberUnit       = '%'
    subtitle         = 'Dec 2017'
    title            = 'Fastest Jet Seats Occupancy'
    unit1            = '%'
    unit2            = '%'
    targetValue      = CONV ad_percnt3( '85' )
    targetValueLabel = '85'
    minValue         = 0
    maxValue         = '100'
    actual           = CONV ad_percnt3( '76.5' )
    color            = 'Error'                            "Good or Error
    scale            = '' ).

ENDMETHOD.

ZCL_TILE_NUM_BT class source code can be downloaded from here

Numeric Content & Bullet Microchart Custom Tile is configured in Fiori Launchpad Designer as displayed below:

Note: /sap/opu/odata/SAP/ZTILE_NUM_BT_SRV/ZTILES_NUM_BT(‘Flight Occ’)/?$format=json URL has ‘Flight Occ’ entity key corresponds to ZCL_TILE_NUM_BT=>GET_ENTITY_FLIGHT_OCC method

 

2×1 Numeric Content & Comparison Microchart

 

This is a structure of  Numeric Content & Comparison Microchart Custom Tile Fiori project in Web IDE:

You can download the project from here

Since my tile is 2×1 some specific configuration needs to be done in CustomChip.xml file:

Below is a portion of CustomTile.controller.js code that passes additional data to the custom tile:

successHandleFn: function(oResult) {
	var oConfig = this.getView().getModel().getProperty("/config");
	this.oDataRequest = undefined;
	var oData = oResult,
		oDataToDisplay;
	oDataToDisplay = sap.ushell.components.tiles.utilsRT.getDataToDisplay(oConfig, oData);
	var aKeys = [
		// Additional data for our KPI Tile //
		"footer1", "footer2", "unit1", "unit2", "value1", "value2",
		"title1", "title2", "displayValue1", "displayValue2", "deltaDisplayValue", "color"
		// End additional data //
	];
	// Prepare emp object:
	oResult.results = {};
	for (var i = 0; i < aKeys.length; i++) {
		//sName = aKeys[i];
		if (i === 4 || i === 5) {
			oResult.results[aKeys[i]] = parseFloat(oResult[aKeys[i]]);
		} else {
			oResult.results[aKeys[i]] = oResult[aKeys[i]];
		}
	}
	// Store the additional results back to emp
	oDataToDisplay.emp = oResult.results;

	// set data to display
	this.getView().getModel().setProperty("/data", oDataToDisplay);

	// rewrite target URL
	this.getView().getModel().setProperty("/nav/navigation_target_url",
		sap.ushell.components.tiles.utilsRT.addParamsToUrl(
			this.navigationTargetUrl,
			oDataToDisplay
		));
}

Note: value1 and value2 are converted to float to have them displayed correctly

Below is a portion of CustomTile.view.js code that displays the custom tile data:

return new sap.m.GenericTile({
	header: '{/data/display_title_text}',
	subheader: '{/data/display_subtitle_text}',
	frameType: "TwoByOne", //TwoByOne
	tileContent: [new sap.m.TileContent({
			footer: '{/data/emp/footer1}',
			unit: '{/data/emp/unit1}',
			content: [
				new sap.m.NumericContent({
					scale: '{/data/display_number_factor}',
					value: '{/data/display_number_value}',
					truncateValueTo: 5, //Otherwise, The default value is 4.
					indicator: '{/data/display_state_arrow}',
					valueColor: '{/data/display_number_state}',
					icon: '{/data/display_icon_url}',
					width: '100%'
				})
			]
		}),
		new sap.m.TileContent({
			footer: '{/data/emp/footer2}',
			unit: '{/data/emp/unit2}',
			content: [
				new sap.suite.ui.microchart.DeltaMicroChart({
					value1: '{/data/emp/value1}',
					value2: '{/data/emp/value2}',
					title1: '{/data/emp/title1}',
					title2: '{/data/emp/title2}',
					displayValue1: '{/data/emp/displayValue1}',
					displayValue2: '{/data/emp/displayValue2}',
					deltaDisplayValue: '{/data/emp/deltaDisplayValue}',
					color: '{/data/emp/color}'
				})
			]
		})
	],
	press: [oController.onPress, oController]
});

This is how Numeric Content & Comparison Microchart Custom Tile is registered

Once registered the tile is available in Fiori Launchpad Designer

ZTILE_NUM_DELTA_SRV OData Service is created to feed Numeric Content & Bullet Microchart Custom Tile with data

Below is ZTILE_NUM_DELTA_BT Entity Type of the service

Note: first comes properties of Standard Dynamic Tile followed by properties specific to my Numeric Content & Bullet Microchart Tile (in red rectangle)

ZTILES_NUM_DELTA Entity Set is defined based on ZTILE_NUM_DELTA Entity Type

ZTILE_NUM_DELTA_SRV OData Service has GetEntity (Read) operation implemented for ZTILES_NUM_DELTA Entity Set

Below is the implementation:

METHOD ztiles_num_delta_get_entity.

  er_entity = zcl_tile_num_delta=>get_entity( io_tech_request_context ).

ENDMETHOD.

Note: ZCL_TILE_NUM_DELTA=>GET_ENTITY method takes request context as an input and calls method that correspond to entity key

METHOD get_entity.

  DATA(wt_keys) = io_tech_request_context->get_keys( ).
  TRY.
    DATA(w_title) = wt_keys[ name = 'TITLE' ]-value.
    DATA(w_method) = REPLACE( val =  |GET_ENTITY_{ w_title CASE = UPPER }| regex = '\s' WITH = '_' OCC = 0 ).
    CALL METHOD (w_method) RECEIVING rs_entity = rs_entity.
  CATCH cx_sy_itab_line_not_found cx_sy_dyn_call_error.
  ENDTRY.

ENDMETHOD.

Note: this method dynamically calls respective method for each entity key. In case of ‘Flight Payment’ entity key ZCL_TILE_NUM_DELTA=>GET_ENTITY_FLIGHT_PAYMENT method is called

This is how ZCL_TILE_NUM_DELTA=>GET_ENTITY_FLIGHT_PAYMENT method is implemented:

METHOD get_entity_flight_payment.

  rs_entity =
    VALUE #( icon              = 'sap-icon://money-bills'
             number            = '152'
             numberDigits      = '4'
             numberState       = 'Positive'              "Positive or Error
             numberFactor      = 'M'
             stateArrow        = 'Up'                    "None, Up or Down
             subtitle          = 'Dec 2017'
             title             = 'Fastest Jet Payments'
             unit1             = '$'
             unit2             = '$'
             value1            = '152'
             value2            = '147'
             title1            = 'Jan 2018'
             title2            = 'Jan 2017'
             displayValue1     = '142 M'
             displayValue2     = '147 M'
             deltaDisplayValue = '+5'
             color             = 'Good' ).                "Good or Error

ENDMETHOD.

ZCL_TILE_NUM_DELTA class source code can be downloaded from here

Numeric Content & Comparison Microchart Tile is configured in Fiori Launchpad Designer as displayed below:

Note: /sap/opu/odata/SAP/ZTILE_NUM_DELTA_SRV/ZTILES_NUM_DELTA(‘Flight Payment’)/?$format=json URL has ‘Flight Payment’ entity key corresponds to ZCL_TILE_NUM_DELTA=>GET_ENTITY_FLIGHT_PAYMENT method

 

In second part of my blog I will demonstrate how to reveal some more analytical insight with 2×1 Custom Numeric Content Fiori Launchpad Tiles visualizing trend with Microchart.

To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

  1. Michael Smith

    Uladzislau,

    Great blog – thanks for sharing.

    Do these custom tile types survive UI5 upgrades?  Or do they have to be created all over again after an upgrade?

    Thanks,

    Michael

    (0) 

Leave a Reply