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: 
AshishAnand
Employee
Employee
In addition to the conventional smart filter bar (compact filters) present in other Fiori Elements floorplans, Analytical List Page (ALP) also provides something called visual filters. Which renders your filters in the form of analytical charts (donut, line and bar) to help the end-user with better visualisation of data. In an ALP application, any visual filter will always have a corresponding filter field in the compact filter but a compact filter field can not have any corresponding visual filter. Visual filter and compact filter in an ALP application will always be in sync in terms of value help and selected value.

ALP's Visual filter


ALP's Compact Filter


In this blog, I'll discuss different configurations and annotation for filter area of an ALP application.

Prerequisites



  1. Make sure you have been to the previous blog of this blog series and already created a bare bone ALP application.

  2. For reference, you can clone the GIT repo for this sample application which we are building.


Adding filters


To add filters, "UI.SelectionFields" annotation is used
				<Annotation Term="UI.SelectionFields">
<Collection>
<PropertyPath>Currency</PropertyPath>
<PropertyPath>Product</PropertyPath>
<PropertyPath>DeliveryMonth_Text</PropertyPath>
<PropertyPath>DeliveryDateTime</PropertyPath>
</Collection>
</Annotation>
</Annotations>

Please note that the filters (both visual and compact) will come in order in which they are mention in the "UI.SelectionFields" annotation.

Defaults values for filters


Default filter values can be configured by defining the "Common.FilterDefaultValue" annotation for a property type.
<Annotations Target="SEPMRA_PROD_MAN.SEPMRA_C_PD_ProductSalesDataType/Currency">
<Annotation Term="Common.FilterDefaultValue" String="USD"/>
</Annotations>

Another way of defining default values for the filter is via the parameters of selectionVariant or selectionPresentatioVariant of the ALP application. You need to to make the manifest property "filterDefaultsFromSelectionVariant" as true in order to use this functionality which by default is false.
<Annotation Term="UI.SelectionPresentationVariant">
<Record Type="UI.SelectionPresentationVariantType">
<PropertyValue Property="SelectionVariant">
<Record Type="UI.SelectionVariantType">
<PropertyValue Property="Parameters">
<Collection>
<Record Type="UI.Parameter">
<PropertyValue Property="PropertyName" PropertyPath="Currency"/>
<PropertyValue Property="PropertyValue" String="USD"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</PropertyValue>
</Record>
</Annotation>

The default filter values from the "Common.FilterDefaultValue" annotations are overwritten by the variant management or navigation context.

Defining the value help for the filters


Value help for the filters can be defined using "Common.ValueList" annotation:
			<Annotations Target="SEPMRA_PROD_MAN.SEPMRA_C_PD_ProductSalesDataType/DeliveryDateTime">
<Annotation Term="Common.ValueList">
<Record Type="Common.ValueListType">
<PropertyValue Property="CollectionPath" String="SEPMRA_C_PD_ProductSalesData"/>
<PropertyValue Property="Parameters">
<Collection>
<Record Type="Common.ValueListParameterInOut">
<PropertyValue Property="LocalDataProperty" PropertyPath="DeliveryDateTime"/>
<PropertyValue Property="ValueListProperty" String="DeliveryDateTime"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>

Please note that there should be no qualifier for these valueList annotations.


Record Type: Common.ValueListParameterOut determines the

  • Elements of the main entity set that make it to the filter query

  • Field from a value help entity set that sets the field value in the main entity set



Record Type: Common.ValueListParameterIn determines the filtering data set from a value help entity set


Record Type: Common.ValueListParameterInOut combination of both in and out parameters. In the above example, both the in and out combination was same hence I have used InOut for simplicity.



Defining visual filters


