**TITLE**: Configuring Analytical List Page (ALP) App Extensions for SAP Fiori elements (OData V2)

**INTRODUCTION**: This document provides concise, code-focused steps to extend and configure Analytical List Page (ALP) apps built with SAP Fiori elements (OData V2). It summarizes where to place extension configuration (manifest.json), how to register controller extensions, where to implement Component-level refresh logic, and which extension types to implement (charts, tables, custom filters, custom actions, message strip). Use the provided skeletons to implement extension points and wiring in your project.

**TAGS**: fiori-elements-framework, ALP, analytical-list-page, OData V2, manifest.json, Component.js, controllerExtensions, smart-table, chart, custom-filters, custom-actions, message-strip

STEP: 1 — Applicability and prerequisites

DESCRIPTION: Confirm applicability and prerequisites before implementing ALP extensions. This entire extension workflow applies only to SAP Fiori elements for OData V2. Ensure your project uses the ALP floorplan and has standard files: webapp/manifest.json and webapp/Component.js (or equivalent component bootstrap).

LANGUAGE: Text

CODE:
```text
Applicability: SAP Fiori elements — Analytical List Page (ALP) for OData V2 only.
Required files: webapp/manifest.json, webapp/Component.js, webapp/controller/, webapp/ext/ (optional)
Related docs to consult while implementing:
- Analytical List Page
- Refresh API (Component.js)
- Smart Table Extensions
- Chart Extensions
- Creating Custom Filters
- Defining Custom Actions
- Adding a Custom Message Strip
```

STEP: 2 — Register a controller extension in manifest.json

DESCRIPTION: Register your custom controller to extend the ALP controller using sap.ui.controllerExtensions in manifest.json. This tells the framework to load your controller that can implement hooks for charts, tables, toolbar, and custom actions. Keep the key exactly matching the ALP controller: "sap.suite.ui.generic.template.AnalyticalListPage.view.AnalyticalListPage".

LANGUAGE: JSON

CODE:
```json
{
  "sap.ui5": {
    "extends": {
      "extensions": {
        "sap.ui.controllerExtensions": {
          "sap.suite.ui.generic.template.AnalyticalListPage.view.AnalyticalListPage": {
            "controllerName": "my.namespace.ext.AnalyticalListPageController"
          }
        }
      }
    }
  }
}
```

STEP: 3 — Create the controller extension skeleton

DESCRIPTION: Implement the controller file referenced by manifest.json. Use the controller to attach handlers for chart events, table custom actions, and view extension points. Keep methods small and focused. Example skeleton shows standard onInit override and placeholders for handler functions.

LANGUAGE: JavaScript

CODE:
```javascript
// File: webapp/ext/AnalyticalListPageController.js
sap.ui.define([
  "sap/ui/core/mvc/Controller"
], function(Controller) {
  "use strict";

  return Controller.extend("my.namespace.ext.AnalyticalListPageController", {
    onInit: function() {
      // Initialization logic, e.g., attach to view models or register event handlers
    },

    // Example handler invoked by custom action configured in annotations/manifest
    onCustomAction: function(oEvent) {
      // read selected contexts, perform action, refresh bindings if needed
    },

    // Example chart select handler
    onChartSelect: function(oEvent) {
      // implement drilldown or navigation logic
    }
  });
});
```

STEP: 4 — Implement Component-level refresh behavior (refresh API)

DESCRIPTION: Use the Component-level refresh mechanism to refresh header, filter, and content area elements. If you need to programmatically refresh the ALP binding sets (for example after a backend action), implement a helper on the Component to call the model refresh API or framework-provided refresh method. The example shows a safe, generic approach using the ODataModel refresh; adapt to your template/framework API if a framework-specific refreshBinding function exists.

LANGUAGE: JavaScript

CODE:
```javascript
// File: webapp/Component.js
sap.ui.define([
  "sap/ui/core/UIComponent"
], function(UIComponent) {
  "use strict";

  return UIComponent.extend("my.namespace.Component", {
    metadata: {
      manifest: "json"
    },

    // Generic refresh helper (adapt to template-specific API if available)
    refreshAllBindings: function() {
      // For ODataModel
      var oModel = this.getModel();
      if (oModel && typeof oModel.refresh === "function") {
        // true -> reload from server; set bIncludePendingChanges as appropriate
        oModel.refresh(true);
      }

      // If using framework-provided refreshBinding API, call it here instead.
      // Example placeholder: this._oTemplateContract.refreshBinding();
    }
  });
});
```

STEP: 5 — Add custom actions (chart / table / global) via annotations + manifest wiring

DESCRIPTION: Define custom actions in annotations (or metadata) and ensure the UI wiring points to your controller handlers. Custom actions can be scoped to chart, table, or global toolbar. Implement the logic in the controller extension created earlier and refresh bindings via Component helper as needed. Keep action definitions in annotation files and manifest wiring consistent.

LANGUAGE: Text

CODE:
```text
Action implementation checklist:
1. Add custom action annotation(s) to your OData V2 annotations file (XML) or CDS annotations.
2. Ensure action uses correct 'appliesTo' target (Chart/Table/Global).
3. Implement a controller handler (e.g., onCustomAction) referenced by the action (manifest/controllerExtension).
4. From handler, call this.getOwnerComponent().refreshAllBindings() or appropriate framework refresh.
References:
- Use "Defining Custom Actions" doc for annotation structure and manifest wiring.
```

STEP: 6 — Extend Smart Table behavior

DESCRIPTION: To add custom table actions or modify table behavior, use Smart Table extension points and annotations. Configure table-level custom actions using annotation-driven approaches and add controller handlers for action logic and UI modifications.

LANGUAGE: Text

CODE:
```text
Smart Table extension checklist:
1. Define custom actions in annotation (Action or UI.LineItem related annotations).
2. Use manifest/controllerExtensions to point to your extension controller.
3. In controller, capture table events (e.g., selectionChange, actions) and implement logic.
4. Refresh table binding if action changes backend state: this.getOwnerComponent().refreshAllBindings().
Reference: Smart Table Extensions documentation.
```

STEP: 7 — Extend Chart behavior

DESCRIPTION: Define chart actions and drilldown behavior via annotations and implement handlers in the controller extension. Charts can host custom actions that must be wired to controller methods.

LANGUAGE: Text

CODE:
```text
Chart extension checklist:
1. Use chart-specific annotations for toolbar actions and drilldown configuration.
2. Wire actions to controller extension handlers via manifest/controllerExtensions.
3. Implement selection and action handlers to navigate, filter, or call backend actions.
4. After backend changes, refresh content and KPI via component refresh helper.
Reference: Chart Extensions documentation.
```

STEP: 8 — Add custom filters and KPI tags

DESCRIPTION: Implement custom filters (for compact filters and KPI tags) by extending annotations and wiring any required control fragments. Use the controller extension to manage custom filter lifecycle and update the filter bar programmatically when needed.

LANGUAGE: Text

CODE:
```text
Custom filters implementation checklist:
1. Define custom filter fields in annotations or add a filter bar fragment.
2. Wire the fragment via manifest/extensionPoint or controllerExtensions.
3. In controller, respond to filter change events and update the list/table bindings.
4. Update KPI tags programmatically when filters change (retrieve values and set them).
Reference: Creating Custom Filters documentation.
```

STEP: 9 — Add a custom message strip above the table

DESCRIPTION: To show custom texts above the table, add a message strip fragment and include it within the ALP view using the available extension point. Register the fragment in manifest or load it programmatically from the controller extension.

LANGUAGE: Text

CODE:
```text
Message strip extension checklist:
1. Create an XML fragment for the message strip (e.g., webapp/ext/MessageStrip.fragment.xml).
2. Insert the fragment via a view extension point or load/attach it in your controller's onInit:
   - this.byId("yourExtensionPlaceholder").addContent(sFragment);
3. Control visibility and text from the controller based on application state.
Reference: Adding a Custom Message Strip to List Report and Analytical List Page documentation.
```

STEP: 10 — Cross-reference and additional resources

DESCRIPTION: Use the related documents while implementing each step. They contain detailed examples for annotations, manifest wiring, and framework-specific APIs.

LANGUAGE: Text

CODE:
```text
Related documentation to consult:
- Analytical List Page (ALP)
- Refresh API (Component.js)
- Smart Table Extensions
- Chart Extensions
- Creating Custom Filters
- Defining Custom Actions
- Adding a Custom Message Strip to List Report and Analytical List Page
```

fiori-elements-framework
ALP
analytical-list-page
OData V2
manifest.json
Component.js
controllerExtensions
smart-table
chart
custom-filters
custom-actions
message-strip


**TITLE**: Configuring Card Filters (SelectionVariant and URL filters)

**INTRODUCTION**: How to add and configure filters for SAP Fiori cards and overview pages using the com.sap.vocabularies.UI.v1.SelectionVariant annotation or by passing filter parameters in the URL. Includes XML annotation example, CAP CDS example, ABAP CDS guidance, and URL filter usage notes.

**TAGS**: fiori-elements-framework, annotations, selectionvariant, card-filters, CAP, ABAP, XML, CDS, URL-filters

**STEP**: 1 — Add filters via XML Annotation (SelectionVariant)

**DESCRIPTION**: Use the com.sap.vocabularies.UI.v1.SelectionVariant annotation on a card/entity to define filter SelectOptions. You can provide multiple SelectOptions. The example filters records by the TotalSum property to return values between 0 and 8000. Keep the annotation Qualifier to reference it from card definitions.

**LANGUAGE**: XML

**CODE**:
```xml
<Annotation Term="com.sap.vocabularies.UI.v1.SelectionVariant" Qualifier="bubble">
    <Record>
        <PropertyValue Property="SelectOptions">
            <Collection>
            <Record>
               <PropertyValue Property="PropertyName" PropertyPath="TotalSum" />
               <PropertyValue Property="Ranges">
                  <Collection>
                     <Record>
                        <PropertyValue Property="Sign"
                           EnumMember="com.sap.vocabularies.UI.v1.SelectionRangeSignType/I" />
                        <PropertyValue Property="Option"
                           EnumMember="com.sap.vocabularies.UI.v1.SelectionRangeOptionType/BT" />
                        <PropertyValue Property="Low" String="0" />
                        <PropertyValue Property="High" String="8000" />
                     </Record>
                  </Collection>
               </PropertyValue>
            </Record>
            </Collection>
        </PropertyValue>
    </Record>
</Annotation>
```

**STEP**: 2 — Add filters via CAP CDS (UI.SelectionVariant)

