Binding an OData Service to charts and tables
- Tim Schauder
Owned by Tim Schauder
This tutorial will show how to
- ... use the WebIDE to create a simple UI5 App
- ... register graphomate for UI5 Resources to your project
- ... display data from an OData service using graphomate charts and tables for UI5
- ... use Aggregation Binding in XML Views
- ... manually set data to the components defined in the view using the corresponding controller
1 Creating the App
- Log in to your SAP Cloud Platform and open the WebIDE
- Select File → new → project from template
- Create an UI5 Application using the wizard
2 Adding graphomate for UI5 Resources
- Upload the content of the zip containing the current version of 'graphomate for UI5' extensions by right clicking your project's webapp folder and selecting import → file or project
- Import it to /webapp/res
- Change the directory tree to look as the following, resulting in the graphomate directory being a direct child of webapp/res:
- Now you need to register the newly added resources by opening the mainifest.json file and adding the following entries:
3 Creating a Destination
- In order to successfully request data from an OData service you need to create a proxy connection. Therefor log in to your cloud platform cockpit and select connectivity → destinations from your side menu
- We use the microsoft OData test service northwind in this tutorial. To be able to get data from this service add a new destination like the following:
4 Adding an OData Service to Your App
- By right clicking your project in WebIDE and selecting new → OData Service you can bind an OData Service to your app
- Select your newly created destination from the drop down menu and add the following service URL: V2/Northwind/Northwind.svc (normally it would be prefixed with services.odata.org, but that part is being managed by your northwind destination proxy service)
- Click test to check the connection
- In the last step of the wizard select default model to create a default OData Model for your app
5 Adding Table & Chart to Your View
- Open the view of your app (webapp → view → View1.view.xml)
- For this demo we ...
- ... create basic table and chart instances in the view
- ... bind data from the OData model to the Tables's aggregation 'rows' by using Aggregation Binding Syntax
- ... manually bind data from the OData model to the Chart's data series properties by using the controller
- The Following code describes an xml view which defines a table and a simple chart:
View1.view.xml
<mvc:View controllerName="tutorial.ODataTutorial.controller.View1" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m" xmlns:tables="graphomate.ui.tables" xmlns:charts="graphomate.ui.charts" > <App id="idAppControl"> <pages> <Page title="OData Tutorial"> <content> <VBox alignItems="Center"> <items> <!--Here we use Aggregation Binding to create a row for each product --> <tables:Table width="700px" rows="{/Products}" showFilterHelper="true"> <tables:rows> <!--Here Expression Binding is used to concatenate the values of a row into an array --> <tables:Row title="{ProductName}" dataPerColumn="{=[${UnitsInStock},${UnitsOnOrder}]}" /> </tables:rows> <tables:columns> <!--The columns' ids get prefixed by UI5, so the prefix has to be part of the DeviationColumn's base and measure ids --> <tables:DataColumn title="Units in Stock" id="measure" /> <tables:DataColumn title="Units on Order" id="base" /> <tables:DeviationColumn title="Units Available" type="Absolute" baseColumnId="__xmlview0--base" measureColumnId="__xmlview0--measure" /> </tables:columns> </tables:Table> <!--This chart is not bound to any data in the view. Its data gets initialized in the controller--> <charts:Chart id="gmChart0" width="700px" height="600px" chartType="OffsetBar" rotated="true" showSeriesLabelsRight="true" padding="20" /> </items> </VBox> </content> </Page> </pages> </App> </mvc:View>
- The Following code describes the matching controller which prepares the data and sets it to the chart for this demo case. The data series of an graphomate chart only accepts data of type 'float[]'. Depending on the data structure used in the model, it could be required to use formatter functions or Expression Binding to map the object based data structure to an array of float values. An Example using formatter functions is implemented below:
View1.controller.js
sap.ui.define([ "sap/ui/core/mvc/Controller" ], function (Controller) { "use strict"; return Controller.extend("tutorial.ODataTutorial.controller.View1", { onInit: function() {}, /** Takes an object and returns an array of its values */ toArray: function(obj) { return Object.keys(obj).map(function(key) { return obj[key] }) }, /** Filters an array of products to only include products of specific characteristics */ filterProducts: function(products) { return products.filter(function(product){ return product.UnitsOnOrder > 0 && product.UnitsInStock > 0 && product.UnitsOnOrder < 50; }) }, /** Attaches an handler which gets called when the OData model finished loading data */ onAfterRendering: function() { var self = this; this.getView().getModel().attachRequestCompleted(function(){ self.setChartData(); }); }, /** Retrieves data from OData model when received and sets it to the chart */ setChartData: function() { var productData = this.filterProducts(this.toArray(this.getView().getModel().oData)); this.getView().byId('__xmlview0--gmChart0') .setSeries1(productData.map(function(product) { return product.UnitsOnOrder; })) .setSeries2(productData.map(function(product) { return product.UnitsInStock; })) .setCategoryLabels([productData.map(function(product) { return product.ProductName; })]) .setSeriesLabels(["UnitsOnOrder", "UnitsInStock"]); } }); });
6 Test Your App
- In WebIDE right click the your project and select Run → Run As SAP Fiori Launchpad Sandbox to test your app in a new browser tab
- Apart from the factual incorrectness, which creates a wrong relationship between 'Units in Stock' and 'Units on Order', the resulting app should contain a clear visualization of available products: