Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
simon_hoeg
Advisor
Advisor

Summary


Since Business Suite 7 Innovations 2010, many of the UIs provided by SAP are built using Floorplan Manager for Web Dynpro ABAP (FPM). These UIs are very flexible and easy to adapt to the needs of individual customers. This blog presents an introduction on how to involve Java Script Chart libraries in Floorplan Manager Applications on basis of the new HTML Island UI Element provided by Web Dynpro ABAP from SAP Netweaver 7.31 SP5.

Introduction


Graphical representations of data (charts) represent a widespread instrument to simplify the understanding of large quantities of data and their inner relations. A chart usually acts a compendium or replacement for tabular data.

For a long time web application developers have built charts with the help of browser plug-in’s or add-ons such as Adobe Flash or MS Silverlight. That used to be the best solution, but required some additional resources and also did not work on all touch-enabled operating systems such as Apple's iOS. Recently, several free Java Script libraries came up that make use of Open Web Standards such as HTML5, CSS3, AJAX and SVG.

HTML5 provides the so-called Canvas that allows for fast drawing of graphics on web pages on the fly. This is done usually via Java Script. Basically, the <canvas> element represents a rectangular area on an HTML page, and it has several methods for drawing paths, boxes, circles, characters, and adding images. Modern browsers such as Internet Explorer 9, Firefox, Opera, Chrome and Safari support this element.

At this point, web application developers are likely to pose the questions:

  • Is it possible to bring that innovation into a Web Dynpro ABAP based web application?

  • How can I make use of a complete Java Script library within the Floorplan Manager UI Framework?

  • How can I implement several HTML5 charts without time consuming efforts on Java Script, JSON etc.?


This blog tries to answer these questions.

Chart Libraries based on Java Script


There are several excellent Java Script libraries available in the World Wide Web that are available with a free software licensethat belongs to the license family of MIT (Massachusetts Institute of Technology) or BSD (Berkeley Software Distribution).

The single libraries have a focus on very different uses cases, rendering techniques and dependencies. Naturally, developers should carefully choose one that fits to their requirements. Of more interest in our context are the ones that are dedicated to business graphics and that already use the HTML5 Canvas such as RGraph, Flotr2, Highcharts or Processing.js. Also, the SAP library CVOM (Common Visual Object Modeler) fulfills that requirement. Other libraries like dygraphs, Flot and Flotr use the so-called Explorer Canvas, a Java Script based emulation that let you handle VML (Vector Markup Language) the same way as HTML5 Canvas.

In contrast to the previously mentioned libraries, D3 (Data-Driven Documents) allows deeper control over the final visual result. It is the official successor of the previous Protovis framework and obviously a very prominent and efficient visualization library. D3 allows you to bind arbitrary data to a document object model, and then apply data-driven transformations to the document. It affords extraordinary flexibility, exposing the full capabilities of CSS3, HTML5 and SVG (Scalable Vector Graphics). Chart libraries such as Rickshaw, Cubism.js, Polychart.js or CVOM are explicitly built on top of D3.

HTML Island in Web Dynpro ABAP


With Netweaver 731 SP5 a new UI element, the HTML Island has been introduced by Web Dynpro ABAP. The new UI element allows you to embed custom HTML, JavaScript and CSS sources directly into the Web Dynpro HTML page. This approach comes in two flavors: HTML Island and HTML container, both are subclasses of the HTML Element:

  • The HTML Island is used to embed custom HTML controls that are mostly rendered on client side. They can survive round-trips without getting rendered each time. This is useful for controls like charts.

  • The HTML Container can aggregate custom HTML and Web Dynpro UI elements. It is re-rendered each time the UI changes. This is useful for decorating or enhancing existing Web Dynpro UI elements.


Both controls allow for aggregation of scripts and CSS sources. To enable communication with an HTML Island or HTML Container single JavaScript calls can be triggered via the Web Dynpro backend (see Figure 1 below).

From a perspective of a web application developer, the new HTML elements offer almost unlimited possibilities. A wide range of Java Script libraries can be embedded along with an appropriate HTML and CSS. Typical use cases cover graphs and charts, string and mathematic functions, geographic maps, bar codes, game controls, rich text edit controls and all kind of effects on images, but also complete touch-enabled user interfaces.



