Intro

Every once in a while, you may find yourself wanting to stretch the visual limits of SAPUI5. Luckily, SAPUI5 provides the option of using other controls libraries. In principle, this should be fairly straight-forward. Some of the 3rd party control libraries are even built on JQuery, and thus share the same foundation as UI5. Including them in your UI5 app should in principle be easy.

In real life, however, most such third-party control libraries need some tweaking in order to be seamlessly integrated in a UI5 environment. This is particularly true when working with XML views, which is the preferred way of creating UI5 applications. XML views in SAPUI5 can have some “quirky” consequences on the related controller Javascript code needed for third-party controls. Also, the fact that most of the documentation for the main third-party control libraries refer to Javascript views, not XML, can pose interesting challenges.

This blog aims to provide a walkthrough of challenges and pitfalls related to using controls from the Kendo UI framework in SAPUI5. I will focus on some simple chart implementations, and show how to use these in XML views. Also, I will show how to feed remote data into the chart controls, using OData.

Note: some of the code screenshots may be difficult to read; please click them in order to enlarge!

Preparations

The following example has been created using the Web IDE on the HANA Cloud Platform – HCP. In the Web IDE, select New->Project from template->SAPUI5 Application. This gives you a simple UI5 application with one view (which should be of type XML).

The next step is to import the CSS and Javascript libraries into the application. Using references to content on the web is not recommended, as this might result in cross-domain errors under certain circumstances (such as when running your app from a Fiori Launchpad).

This is the folder structure with the Kendo JS and CSS libraries:

/wp-content/uploads/2016/01/pic1_871871.png

Creating the simple app

We’ll create a simple app based on a sample OData service, and implement a Kendo chart control to visualize the data. The Kendo chart control provides a wide range of different chart types; I will show a couple of these. The functionality is similar – once you implement one, you can easily switch to another.

The OData service resides on a Netweaver Gateway system. For the purpose of illustration, I have created a simple table that shows the distribution of zombie observations across the US. (Another distinct advantage of using zombies is the fact that zombie starts with the letter “Z”, which makes it particularly useful for creating custom SAP objects like “zombietable”.)


The OData service based on my zombie table is created in the Gateway Builder (transaction SEGW). This is outside the scope of this blog; there’s an excellent book from SAP Press dealing with these topics.

The resulting metadata of my OData service (extract):

/wp-content/uploads/2016/01/pic2_871873.png

And part of the resulting ZombieSet record set:

/wp-content/uploads/2016/01/pic3_871874.png

With our OData service set up and running, it’s time to do the fun stuff: the Kendo in UI5 application.

The UI5 application

As mentioned, I started by using the Web IDE wizard to create a simple UI5 project. The wizard provides the folder structure we need for our app, and we can also ask it to generate the first view (which should be of type XML). The advantage of XML views is that it forces us to adhere to the MVC pattern, unlike Javascript views which literally allows for any kind of Javascript functionality to be embedded into the view code. (Don’t use Javascript views, use XML! Grown-ups never use Javascript views!!)

If we follow the wizard’s recommendations, we’ll end up having one initial view called “View1” with a related controller.

I already mentioned the need for importing the Kendo CSS and Javascript files into their specific folders (the existing css folder for the CSS files, and Kendo JS files into a specific folder). When this is done, we need to register these in the manifest.json file:

/wp-content/uploads/2016/01/pic4_871875.png

The manifest.json file is a JSON model which acts as the “repository” of resources for our application. It should already contain a reference to the UI5 css file (css/style.css); all we need is to add the remaining Kendo CSS references, and also a specific section for the Kendo Javascript files as seen above. By doing this, there is no need to make references to these resources in the index.html file.

Our XMLview file will be quite simple. All it contains is a “div” element which holds our Kendo chart (and another div to encapsulate it). This is the code:

/wp-content/uploads/2016/01/pic5_871876.png