**DESCRIPTION**: For CAP projects, define UI.SelectionVariant with SelectOptions containing PropertyName and Ranges. Use Sign and Option enums (#I, #BT) and provide Low/High as strings. This will be applied to the generated metadata and used by cards.

**LANGUAGE**: CDS

**CODE**:
```

UI.SelectionVariant #bubble: {
    SelectOptions: [
        {
            PropertyName: TotalSum,
            Ranges: [
                {
                    Sign: #I,
                    Option: #BT,
                    Low: '0',
                    High: '8000'
                }
            ]
        }
    ]
}
```

**STEP**: 3 — ABAP CDS Guidance

**DESCRIPTION**: If using ABAP CDS, there is no sample ABAP CDS annotation provided here. Use the local XML annotation (SelectionVariant) in the service metadata if ABAP CDS sample is not available.

**LANGUAGE**: ABAP CDS

**CODE**:
```abap
-- No ABAP CDS annotation sample is provided. Use the XML SelectionVariant annotation shown in Step 1.
```

**STEP**: 4 — Use URL filter parameters for Overview Pages

**DESCRIPTION**: You can set filters when launching Fiori overview pages by appending filter parameters to the URL. Only string or integer values are accepted. The filter is applied automatically if the filter property exists in the entity set. Use this method when launching pages from FLP or other applications.

**LANGUAGE**: URL

**CODE**:
```
Example URL:
http://abc#Equipment-overviewPage?EquipmentNumber=123456
```

**STEP**: 5 — Currency Display Preference

**DESCRIPTION**: The currency display on cards follows the SAP Fiori Launchpad user settings. The DisplayCurrency field of the application in the FLP user settings determines how currency values are shown. No additional annotation is required for this preference.

fiori-elements-framework annotations selectionvariant card-filters CAP ABAP XML CDS URL-filters


**TITLE**: Configuring Card Navigation for SAP Fiori Overview Pages (OVP)

**INTRODUCTION**: This doc shows how to configure card navigation for SAP Fiori overview pages (OVP). It covers intent-based navigation (DataFieldForIntentBasedNavigation), URL navigation (DataFieldWithUrl), how to reference Identification and LineItem annotations from manifest.json, custom navigation extensions (doCustomNavigation), and adding staticParameters in the manifest to pass navigation parameters.

**TAGS**: fiori-elements-framework, sap-ovp, manifest.json, annotations, DataFieldForIntentBasedNavigation, DataFieldWithUrl, custom-navigation, doCustomNavigation, staticParameters

STEP: Navigation annotation types and behavior

DESCRIPTION: Use these annotation terms to configure navigation on OVP cards. Key points:
- DataFieldForIntentBasedNavigation — configure intent-based navigation to another Fiori app (semanticObject + action).
- DataFieldWithUrl — configure external URL navigation (opens in new tab) or construct a URL for a specific application route.
- Only list/table cards can pass single-record context to the navigation destination; provide navigation config in com.sap.vocabularies.UI.v1.LineItem for that behavior.
- If multiple navigation records exist in Identification or LineItem, the first record is used. Records are sorted by ImportanceType and order of entry.

LANGUAGE: Text

CODE:
```text
Navigation information is taken from the `com.sap.vocabularies.UI.v1.Identification`

-   `com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation`: Used to define intent-based navigation to SAP Fiori application.

-   `com.sap.vocabularies.UI.v1.DataFieldWithUrl term`: Used to configure navigation to external apps and websites.

The recommended way to configure intent-based navigation is to use `DataFieldForIntentBasedNavigation`. However, if navigation to a specific application is required and the route isn't configured as a target mapping, you can use `DataFieldWithUrl` to construct the specific application. The overview page identifies this as an intent-based navigation and open the target application in the relevant context in the same tab.

Note that information about the single record selected can only be passed to the navigation destination only from list or table cards. To enable this behavior, provide navigation configuration in the `com.sap.vocabularies.UI.v1.LineItem` term used by the specific card.

If more than one navigation record is provided in the `com.sap.vocabularies.UI.v1.Identification` or `com.sap.vocabularies.UI.v1.LineItem` terms, the first record is used for each term. The navigation records are sorted according to their importance, set in the`com.sap.vocabularies.UI.v1.ImportanceType` annotation, and their order of entry.
```

STEP: Reference Identification annotation from manifest.json

DESCRIPTION: Configure the identificationAnnotationPath (optionally with a qualifier) in the card settings to point to the Identification annotation to use for card-level navigation. If not configured, the unqualified com.sap.vocabularies.UI.v1.Identification term is used.

LANGUAGE: JSON

CODE:
```json
"sap.ovp": {
    ...
    "cards": {
        ...
        "card04": {
            "model": "ZCD204_EPM_DEMO_SRV",
            "template": "sap.ovp.cards.list",
            "settings": {
                "sortBy": "Price",
                "sortOrder": "descending",
                "listFlavor": "bar",
                "annotationPath": "com.sap.vocabularies.UI.v1.LineItem#bar",
                "identificationAnnotationPath": "com.sap.vocabularies.UI.v1.Identification#bar",
                "category": "{{card04_category}}",
                "entitySet": "Products"
            }
        },
        ...
    }
}
```

STEP: Enable custom navigation via controller extension

DESCRIPTION: To provide multiple or conditional navigation targets per card/line item, extend the OVP main controller and implement doCustomNavigation. First, add a controller extension to the manifest to register your extended controller.

LANGUAGE: JSON

CODE:
```json
"extends": {
            "extensions": {
                "sap.ui.controllerExtensions": {
                    "sap.ovp.app.Main": {
                        "controllerName": "my_app.ext.controller.OverViewPageExt"
                    }
                }
            }
        }
```

STEP: Implement doCustomNavigation controller handler

DESCRIPTION: Implement doCustomNavigation(sCardId, oContext, oNavigationEntry) in your extension controller to override or supply navigation entries. Input parameters:
- sCardId (String): card ID as defined in manifest.json.
- oContext (Object): UI5 binding context of the clicked card item (use oContext.getProperty(oContext.sPath) to access the entity).
- oNavigationEntry (Object): original navigation entry derived from annotations.

Return: an object (or null/undefined) that matches the navigation entry shape and contains string attributes:
- type (mandatory): "com.sap.vocabularies.UI.v1.DataFieldWithUrl" or "com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation"
- semanticObject (required for DataFieldForIntentBasedNavigation)
- action (required for DataFieldForIntentBasedNavigation)
- url (required for DataFieldWithUrl)
- label (optional)

Return an object when you need a custom target; otherwise return null/undefined to fall back to annotation-defined navigation.

LANGUAGE: JavaScript

CODE:
```javascript
doCustomNavigation: function (sCardId, oContext, oNavigationEntry) {
         var oCustomNavigationEntry;
         var oEntity = oContext && oContext.getProperty(oContext.sPath);

         if (sCardId === "card001" && oEntity.PurchaseOrder === "4500003575") {
              oCustomNavigationEntry = {};
              oCustomNavigationEntry.type = "com.sap.vocabularies.UI.v1.DataFieldForIntentBasedNavigation";
              oCustomNavigationEntry.semanticObject = "Action";
              oCustomNavigationEntry.action = "toappnavsample2";
              oCustomNavigationEntry.url = "";
              oCustomNavigationEntry.label = "";
         }
         return oCustomNavigationEntry;
}
```

STEP: Static parameters for intent-based navigation

DESCRIPTION: Provide staticParameters in the card settings of manifest.json to send constant key/value pairs during IntentBasedNavigation from the overview page to a target application.

LANGUAGE: JSON

CODE:
```json
"staticParameters": {
              "parameter1": "parameterValue1",
              "parameter2": "parameterValue2"
            },
```

fiori-elements-framework sap-ovp manifest.json annotations DataFieldForIntentBasedNavigation DataFieldWithUrl custom-navigation doCustomNavigation staticParameters


**TITLE**: Configuring Card Properties (Overview Page Cards)

**INTRODUCTION**: This document lists the mandatory configuration items required for all Fiori overview page cards and shows a minimal manifest.json example. Use these properties when defining card entries so the card instance can be instantiated and provided with the correct model, template, settings, and entity set.

**TAGS**: fiori-elements-framework, overview-page, cards, card-configuration, manifest.json

**STEP**: Mandatory card properties

**DESCRIPTION**: All overview page cards inherit generic capabilities (header, footer, navigation, etc.). The following properties are mandatory for every card and must be provided in the card configuration:

- model: Name of the client-side model to provide to the card instance (string).
- template: Card component package or card type to instantiate (string).
- settings: Internal card configuration object passed to the card instance (object).
- entitySet: OData entity set name used by the card (string).

Provide these keys in each card definition to ensure the framework can instantiate and bind the card correctly.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "model": "string",       /* Name of the model for the card */
  "template": "string",    /* Card type / component package to instantiate */
  "settings": {            /* Internal card settings (object) */
    "...": "..."
  },
  "entitySet": "string"    /* OData entity set name */
}
```

**STEP**: Example: Minimal manifest.json card configuration (overview page)

**DESCRIPTION**: Minimal example showing required properties used inside a typical overview page (sap.ovp) card configuration. Replace example values (MyCardId, MyModel, sap.ovp.cards.list, Products) with your concrete IDs, model names, templates, settings, and entity sets.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "sap.ovp": {
    "cards": {
      "MyCardId": {
        "model": "MyModel",
        "template": "sap.ovp.cards.list",
        "settings": {
          "title": "Top Products",
          "subTitle": "Sales overview",
          "chartType": "bar" /* optional settings specific to the template */
        },
        "entitySet": "Products"
      }
    }
  }
}
```

**STEP**: Implementation notes

**DESCRIPTION**: Actionable points for code generation and implementation:
- Always include model, template, settings, and entitySet in each card definition.
- settings is template-specific: include only properties supported by the chosen template.
- Use the correct model name as registered in your application (e.g., in manifest dataSources or component initialization).
- Use the exact entitySet name from your OData service metadata. Mismatches prevent data binding.

**LANGUAGE**: plaintext

**CODE**:
```text
All cards inherit common capabilities (header, footer, navigation, etc.). Ensure the mandatory properties are present and validated at generation time to avoid runtime instantiation errors.
```

fiori-elements-framework overview-page cards card-configuration manifest.json


**TITLE**: Configuring Chart Facets and Chart Annotations for SAP Fiori Elements

**INTRODUCTION**: Practical, code-focused guide showing how to configure chart facets and chart definitions in SAP Fiori Elements. Includes UI.ReferenceFacet, UI.Chart, manifest.json controlConfiguration settings, aggregation-related annotations (groupable/aggregatable, transformation aggregation, dynamic measures, custom aggregation), criticality coloring, time-axis rules, and relevant restrictions. Use these snippets directly in XML annotations, ABAP CDS, CAP CDS, and manifest.json to implement charts in List Reports and Object Pages.

**TAGS**: UI.ReferenceFacet, UI.Chart, chart-facet, aggregation, DynamicMeasures, Analytics.AggregatedProperty, manifest.json, criticality, time-axis, SAP Fiori Elements, OData V4, OData V2

**STEP**: 1 — Add a Chart Facet (ReferenceFacet) to an Entity
**DESCRIPTION**: Define a chart facet on an entity type using UI.ReferenceFacet to point to the chart annotation. Examples provided for XML annotation, ABAP CDS, and CAP CDS.
**LANGUAGE**: XML
**CODE**:
```xml
<Annotations Target="STTA_PROD_MAN.STTA_C_MP_ProductType">
   <Annotation Term="UI.Facets">
      <Record Type="UI.ReferenceFacet">
         <PropertyValue Property="Label" String="{@i18n>@SalesData}"/>
         <PropertyValue Property="Target" AnnotationPath="to_ProductSalesData/@UI.Chart"/>
      </Record>
   </Annotation>
</Annotations>
```

**LANGUAGE**: ABAP CDS
**CODE**:
```
@UI.facet: [
 {
  label: '{@i18n>@SalesData}',
  type: #CHART_REFERENCE,
  purpose: #STANDARD,
  targetElement: '_productSalesData'
 }
]
```

**LANGUAGE**: CAP CDS
**CODE**:
```
annotate STTA_PROD_MAN.STTA_C_MP_ProductType @(
  UI.Facets : {
    $Type : 'UI.ReferenceFacet',
    Label : '{@i18n>@SalesData}',
    Target : 'to_ProductSalesData/@UI.Chart'
  }
);
```