Figure 1: High level architecture of the new HTML Elements

Communication between Web Dynpro and HTML Element


The communication between Web Dynpro and the HTML Element is accomplished via JavaScript calls. These calls can be send from the backend using an API that is accessed through class CL_WD_HTML_SCRIPT_CALL respectively interface IF_WD_HTML_SCRIPT_CALL. The code example below illustrates how to do a simple call to a HTML Island; typically this can be done in method WDDOMODIFYVIEW:

lo_html_island->add_script_call( cl_wd_html_script_call=>new_call( )->variable( `myJSVariable`)->function( `greet` )->add_string( `Hello World` ) ).

This ABAP coding would lead to a JavaScript call myJSVariable.greet('Hello World').

Vice versa, the HTML Island UI element can have an arbitrary number of events that fire a Web Dynpro action. Once these events are defined in the backend we can fire them from the browser using a callback JavaScript API. To do so, we need to pass this callback API to the client. Here again, the script call API comes into the game.

Let's assume, we want to fire Web Dynpro action ON_GREET from the client. For this we add an event to the HTML Island and provide a name, in our example onGreet. Then we need to pass the callback API to the client, for instance:

lo_html_island->add_script_call( cl_wd_html_script_call=>new_call( )->variable( `myJSVariable` )->function( `setApi` )->add_callback_api( ) ).

This causes the system to perform a JavaScript call on the client myJSVariable.setApi(<ReferenceToCallbackApi>). On the client we can now use this <ReferenceToCallbackApi> to execute the event on the backend:

<ReferenceToCallbackApi>.fireEvent('onGreet').

This causes the Web Dynpro action ON_GREET to be executed.

An excellent demo (Web Dynpro component WDR_TEST_HTML_ELEMENT) exposing several applications that illustrate all the possibilities around the HTML Island and HTML Container is available with SAP Netweaver 7.31 SP5.

A Configurable Chart UIBB for Floorplan Manager Applications


While Web Dynpro ABAP has prepared the technical basis, it is the Floorplan Manager UI Framework in particular that allows for efficient, easy and consistent web application development. It provides a straightforward approach to bring amazing enhancements into a web application that is provided by any Java Script library.

A natural concept that arises from the previous discussion is that an application developer creates his own Java Script library based UI Building Block (UIBB) on the basis of a freestyle component, i.e. a Web Dynpro component that implements the interface IF_FPM_UI_BUILDING_BLOCK. The Freestyle UIBB itself has an explicit configuration context that describes the required settings and options of the Java Script library being used, such as the chart type, colors, labels, grid lines, animations etc. Based on the type of chart and animation a corresponding custom Java Script and CSS source can be involved during the runtime. Due to the configuration capabilities very different charts can be described by this single UI Building Block. Similar to the GUIBB approach, a feeder class could be used for the data retrieval during the application runtime. In Figure 2 this concept is briefly outlined.



Figure 2: Concept for a Configurable Chart UIBB

The configurable Chart UIBB consists of a component controller and explicit configuration context. The component controller communicates with a feeder class for data retrieval and event processing. The configuration context has a structure that is related to the properties of the involved Java Script library, it gets the corresponding configuration data from the data base. The rendering part is using the HTML Island to embed Java Script and CSS sources. The Floorplan Controller communicates via Web Dynpro interface IF_FPM_UI_BUILDING_BLOCK with the configurable Chart UIBB; it has all the knowledge about the overall application structure that is addressed by the running Web Dynpro application.

Let's recap the advantages that are offered by this freestyle approach:

  • The Chart UIBB can be configured for very different charts in Floorplan Manager applications

  • Data retrieval and event processing, as well as the application logic is defined entirely in the backend system (at least in the feeder class)

  • Like with all UI Building Blocks the Chart UIBB can added to each Floorplan Manager application and is subject to useful features of the Floorplan Manager Runtime (phase model, events, navigation, message handling, data-loss handling, personalization etc.)

  • The configurable Chart UIBB is integrated into the Floorplan Manager development infrastructure (Configuration Editor, Application Hierarchy Browser, Deep-Copy).

  • The configurable Chart UIBB can make use of Web Dynpro adaptation techniques such as customizing and enhancement (see our Adaptation Guide).


