SAP Fiori Overview Page (OVP): Analytische Dashboards erstellen

kategorie
Fiori
Veröffentlicht
autor
Johannes

Die SAP Fiori Overview Page (OVP) ist ein maechtiges Dashboard-Template fuer analytische und transaktionale Anwendungen. Mit Karten (Cards) erstellst du kompakte, informationsdichte UIs fuer Management und Power User.

Was ist eine Overview Page?

Eine Overview Page ist ein Karten-basiertes Dashboard, das mehrere Informationsquellen auf einer Seite zusammenfuehrt. Jede Karte zeigt Daten aus einem eigenen OData-Service.

Typische Anwendungsfaelle

  • Executive Dashboard mit KPIs
  • Vertriebsuebersicht mit offenen Angeboten
  • Einkaufsmonitor mit Bestellstatus
  • Projektmanagement-Cockpit

Vorteile gegenueber List Report

AspektList ReportOverview Page
FokusEine EntityMehrere Entities
LayoutTabelle/FormularKarten-Grid
NavigationDrill-DownCross-App Navigation
ZielgruppeSachbearbeiterManager/Entscheider

OVP Architektur

+-----------------------------------------------+
| Overview Page |
| +----------+ +----------+ +----------+ |
| | List Card| |Chart Card| |Stack Card| |
| | (Orders)| | (Revenue)| | (Tasks) | |
| +----------+ +----------+ +----------+ |
| +----------+ +----------+ |
| |Table Card| | KPI Card | |
| | (Items) | | (Margin) | |
| +----------+ +----------+ |
+-----------------------------------------------+
| | |
OData Service Service Service
| | |
CDS View CDS View CDS View

Jede Karte:

  • Hat einen eigenen CDS View mit Annotations
  • Wird ueber einen Service Binding exponiert
  • Kann andere Filter und Darstellungen haben

Card-Typen im Ueberblick

Card-TypVerwendungVisualisierung
List CardTop-N ListenNummerierte Eintraege
Table CardTabellarische DatenSpalten-Layout
Chart CardKennzahlenBalken, Linien, Pie
Stack CardGruppierte ObjekteStapel mit Quick-View
KPI CardEinzelne KennzahlGrosse Zahl + Trend

List Card erstellen

Die List Card zeigt eine sortierte Liste von Eintraegen (z.B. “Top 5 offene Bestellungen”).

CDS View fuer List Card