**STEP**: 2 — Define the UI.Chart Annotation (Chart Definition)
**DESCRIPTION**: Create a chart definition on the chart entity type: set Title, ChartType, Dimensions, and Measures. Examples for XML, ABAP CDS, and CAP CDS are provided.
**LANGUAGE**: XML
**CODE**:
```xml
<Annotations Target="STTA_PROD_MAN.STTA_C_MP_ProductSalesDataType">
   <Annotation Term="UI.Chart">
      <Record>
         <PropertyValue Property="Title" String="Test Chart"/>
         <PropertyValue Property="ChartType" EnumMember="UI.ChartType/Column"/>
         <PropertyValue Property="Dimensions">
            <Collection>
               <PropertyPath>DeliveryMonth</PropertyPath>
            </Collection>
         </PropertyValue>
         <PropertyValue Property="Measures">
            <Collection>
               <PropertyPath>Revenue</PropertyPath>
            </Collection>
         </PropertyValue>
      </Record>
   </Annotation>
</Annotations>
```

**LANGUAGE**: ABAP CDS
**CODE**:
```
@UI.Chart: [
  {
    title: 'Test Chart',
    chartType: #COLUMN,
    dimensions: [
      'DELIVERYMONTH'
    ],
    measures: [
      'REVENUE'
    ]
  }
]
annotate view STTA_C_MP_PRODUCTSALESDATA with {

}
```

**LANGUAGE**: CAP CDS
**CODE**:
```
annotate STTA_PROD_MAN.STTA_C_MP_ProductSalesDataType @(
  UI.Chart : {
    Title : 'Test Chart',
    ChartType : #Column,
    Dimensions : [
        DeliveryMonth
    ],
    Measures : [
        Revenue
    ]
  }
);
```

**STEP**: 3 — Restriction: Navigation Properties Not Supported in UI.Chart
**DESCRIPTION**: The UI.Chart term cannot use navigation properties as dimensions/measures. Ensure chart properties reference properties directly present on the chart entity.

**LANGUAGE**: XML
**CODE**:
```xml
<!-- Note: Do not use navigation property references inside UI.Chart -->
```

**STEP**: 4 — OData V2 Restriction (SAP Fiori Elements)
**DESCRIPTION**: Charts are supported only for entities/services that are not draft-enabled or are read-only when using SAP Fiori Elements for OData V2.
**LANGUAGE**: None
**CODE**:
```text
Restriction: Charts are only supported for entities or services that are not draft enabled or for read-only entities or services.
```

**STEP**: 5 — Enabling Chart for Draft-Enabled Entities (OData V4)
**DESCRIPTION**: You can define charts against draft-enabled entities in OData V4. Only active data is used for chart display. No code change required beyond chart annotation on the aggregate/active entity.

**LANGUAGE**: None
**CODE**:
```text
Enable chart on draft-enabled entity: chart displays only active (non-draft) data.
```

**STEP**: 6 — Configure Chart Header Text and Visibility via manifest.json
**DESCRIPTION**: Use controlConfiguration in manifest.json to set chart header visibility and custom header text. Applies to charts inside List Report pages (not object page charts).
**LANGUAGE**: JSON
**CODE**:
```json
"BusinessPartnersList": {
   "type": "Component",
   "id": "BusinessPartnersList",
   "name": "sap.fe.templates.ListReport",
   "options": {
      "settings": {
         "controlConfiguration": {
            "@com.sap.vocabularies.UI.v1.Chart": {
               "chartSettings": {
                  "headerVisible": false,  // Can be true (default) or false
                  "header": "My Custom chart title"
               }
            }
         }
      }
   }
}
```

**STEP**: 7 — Configure Chart Selection Mode via manifest.json
**DESCRIPTION**: Allow end users to select chart data points (None / Single / Multiple). Set selectionMode in controlConfiguration.
**LANGUAGE**: JSON
**CODE**:
```json
"BusinessPartnersList": {
   "type": "Component",
   "id": "BusinessPartnersList",
   "name": "sap.fe.templates.ListReport",
   "options": {
      "settings": {
         "controlConfiguration": {
            "@com.sap.vocabularies.UI.v1.Chart": {
               "chartSettings": {
                  "selectionMode": "None" // None/Single/Multiple (default)
               }
            }
         }
      }
   }
}
```

**STEP**: 8 — Add Criticality Coloring for Chart Values (UI.ValueCriticality)
**DESCRIPTION**: Annotate properties with UI.ValueCriticality to map value strings to UI.CriticalityType values. Use XML, ABAP CDS, or CAP CDS examples.
**LANGUAGE**: XML
**CODE**:
```xml
<Annotations Target="com.c_salesordermanage_sd_aggregate.SalesOrderManage/SalesOrderType">
    <Annotation Term="UI.ValueCriticality">
        <Collection>
            <Record Type="UI.ValueCriticalityType">
                <PropertyValue Property="Value" String="CCLN"/>
                <PropertyValue Property="Criticality" EnumMember="UI.CriticalityType/Negative"/>
            </Record>
            <Record Type="UI.ValueCriticalityType">
                <PropertyValue Property="Value" String="CR"/>
                <PropertyValue Property="Criticality" EnumMember="UI.CriticalityType/Critical"/>
            </Record>
            <Record Type="UI.ValueCriticalityType">
                <PropertyValue Property="Value" String="OR"/>
                <PropertyValue Property="Criticality" EnumMember="UI.CriticalityType/Positive"/>
            </Record>
        </Collection>
    </Annotation>
</Annotations>
```

**LANGUAGE**: ABAP CDS
**CODE**:
```
annotate view C_SALESORDERMANAGE_SD_AGGREGATE.SALESORDERMANAGE with {

@UI.ValueCriticality: [
  {
    value: 'CCLN',
    criticality: #NEGATIVE
  },
  {
    value: 'CR',
    criticality: #CRITICAL
  },
  {
    value: 'OR',
    criticality: #POSITIVE
  }
]

salesordertype;
}
```

**LANGUAGE**: CAP CDS
**CODE**:
```
SalesOrderType         @(
        UI.ValueCriticality   : [
        {
            Value       : 'CCLN',
            Criticality : #Negative
        },
        {
            Value       : 'CR',
            Criticality : #Critical
        },
       {
            Value       : 'OR',
            Criticality : #Positive
        }
        ]
    );
```

**STEP**: 9 — Time Axis Support Rules
**DESCRIPTION**: Time axis is automatically enabled when the chart dimension is Edm.Date or Edm.DateTimeOffset. Also enabled for String dimensions annotated with specific Common annotations (fiscal/calendar/year/month/quarter/week/date).
**LANGUAGE**: None
**CODE**:
```text
Enable time axis when dimension type is:
- Edm.Date
- Edm.DateTimeOffset

Or when dimension is String and annotated with:
- @Common.IsFiscalYear
- @Common.IsFiscalYearPeriod
- @Common.IsCalendarYearMonth
- @Common.IsCalendarYearQuarter
- @Common.IsCalendarYearWeek
- @Common.IsCalendarDate
```

**STEP**: 10 — Enable Aggregation: Declare Groupable and Aggregatable Properties (Entity Set Level)
**DESCRIPTION**: At entity set level, declare GroupableProperties and AggregatableProperties (Aggregation.ApplySupported). Use XML or CAP CDS to list properties that can be used as dimensions (groupable) or measures (aggregatable).
**LANGUAGE**: XML
**CODE**:
```xml
<Annotations Target="sap.fe.managepartners.ManagePartnersService.EntityContainer/BusinessPartners">
    <Annotation Term="Aggregation.ApplySupported">
        <Record Type="Aggregation.ApplySupportedType">
            <PropertyValue Property="AggregatableProperties">
                <Collection>
                    <Record Type="Aggregation.AggregatablePropertyType">
                        <PropertyValue Property="Property">
                            <PropertyPath>SalesAmount</PropertyPath>
                        </PropertyValue>
                    </Record>
                    <Record Type="Aggregation.AggregatablePropertyType">
                        <PropertyValue Property="Property">
                            <PropertyPath>SalesAmountLocalCurrency</PropertyPath>
                        </PropertyValue>
                    </Record>
                    ....
                    ....
                </Collection>
            </PropertyValue>
            <PropertyValue Property="GroupableProperties">
                <Collection>
                    <PropertyPath>AccountResponsible</PropertyPath>
                    <PropertyPath>Country</PropertyPath>
                    ....
                    ....
                </Collection>
            </PropertyValue>
        </Record>
    </Annotation>
</Annotations>
```

**LANGUAGE**: CAP CDS
**CODE**:
```
@Aggregation.ApplySupported : {
     GroupableProperties : [AccountResponsible, Country, .......],
     AggregatableProperties: [{
          Property: SalesAmount
          },{
          Property: SalesAmountLocalCurrency
          },
          ....
          ....
     ]
}
```

**STEP**: 11 — Transformation Aggregation with Standard Methods (Analytics.AggregatedProperty)
**DESCRIPTION**: Define Aggregation.ApplySupported on entity set and list Analytics.AggregatedProperty records to expose aggregated results (min, max, etc.). Use XML or CAP CDS examples.
**LANGUAGE**: XML
**CODE**:
```xml
<Annotations Target="com.c_salesordermanage_sd_aggregate.SalesOrderManage">
    <Annotation Term="Aggregation.ApplySupported">
        …
        …
    </Annotation>
    <Annotation Term="Analytics.AggregatedProperty">
        <Record Type="Analytics.AggregatedPropertyType">
            <PropertyValue Property="Name" String="minPrice"/>
            <PropertyValue Property="AggregationMethod" String="min"/>
            <PropertyValue Property="AggregatableProperty" PropertyPath="NetPricing"/>
            <Annotation Term="Common.Label" String="Minimum Net Price"/>
         </Record>
    </Annotation>
    <Annotation Term="Analytics.AggregatedProperty" Qualifier="max">
        <Record Type="Analytics.AggregatedPropertyType">
            <PropertyValue Property="Name" String="maximumPrice"/>
            <PropertyValue Property="AggregationMethod" String="max"/>
            <PropertyValue Property="AggregatableProperty" PropertyPath="NetPricing"/>
            <Annotation Term="Common.Label" String="Maximum Net Price"/>
         </Record>
    </Annotation>
</Annotations>
```

**LANGUAGE**: CAP CDS
**CODE**:
```
annotate com.c_salesordermanage_sd_aggregate.SalesOrderManage with @(
  Aggregation.ApplySupported        : {
    AggregatableProperties   : [{Property : NetPricing}],
    CustomAggregationMethods : ['Custom.concat']
  },
  Analytics.AggregatedProperty      : {
    Name                 : 'minPrice',
    AggregationMethod    : 'min',
    AggregatableProperty : 'NetPricing',
    ![@Common.Label]     : 'Minimum Net Price'
  }
});
```

**STEP**: 12 — Use Transformation Aggregate-Based Measures in Charts: DynamicMeasures + MeasureAttributes
**DESCRIPTION**: When using transformation-aggregate-based measures in charts, define them as DynamicMeasures (not in Measures). Show XML and CAP CDS examples: specify Measures, DynamicMeasures, MeasureAttributes, DimensionAttributes for correct chart mapping.
**LANGUAGE**: XML
**CODE**:
```xml
<Annotation Term="UI.Chart">
    <Record Type="UI.ChartDefinitionType">
        <PropertyValue Property="Title" String="Sales Chart"/>
        <PropertyValue Property="ChartType" EnumMember="UI.ChartType/Column"/>
        <PropertyValue Property="Measures">
            <Collection>
                <PropertyPath>avgPricing</PropertyPath>
            </Collection>
        </PropertyValue>
        <PropertyValue Property="DynamicMeasures">
            <Collection>
                <AnnotationPath>@Analytics.AggregatedProperty#sum</AnnotationPath>
            </Collection>
        </PropertyValue>
        <PropertyValue Property="Dimensions">
            <Collection>
                <PropertyPath>SalesOrganization</PropertyPath>
            </Collection>
        </PropertyValue>
        <PropertyValue Property="MeasureAttributes">
            <Collection>
                <Record Type="UI.ChartMeasureAttributeType">
                    <PropertyValue Property="Measure" PropertyPath="avgPricing"/>
                    <PropertyValue Property="Role" EnumMember="UI.ChartMeasureRoleType/Axis1"/>
                </Record>
                <Record Type="UI.ChartMeasureAttributeType">
                    <PropertyValue Property="DynamicMeasure" AnnotationPath="@Analytics.AggregatedProperty#sum"/>
                    <PropertyValue Property="Role" EnumMember="UI.ChartMeasureRoleType/Axis1"/>
                </Record>
            </Collection>
        </PropertyValue>
        <PropertyValue Property="DimensionAttributes">
            <Collection>
                <Record Type="UI.ChartDimensionAttributeType">
                    <PropertyValue Property="Dimension" PropertyPath="SalesOrganization"/>
                    <PropertyValue Property="Role" EnumMember="UI.ChartDimensionRoleType/Category"/>
                </Record>
            </Collection>
        </PropertyValue>
    </Record>
</Annotation>
```