An ALP must have a visual filter because the visual filter is the most distinguishing factor which differentiates an ALP application from a List Report application. You need an aggregated entity set to define an ALP visual filter i.e. an entity type defined as sap:semantics="aggregate" in the metadata. An aggregated entity type will also have dimensions and measures attributes.
<EntityType Name="SEPMRA_C_PD_ProductSalesDataType" sap:semantics="aggregate" sap:label="Monthly Sales (only recent periods)" sap:content-version="1">
<Key>
<PropertyRef Name="ID"/>
</Key>
<Property Name="ID" Type="Edm.String" Nullable="false"/>
<Property Name="Product" Type="Edm.String" MaxLength="10" sap:aggregation-role="dimension" sap:display-format="UpperCase" sap:label="Product ID" sap:quickinfo="EPM Fiori Ref Apps: Product ID"/>
<Property Name="DeliveryDateTime" Type="Edm.DateTime" Precision="0" sap:aggregation-role="dimension" sap:display-format="Date" sap:label="Delivery Date"/>
<Property Name="DeliveryMonth" Type="Edm.String" MaxLength="2" sap:aggregation-role="dimension" sap:display-format="NonNegative" sap:text="DeliveryMonth_Text" sap:label="Month" sap:quickinfo="Month number"/>
<Property Name="DeliveryMonth_Text" Type="Edm.String" MaxLength="10" sap:aggregation-role="dimension" sap:label="Month" sap:quickinfo="Month long text" sap:creatable="false" sap:updatable="false"/>
<Property Name="Revenue" Type="Edm.Decimal" Precision="16" Scale="3" sap:aggregation-role="measure" sap:unit="Currency" sap:label="Revenue" sap:filterable="false"/>
<Property Name="Currency" Type="Edm.String" MaxLength="5" sap:aggregation-role="dimension" sap:label="ISO Currency Code" sap:quickinfo="EPM: Currency Code" sap:value-list="standard" sap:semantics="currency-code"/>
<NavigationProperty Name="to_Currency" Relationship="SEPMRA_PROD_MAN.assoc_72566A4A59B7E929287D37F8CF88FB8C" FromRole="FromRole_assoc_72566A4A59B7E929287D37F8CF88FB8C" ToRole="ToRole_assoc_72566A4A59B7E929287D37F8CF88FB8C"/>
<NavigationProperty Name="to_MonthName" Relationship="SEPMRA_PROD_MAN.assoc_BEF8734D3DB95728942443F9CA4E389E" FromRole="FromRole_assoc_BEF8734D3DB95728942443F9CA4E389E" ToRole="ToRole_assoc_BEF8734D3DB95728942443F9CA4E389E"/>
</EntityType>

A visual filter of an ALP application is defined via another "Common.ValueList" annotation with a qualifier and PresentationVariantQualifier property which points to the chart annotation. So if you want to have have both value list and visual filter for the same filter property, then you should define two Common.ValueList annotation for the same filter property, one without qualifier for value list and another with qualifier and PresentationVariantQualifier for the visual filter
			<Annotations Target="SEPMRA_PROD_MAN.SEPMRA_C_PD_ProductSalesDataType/Currency">
<Annotation Term="Common.FilterDefaultValue" String="USD"/>
<Annotation Term="Common.ValueList" Qualifier="CurrencyVisualFilter">
<Record Type="Common.ValueListType">
<!--<PropertyValue Property="SelectionVariantQualifier" String="CurrencyVisualFilter"/>-->
<PropertyValue Property="CollectionPath" String="SEPMRA_C_PD_ProductSalesData"/>
<PropertyValue Property="Parameters">
<Collection>
<Record Type="Common.ValueListParameterInOut">
<PropertyValue Property="LocalDataProperty" PropertyPath="Currency"/>
<PropertyValue Property="ValueListProperty" String="Currency"/>
</Record>
</Collection>
</PropertyValue>
<PropertyValue Property="PresentationVariantQualifier" String="CurrencyVisualFilter"/>
</Record>
</Annotation>
<Annotation Term="Common.ValueList">
<Record Type="Common.ValueListType">
<PropertyValue Property="CollectionPath" String="SEPMRA_C_CurrencyValueHelp"/>
<PropertyValue Property="Parameters">
<Collection>
<Record Type="Common.ValueListParameterIn">
<PropertyValue Property="LocalDataProperty" PropertyPath="Currency"/>
<PropertyValue Property="ValueListProperty" String="Currency"/>
</Record>
<Record Type="Common.ValueListParameterOut">
<PropertyValue Property="LocalDataProperty" PropertyPath="Currency"/>
<PropertyValue Property="ValueListProperty" String="Currency"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>
</Annotations>

Below is the PresentationVariant annotation for the currency visual filter:
<Annotation Term="UI.PresentationVariant" Qualifier="CurrencyVisualFilter">
<Record Type="UI.PresentationVariantType">
<!--<PropertyValue Property="SortOrder">-->
<!-- <Collection>-->
<!-- <Record Type="Common.SortOrderType">-->
<!-- <PropertyValue Property="Property" PropertyPath="Revenue"/>-->
<!-- </Record>-->
<!-- </Collection>-->
<!--</PropertyValue>-->
<PropertyValue Property="Visualizations">
<Collection>
<AnnotationPath>@UI.Chart#CurrencyVisualFilter</AnnotationPath>
</Collection>
</PropertyValue>
</Record>
</Annotation>