That’s it – really. I promise the controller will be a bit more complicated!

Kendo source code

In order to include a Kendo UI control, we need to embed some Kendo Javascript code into our view controller. The Kendo UI site contains sample code for all of the Kendo controls. Ideally, all we would have to do is copy the code related to “our” control (the Kendo chart in our case) and paste it into our view controller. However, there are two major hurdles waiting for us: the fact that we’re using XML views, and that Kendo controls only work with JSON data. Since we’re in an SAP environment, we’re of course using OData, and as already mentioned we also decided to stick to XML views.

Both of these hurdles require some tweaking of the Kendo code.

Let’s look at the standard Kendo code for a bar chart:

/wp-content/uploads/2016/01/pic6_871877.png

This is an excerpt. As we can see, the data source here is a JSON model. This will not work for us; we receive our remote data in OData format, and what we need to do is convert this into JSON.

Luckily, this is easy enough with SAPUI5 – we’ll see that in a minute.

Here is the controller code, section by section.

/wp-content/uploads/2016/01/pic7_871878.png

The main part here contains the onAfterRendering method. This is where we invoke the Kendo script – we do this after SAPUI5 has finished the general rendering of the view, that is, built all the standard UI5 framework elements.

We start by declaring our OData service url, and the path to the relevant record set within this service.

We then define a variable for the OData model.

Then, we set the scope variable that equal to this. “this” is a reference to the current scope, or “where we are now” in layman’s terms. By defining a new variable “that” and aligning it with “this”, we can refer to the createChart function inside the “success” callback function for our oDataModel.read logic. OK, this might seem complex (as promised), but the main idea is that we need to keep a reference to “where” we can retrieve the createChart function. Without using the “that” variable, we will loose sight of it within the “success” function, since we will have another scope there – “this” will not refer to the context where createChart is defined anymore.

It’s a bit like going through a wormhole to another universe, and trying to find Andromeda by looking at the sky. Won’t work. By declaring “that” before going, and taking it with you, you won’t be lost.

What goes on inside the “success” function – which is only invoked if the read of the OData model succeeds – is that we call the createChart function (I’ll get to it in a minute), then invoke a couple of Kendo-related commands that adds attributes to the finished chart.

The next part of our controller contains the actual Kendo chart function:

/wp-content/uploads/2016/01/pic8_871879.png

This is almost a copy/paste of the code from the Kendo samples site. The only things changed are the variable names (ZombieNumber and ZombieCity, from our OData model), as well as the “selector” – which actually warrants a section of its own. Finally, the specification of our data source and schema, which is also explained in detail below.

Use of selectors in Kendo code

Kendo JS is based on JQuery, and uses “selectors” in order to identify page elements. Selectors are a key concept in JQuery (and thus SAPUI5) – this is worth reading up on. As in “the following section won’t make much sense if you don’t know what a selector is”. I’ve provided a link to some excellent info further down.

Anyway, this whole selector thing poses a specific challenge when working with SAPUI5 XML views. In these views, the element id’s are “amended” by SAPUI5 on rendering. What happens is that the view name is added as a prefix to the element id, in order to uniquely define elements across views. Here is an example:

In our Kendo chart, the “div” element is named “chart”, as seen below:

/wp-content/uploads/2016/01/pic9_871880.png

What happens if we simply paste the standard Kendo Javascript code into our controller – with a selector “chart”? Let’s look at how the sample Kendo code appears:

/wp-content/uploads/2016/01/pic10_871881.png

This is the start of the createChart function, as retrieved from the Kendo sample site. As we can see, the function starts by using a selector identifying the “chart” element in our XML page. What happens if we use the code with the selector “as-is”?

The chart will not appear. This is because of the re-naming of our div element by the SAPUI5 rendering. If we look at the debugger, we can expand the elements to find our div:

/wp-content/uploads/2016/01/pic11_871882.png