**LANGUAGE**: CAP CDS
**CODE**:
```
Chart                                                    : {
      $Type               : 'UI.ChartDefinitionType',
      Title               : 'Sales Chart',
      ChartType           : #Column,
      Measures            : [avgPricing],
      DynamicMeasures     : ['@Analytics.AggregatedProperty#sum'],
      Dimensions          : [SalesOrganization],
      MeasureAttributes   : [
        {
          $Type   : 'UI.ChartMeasureAttributeType',
          Measure : avgPricing,
          Role    : #Axis1
        },
        {
          $Type          : 'UI.ChartMeasureAttributeType',
          DynamicMeasure : '@Analytics.AggregatedProperty#sum',
          Role           : #Axis1
        }
      ],
      DimensionAttributes : [{
        $Type     : 'UI.ChartDimensionAttributeType',
        Dimension : SalesOrganization,
        Role      : #Category
      }]
    }
```

**STEP**: 13 — Transformation Aggregation with Custom Aggregation Methods (Entity Set Level)
**DESCRIPTION**: Declare Aggregation.CustomAggregate qualifiers for custom aggregate measures on the entity set and mark groupable properties. Use XML and CAP CDS examples.
**LANGUAGE**: XML
**CODE**:
```xml
<Annotations Target="sap.fe.managepartners.ManagePartnersService.EntityContainer/BusinessPartners">
     <Annotation Term="Aggregation.CustomAggregate" Qualifier="RequestedQuantity">
        <String>Edm.Decimal</String>
     </Annotation>
     <Annotation Term="Aggregation.CustomAggregate" Qualifier="RequestedQuantityLocalUnit">
        <String>Edm.Decimal</String>
     </Annotation>
</Annotations>

<Annotations Target="sap.fe.managepartners.ManagePartnersService.BusinessPartners/Name">
     <Annotation Term="Aggregation.Groupable">
        <Bool>true</Bool>
     </Annotation>
     <Annotation Term="Common.Label">
        <String>Partner Name</String>
     </Annotation>
</Annotations>
```

**LANGUAGE**: CAP CDS
**CODE**:
```
@Aggregation.CustomAggregate #RequestedQuantity          : 'Edm.Decimal'
@Aggregation.CustomAggregate #RequestedQuantityLocalUnit : 'Edm.Decimal'

entity BusinessPartners {
               Name   : String @Common : { Label: 'Partner Name' }
               @Aggregation.Groupable: true;
}
```

**STEP**: 14 — Restrictions and Important Notes (Summary)
**DESCRIPTION**: Consolidated restrictions and operational notes to apply when implementing charts.
**LANGUAGE**: None
**CODE**:
```text
- Navigation properties inside UI.Chart are not supported.
- OData V2: Charts are not supported for draft-enabled or transactional entities; only non-draft or read-only.
- Chart personalization settings and selections are not saved in iAppState (not part of variant).
- Properties from associated entity sets (measures/dimensions/text associations) are not supported.
- Semantic coloring via UI.Criticality and UI.CriticalityCalculation is not supported for chart controls.
- Aggregations on draft-enabled entities are not supported in ABAP CDS (SADL does not support $apply on draft/transactional entities).
- For chart selection and aggregation behavior, backend must support transformation filters and Aggregation.ApplySupported must be present.
- Unit properties annotated as custom aggregate may be allowed but do not appear in the list of measures for chart selection.
```

UI.ReferenceFacet
UI.Chart
chart-facet
aggregation
DynamicMeasures
Analytics.AggregatedProperty
manifest.json
criticality
time-axis
SAP Fiori Elements
OData V4
OData V2


**TITLE**: Configuring Charts for Overview Pages (Annotations and manifest.json)

**INTRODUCTION**: This document provides actionable annotation and manifest.json examples and requirements to configure analytical chart cards in SAP Fiori overview pages. Use these snippets when generating or modifying annotation files (XML, ABAP CDS, CAP CDS) and manifest.json to control chart type, measures/dimensions roles, formatting, semantic forecasting, color palettes, stable dimension coloring, time-series behavior, and data labels.

**TAGS**: fiori-elements-framework, charts, annotations, UI.Chart, UI.DataPoint, manifest.json, CDS, ABAP, CAP, colorPalette, semantic-pattern, time-series

STEP: Required Annotation Terms (summary)
DESCRIPTION: Ensure these annotation terms are present in the annotation file used by the card. They apply across chart types and control navigation, filtering, sorting, limits, chart definition, measures and dimensions, and their roles.
LANGUAGE: Text
CODE:
```text
Required annotation terms:
- UI.Identification         : mandatory, configures navigation targets and parameters for the card.
- UI.SelectionVariant.SelectOptions : optional, defines filters applied when retrieving card data.
- UI.PresentationVariant.SortOrder  : optional, defines sort order.
- UI.PresentationVariant.MaxItems   : optional, limits maximum records fetched from backend (avoid for charts that need full dataset like donut charts).
- UI.Chart                 : mandatory, defines chart (type, measures, dimensions).
- UI.Chart.MeasureAttributes.Measure : defines measures used.
- UI.Chart.MeasureAttributes.Role    : specifies measure role (interpretation varies by chart type).
- UI.Chart.DimensionAttributes.Dimension : defines dimensions.
- UI.Chart.DimensionAttributes.Role      : specifies dimension role (category or series).
```

STEP: Formatting Numeric Values in Charts (XML annotation)
DESCRIPTION: Configure number formatting for chart measures by referencing a UI.DataPoint annotation with ValueFormat containing ScaleFactor and NumberOfFractionalDigits. Attach this DataPoint to a measure in UI.Chart via DataPoint annotation path.
LANGUAGE: XML
CODE:
```xml
<Annotation Term="UI.DataPoint" Qualifier=" Eval_by_Currency_TotalSales ">
  <Record Type="UI.DataPointType">
    <PropertyValue Property="Value" Path="Sales"/>
    <PropertyValue Property="ValueFormat">
      <Record>
        <PropertyValue Property="ScaleFactor" Decimal="1000" />
        <PropertyValue Property="NumberOfFractionalDigits" Int="3" />
      </Record>
    </PropertyValue>
  </Record>
</Annotation>

<Annotation Term="UI.Chart" Qualifier="Eval_by_Currency">
  <Record Type="UI.ChartDefinitionType">
    <PropertyValue Property="Title" String="View1" />
    <PropertyValue Property="ChartType" EnumMember="UI.ChartType/Bubble"/>
    <PropertyValue Property="MeasureAttributes">
      <Collection>
        …
        <Record Type="UI.ChartMeasureAttributeType">
          <PropertyValue Property="Measure" PropertyPath="TotalSales" />
          <PropertyValue Property="Role" EnumMember="UI.ChartMeasureRoleType/Axis2" />
          <PropertyValue Property="DataPoint" AnnotationPath="@UI.DataPoint#Eval_by_Currency-TotalSales"/>
        </Record>
        …
      </Collection>
    </PropertyValue>
    …
  </Record>
</Annotation>
```

STEP: Formatting Numeric Values in Charts (ABAP CDS)
DESCRIPTION: Example ABAP CDS syntax: add @UI.dataPoint with valueFormat and attach UI.Chart annotation with measureAttributes referencing the datapoint (use asDataPoint:true).
LANGUAGE: ABAP CDS
CODE:
```
@UI.dataPoint: {
  valueFormat: {
    scaleFactor: 1000,
    numberOfFractionalDigits: 3
  }
}
property_name;

@UI.Chart: [
  {
    title: 'View1',
    chartType: #BUBBLE,
    measureAttributes: [
      {
        measure: 'TotalSales',
        role: #AXIS_2,
        asDataPoint: true
      }
    ],
    qualifier: 'Eval_by_Currency'
  }
]
annotate view VIEWNAME with { }
```

STEP: Formatting Numeric Values in Charts (CAP CDS)
DESCRIPTION: CAP CDS syntax: define UI.DataPoint and UI.Chart with MeasureAttributes referencing the DataPoint via DataPoint property.
LANGUAGE: CAP CDS
CODE:
```
UI.DataPoint # Eval_by_Currency-TotalSales  : {
    $Type : 'UI.DataPointType',
    ValueFormat : {
        ScaleFactor : 1000,
        NumberOfFractionalDigits : 3
    }
},
UI.Chart #Eval_by_Currency : {
    $Type : 'UI.ChartDefinitionType',
    Title : 'View1',
    ChartType : #Bubble,
    MeasureAttributes : [
        {
            $Type : 'UI.ChartMeasureAttributeType',
            Measure : TotalSales,
            Role : #Axis2,
            DataPoint : '@UI.DataPoint#Eval_by_Currency-TotalSales'
        }
    ]
}
```

STEP: Semantic Pattern — Purpose and Requirements (summary)
DESCRIPTION: Enable semantic pattern to compare actual vs forecast values. Supported in line, column, and vertical bullet chart cards. Requirements:
- DataPoint annotation must include ForecastValue referencing a measure.
- Chart annotation:
  - line/column: 1 dimension + 1 measure
  - vertical bullet: 1 dimension + 1–2 measures
When conditions are met, the chart will display actual as solid and forecast as dashed (or dotted for line charts).
Referenced illustration file: images/Semantic_Pattern_for_Charts_in_Overview_Pages_62a0e9a.png
LANGUAGE: Text
CODE:
```text
Semantic pattern behavior:
- Enabled when DataPoint.ForecastValue exists and chart dimension/measure counts match the supported patterns.
- Visuals:
  - Column & vertical bullet: forecast shown dashed.
  - Line: forecast shown dotted.
- If requirements not met, semantic pattern is not applied.
```

STEP: Semantic Pattern Example (XML)
DESCRIPTION: XML example: DataPoint with ForecastValue and UI.Chart with measure linked to the data point to enable semantic forecast rendering.
LANGUAGE: XML
CODE:
```xml
<Annotation Term="UI.DataPoint" Qualifier="Column_Forecast">
  <Record Type="UI.DataPointType">
    <PropertyValue Property="Title" String="Sales Performance"/>
    <PropertyValue Property="Value" Path="Sales"/>
    <PropertyValue Property="ValueFormat">
      <Record>
        <PropertyValue Property="ScaleFactor" Decimal="0"/>
        <PropertyValue Property="NumberOfFractionalDigits" Int="3"/>
      </Record>
    </PropertyValue>
    <PropertyValue Property="ForecastValue" Path="SalesShare"/>
  </Record>
</Annotation>

<Annotation Term="UI.Chart" Qualifier="Eval_by_Currency_Column">
  <Record Type="UI.ChartDefinitionType">
    <PropertyValue Property="Title" String="Column chart for shape" />
    <PropertyValue Property="ChartType" EnumMember="UI.ChartType/Column" />
    <PropertyValue Property="MeasureAttributes">
      <Collection>
        <Record Type="UI.ChartMeasureAttributeType">
          <PropertyValue Property="Measure" PropertyPath="Sales" />
          <PropertyValue Property="DataPoint">
            <AnnotationPath>@UI.DataPoint#Column_Forecast</AnnotationPath>
          </PropertyValue>
          <PropertyValue Property="Role" EnumMember="UI.ChartMeasureRoleType/Axis1" />
        </Record>
      </Collection>
    </PropertyValue>
    <PropertyValue Property="DimensionAttributes">
      <Collection>
        <Record Type="UI.ChartDimensionAttributeType">
          <PropertyValue Property="Dimension" PropertyPath="SupplierCompany" />
          <PropertyValue Property="Role" EnumMember="UI.ChartDimensionRoleType/Category" />
        </Record>
      </Collection>
    </PropertyValue>
  </Record>
</Annotation>
```

