Introduction
I've been exploring CAP lately and this time, I thought of creating a Fiori
Ovierview Page (OVP) on top of CAP.
In OVP, charts are important elements for helping data visualization.
What is OVP in general and how to create them is explained in detail in
ashish.anand4's
blog series.
In this blog, I'm going to share my experience on creating charts on top of CAP service.
Actually, I haven't been able to add UI.Chart annotation directly on CAP, and resorted to Fiori elements app's local annotation. If someone knows how to do this, please let me know in the comments section below.
update: Thanks to
oliver.klemenz, the app is running without local annotations.
The code is available at my
GitHub repository.
Context
I'm going to develop a simple OVP app which shows past expenses and aggregated expenses grouped by category. The app will look like below picture.
Developing Environment
Steps
- Create a CAP service
- Create a OVP app
1. Create a CAP service
1.1. Create
db/schema.cds.
I refereed to
gregorw's
GitHub repository and got the idea about how to create an entity capable of showing aggregated values.
First I created a simple
Expenses entity and added a view
ExpensisAnalyitcs which aggregates its amount.
namespace demo.aggregate;
using { Currency, cuid } from '@sap/cds/common';
entity Expenses : cuid {
category: String @title: 'Category';
amount: Decimal(9,2) @title: 'Amount';
currency: Currency @title: 'Currency';
postingDate: DateTime @title: 'Posting Date'
}
@Aggregation.ApplySupported.PropertyRestrictions: true
view ExpensesAnalytics as select from Expenses {
key ID,
@Analytics.Dimension: true
category,
@Analytics.Measure: true
@Aggregation.default: #SUM
amount,
@Analytics.Dimension: true
currency
};
1.2. Create
srv/cat-service.cds.
I simply exposed the two entities and added UI annotations.
using demo.aggregate as db from '../db/schema';
service CatalogService {
entity Expenses as projection on db.Expenses
view ExpensesAnalytics as select from db.ExpensesAnalytics
}
annotate CatalogService.ExpensesAnalytics with @(
UI: {
Chart: {
$Type: 'UI.ChartDefinitionType',
ChartType: #Donut,
Measures: ['amount'],
MeasureAttributes: [{
$Type: 'UI.ChartMeasureAttributeType',
Measure: 'amount',
Role: #Axis1
}],
Dimensions: ['category'],
DimensionAttributes: [{
$Type: 'UI.ChartDimensionAttributeType',
Dimension: 'category',
Role: #Category
}]
}
}
);
annotate CatalogService.Expenses with @(
UI: {
SelectionFields: [postingDate, category],
LineItem: [
{ Value: postingDate },
{ Value: category },
{ Value: amount },
{ Value: currency_code }
],
}
);
1.3. Adapt CAP service to OData v2.
CAP services needs to be adapted to OData v2 to be consumed by Fiori Tools.
For this, use
@sap/cds-odata-v2-adapter-proxy.
The settings are described in my previous
blog.
2. Create a OVP app
Next, add a OVP app within the same project. I used
Fiori Tools for generating the app.
2.1. Generate a Fiori project
1. Select Overview Page from the templates.
2. Select
Connect to an OData Source as Data source, and specify your local CAP OData URL:
http://localhost:4004/v2/catalog/
3. Select “Expenses” as Filter Entity.
4. Type below information.
Module Name |
ovptest |
Title |
OVP Test |
Namespace |
demo |
Description |
OVP Test |
Project Folder |
Your CAP project’s root folder |
5. Move to
ovptest folder you’ve just created and run the app.
npm start
At this moment, nothing is there (even the filter!).
2.2. Add a Global Filter
In
ovptest/webapp/manifest.json, fill in globalFilterEntityType.
"sap.ovp": {
"globalFilterModel": "mainService",
"globalFilterEntityType": "Expenses",
"containerLayout": "resizable",
"enableLiveFilter": true,
"considerAnalyticalParameters": false,
"cards": {}
}
As soon as you do so, the FilterBar will appear.
2.3. Add a List Card
Add below settings to
ovptest/webapp/manifest.json.
"sap.ovp": {
...
"cards": {
"list01": {
"model": "mainService",
"template": "sap.ovp.cards.list",
"settings": {
"title": "Expense List",
"entitySet": "Expenses",
"identificationAnnotationPath": "com.sap.vocabularies.UI.v1.Identification",
"presentationAnnotationPath": "com.sap.vocabularies.UI.v1.PresentationVariant#Default",
"annotationPath": "com.sap.vocabularies.UI.v1.LineItem"
}
}
}
A list card will be shown.
2.4. Add a Donut Chart
Add below settings to
ovptest/webapp/manifest.json, below "list01" card.
For the chart I'm using aggregated entity:
ExpensesAnalytics.
"chart01": {
"model": "mainService",
"template": "sap.ovp.cards.charts.analytical",
"settings": {
"title": "Expense Chart",
"entitySet": "ExpensesAnalytics",
"chartAnnotationPath": "com.sap.vocabularies.UI.v1.Chart"
}
}
The chart has been loaded, and we can observe that it's showing aggregated amount.
For comparison, I added the same chart on top of normal Expenses entity.
Resulting chart is not aggregated as shown below.
Conclusion
These are what I've learned so far:
- To show aggregated chart on Fiori elements app, the base entity requires @Aggregation annotation.
UI.Chart annotation on CAP doesn't seem to work and one has to add local annotation to Fiori elements apps.
References