In addition, the application developer may use the Java Script library that exactly fulfills the desired features. It is possible also to integrate several libraries in one configurable Chart UIBB. This is an important point, as requirements for graphic rendering and its technical realization usually progress faster than the business logic and corresponding application structure. Furthermore, the application developer has to create answers to new data base technologies that are much faster than before as well as modern operating systems and devices that offer touch-enabled user interfaces.

From SAP Netweaver 7.31 SP5 onwards, Web Dynpro ABAP and Floorplan Manager explicitly allow for a larger scope and more open space to keep up with these most recent innovations.

Demo Application


With SAP Netweaver 7.31 SP 6 and 7 an Overview Page Floorplan application FPM_DEMO_CHART is delivered that is based on the concept described above. The demo application shows three charts based on a random signal that consists of 4-tuples (longitude, latitude, time, magnitude). The random signal has a 1/f frequency spectrum with regard to the magnitude dimension:

  1. A bubble chart that shows the space and magnitude distribution of the signal over the earth surface. It provides tooltips that show the values for each dimension and it has a mouse selector. The latter allows for selecting values respectively interactive zooming into the chart:

  2. A step chart that shows the time and magnitude distribution over 24 hours. Like the first chart it provides tooltips that show the values for each dimension and it allows for selecting values respectively an interactive zooming regarding dimension time:

  3. A pie chart as well as a bar chart that show the distribution of the magnitude dimension between 0 and 10. Like the first and second chart it provides a tooltip that shows the values for each dimension:


 

Each chart is described by a component configuration that belongs to either Web Dynpro component FPM_DEMO_CHART_UIBB (Flotr2 Chart Library) or FPM_DEMO_CVOM_UIBB (CVOM Chart Library) or FPM_DEMO_VIZFRAME_UIBB (VizFrame Chart Library). This becomes apparent when looking at the application structure of this demo, which is shown in the following screen of the Application Hierarchy Browser:



The Freestyle UI Building Blocks FPM_DEMO_CHART_UIBB (Flotr2 chart library) or FPM_DEMO_CVOM_UIBB (CVOM chart library) or FPM_DEMO_VIZFRAME_UIBB (VizFrame chart library) hold the necessary Java Script files of the corresponding Java Script library as MIME objects. In addition a small Java Script snippet is needed to create and update the charts as well as to set-up the needed event listeners. With regard to the VizFrame chart library the snippet looks like this:
if (typeof SAPFPM_vizFrameSelect == "undefined") {
SAPFPM_vizFrameSelect = {

mBuffer: {},
mRootRef: {},

createChart: function(id, data, dataset, feeditems, options, type, api) {

// hourglass
this.mRootRef[id] = document.getElementById(id);
this.mRootRef[id].className = "urLoadImg";
this.mRootRef[id].style.backgroundPosition = "center center";
this.mRootRef[id].style.backgroundRepeat = "no-repeat";

var that = this;

sap.ui.getCore().attachInit(function() {
// render
that._createChart(id, data, dataset, feeditems, options, type, api);
});

},

_createChart: function(id, data, dataset, feeditems, options, type, api) {

// clear hourglass
this.mRootRef[id].className = "";
this.mRootRef[id].style.backgroundPosition = "";
this.mRootRef[id].style.backgroundRepeat = "";


// create a VizFrame
var oVizFrame = new sap.viz.ui5.controls.VizFrame({
'width': '100%',
'height': '400px',
'vizType': type
});

var oModel = new sap.ui.model.json.JSONModel(eval(data));
var oDataset = new sap.viz.ui5.data.FlattenedDataset(eval('(' + dataset + ')'));
oVizFrame.setDataset(oDataset);
oVizFrame.setModel(oModel);

if (feeditems) {
var aFeedItems = eval(feeditems);
for (var i = 0; i < aFeedItems.length; i++) {
oVizFrame.addFeed(new sap.viz.ui5.controls.common.feeds.FeedItem(aFeedItems[i]));
}
}

oVizFrame.setVizProperties(eval('(' + options + ')'));

// use local storage for mapping of id's
this.mBuffer[id] = oVizFrame;

oVizFrame.attachSelectData(function(oEvent) {
var aSelection = [];
for (var i = 0; i < oEvent.mParameters.data.length; i++) {
aSelection[i] = oEvent.mParameters.data[i].data._context_row_number;
}
api.fireEvent("onSelect", JSON.stringify(aSelection));
});

oVizFrame.attachDeselectData(function(oEvent) {
api.fireEvent("onDeselect");
});

// render
oVizFrame.placeAt(id);

},

updateChart: function(id, data) {
var oModel = new sap.ui.model.json.JSONModel(eval(data));
var oVizFrame = this.mBuffer[id];
oVizFrame.setModel(oModel);
}
};
}