STEP: Semantic Pattern Example (ABAP CDS)
DESCRIPTION: ABAP CDS example that annotates a property with forecast and adds UI.Chart annotation for the chart qualifier.
LANGUAGE: ABAP CDS
CODE:
```
@UI.dataPoint: {
  title: 'Sales Performance',
  forecastValue: 'SalesShare',
  valueFormat: { scaleFactor: 0, numberOfFractionalDigits: 3 }
}
Sales;

@UI.Chart: [
  {
    title: 'Column chart for shape',
    chartType: #COLUMN,
    measureAttributes: [
      {
        measure: 'Sales',
        role: #AXIS_1,
        asDataPoint: true
      }
    ],
    dimensionAttributes: [
      {
        dimension: 'SupplierCompany',
        role: #CATEGORY
      }
    ],
    qualifier: 'Eval_by_Currency_Column'
  }
]
annotate view VIEWNAME with { }
```

STEP: Semantic Pattern Example (CAP CDS)
DESCRIPTION: CAP CDS equivalent for DataPoint with ForecastValue and UI.Chart linking to that datapoint.
LANGUAGE: CAP CDS
CODE:
```
UI.DataPoint #Column_Forecast : {
    $Type : 'UI.DataPointType',
    Title : 'Sales Performance',
    Value : Sales,
    NumberFormat : {
        ScaleFactor : 0,
        NumberOfFractionalDigits : 3
    },
    ForecastValue : SalesShare
},
UI.Chart #Eval_by_Currency_Column : {
    $Type : 'UI.ChartDefinitionType',
    Title : 'Column chart for shape',
    ChartType : #Column,
    MeasureAttributes : [
        {
            $Type : 'UI.ChartMeasureAttributeType',
            Measure : Sales,
            DataPoint : '@UI.DataPoint#Column_Forecast',
            Role : #Axis1
        }
    ],
    DimensionAttributes : [
        {
            $Type : 'UI.ChartDimensionAttributeType',
            Dimension : SupplierCompany,
            Role : #Category
        }
    ]
},
```

STEP: Chart Types, Dimension & Measure Roles, and Time Series Rules
DESCRIPTION: Rules for chart types, role properties and automatic time-axis behavior. Use these rules when generating chart annotations.
LANGUAGE: Text
CODE:
```text
Chart types supported in overview pages:
- line, donut, bubble, column, stacked column, vertical bullet, combination, scatter

Dimension role:
- role: "category" or "series"
- default: "category" if not specified

Measure role:
- role: "axis1", "axis2", or "axis3"
- default: "axis1" if not specified
- interpretation of axis roles depends on chart type

Time series automatic usage (analytic cards use a time axis automatically when ALL conditions met):
- Chart type: line, bubble, column, or combination
- Chart has exactly one dimension
- Dimension data type: edm.datetime OR edm.string with OData metadata sap:semantics="yearmonthday"
- For bubble charts: exactly two measures
- For combination charts: at least two measures

Note: Only line, bubble, column, and combination charts support time axis.
```

STEP: Color Palette (semantic coloring) — manifest.json snippet
DESCRIPTION: Define colorPalette in manifest.json to map four semantic states (0..3) to UI CSS color tokens and legend text. All four entries are mandatory and must use SAP Fiori semantic palette tokens.
LANGUAGE: JSON
CODE:
```json
"colorPalette": {
  "0": {
    "color": "sapUiChartPaletteSemanticNeutral",
    "legendText": "{{OTHERS}}"
  },
  "1": {
    "color": "sapUiChartPaletteSemanticBadDark1",
    "legendText": "{{BAD}}"
  },
  "2": {
    "color": "sapUiChartPaletteSemanticCriticalDark2",
    "legendText": "{{CRITICAL}}"
  },
  "3": {
    "color": "sapUiChartPaletteSemanticCritical",
    "legendText": "{{GOOD}}"
  }
}
```

STEP: Stable Coloring with Dimension Values (enable + palette rules snippet)
DESCRIPTION: For column stack charts, enable stable colors and map specific dimension values to colors using colorPalette.dimensionSettings. Set bEnableStableColors to true in the card settings and provide dimensionSettings rules: each rule must include dimensionValue and color; index is optional (defines legend order). If only dimensionValue/index is provided without color, legends are ordered but default colors are used.
LANGUAGE: JSON
CODE:
```json
// colorPalette.dimensionSettings sample
"colorPalette": {
  "dimensionSettings": {
    "StatusCriticality": {
      "rule1": {
        "color": "<colorValue1>",
        "dimensionValue": "<dimensionValue1>"
      },
      "rule2": {
        "color": "<colorValue2>",
        "dimensionValue": "<dimensionValue2>"
      }
    }
  }
}
```

STEP: Card manifest example with stable colors, color mapping, and legend ordering
DESCRIPTION: Full card settings example to enable stable colors, set chartAnnotationPath, and configure colorPalette.dimensionSettings with index property to order legends. Place under "sap.ovp"."cards"."<card_id>" in manifest.json.
LANGUAGE: JSON
CODE:
```json
"sap.ovp": {
  ...
  "cards": {
    ...
    "<card_id>": {
      "model": "<model_name>",
      "template": "sap.ovp.cards.charts.analytical",
      "settings": {
        "title": "<Card title>",
        "entitySet": "<entitySet>",
        "chartAnnotationPath": "com.sap.vocabularies.UI.v1.Chart#Eval_by_Currency_ColumnStacked",
        "bEnableStableColors": true,
        "colorPalette": {
          "dimensionSettings": {
            "<dimensionAttribute>": {
              "<dimensionValue1>": {
                "color": "sapUiChartPaletteSemanticGood",
                "dimensionValue": "<dimensionValue1>",
                "index": 0
              },
              "<dimensionValue2>": {
                "color": "sapUiChartPaletteSemanticNeutral",
                "dimensionValue": "<dimensionValue2>",
                "index": 1
              },
              "<dimensionValue3>": {
                "color": "sapUiChartPaletteSemanticCriticalDark2",
                "dimensionValue": "<dimensionValue3>",
                "index": 2
              }
            }
          }
        }
      }
    }
  }
}
```

STEP: Data Label in Analytical Chart (manifest.json)
DESCRIPTION: Enable visible data labels in analytical cards by setting sap.ovp.chartSettings.showDataLabel to true (default: false). Place under "sap.ovp" in manifest.json.
LANGUAGE: JSON
CODE:
```json
"sap.ovp": {
  "globalFilterModel": "salesOrder",
  "globalFilterEntityType": "GlobalFilters",
  "chartSettings": {
    "showDataLabel": true
  }
}
```

STEP: Related Links and Image Reference
DESCRIPTION: Reference resources for further details and illustrative image file path used in original docs.
LANGUAGE: Text
CODE:
```text
Related:
- Chart Cards Used in Overview Pages: chart-cards-used-in-overview-pages-68e62ad.md
Image illustrating semantic pattern behavior:
- images/Semantic_Pattern_for_Charts_in_Overview_Pages_62a0e9a.png
```

fiori-elements-framework charts annotations UI.Chart UI.DataPoint manifest.json CDS ABAP CAP colorPalette semantic-pattern time-series


**TITLE**: Configuring Custom Messages for Cards (getCustomMessage)

**INTRODUCTION**: Define a getCustomMessage function in your extension controller to provide custom messages and optional icons per card for success (including "success with no data") and error scenarios. Use the response object and card ID to decide which message and icon to return. Error scenarios show a default icon; success/no-data scenarios can include a custom icon.

**TAGS**: fiori-elements-framework, sapui5, custom-messages, extension-controller, cards, ui5

**STEP**: 1 — Add getCustomMessage to your extension controller

**DESCRIPTION**: Implement getCustomMessage(oResponse, sCardId) inside the extension controller file that is used for the card(s). The method receives:
- oResponse: response object from the service (use getParameters() to inspect success flag etc.)
- sCardId: the card identifier string

Return an object with:
- sMessage: (string) message to display
- sIcon: (string, optional) icon URI for success/no-data scenarios (e.g., "sap-icon://message-information")

For error scenarios, do not need to provide sIcon — a default error icon will be displayed. If you do not handle a card, return undefined.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
getCustomMessage: function (oResponse, sCardId) {
 if (sCardId == "card001") {
  if (oResponse && oResponse.getParameters() && oResponse.getParameters().success) {
    return {
       sMessage: "My Custom Message for No Data", //message in case of success and no data
       sIcon: "sap-icon://message-information"    //icon in case of success and no data
     }
  } else {
    return {
       sMessage: "My Custom Message for Error" //message in case of error
           }
         }
  }
},
```

**STEP**: 2 — Recommended: robust pattern and handling multiple cards

**DESCRIPTION**: Use defensive checks and explicit returns for multiple cards. Return undefined for cards you do not customize. Check success using oResponse.getParameters().success and handle both success-with-no-data and error cases. Include sIcon only for success/warning/info scenarios.

**LANGUAGE**: JavaScript

**CODE**:
```javascript
// Example: extension controller snippet handling multiple cards robustly
getCustomMessage: function (oResponse, sCardId) {
  // Ensure parameters exist
  var bSuccess = !!(oResponse && oResponse.getParameters && oResponse.getParameters().success);

  switch (sCardId) {
    case "card001":
      if (bSuccess) {
        // Success with no data: custom message + icon
        return {
          sMessage: "Card 001: No data available",
          sIcon: "sap-icon://message-information"
        };
      } else {
        // Error: custom message (default error icon will be used)
        return {
          sMessage: "Card 001: Failed to load data"
        };
      }

    case "card002":
      if (bSuccess) {
        return {
          sMessage: "Card 002: Operation completed successfully",
          sIcon: "sap-icon://accept"
        };
      } else {
        return {
          sMessage: "Card 002: An error occurred"
        };
      }

    default:
      // Do not override messages for other cards
      return undefined;
  }
}
```

fiori-elements-framework sapui5 custom-messages extension-controller cards ui5


**TITLE**: Configure Date Fields with a Valid Date Range (OData V4, SAP Fiori elements)

**INTRODUCTION**: Use Org.OData.Validation.V1 annotations to restrict Date-type properties to a valid date range so users can only pick valid dates in the date picker. This applies to SAP Fiori elements for OData V4. Provide either literal dates or path references to other properties. For CAP CDS use $edmJson date literals or property names. ABAP CDS does not support path-based Validation in annotations; use local XML annotation instead.

**TAGS**: fiori-elements-framework, OData V4, annotations, Validation, Date, SAP, CAP, CDS, XML, edmx

**STEP**: Add the Validation vocabulary reference (XML)

**DESCRIPTION**: Include the Org.OData.Validation.V1 vocabulary reference in your annotation XML so Validation.Minimum and Validation.Maximum terms are available.

**LANGUAGE**: XML

**CODE**:
```xml
<edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Validation.V1.xml">
       <edmx:Include Alias="Validation" Namespace="Org.OData.Validation.V1" />
</edmx:Reference>
...
...
<Annotations Target="com.service.Entity/DateProperty">
        <Annotation Term="Validation.Minimum" Date="2024-07-01" />
	<Annotation Term="Validation.Maximum" Date="2024-12-31" />
</Annotations>

```

**STEP**: Configure a fixed date range (XML annotation)

**DESCRIPTION**: Set literal minimum and maximum dates directly in the XML annotation for the Date property so the date picker disables values outside this range.

**LANGUAGE**: XML

**CODE**:
```xml
<edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Validation.V1.xml">
       <edmx:Include Alias="Validation" Namespace="Org.OData.Validation.V1" />
</edmx:Reference>
...
...
<Annotations Target="com.service.Entity/DateProperty">
        <Annotation Term="Validation.Minimum" Date="2024-07-01" />
	<Annotation Term="Validation.Maximum" Date="2024-12-31" />
</Annotations>
```

**STEP**: Configure a fixed date range (CAP CDS)

**DESCRIPTION**: Use $edmJson date literals in CAP CDS to set static Validation.Minimum and Validation.Maximum for the Date property.

**LANGUAGE**: CDS

**CODE**:
```cds
DateProperty :
       Date @(Validation: {
          Minimum: {$edmJson: {$Date: '2024-07-01'}},
          Maximum: {$edmJson: {$Date: '2024-12-31'}}
        });
```

**STEP**: Configure a dynamic date range using path references (XML annotation)

**DESCRIPTION**: Reference other Date properties (e.g., MinimumDate and MaximumDate) using Path in the XML annotation so the valid range is driven by data in the entity.

**LANGUAGE**: XML

**CODE**:
```xml
<edmx:Reference Uri="https://oasis-tcs.github.io/odata-vocabularies/vocabularies/Org.OData.Validation.V1.xml">
       <edmx:Include Alias="Validation" Namespace="Org.OData.Validation.V1" />
</edmx:Reference>
...
...
<Annotations Target="com.service.Entity/DateProperty">
        <Annotation Term="Validation.Minimum" Path="MinimumDate" />
	<Annotation Term="Validation.Maximum" Path="MaximumDate" />
</Annotations>
```

**STEP**: Configure a dynamic date range using path references (CAP CDS)

**DESCRIPTION**: Define MinimumDate and MaximumDate properties on the entity and reference them by name in the Validation annotation for DateProperty.

**LANGUAGE**: CDS

**CODE**:
```cds
MinimumDate: Date;
MaximumDate: Date;
DateProperty: Date @(Validation: {
  Minimum: MinimumDate,
  Maximum: MaximumDate
});
```

**STEP**: Platform limitation and recommendation

**DESCRIPTION**: Note that path-based Validation (using MinimumDate/MaximumDate) is not supported in ABAP CDS annotations. To apply dynamic ranges in ABAP scenarios, use a local XML annotation file (local annotations) instead of ABAP CDS annotations.

fiori-elements-framework
OData V4
annotations
Validation
Date
SAP
CAP
CDS
XML
edmx


**TITLE**: Configuring Default Filter Values for SAP Fiori elements

**INTRODUCTION**: How to configure default filter values for filter bar fields in SAP Fiori elements using UI.SelectionVariant or Common.FilterDefaultValue annotations (XML, ABAP CDS, CAP CDS). Includes interaction priority between annotation defaults, user variants, navigation context, and manifest settings for OData V2 Analytical List Page.

**TAGS**: fiori-elements, annotations, SelectionVariant, FilterDefaultValue, CDS, XML, manifest, OData

**STEP**: 1 — Use UI.SelectionVariant to set default filter values

**DESCRIPTION**: Add a UI.SelectionVariant annotation (local XML or CDS) to define default parameter and filter values. Use SelectionVariant for complex ranges and multi-value filters. If you configure SelectionVariant in the manifest, the framework will use it as the standard variant. Note: SelectionOption/SelectOptions is not supported in ABAP CDS — use local XML for range-based filter defaults when using ABAP CDS.

**LANGUAGE**: XML

**CODE**:
```xml
<Annotation Term="UI.SelectionVariant" Qualifier="Default">
    <Record>
        <PropertyValue Property="Parameters">
            <Collection>
                <Record Type="UI.Parameter">
                    <PropertyValue Property="PropertyName" PropertyPath="P_CompanyCode" />
                    <PropertyValue Property="PropertyValue" String="EASI" />
                </Record>
            </Collection>
        </PropertyValue>
        <PropertyValue Property="SelectOptions">
            <Collection>
                <Record Type="UI.SelectOptionType">
                    <PropertyValue Property="PropertyName" PropertyPath="Customer"/>
                    <PropertyValue Property="Ranges">
                        <Collection>
                            <Record Type="UI.SelectionRangeType">
                                <PropertyValue EnumMember="UI.SelectionRangeSignType/I" Property="Sign"/>
                                <PropertyValue EnumMember="UI.SelectionRangeOptionType/EQ" Property="Option"/>
                                <PropertyValue Property="Low" String="ABC"/>
                            </Record>
                        </Collection>
                    </PropertyValue>
                </Record>
            </Collection>
        </PropertyValue>
    </Record>
</Annotation>
```

**LANGUAGE**: ABAP CDS

**CODE**:
```
@UI.selectionVariant: [
  {
    qualifier: 'SVForQuantity',
    parameters: [{name: 'PropertyName', value: 'P_CompanyCurrency' },{ name: 'PropertyValue', value: 'EASI'}]
  }
]
```

**LANGUAGE**: CAP CDS

**CODE**:
```
UI.SelectionVariant #Default : {
    Parameters : [
        {
            $Type : 'UI.Parameter',
            PropertyName : P_CompanyCode,
            PropertyValue : 'EASI'
        }
    ],
    SelectOptions : [
        {
            $Type : 'UI.SelectOptionType',
            PropertyName : Customer,
            Ranges : [
                {
                    $Type : 'UI.SelectionRangeType',
                    Sign : #I,
                    Option : #EQ,
                    Low : 'ABC'
                }
            ]
        }
    ]
}
```

**STEP**: 2 — Use Common.FilterDefaultValue for single-value defaults

**DESCRIPTION**: Use Common.FilterDefaultValue when you only need a single static default value on a filter field. This annotation does not support complex expressions (e.g., "startsWith") or multi-value logic (e.g., Status = "A" or "B"). If a SelectionVariant is present, SelectionVariant takes precedence and Common.FilterDefaultValue is ignored for those filters.

**LANGUAGE**: XML

**CODE**:
```xml
<Annotations Target="STTA_PROD_MAN.STTA_C_MP_ProductType/Supplier">
    <Annotation Term="Common.FilterDefaultValue" String="100000047"/>
</Annotations>
```

**LANGUAGE**: ABAP CDS

**CODE**:
```
@Consumption.filter.defaultValue: '100000047'
Supplier;
```

**LANGUAGE**: CAP CDS

**CODE**:
```
annotate STTA_PROD_MAN.STTA_C_MP_ProductType with {
    @Common.FilterDefaultValue : '100000047'
    Supplier
};
```

**STEP**: 3 — Manifest setting for Analytical List Page (OData V2)

**DESCRIPTION**: For SAP Fiori elements Analytical List Page (OData V2), enable consideration of filter defaults from SelectionVariant by setting filterDefaultsFromSelectionVariant to true in the component/page settings of manifest.json.

**LANGUAGE**: JSON

**CODE**:
```json
{
  "sap.ui5": {
    "models": { /* ... */ }
  },
  "sap.ui.generic.app": {
    "pages": [
      {
        "component": {
          "name": "sap.suite.ui.generic.template.AnalyticalListPage",
          "settings": {
            "filterDefaultsFromSelectionVariant": true
          }
        }
      }
    ]
  }
}
```

**STEP**: 4 — Priority: combining values from multiple sources

**DESCRIPTION**: When multiple sources provide values for a filter field (navigation context, user-defined variant, standard variant + annotations, FLP user defaults), the framework evaluates them in this priority order and with these rules:

- Navigation context
  - Overrides everything; navigation context is applied. (Navigation context includes FLP tile target mapping configuration / navigation source and target mapping default values.)
  - Filter values applied by annotation/variant are cleared and overwritten by incoming navigation context.

- User-defined default variant (not equal to standard variant, and no navigation context)
  - Overrides everything including FLP user default values.

- Standard variant (no navigation context) combined with annotation values (UI.SelectionVariant or Common.FilterDefaultValue)
  - Merge logic with FLP user default values:
    1. If only FLP user default values exist for a field (no annotation values) → retain FLP values.
    2. If only annotation values exist (no FLP values) → retain annotation values.
    3. If both FLP user default values and annotation values exist → only FLP user default values are considered.
- Tip: FLP user default values mark the standard variant as dirty (unlike annotation/manifest defaults).

**LANGUAGE**: text

**CODE**:
```
Priority summary:
1) Navigation context (highest) — overrides
2) User-defined default variant — overrides everything (if present and no navigation context)
3) Standard variant + annotations — merged with FLP user defaults per rules above
```

**STEP**: 5 — Additional rules, restrictions, and recommendations

**DESCRIPTION**: Important operational details to preserve when implementing default filter values.

**LANGUAGE**: text

**CODE**:
```
- Default values from annotations:
  - Applied only on application load and only when the application is launched with a standard variant.
  - Do not affect visibility of filter fields.
  - Are cleared/overwritten by incoming navigation context.

- Date values:
  - Use ISO format YYYY-MM-DD for date default values.

- DisplayCurrency:
  - Default values for DisplayCurrency can also come from SAP Fiori launchpad (FLP). Handle FLP-sourced defaults accordingly.

- ABAP CDS limitation:
  - SelectionOption / SelectOptions (range/multi-value) is not supported in ABAP CDS annotations. Use local XML annotations if you need range/selectOptions.

- OData V4 Analytical List Page restriction:
  - You cannot define default values for filter fields using UI.SelectionVariant in Analytical List Page-based applications for OData V4.
```

fiori-elements annotations SelectionVariant FilterDefaultValue CDS XML manifest OData


**TITLE**: Configure Default Visualizations, Sort Order, and Filter Defaults (UI.SelectionPresentationVariant, UI.PresentationVariant, UI.SelectionVariant)

**INTRODUCTION**: Configure default UI behavior for List Reports and Analytical/List Pages in SAP Fiori elements by using UI.SelectionPresentationVariant (ties UI.SelectionVariant and UI.PresentationVariant), UI.PresentationVariant (visualizations, sort, MaxItems, RequestAtLeast), UI.SelectionVariant (default filter values), UI.LineItem and UI.Chart annotations. Use manifest.json settings to point the app to a default (qualified) annotation. The examples below show XML, ABAP CDS, and CAP CDS formats.

**TAGS**: fiori-elements-framework, annotations, SelectionPresentationVariant, PresentationVariant, SelectionVariant, LineItem, Chart, manifest, odata-v2, odata-v4

STEP: Define UI.SelectionPresentationVariant (qualifier) linking SelectionVariant and PresentationVariant

DESCRIPTION: Create a SelectionPresentationVariant record that references a SelectionVariant and a PresentationVariant by qualifier. This defines the default filter values and the default visualization (sort, visualizations). Ensure the referenced SelectionVariant and PresentationVariant exist and paths are correct.

LANGUAGE: XML
CODE:
```xml
<Annotations Target="self.BookingType">
    ...
    <Annotation Term="UI.SelectionPresentationVariant" Qualifier="BookingSPV">
        <Record>
            <PropertyValue Property="Text" String="Default"/>
            <PropertyValue Property="SelectionVariant" Path="@UI.SelectionVariant#BookingSV"/>
            <PropertyValue Property="PresentationVariant" Path="@UI.PresentationVariant#BookingPV"/>
        </Record>
    </Annotation>
    ...
