The blog explains how to use Harvey Ball Micro Chart in List and Object page with CDS Annotations. Harvey Ball Micro Chart visualise a value compared to its total. Unlike the pie chart which plots multiple values or sections, Harvey Ball Micro Chart visualise just one value from a total. Semantic colours to shows a positive, critical, or negative state can also be specified.
CDS ZI_FlightBooking
To start with I have CDS view ZI_FlightBooking exposing table SFLIGHT fields. In Harvey Ball Micro Chart we will be plotting Occupancy_Economy against Capacity_Economy. OccupancyLevel_Economy is occupancy percentage which will be used for semantic colours.
@AbapCatalog.sqlViewName: 'ZIFLBOOK'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Flight Booking'
define view ZI_FlightBooking
as select from sflight
association [*] to S_Bookings as _Bookings on $projection.CarrierId = _Bookings.CarrierId
and $projection.ConnectionId = _Bookings.ConnectionId
and $projection.FlightDate = _Bookings.FlightDate
{
key carrid as CarrierId,
key connid as ConnectionId,
key fldate as FlightDate,
planetype as PlaneType,
price as Price,
paymentsum as TotalPayment,
currency as CurrencyCode,
seatsmax as Capacity_Economy,
seatsocc as Occupancy_Economy,
seatsmax_b as Capacity_Business,
seatsocc_b as Occupancy_Business,
seatsmax_f as Capacity_First,
seatsocc_f as Occupancy_First,
division( seatsocc , seatsmax , 2 ) * 100 as OccupancyLevel_Economy,
division( seatsocc_b , seatsmax_b , 2 ) * 100 as OccupancyLevel_Business,
division( seatsocc_f , seatsmax_f , 2 ) * 100 as OccupancyLevel_First,
_Bookings
}
CDS ZFlight_HMC
Secondly, I’ve CDS view ZFlight_HMC which is built on ZI_FlightBooking. Here I have added field CriticalEconomy. CriticalEconomy field derives semantic colour number based on OccupancyLevel_Economy. Metadata extension is allowed and the rest of the annotation will be added in the metadata extension file.
@AbapCatalog.sqlViewName: 'ZFLIGHT2'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Flight Bookings Havey MicroChart'
@Metadata.allowExtensions: true
define view ZFLIGHT_HMC
as select from ZI_FlightBooking
association [1] to S_Carrier as _Carrier on $projection.CarrierId = _Carrier.CarrierId
{
@ObjectModel.text.element: ['CarrierName']
key CarrierId,
key ConnectionId,
key FlightDate,
@Semantics.text: true
_Carrier.Name as CarrierName,
PlaneType,
Price,
@Semantics.amount.currencyCode: 'CurrencyCode'
TotalPayment,
@Semantics.currencyCode: true
CurrencyCode,
Capacity_Economy,
Occupancy_Economy,
case when OccupancyLevel_Economy >= 75 then 3
when OccupancyLevel_Economy >= 50 then 2
else 1 end as CriticalEconomy,
_Bookings,
_Carrier
}
Metadata Extension
And this is metadata extension file which renders Fiori Element List Report with Object Page with identification facet in it.
@Metadata.layer: #CORE
@UI.headerInfo: { typeName: 'Flight' ,
typeNamePlural: 'Fights',
title: { value: 'CarrierName' } }
annotate view ZFLIGHT_HMC with
{
@UI.facet: [
{ id:'idGeneralInformation' ,
type: #COLLECTION ,
label: 'General Information' ,
position: 10 } ,
{ type: #IDENTIFICATION_REFERENCE ,
label : 'General Information',
parentId: 'idGeneralInformation',
id: 'idIdentification' ,
position: 10 } ]
@UI.selectionField: [{ position: 10 }]
@UI.lineItem: [{ position: 10 }]
@UI.identification: [{ position: 10 }]
CarrierId;
@UI.selectionField: [{ position: 20 }]
@UI.lineItem: [{ position: 20 }]
@UI.identification: [{ position: 20 }]
ConnectionId;
@UI.selectionField: [{ position: 30 }]
@UI.lineItem: [{ position: 30 }]
@UI.identification: [{ position: 30 }]
FlightDate;
@UI.selectionField: [{ position: 40 }]
@UI.lineItem: [{ position: 40 }]
PlaneType;
@UI.lineItem: [{ position: 50 }]
TotalPayment;
@UI.lineItem: [{ position: 60 }]
@UI.dataPoint: { criticality: 'CriticalEconomy' }
Occupancy_Economy;
}
List Report App
At this point you will get this List Report an Object Page app in WebIDE. Note field Occupancy_Economy has annotation @UI.dataPoint with criticality set to use field CriticalEconomy.
Next we will look at Harvey Ball Micro Chart related annotations.
Harvey Ball Micro Chart Annotations
Following annotations are added Metadata Extension file
@UI.chart – defines the chart. We specify the field which we will be plotting, Occupany_Economy in this case.
@UI.presentationVariant.requestAtLeast – we need fields Occupancy_Economy, Capacity_Economy and CriticalEconomy selected by the app in order to render the chart properly.
@UI.lineItem – Here we have specified type: #AS_CHART. Also, note that valueQualifier is referring to qualifier or @UI.chart. This way you can have multiple charts defined in CDS view and still be able to refer them uniquely.
@Metadata.layer: #CORE
@UI.headerInfo: { typeName: 'Flight' ,
typeNamePlural: 'Fights',
title: { value: 'CarrierName' } }
@UI.chart: [{ qualifier: 'qualEconomy' ,
chartType: #PIE ,
measures: ['Occupancy_Economy'],
measureAttributes: [{
measure: 'Occupancy_Economy' ,
asDataPoint: true
}]
}]
@UI.presentationVariant: [
{
requestAtLeast:[
'Occupancy_Economy',
'Capacity_Economy',
'CriticalEconomy' ] } ]
annotate view ZFLIGHT_HMC with
{
@UI.facet: [
{ id:'idGeneralInformation' ,
type: #COLLECTION ,
label: 'General Information' ,
position: 10 } ,
{ type: #IDENTIFICATION_REFERENCE ,
label : 'General Information',
parentId: 'idGeneralInformation',
id: 'idIdentification' ,
position: 10 } ]
@UI.selectionField: [{ position: 10 }]
@UI.lineItem: [{ position: 10 }]
@UI.identification: [{ position: 10 }]
CarrierId;
@UI.selectionField: [{ position: 20 }]
@UI.lineItem: [{ position: 20 }]
@UI.identification: [{ position: 20 }]
ConnectionId;
@UI.selectionField: [{ position: 30 }]
@UI.lineItem: [{ position: 30 }]
@UI.identification: [{ position: 30 }]
FlightDate;
@UI.selectionField: [{ position: 40 }]
@UI.lineItem: [{ position: 40 }]
PlaneType;
@UI.lineItem: [{ position: 50 }]
TotalPayment;
@UI.lineItem: [{ position: 60 ,
type: #AS_CHART,
valueQualifier: 'qualEconomy',
label: 'Occupied Economy' }]
@UI.dataPoint: { criticality: 'CriticalEconomy' }
Occupancy_Economy;
}
If you refresh the app at this point you would see chart placeholder in the List Report but without any chart.
The issue is we haven’t yet defined the maximum value Capacity_Economy. Usually, this goes in @UI.dataPoint.maximumValue but in Onprem S4 1909 version (which I am using) this annotation accepts decimal float value i.e. I can specify a number e.g 300 here but I cannot specify the name of the field where is maximum value is.
You can see in below screenshot that Eclipse is complaining about field name Capacity_Economy in the annotation @UI.dataPoint.maximumValue.
Local Annotation
To get around this issue override the @UI.dataPoint annotation in local annotation file and add MaximumValue to it. Make sure to choose ‘Path’ and specify Capacity_Economy field as target.
You will now see Harvey Ball Micro Chart in List Report.
Adding Chart to Object Page
To add this chart in Object page we will have to use Facet of type: #CHART_REFERENCE with targetQualifier.
@Metadata.layer: #CORE
@UI.headerInfo: { typeName: 'Flight' ,
typeNamePlural: 'Fights',
title: { value: 'CarrierName' } }
@UI.chart: [{ qualifier: 'qualEconomy' ,
chartType: #PIE ,
measures: ['Occupancy_Economy'],
measureAttributes: [{
measure: 'Occupancy_Economy' ,
asDataPoint: true
}]
}]
@UI.presentationVariant: [
{
requestAtLeast:[
'Occupancy_Economy',
'Capacity_Economy',
'CriticalEconomy' ] } ]
annotate view ZFLIGHT_HMC with
{
@UI.facet: [
{ id : 'idHeaderEco' ,
type: #CHART_REFERENCE ,
label: 'Header' ,
purpose: #HEADER ,
targetQualifier: 'qualEconomy'} ,
{ id:'idGeneralInformation' ,
type: #COLLECTION ,
label: 'General Information' ,
position: 10 } ,
{ type: #IDENTIFICATION_REFERENCE ,
label : 'General Information',
parentId: 'idGeneralInformation',
id: 'idIdentification' ,
position: 10 } ]
@UI.selectionField: [{ position: 10 }]
@UI.lineItem: [{ position: 10 }]
@UI.identification: [{ position: 10 }]
CarrierId;
@UI.selectionField: [{ position: 20 }]
@UI.lineItem: [{ position: 20 }]
@UI.identification: [{ position: 20 }]
ConnectionId;
@UI.selectionField: [{ position: 30 }]
@UI.lineItem: [{ position: 30 }]
@UI.identification: [{ position: 30 }]
FlightDate;
@UI.selectionField: [{ position: 40 }]
@UI.lineItem: [{ position: 40 }]
PlaneType;
@UI.lineItem: [{ position: 50 }]
TotalPayment;
@UI.lineItem: [{ position: 60 ,
type: #AS_CHART,
valueQualifier: 'qualEconomy',
label: 'Occupied Economy' }]
@UI.dataPoint: { criticality: 'CriticalEconomy' }
Occupancy_Economy;
}
There, you have it in List and Object Pages.
Below XML annotation and screen shot from Annotation Modeler. This would help if you need to develop this using location annotation instead of CDS,
XML Annotations
Chart
<Annotation Term="UI.Chart" Qualifier="qualEconomy">
<Record Type="UI.ChartDefinitionType">
<PropertyValue Property="ChartType" EnumMember="UI.ChartType/Pie"/>
<PropertyValue Property="Measures">
<Collection>
<PropertyPath>Occupancy_Economy</PropertyPath>
</Collection>
</PropertyValue>
<PropertyValue Property="MeasureAttributes">
<Collection>
<Record Type="UI.ChartMeasureAttributeType">
<PropertyValue Property="Measure" PropertyPath="Occupancy_Economy"/>
<PropertyValue Property="Role" EnumMember="UI.ChartMeasureRoleType/Axis1"/>
<PropertyValue Property="DataPoint" AnnotationPath="@UI.DataPoint#Occupancy_Economy"/>
</Record>
</Collection>
</PropertyValue>
</Record>
</Annotation>
DataPoint
<Annotation Term="UI.DataPoint" Qualifier="Occupancy_Economy">
<Record Type="UI.DataPointType">
<PropertyValue Property="Value" Path="Occupancy_Economy"/>
<PropertyValue Property="Title" String="Occupied econ."/>
<PropertyValue Property="Criticality" Path="CriticalEconomy"/>
<PropertyValue Property="MaximumValue" Path="Capacity_Economy"/>
</Record>
</Annotation>
LineItem
<Annotation Term="UI.LineItem">
<Collection>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="CarrierId"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="ConnectionId"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="FlightDate"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="PlaneType"/>
</Record>
<Record Type="UI.DataField">
<PropertyValue Property="Value" Path="TotalPayment"/>
</Record>
<Record Type="UI.DataFieldForAnnotation">
<PropertyValue Property="Label" String="Occupied Economy"/>
<PropertyValue Property="Target" AnnotationPath="@UI.Chart#qualEconomy"/>
</Record>
</Collection>
</Annotation>
HeaderFacet
<Annotation Term="UI.HeaderFacets">
<Collection>
<Record Type="UI.ReferenceFacet">
<PropertyValue Property="Label" String="Header"/>
<PropertyValue Property="ID" String="idHeaderEco"/>
<PropertyValue Property="Target" AnnotationPath="@UI.Chart#qualEconomy"/>
</Record>
</Collection>
</Annotation>
Annotation Modeler
Chart
DataPoint
LineItem
HeaderFacet
Do you know how to set size for the micro chart e.g. S (Small) or XS (Extra Small)?
Hello, I don’t think you can control size through annotation. You could add microchart using column extension to list report which gives you more control on how it is rendered and it will also allow you to specify the size.
https://blogs.sap.com/2020/12/19/fiori-elements-stacked-bar-micro-chart-in-list-report/
Css might be another way of changing the size.