As can be seen, SAPUI5 prefixes the element id with two underscores, followed by the view name (which, by the way, does not correspond to the actual view name as given by us; SAPUI5 generates brand new view names following the convention “xmlviewN”, where N is a number starting with 0), then two dashes, then finally our given id for the chart. Thus, “chart” in “View1” becomes “__xmlview0—chart”.

What we need to do, is tweak the Kendo code to correspond to the “new” naming done by SAPUI5. By altering the above selector slightly, we can make it look for all “div” elements containing the string “chart”:

/wp-content/uploads/2016/01/pic12_871886.png

Note that I am also passing our JSON “myData” to the function – this is my JSON model as derived from the original OData service. The main thing here is that the selector now works also in an SAPUI5 XML content.

More info on JQuery selectors and how to build them can be found here:

http://www.w3schools.com/jquery/jquery_ref_selectors.asp

Data provisioning – stuffing our charts with zombies

Kendo UI controls work with static, local or remote data. Static in this context means hard-coded values in the Javascript code for the Kendo control. This is usually not too interesting from an SAPUI5 point of view.

Local data relate to locally defined JSON models. This also amounts to hard-coding for mockup scenarios, and is also not very interesting for “real” applications.

Our example works with remote data – provided by a Gateway OData service. For use in the Kendo controls, the data will have to be in JSON format. Because of this “limitation”, we translated the data to JSON format when reading the OData service.

One issue with this way of providing JSON data from an OData source is that the Kendo code has issues with “complex” data models, such as the ones provided by OData-to-JSON conversion. If we simply declare our chart by copying and pasting the generic Kendo sample code, like most exampoles found on the site (related to JSON models) we may run into problems.

Running “standard” Kendo chart code will easily result in the following error:

/wp-content/uploads/2016/01/pic13_871887.png

This is due to the relative complexity of our JSON data:

/wp-content/uploads/2016/01/pic14_871888.png

Note the “results” element at the top of the JSON structure.

In order to resolve this, we need to declare a “schema” in our dataSource parameter for the chart:

/wp-content/uploads/2016/01/pic15_871889.png

Here, we declare the header node = “results” – this is all that is needed to enable Kendo to correctly traverse the JSON model.

A Kendo forum post regarding this issue can be found here:

http://www.telerik.com/forums/kendo-chart-e-slice-is-not-a-function-with-remote-data

Resulting UI

The result of our efforts:

/wp-content/uploads/2016/01/pic16_871890.png

As can be seen, Las Vegas is the place to steer clear of, regarding zombies.

Changing the chart type: Donut chart

With the above framework in place, it’s fairly easy to create new chart types. We simply alter the createChart function to specify a different type:

/wp-content/uploads/2016/01/pic17_871891.png

Result:

/wp-content/uploads/2016/01/pic18_871892.png

(Note that some chart types are suitable for specific types of data – depending on the complexity of the data).

I hope this provided some ideas of what is possible; the concepts should be useful also for other 3rd party UI libraries.

These examples were developed using Web IDE on a HANA Cloud platform, with data pulled from a Gateway system.


To report this post you need to login first.

6 Comments

You must be Logged on to comment or reply to a post.

  1. Klaus Kronawetter

    Really nice and clean blog post!

    But to be honest, I don’t really see the need for a ‘third party’ chart engine.

    I think the sap.viz charts look great… besides, the Kendo charts are not free to use, right?

    (0) 
    1. Trond Stroemme Post author

      Hi,

      no, Kendo is not free. Nor would you normally need to deviate from the standard UI5 controls (or extensions). But my idea was to explore the use of 3rd party controls as a concept, and provide some guidelines.

      So, explore and enjoy 🙂

      (0) 
  2. Mauro Cattaneo

    I managed to integrate also Kendo UI Scheduler control…but only using hard-coded json data inside the controller. I want to be able to use it but with mockdata: is it possible? Can I have an example of how to do it? Thanks a lot

    (0) 

Leave a Reply