</Annotations>
```

LANGUAGE: ABAP CDS
CODE:
```abap
//@Scope: [ENTITY] ("Booking")
@UI: {
    selectionPresentationVariant: [ {
        qualifier: 'BookingSPV',
        selectionVariantQualifier: 'BookingSV',
        presentationVariantQualifier: 'BookingPV'
    } ],
    ...
}
```

LANGUAGE: CAP CDS
CODE:
```cds
annotate TravelService.Travel with @UI: {
    SelectionPresentationVariant #BookingSPV : {
        SelectionVariant : ![@UI.SelectionVariant#BookingSV],
        PresentationVariant : ![@UI.PresentationVariant#BookingPV]
    }
    ...
}
```

STEP: Define UI.SelectionVariant (default filter values)

DESCRIPTION: Use SelectionVariant to define default filter values (SelectOptions / Ranges). Add this annotation and reference it from SelectionPresentationVariant or use as unqualified default.

LANGUAGE: XML
CODE:
```xml
<Annotations Target="self.BookingType">
    ...
    <Annotation Term="UI.SelectionVariant" Qualifier="BookingSV">
        <Record>
            <PropertyValue Property="SelectOptions">
                <Collection>
                    <Record Type="UI.SelectOptionType">
                        <PropertyValue Property="PropertyName" PropertyPath="BookingStatus"/>
                        <PropertyValue Property="Ranges">
                            <Collection>
                                <Record Type="UI.SelectionRangeType">
                                    <PropertyValue Property="Sign" EnumMember="UI.SelectionRangeSignType/I"/>
                                    <PropertyValue Property="Option" EnumMember="UI.SelectionRangeOptionType/EQ"/>
                                    <PropertyValue Property="Low" String="N"/>
                                </Record>
                            </Collection>
                        </PropertyValue>
                    </Record>
                </Collection>
            </PropertyValue>
        </Record>
    </Annotation>
    ...
</Annotations>
```

LANGUAGE: ABAP CDS
CODE:
```abap
//@Scope: [ENTITY] (e.g. "Booking")
@UI: {
    selectionVariant: [ {
        qualifier: 'BookingSV',
        filter: 'BookingStatus EQ "N"'
    } ]
}
```

LANGUAGE: CAP CDS
CODE:
```cds
annotate TravelService.Travel with @UI: {
    SelectionVariant #BookingSV: {
        SelectOptions: [ {
            $Type       : 'UI.SelectOptionType',
            PropertyName: BookingStatus,
            Ranges      : [ {
                $Type : 'UI.SelectionRangeType',
                Sign  : #I,
                Option: #EQ,
                Low   : 'N'
            } ]
        } ]
    },
    ...
}
```

STEP: Define UI.PresentationVariant (visualizations, SortOrder, MaxItems)

DESCRIPTION: Use PresentationVariant to define default visualizations (LineItem/Chart), sort order, MaxItems, and other visualization properties. Reference this PV from SelectionPresentationVariant. If PV is missing while SPV points to it, the app throws an error—ensure correct path.

LANGUAGE: XML (OData V4)
CODE:
```xml
<Annotations Target="self.BookingType">
    ...
    <Annotation Term="UI.PresentationVariant" Qualifier="BookingPV">
        <Record>
            <PropertyValue Property="Text" String="Default"/>
            <PropertyValue Property="SortOrder">
                <Collection>
                    <Record Type="Common.SortOrderType">
                        <PropertyValue Property="Property" PropertyPath="BookingID"/>
                        <PropertyValue Property="Descending" Bool="true"/>
                    </Record>

                </Collection>
            </PropertyValue>
            <PropertyValue Property="Visualizations">
                <Collection>
                    <AnnotationPath>@UI.LineItem</AnnotationPath>
                </Collection>
            </PropertyValue>
        </Record>
    </Annotation>
    ...
</Annotations>
```

LANGUAGE: ABAP CDS
CODE:
```abap
//@Scope: [ENTITY] ("Booking")
@UI: {
    presentationVariant: [ {
        qualifier: 'BookingPV',
        sortOrder: [ {
            by: 'BookingID',
            direction: #DESC
        } ],
        visualizations: [ {
            type: #AS_LINEITEM
        } ]
   } ]
}
```

LANGUAGE: CAP CDS
CODE:
```cds
annotate TravelService.Travel with @UI: {
    PresentationVariant #BookingPV: {
        SortOrder : [
            {
                $Type : 'Common.SortOrderType',
                Property : BookingID,
                Descending : true
            }
        ],
        Visualizations : [
            '@UI.LineItem'
        ]
    },
    ...
    ...
}
```

STEP: Define UI.Chart (chart annotation for ALP/main chart or multiple views)

DESCRIPTION: Define chart title, chart type, dimensions and measures. UI.Chart is applicable to ALP main chart and table-multiple-view scenarios.

LANGUAGE: XML
CODE:
```xml
<Annotations Target="STTA_PROD_MAN.STTA_C_MP_ProductSalesDataType">
   <Annotation Term="UI.Chart">
      <Record>
         <PropertyValue Property="Title" String="Test Chart"/>
         <PropertyValue Property="ChartType" EnumMember="UI.ChartType/Column"/>
         <PropertyValue Property="Dimensions">
            <Collection>
               <PropertyPath>DeliveryMonth</PropertyPath>
            </Collection>
         </PropertyValue>
         <PropertyValue Property="Measures">
            <Collection>
               <PropertyPath>Revenue</PropertyPath>
            </Collection>
         </PropertyValue>
      </Record>
   </Annotation>
</Annotations>
```

LANGUAGE: ABAP CDS
CODE:
```abap
@UI.Chart: [
  {
    title: 'Test Chart',
    chartType: #COLUMN,
    dimensions: [
      'DELIVERYMONTH'
    ],
    measures: [
      'REVENUE'
    ]
  }
]
annotate view STTA_C_MP_PRODUCTSALESDATA with {

}
```

LANGUAGE: CAP CDS
CODE:
```cds
annotate STTA_PROD_MAN.STTA_C_MP_ProductSalesDataType @(
  UI.Chart : {
    Title : 'Test Chart',
    ChartType : #Column,
    Dimensions : [
        DeliveryMonth
    ],
    Measures : [
        Revenue
    ]
  }
);
```

STEP: Define UI.LineItem (table columns and importance/criticality)

DESCRIPTION: Use UI.LineItem to define which properties show in table rows, their order (position), importance, text arrangements, and criticality mapping.

LANGUAGE: XML
CODE:
```xml
<Annotations Target="self.Container/Booking">

    <Annotation Term="UI.LineItem">
        <Collection>
            <Record Type="UI.DataField">
                <PropertyValue Property="Value" Path="TravelID"/>
                <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
            </Record>
            <Record Type="UI.DataField">
                <PropertyValue Property="Value" Path="BookingID"/>
                <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
            </Record>
            <Record Type="UI.DataField">
                <PropertyValue Property="Value" Path="BookingDate"/>
                <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
            </Record>
            <Record Type="UI.DataField">
                <PropertyValue Property="Value" Path="CustomerID"/>
                <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
            </Record>
            <Record Type="UI.DataField">
                <PropertyValue Property="Value" Path="CarrierID"/>
                <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
            </Record>
            <Record Type="UI.DataField">
                <PropertyValue Property="Value" Path="ConnectionID"/>
                <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
            </Record>
            <Record Type="UI.DataField">
                <PropertyValue Property="Value" Path="FlightDate"/>
                <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
            </Record>
            <Record Type="UI.DataField">
                <PropertyValue Property="Value" Path="FlightPrice"/>
                <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
            </Record>
            <Record Type="UI.DataField">
                <PropertyValue Property="Criticality" Path="BookingStatusIndicator"/>
                <PropertyValue Property="Value" Path="BookingStatus"/>
                <Annotation Term="UI.Importance" EnumMember="UI.ImportanceType/High"/>
            </Record>
        </Collection>
    </Annotation>
    ...
</Annotations>
```

LANGUAGE: ABAP CDS
CODE:
```abap
//@Scope: [VIEW] ("BOOKING")
annotate view VIEWNAME with {
    @UI.lineItem: [ {
        position: 10 ,
        importance: #HIGH
    } ]
    TravelID;

    @UI.lineItem: [ {
        position: 20 ,
        importance: #HIGH
    } ]
    BookingID;

    @UI.lineItem: [ {
        position: 30 ,
        importance: #HIGH
    } ]
    BookingDate;

    @UI.lineItem: [ {
        position: 40 ,
        importance: #HIGH
    } ]
    @UI.textArrangement: #TEXT_FIRST
    CustomerID;

    @UI.lineItem: [ {
        position: 50 ,
        importance: #HIGH
    } ]
    CarrierID;

    @UI.lineItem: [ {
        position: 60 ,
        importance: #HIGH
    } ]
    ConnectionID;

    @UI.lineItem: [ {
        position: 70 ,
        importance: #HIGH
    } ]
    FlightDate;

    @UI.lineItem: [ {
        position: 80 ,
        importance: #HIGH
    } ]
    FlightPrice;

    @UI.lineItem:       [ {
        position: 90,
        criticality: 'BookingStatusIndicator',
        importance: #HIGH
    } ]
    BookingStatus;
}
```

LANGUAGE: CAP CDS
CODE:
```cds
UI.LineItem : [
    {
        $Type : 'UI.DataField',
        Value : TravelID,
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataField',
        Value : BookingID,
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataField',
        Value : BookingDate,
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataField',
        Value : CustomerID,
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataField',
        Value : CarrierID,
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataField',
        Value : ConnectionID,
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataField',
        Value : FlightDate,
        ![@UI.Importance] : #High
    },
    {
        $Type : 'UI.DataField',
        Value : FlightPrice,
        ![@UI.Importance] : #High
    },
    {
        $Type       : 'UI.DataField',
        Value       : BookingStatus,
        Criticality : BookingStatusIndicator,
        ![@UI.Importance] : #High
    }
]
```

STEP: Manifest setting for default annotation (OData V2: annotationPath)

DESCRIPTION: To force the app to use a specific SelectionPresentationVariant, PresentationVariant, or SelectionVariant at startup, specify annotationPath in manifest.json for the ListReport generic template. This example shows V2 manifest format. annotationPath can point to SelectionPresentationVariant#Qualifier, PresentationVariant#Qualifier, or SelectionVariant#Qualifier. Note: if you point annotationPath to SelectionPresentationVariant, ensure the referenced PresentationVariant exists or the app will fail to load.

LANGUAGE: JSON
CODE:
```json
"component": {
     "name": "sap.suite.ui.generic.template.ListReport",
     "list": true,
     "settings": {
          "annotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#DefaultSPV" // This can also point to PresentationVariant/SelectionVariant instead of SelectionPresentationVariant
     }
}
```

STEP: Manifest setting for default annotation (OData V4: defaultTemplateAnnotationPath)

DESCRIPTION: For SAP Fiori elements V4 (sap.fe.templates.ListReport), set defaultTemplateAnnotationPath under the target options to point to a SelectionPresentationVariant. For V4, defaultTemplateAnnotationPath must reference a SelectionPresentationVariant (not just PresentationVariant or SelectionVariant).

LANGUAGE: JSON
CODE:
```json
"targets": {
    "SalesOrderManageList": {
        "type": "Component",
        "id": "SalesOrderManageList",
        "name": "sap.fe.templates.ListReport",
        "options": {
            "settings": {
                "contextPath": "/SalesOrderManage",
                "defaultTemplateAnnotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#SPVPath",
                 .....
                 .....
            }
        }
    }
}
```

STEP: Inline SelectionVariant/PresentationVariant inside SelectionPresentationVariant (XML + CAP)

DESCRIPTION: You can inline a SelectionVariant (and reference an unqualified PresentationVariant) inside a SelectionPresentationVariant. ABAP CDS does not support inline definitions—use local XML in that case.

LANGUAGE: XML
CODE:
```xml
<Annotation Term="UI.SelectionPresentationVariant" Qualifier="OpenSPVWithPVPath">
   <Record>
    <PropertyValue Property="Text" String="Open">
    </PropertyValue>
    <PropertyValue Property="SelectionVariant">
        <Record Type="UI.SelectionVariantType">
            <PropertyValue Property="Text" String="Open">
            </PropertyValue>
            <PropertyValue Property="SelectOptions">
                <Collection>
                    <Record Type="UI.SelectOptionType">
                        <PropertyValue Property="PropertyName" PropertyPath="OverallSDProcessStatus" />
                        <PropertyValue Property="Ranges">
                            <Collection>
                               <Record Type="UI.SelectionRangeType">
                                   <PropertyValue Property="Sign" EnumMember="UI.SelectionRangeSignType/I" />
                                   <PropertyValue Property="Option" EnumMember="UI.SelectionRangeOptionType/EQ" />
                                   <PropertyValue Property="Low" String="A" />
                                </Record>
                            </Collection>
                        </PropertyValue>
                     </Record>
                </Collection>
            </PropertyValue>
        </Record>
     </PropertyValue>
     <PropertyValue Property="PresentationVariant" Path="@UI.PresentationVariant" />
   </Record>