Below is the chart annotation to which above PV annotation points to:
				<Annotation Term="UI.Chart" Qualifier="CurrencyVisualFilter">
<Record Type="UI.ChartDefinitionType">
<PropertyValue Property="ChartType" EnumMember="UI.ChartType/Donut"/>
<PropertyValue Property="DimensionAttributes">
<Collection>
<Record Type="UI.ChartDimensionAttributeType">
<PropertyValue Property="Dimension" PropertyPath="Currency"/>
<PropertyValue Property="Role" EnumMember="UI.ChartDimensionRoleType/Category"/>
</Record>
</Collection>
</PropertyValue>
<PropertyValue Property="MeasureAttributes">
<Collection>
<Record Type="UI.ChartMeasureAttributeType">
<PropertyValue Property="Measure" PropertyPath="Revenue"/>
<PropertyValue Property="Role" EnumMember="UI.ChartMeasureRoleType/Axis1"/>
<PropertyValue Property="DataPoint" AnnotationPath="@UI.DataPoint#revenue"/>
</Record>
</Collection>
</PropertyValue>
<PropertyValue Property="Measures">
<Collection>
<PropertyPath>Revenue</PropertyPath>
</Collection>
</PropertyValue>
<PropertyValue Property="Dimensions">
<Collection>
<PropertyPath>Currency</PropertyPath>
</Collection>
</PropertyValue>
</Record>
</Annotation>

You can also define datapoint annotation for your measure attribute to define the criticality or semantic colouring of your visual filters:
<Annotation Term="UI.DataPoint" Qualifier="revenue">
<Record Type="UI.DataPointType">
<PropertyValue Property="Value" Path="Revenue"/>
<PropertyValue Property="CriticalityCalculation">
<Record Type="UI.CriticalityCalculationType">
<PropertyValue Property="ImprovementDirection" EnumMember="UI.ImprovementDirectionType/Minimize"/>
<PropertyValue Property="AcceptanceRangeLowValue" Decimal="600000"/>
<PropertyValue Property="AcceptanceRangeHighValue" Decimal="6000000"/>
<PropertyValue Property="ToleranceRangeLowValue" Decimal="200000"/>
<PropertyValue Property="ToleranceRangeHighValue" Decimal="400000"/>
<PropertyValue Property="DeviationRangeLowValue" Decimal="0"/>
<PropertyValue Property="DeviationRangeHighValue" Decimal="199999"/>
</Record>
</PropertyValue>
</Record>
</Annotation>

Exercise for the readers


The above example will create a visual filter for currency field, similarly, you can go ahead and create two more visual filters for product ID and delivery month to make your ALP application filter bar looks like the screenshot I posted at the beginning of this blog.

a little help for the Surprise element in the exercise


Once you create other two visual filters and run your ALP application, you will notice that none of the visual filters is rendering. Because the batch call for all the visual filter is getting timed out as the backend public demo system do not support batch call (I guess).

To overcome this, you can mark your model in the manifest of your application to fire the call individually and do not batch them, by marking the property "useBatch" as false
"": {
"preload": true,
"dataSource": "mainService",
"settings": {
"defaultBindingMode": "TwoWay",
"defaultCountMode": "Inline",
"refreshAfterChange": false,
"useBatch": false,
"metadataUrlParams": {
"sap-value-list": "none"
}
}
}

Please note that this is just a workaround, in a productive scenario all the call must be batched for optimal performance of your application.

In my forthcoming blog where I explain ALP application developer extensions, I'll also discuss how can we group ALP visual filter batch calls for optimal performance.

A word of caution !!


We should never create more than one visual filter for one dimension. Like for in our example we have defined only one visual filter for each dimension i.e. currency, product and delivery. This is because let's say you have defined two visual filters like revenue by currency and quantity by currency and in first visual filter end-user have selected USD and in second visual filter, end-user have selected EUR then the final  query will be like currency eq 'USD' & currency eq 'EUR', which will never yield any results.

Conclusion


In this blog, we successfully configured the filter area of our ALP application and learnt about different settings for the filter area.

What Next?


In the next blog, I’ll about how to configure ALP's chart area.

 
13 Comments