@EndUserText.label: 'Open Orders for OVP'
@ObjectModel.query.implementedBy: 'ABAP:ZCL_OPEN_ORDERS'
@UI.presentationVariant: [{
sortOrder: [{
by: 'TotalAmount',
direction: #DESC
}],
maxItems: 5
}]
define view entity ZC_OVP_OpenOrders
as projection on ZI_Order
{
@UI.lineItem: [{ position: 10 }]
key OrderId,
@UI.lineItem: [{ position: 20 }]
CustomerName,
@UI.lineItem: [{ position: 30, importance: #HIGH }]
@Semantics.amount.currencyCode: 'Currency'
TotalAmount,
Currency,
@UI.lineItem: [{ position: 40, criticality: 'StatusCriticality' }]
Status,
@UI.hidden: true
StatusCriticality
}
where
Status = 'O' -- Open

Card Manifest Annotation

Die OVP-Karte wird in der manifest.json der Fiori-App konfiguriert:

{
"sap.ovp": {
"cards": {
"card_open_orders": {
"model": "mainModel",
"template": "sap.ovp.cards.list",
"settings": {
"title": "Offene Bestellungen",
"subTitle": "Top 5 nach Betrag",
"entitySet": "ZC_OVP_OpenOrders",
"listType": "extended",
"listFlavor": "bar",
"sortBy": "TotalAmount",
"sortOrder": "descending",
"defaultSpan": {
"rows": 3,
"cols": 1
}
}
}
}
}
}

List Card Varianten

listFlavorBeschreibung
standardEinfache Liste
barMit horizontalem Balken
carouselWischbare Karten

Table Card erstellen

Die Table Card zeigt Daten in Spaltenform, ideal fuer strukturierte Informationen.

CDS View fuer Table Card

@EndUserText.label: 'Order Items for OVP'
@UI.headerInfo: {
typeName: 'Position',
typeNamePlural: 'Positionen'
}
@UI.presentationVariant: [{
maxItems: 10
}]
define view entity ZC_OVP_OrderItems
as projection on ZI_OrderItem
{
@UI.lineItem: [{ position: 10 }]
key OrderId,
@UI.lineItem: [{ position: 20 }]
key ItemNumber,
@UI.lineItem: [{ position: 30 }]
MaterialNumber,
@UI.lineItem: [{ position: 40 }]
MaterialDescription,
@UI.lineItem: [{ position: 50 }]
@Semantics.quantity.unitOfMeasure: 'Unit'
Quantity,
Unit,
@UI.lineItem: [{ position: 60, criticality: 'DeliveryCriticality' }]
DeliveryStatus,
@UI.hidden: true
DeliveryCriticality
}

Table Card Manifest

{
"card_order_items": {
"model": "mainModel",
"template": "sap.ovp.cards.table",
"settings": {
"title": "Bestellpositionen",
"subTitle": "Lieferstatus",
"entitySet": "ZC_OVP_OrderItems",
"defaultSpan": {
"rows": 4,
"cols": 2
}
}
}
}

Chart Card erstellen

Chart Cards visualisieren Kennzahlen als Diagramme.

CDS View fuer Chart Card

@EndUserText.label: 'Sales Analytics for OVP'
@Analytics.dataCategory: #CUBE
@UI.chart: [{
qualifier: 'RevenueByMonth',
title: 'Umsatz nach Monat',
chartType: #COLUMN,
dimensions: ['CalendarMonth'],
measures: ['Revenue']
}]
define view entity ZC_OVP_SalesChart
as select from ZI_SalesData
{
@Analytics.dimension: true
@EndUserText.label: 'Monat'
key CalendarMonth,
@Analytics.measure: true
@Aggregation.default: #SUM
@Semantics.amount.currencyCode: 'Currency'
@EndUserText.label: 'Umsatz'
Revenue,
Currency
}

Chart Card Manifest

{
"card_revenue_chart": {
"model": "analyticsModel",
"template": "sap.ovp.cards.charts.analytical",
"settings": {
"title": "Monatlicher Umsatz",
"entitySet": "ZC_OVP_SalesChart",
"chartAnnotationPath": "com.sap.vocabularies.UI.v1.Chart#RevenueByMonth",
"defaultSpan": {
"rows": 3,
"cols": 2
}
}
}
}

Unterstuetzte Chart-Typen

chartTypeVisualisierung
#COLUMNSaeulendiagramm
#BARBalkendiagramm
#LINELiniendiagramm
#PIEKreisdiagramm
#DONUTRingdiagramm
#SCATTERPunktdiagramm
#BUBBLEBlasendiagramm
#HEATMAPWaermekarte

Mehrere Measures

@UI.chart: [{
qualifier: 'RevenueVsCost',
chartType: #COLUMN,
dimensions: ['CalendarMonth'],
measures: ['Revenue', 'Cost'],
measureAttributes: [{
measure: 'Revenue',
role: #AXIS_1
}, {
measure: 'Cost',
role: #AXIS_1
}]
}]

Stack Card erstellen

Die Stack Card gruppiert verwandte Objekte mit Quick-View-Funktion.

CDS View fuer Stack Card

@EndUserText.label: 'Tasks by Priority'
@UI.presentationVariant: [{
groupBy: ['Priority'],
sortOrder: [{
by: 'DueDate',
direction: #ASC
}]
}]
@UI.headerInfo: {
typeName: 'Aufgabe',
typeNamePlural: 'Aufgaben',
title: { value: 'TaskTitle' },
description: { value: 'AssigneeName' }
}
define view entity ZC_OVP_Tasks
as projection on ZI_Task
{
@UI.lineItem: [{ position: 10 }]
key TaskId,
@UI.lineItem: [{ position: 20 }]
TaskTitle,
@UI.lineItem: [{ position: 30 }]
AssigneeName,
@UI.lineItem: [{ position: 40, criticality: 'PriorityCriticality' }]
Priority,
@UI.lineItem: [{ position: 50 }]
DueDate,
@UI.hidden: true
PriorityCriticality
}

Stack Card Manifest

{
"card_tasks_stack": {
"model": "mainModel",
"template": "sap.ovp.cards.stack",
"settings": {
"title": "Meine Aufgaben",
"subTitle": "Nach Prioritaet gruppiert",
"entitySet": "ZC_OVP_Tasks",
"identificationAnnotationPath": "com.sap.vocabularies.UI.v1.Identification",
"objectStreamCardsSettings": {
"showFirstActionInFooter": true
},
"defaultSpan": {
"rows": 4,
"cols": 1
}
}
}
}

KPI Card mit Trend

KPI Cards zeigen eine einzelne Kennzahl mit Trendindikator.

CDS View fuer KPI Card

@EndUserText.label: 'Margin KPI'
@Analytics.dataCategory: #CUBE
@UI.chart: [{
qualifier: 'MarginKPI',
chartType: #BULLET,
measures: ['MarginPercent'],
measureAttributes: [{
measure: 'MarginPercent',
role: #AXIS_1
}]
}]
@UI.dataPoint: [{
qualifier: 'MarginDP',
title: 'Marge',
valueFormat: { scaleFactor: 1, numberOfFractionalDigits: 1 },
criticalityCalculation: {
improvementDirection: #MAXIMIZE,
toleranceRangeLowValue: 15,
deviationRangeLowValue: 10
},
trend: 'MarginTrend',
targetValue: 20
}]
define view entity ZC_OVP_MarginKPI
as select from ZI_MarginData
{
@Analytics.measure: true
@Aggregation.default: #AVG
MarginPercent,
-- Trend: 1 = Up, 0 = Stable, -1 = Down
MarginTrend
}

KPI Card Manifest

{
"card_margin_kpi": {
"model": "analyticsModel",
"template": "sap.ovp.cards.charts.analytical",
"settings": {
"title": "Durchschnittliche Marge",
"entitySet": "ZC_OVP_MarginKPI",
"dataPointAnnotationPath": "com.sap.vocabularies.UI.v1.DataPoint#MarginDP",
"chartAnnotationPath": "com.sap.vocabularies.UI.v1.Chart#MarginKPI",
"defaultSpan": {
"rows": 2,
"cols": 1
}
}
}
}

Criticality Calculation

Die automatische Ampel-Berechnung basiert auf:

ParameterBeschreibung
improvementDirection#MAXIMIZE, #MINIMIZE, #TARGET
toleranceRangeLowValueGrenze Gelb/Gruen (bei MAXIMIZE)
deviationRangeLowValueGrenze Rot/Gelb (bei MAXIMIZE)
targetValueZielwert fuer #TARGET

Globale Filter

OVP unterstuetzt globale Filter, die alle Karten gleichzeitig filtern.

Filter in CDS definieren

@UI.selectionField: [{ position: 10 }]
@Consumption.filter.selectionType: #SINGLE
SalesOrg,
@UI.selectionField: [{ position: 20 }]
@Consumption.filter.selectionType: #RANGE
OrderDate,
@UI.selectionField: [{ position: 30 }]
@Consumption.filter.selectionType: #MULTI
Status

Filter im Manifest aktivieren

{
"sap.ovp": {
"globalFilterModel": "mainModel",
"globalFilterEntitySet": "ZC_OVP_GlobalFilter",
"showDateInRelativeFormat": true,
"containerLayout": "resizable",
"enableLiveFilter": true,
"cards": { ... }
}
}

Karten koennen zu anderen Apps navigieren.

Intent-basierte Navigation

{
"card_open_orders": {
"settings": {
"navigation": "dataPointNav",
"identificationAnnotationPath": "com.sap.vocabularies.UI.v1.Identification",
"intentSemanticObject": "Order",
"intentAction": "display"
}
}
}

CDS Navigation Annotation

@UI.lineItem: [{
position: 10,
type: #WITH_INTENT_BASED_NAVIGATION,
semanticObjectAction: 'display'
}]
@Consumption.semanticObject: 'Order'
OrderId,

Responsive Layout

OVP Cards passen sich automatisch an verschiedene Bildschirmgroessen an.

Span-Konfiguration

{
"defaultSpan": {
"rows": 3, // Hoehe in Grid-Einheiten
"cols": 2, // Breite in Grid-Einheiten
"showOnlyHeader": false
}
}

Layout-Breakpoints

BreiteSpaltenEmpfehlung
< 600px1Mobile
600-1023px2Tablet
1024-1439px3Desktop
>= 1440px4Wide Desktop

Komplettes OVP Beispiel

manifest.json

{
"sap.app": {
"id": "z.sales.ovp",
"type": "application",
"title": "Sales Overview"
},
"sap.ovp": {
"globalFilterModel": "mainModel",
"globalFilterEntitySet": "ZC_OVP_GlobalFilter",
"containerLayout": "resizable",
"enableLiveFilter": true,
"cards": {
"card01_open_orders": {
"model": "mainModel",
"template": "sap.ovp.cards.list",
"settings": {
"title": "Offene Bestellungen",
"subTitle": "Top 5 nach Wert",
"entitySet": "ZC_OVP_OpenOrders",
"listFlavor": "bar",
"sortBy": "TotalAmount",
"sortOrder": "descending",
"defaultSpan": { "rows": 3, "cols": 1 }
}
},
"card02_revenue": {
"model": "analyticsModel",
"template": "sap.ovp.cards.charts.analytical",
"settings": {
"title": "Monatsumsatz",
"entitySet": "ZC_OVP_SalesChart",
"chartAnnotationPath": "com.sap.vocabularies.UI.v1.Chart#RevenueByMonth",
"defaultSpan": { "rows": 3, "cols": 2 }
}
},
"card03_tasks": {
"model": "mainModel",
"template": "sap.ovp.cards.stack",
"settings": {
"title": "Meine Aufgaben",
"entitySet": "ZC_OVP_Tasks",
"defaultSpan": { "rows": 4, "cols": 1 }
}
},
"card04_margin": {
"model": "analyticsModel",
"template": "sap.ovp.cards.charts.analytical",
"settings": {
"title": "Marge",
"entitySet": "ZC_OVP_MarginKPI",
"dataPointAnnotationPath": "com.sap.vocabularies.UI.v1.DataPoint#MarginDP",
"defaultSpan": { "rows": 2, "cols": 1 }
}
}
}
},
"sap.ui5": {
"models": {
"mainModel": {
"dataSource": "mainService",
"settings": { "defaultBindingMode": "TwoWay" }
},
"analyticsModel": {
"dataSource": "analyticsService",
"settings": { "defaultBindingMode": "OneWay" }
}
},
"dependencies": {
"libs": {
"sap.ovp": {}
}
}
}
}

Service Bindings fuer OVP

Fuer OVP werden typischerweise mehrere Service Bindings benoetigt:

Transaktionaler Service

@EndUserText.label: 'Sales OVP Service'
define service ZSB_SALES_OVP {
expose ZC_OVP_OpenOrders;
expose ZC_OVP_OrderItems;
expose ZC_OVP_Tasks;
expose ZC_OVP_GlobalFilter;
}

Analytischer Service

@EndUserText.label: 'Sales Analytics Service'
define service ZSB_SALES_ANALYTICS {
expose ZC_OVP_SalesChart;
expose ZC_OVP_MarginKPI;
}

Best Practices

Karten-Design

  1. Maximal 6-8 Karten pro OVP - zu viele ueberfordern
  2. Wichtigste Karten oben links - Leserichtung beachten
  3. Einheitliche Hoehe fuer benachbarte Karten
  4. Aussagekraeftige Titel - Was zeigt die Karte?

Performance

  1. Aggregationen auf DB-Ebene - Nicht in ABAP berechnen
  2. maxItems begrenzen - Nicht mehr als 10-20 Eintraege
  3. Separate Services fuer Analytics vs. Transaktional
  4. Lazy Loading - Karten laden bei Bedarf

Annotations

-- Gute Praxis: Presentation Variant definieren
@UI.presentationVariant: [{
qualifier: 'Default',
sortOrder: [{ by: 'Priority', direction: #DESC }],
maxItems: 5,
visualizations: [{
type: #AS_LINEITEM
}]
}]

Haeufige Fehler

ProblemUrsacheLoesung
Karte leerFalscher EntitySetService Binding pruefen
Keine AggregationAnalytics Annotations fehlen@Analytics.measure hinzufuegen
Filter wirkt nichtglobalFilterEntitySet falschGleiche Entity fuer Filter verwenden
Chart zeigt nichtschartAnnotationPath falschQualifier in CDS pruefen

Verwandte Themen


Zusammenfassung

Die Fiori Overview Page eignet sich hervorragend fuer:

  • Management-Dashboards mit KPIs
  • Ueberblicksseiten mit mehreren Datenquellen
  • Quick-Access zu wichtigen Informationen

Kern-Annotations:

  • @UI.chart fuer Chart Cards
  • @UI.dataPoint fuer KPI Cards
  • @UI.presentationVariant fuer Sortierung und Limits
  • @Analytics.measure/dimension fuer Aggregationen

Mit der richtigen Kombination aus CDS Views und manifest.json-Konfiguration erstellst du informative Dashboards ohne SAPUI5-Code.