Use of an IFRAME and HTML5 postmessages to avoid conflicts on the client side


To minimize trouble among the loaded Java Script libraries, it does make sense to encapsulate parts of the HTML Island content in an IFRAME. In this case you can use the Window.postmessage API to ensure a bi-directional communication between the main Window and IFRAME. With regard to the Flotr2 chart library you can see the coding for the HTML Island and the static HTML page (inside the IFRAME) below.

Script of Variable SAPFPM_flotr2Select
var SAPFPM_flotr2Select = SAPFPM_flotr2Select || {

mRoot: {},

setData: function(data, options, api) {

var oParameter = {
data: eval(data),
options: eval('(' + options + ')'),
};

// create and render iFrame
var oIframe = document.createElement("IFRAME");
var sUrl = "/sap/bc/webdynpro/sap/public/bc/fpm/demo/sap.fpm.demo.flotr2Select.htm";
oIframe.setAttribute("src", sUrl);
oIframe.setAttribute("height", "100%");
oIframe.setAttribute("width", "100%");
oIframe.setAttribute("frameBorder", "0");

this.mRoot[api.htmlIslandId] = document.getElementById(api.htmlIslandId);
this.mRoot[api.htmlIslandId].appendChild(oIframe);

//hourglass
this.mRoot[api.htmlIslandId].className = "urLoadImg";
this.mRoot[api.htmlIslandId].style.backgroundPosition = "center center";
this.mRoot[api.htmlIslandId].style.backgroundRepeat = "no-repeat";

// set data
oIframe.onload = function() {
//clear hourglass
SAPFPM_flotr2Select.mRoot[api.htmlIslandId].className = "";
SAPFPM_flotr2Select.mRoot[api.htmlIslandId].style.backgroundPosition = "";
SAPFPM_flotr2Select.mRoot[api.htmlIslandId].style.backgroundRepeat = "";
// transfer parameter
this.contentWindow.postMessage(JSON.stringify(oParameter), window.location.origin);
};
}
};

Content of the static HTML page sap.fpm.demo.flotr2Select.htm
<!DOCTYPE html>
<html>

<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="UTF-8">
<script type="text/javascript" src="/sap/bc/webdynpro/sap/public/bc/fpm/demo/flotr2.min.js">
</script>

<script>
// event listener
window.addEventListener("message", setParameter, false);

function setParameter(event) {

// create and set data model
var parameter = JSON.parse(event.data);
var container = document.getElementById("content");

// Draw graph with default options, overwriting with passed options
function drawGraph(opts) {

// Clone the options, so the 'options' variable always keeps intact.
var o = Flotr._.extend(Flotr._.clone(parameter.options), opts || {});

// Return a new graph.
return Flotr.draw(container, parameter.data, o);
}

// Actually draw the graph.
graph = drawGraph();
// Hook into the 'flotr:select' event.
Flotr.EventAdapter.observe(container, 'flotr:select', function (area) {
// Draw graph with new area
graph = drawGraph({ xaxis: { min: area.x1, max: area.x2 }, yaxis: { min: area.y1, max: area.y2 } });
});
// When graph is clicked, draw the graph with default area.
Flotr.EventAdapter.observe(container, 'flotr:click', function () { drawGraph(); });

};

</script>

</head>

<body>
<div id="content" style="width:100%;height:375px;overflow:hidden;">
</div>
</body>

</html>
6 Comments