</Annotation>

<Annotation Term="UI.PresentationVariant">
    <Record>
        <PropertyValue Property="MaxItems" Int="2" />
        <PropertyValue Property="SortOrder">
            <Collection>
                <Record Type="Common.SortOrderType">
                  <PropertyValue Property="Property" PropertyPath="ID" />
                </Record>
            </Collection>
        </PropertyValue>
        <PropertyValue Property="Visualizations">
            <Collection>
                <AnnotationPath>@UI.LineItem</AnnotationPath>
            </Collection>
        </PropertyValue>
    </Record>
</Annotation>
```

LANGUAGE: CAP CDS
CODE:
```cds
UI.SelectionPresentationVariant #OpenSPVWithPVPath           : {
        Text                : 'Open',
        SelectionVariant    : {
            Text          : 'Open',
            SelectOptions : [{
                PropertyName : OverallSDProcessStatus,
                Ranges       : [{
                      Sign : #I,
                    Option : #EQ,
                   Low    : 'A'
                }]
            }]
        },
        PresentationVariant : ![@UI.PresentationVariant]
    },

UI.PresentationVariant                             : {
        MaxItems       : 2,
        SortOrder      : [{Property : ID}],
        Visualizations : ['@UI.LineItem']
    }
```

STEP: Request additional properties for backend read (RequestAtLeast)

DESCRIPTION: Use PresentationVariant.RequestAtLeast to ensure additional properties are requested from the backend even when not displayed in the visualization. Useful to avoid extra round-trips when personalization or client-side needs require them.

LANGUAGE: XML
CODE:
```xml
<Annotations xmlns=http://docs.oasis-open.org/odata/ns/edm Target="ZFAR_CUSTOMER_LINE_ITEMS2_SRV.Item">
    <Annotation Term="com.sap.vocabularies.UI.v1.PresentationVariant">
        <Record>
            <PropertyValue Property="Visualizations">
                <Collection>
                    <AnnotationPath>@UI.LineItem</AnnotationPath>
                </Collection>
            </PropertyValue>
            <PropertyValue Property="RequestAtLeast">
                <Collection>
                    <PropertyPath>Customer</PropertyPath>
                    <PropertyPath>CompanyCode</PropertyPath>
               </Collection>
            </PropertyValue>
        </Record>
    </Annotation>
</Annotations>
```

LANGUAGE: ABAP CDS
CODE:
```abap
@UI.PresentationVariant: [
  {
    requestAtLeast: [
      'CUSTOMER',
      'COMPANYCODE'
    ],
    visualizations: [{type: #AS_LINEITEM }]
  }
]
annotate view ITEM with {

}
```

LANGUAGE: CAP CDS
CODE:
```cds
annotate ZFAR_CUSTOMER_LINE_ITEMS2_SRV.Item @(
  com.sap.vocabularies.UI.v1.PresentationVariant : {
    Visualizations : [
        '@UI.LineItem'
    ],
    RequestAtLeast : [
        Customer,
        CompanyCode
    ]
  }
);
```

STEP: Configure default SortOrder

DESCRIPTION: Define SortOrder entries in PresentationVariant to set default column sort direction(s). For amount fields with currency/unit, the sort first groups by currency/unit then by amount.

LANGUAGE: XML
CODE:
```xml
<Annotations xmlns="http://docs.oasis-open.org/odata/ns/edm" Target="ZFAR_CUSTOMER_LINE_ITEMS2_SRV.Item">
    <Annotation Term="com.sap.vocabularies.UI.v1.PresentationVariant">
        <Record>
            <PropertyValue Property="Visualizations">
                <Collection>
                    <AnnotationPath>@UI.LineItem</AnnotationPath>
                </Collection>
            </PropertyValue>
            <PropertyValue Property="SortOrder">
                <Collection>
                    <Record>
                        <PropertyValue Property="Property" PropertyPath="CompanyCode"/>
                        <PropertyValue Property="Descending" Bool="true"/>
                    </Record>
                    <Record>
                        <PropertyValue Property="Property" PropertyPath="Customer"/>
                    </Record>
                </Collection>
            </PropertyValue>
        </Record>
    </Annotation>
</Annotations>
```

LANGUAGE: ABAP CDS
CODE:
```abap
@UI.PresentationVariant: [
  {

    sortOrder: [
      {
        by: 'COMPANYCODE',
        direction: #DESC
      },
      {
        by: 'CUSTOMER'
      }
    ],
    visualizations: [{type: #AS_LINEITEM }]
  }
]
annotate view ITEM with {

}
```

LANGUAGE: CAP CDS
CODE:
```cds
annotate ZFAR_CUSTOMER_LINE_ITEMS2_SRV.Item @(
  com.sap.vocabularies.UI.v1.PresentationVariant : {
    Visualizations : [
        '@UI.LineItem'
    ],

    SortOrder : [
        {
            Property : CompanyCode,
            Descending : true
        },
        {
            Property : Customer
        }
    ]
  }
);
```

STEP: Configure MaxItems (number of rows loaded initially)

DESCRIPTION: Use PresentationVariant.MaxItems to set how many rows are initially loaded into the table. This controls initial data volume.

LANGUAGE: XML
CODE:
```xml
<Annotations xmlns=http://docs.oasis-open.org/odata/ns/edm Target="ZFAR_CUSTOMER_LINE_ITEMS2_SRV.Item">
    <Annotation Term="com.sap.vocabularies.UI.v1.PresentationVariant">
        <Record>
            <PropertyValue Property="Visualizations">
                <Collection>
                    <AnnotationPath>@UI.LineItem</AnnotationPath>
                </Collection>
            </PropertyValue>
            <PropertyValue Property="MaxItems" Int="50" />
        </Record>
    </Annotation>
</Annotations>
```

LANGUAGE: ABAP CDS
CODE:
```abap
@UI.PresentationVariant: [
  {
    maxItems : 50,
    visualizations: [{type: #AS_LINEITEM }]
  }
]
annotate view ITEM with {

}
```

LANGUAGE: CAP CDS
CODE:
```cds
annotate ZFAR_CUSTOMER_LINE_ITEMS2_SRV.Item @(
  com.sap.vocabularies.UI.v1.PresentationVariant : {
    Visualizations : [
        '@UI.LineItem'
    ],
    MaxItems : 50
  }
);
```

STEP: Manifest behavior when annotationPath points to PresentationVariant or SelectionVariant (OData V2 details)

DESCRIPTION: If manifest annotationPath references a PresentationVariant: only visualization (PV) is applied—SelectionVariant defaults are not applied. If annotationPath references a SelectionVariant: default filters are applied; visualization falls back to unqualified PresentationVariant or UI.LineItem/UI.Chart.

LANGUAGE: JSON
CODE:
```json
"component": {
     "name": "sap.suite.ui.generic.template.ListReport",
     "list": true,
     "settings": {
          "annotationPath": "com.sap.vocabularies.UI.v1.SelectionPresentationVariant#DefaultSPV" // This can also point to PresentationVariant/SelectionVariant instead of SelectionPresentationVariant
     }
}
```

STEP: Notes and fallbacks (action points for implementers)

DESCRIPTION: Action-oriented rules to follow:
- Always verify that if you point manifest to SelectionPresentationVariant#Qualifier, the referenced PresentationVariant exists—otherwise the app fails to load.
- If no manifest annotation path is provided, fallback order is:
  1) unqualified UI.SelectionPresentationVariant
  2) unqualified UI.SelectionVariant and UI.PresentationVariant
  3) UI.LineItem or UI.Chart (fallback visualization)
  4) empty table/chart (user can personalize to render desired view)
- For SAP Fiori elements V4 ALP flavor, use ALP-specific configuration (analytical list page uses different descriptor settings). For V4 ListReport use defaultTemplateAnnotationPath pointing to a SelectionPresentationVariant.
- ABAP CDS has no inline SelectionPresentationVariant syntax—use local XML annotations when you need inline definitions.

LANGUAGE: Text
CODE:
```text
- Ensure correct annotation paths and qualifiers to avoid startup errors.
- Fallback resolution order if manifest setting is omitted:
  1) unqualified UI.SelectionPresentationVariant
  2) unqualified UI.SelectionVariant and UI.PresentationVariant
  3) UI.LineItem or UI.Chart
  4) empty control (user personalization possible)
- For sorting amounts with currency/UoM: sort by currency/UoM first, then by amount.
- ABAP CDS: no inline SelectionPresentationVariant support; use XML annotations.
```

STEP: Reference: Default filter values

DESCRIPTION: Use UI.SelectionVariant for default filter values. For actionable examples and detailed behavior when merging selection defaults and user input, consult your project-specific "Configuring Default Filter Values" documentation or follow the SelectionVariant examples above.

LANGUAGE: Text
CODE:
```text
See the SelectionVariant examples in this document for inline and qualified definitions to set default filter values.
```

fiori-elements-framework annotations SelectionPresentationVariant PresentationVariant SelectionVariant LineItem Chart manifest odata-v2 odata-v4


**TITLE**: Configure sap.ui5 Dependencies to Include Required SAPUI5 Libraries

**INTRODUCTION**: Define SAPUI5 library dependencies in the "sap.ui5" section to limit loaded libraries and improve application loading time. For Overview page application instances, include the sap.ovp library and specify minimum versions.

**TAGS**: fiori-elements-framework, sap.ui5, sap.ovp, dependencies, performance

**STEP**: Add required SAPUI5 libraries to the sap.ui5 dependencies section

**DESCRIPTION**: Edit your application's manifest (or relevant configuration) to include a "dependencies" block under "sap.ui5" that specifies the minimum UI5 version and the libraries your app depends on. For Overview page applications, add the "sap.ovp" library with a minVersion to ensure the runtime loads the required library and optimizes loading.

**LANGUAGE**: JSON

**CODE**:
```json
"sap.ui5": {
    ...
    "dependencies": {
        "minUI5Version": "1.32.0",
        "libs": {
            "sap.ovp": {
                "minVersion": "1.32.0"
            }
        }
    },
    ...
}
```