Fiori Elements List Report – Visualising Data – Harvey Ball Micro Chart

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

2 Replies to “Fiori Elements List Report – Visualising Data – Harvey Ball Micro Chart

Leave a Reply