Skip to Content

I’ll give it a try and submit my Weblog to the SDN: End of the Year SDN POINTS BLOW OUT!! Contest () initiated by Craig Cmehil (/people/craig.cmehil/blog). With this hack you get a BSP Page which displays a flicker-free updated chart of how many SDN Users are currently online in the Forum.

Warning!

This example will only run in Safari and Firefox 1.5. SAP’s official Charting tool is IGS (Internet Graphics Server). You find a Example how to use the IGS in the Weblog:

BSP – a Developer’s Journal: Part X – IGS Charting

from Thomas Jung  (/people/thomas.jung3/blog).

The Giants I build on

First I had to retrieve the actual number of Forum Users. This is done by using the HTTP_CLIENT Class which is described in an excellent example in Brian McKellar’s  (/people/brian.mckellar/blog) Weblog

BSP Programming: RSS = HttpClient + XML + XSLT

.0.1.

0.2.

JKL.ParseXML

– parse remote XML file into JavaScript object.0.1.

0.2.

Finally the Canvas Front end was implemented by using the Charting Example  (http://overstimulate.com/projects/canvas/) of Jesse Andrews  (http://overstimulate.com/).</li>

</ul>

Environment

I’ve built this example on a Web AS ABAP 6.40. The Web AS must have Internet access so he can open the URL http://forums.sdn.sap.com/online.jspa.

Retrieve Data

To store the retrieved Data I’ve created a new database table and called it “ZSDNFORUMUSERS”. It consists of this fields:

Field

Key

Data element

Data Type

Length

MANDT

X

S_MANDT

CLNT

3

ERZET

X

ERZET

TIMS

6

ERDAT

X

ERDAT

DATS

8

USERS

INT4

10

This table is filled by the Program “ZGET_SDN_FORUM_USERS” which I’ve run as a background job every 2 minutes:

REPORT  zget_sdn_forum_users.

*

  • Retrive HTML

*

DATA: url         TYPE string,

      http_client TYPE REF TO if_http_client,

      return_code TYPE i,

      content     TYPE string,

      users       TYPE i,

      wa_users    TYPE zsdnforumusers.

  • HTTP URL

url = ‘http://forums.sdn.sap.com/online.jspa‘.

cl_http_client=>create_by_url( EXPORTING url    = url

                               IMPORTING client = http_client ).

http_client->send( ).

http_client->receive( ).

http_client->response->get_status( IMPORTING code = return_code ).

content = http_client->response->get_cdata( ).

http_client->close( ).

*

  • Find ‘There are’ and ‘ user(s) online.’

*

DATA: dummy TYPE string.

IF content CS ‘ There are ‘ AND content CS ‘ user(s) online.’.

  SPLIT content AT ‘There are ‘ INTO dummy content.

  SPLIT content AT ‘ user(s) online.’ INTO dummy content.

ENDIF.

wa_users-mandt = sy-mandt.

wa_users-erzet = sy-uzeit.

wa_users-erdat = sy-datum.

wa_users-users = dummy.

*

  • Save the Data into ZSDNFORUMUSERS

*

INSERT INTO zsdnforumusers values wa_users.

IF sy-subrc = 0.

  COMMIT WORK AND WAIT.

ELSE.

  WRITE: ‘Could not append line’.

ENDIF.

</pre>

Display Data

In Transaction SE80 I created a BSP Application called it “ZSDNFORUMUSERS”. The application consists of two parts. The Backend is split into two parts. Part one retrieves the history of the last 24 Hours to fill the chart initially. Part two retrieves the actual number of Forum Users and provides this value for the Front end in a simple XML Structure. The Front end calls the Backend via XmlHttpRequest.

Backend Part 1

Part 2 of the backend is also a BSP Page with Flow logic called “usersonline24h.xml”. It has a page attribute called “it_users” which if from type tt_users. This type is defined in the Types tab:

TYPES: tt_users TYPE TABLE OF zsdnforumusers.

Event handler OnRequest

  • the handler is called whenever a request is made for a particular page

  • it is used to restore the internal data structures from the request

DATA: datefrom LIKE sy-datum.

datefrom = sy-datum – 1.

SELECT * FROM zsdnforumusers INTO TABLE it_users

  WHERE erdat >= datefrom

  ORDER BY erdat ASCENDING erzet ASCENDING.

</pre>

Layout

Backend Part 2

Part 1 of the backend is also a BSP Page with Flow logic called “usersonline.xml”. It has a page attribute called “users” which if from type I.

Event handler OnRequest

  • the handler is called whenever a request is made for a particular page

  • it is used torestore the internal data structures from the request

CLEAR: users.

DATA: it_users TYPE TABLE OF zsdnforumusers,

      wa_users LIKE LINE OF it_users.

  • Read Users Online from History Table

SELECT * FROM zsdnforumusers INTO TABLE it_users

  ORDER BY erdat DESCENDING erzet DESCENDING.

IF sy-subrc = 0.

  READ TABLE it_users INTO wa_users INDEX 1.

  users = wa_users-users.

ENDIF.

</pre>

Layout

Front end

<p>The front-end is also a BSP Page. Here is only the Layout filled with this Code:</p>

<pre class="sapCode">
<%@page language="abap" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>How many SDN Forum Users are online?</title>
<style type="text/css">

#windowcontainer
.chartLayer

#high {font-family: arial; left: 10px; top: 4px }

#low  {font-family: arial; left: 10px; top: 479px }

#minutes {font-family: arial; left: 712px; top: 500px }

How many SDN Forum Users are online?

(d+) </;

/@cc_on @/

/*@if (@_jscript_version >= 5)

// JScript gives us Conditional compilation, we can cope with old IE versions.

// and security blocked creation of the objects.

try {

  xmlhttp = new ActiveXObject(“Msxml2.XMLHTTP”);

} catch (e) {

  try {

   xmlhttp = new ActiveXObject(“Microsoft.XMLHTTP”);

  } catch (E) {

   xmlhttp = false;

  }

}

@end @*/

if (!xmlhttp && typeof XMLHttpRequest!=’undefined’) {

  xmlhttp = new XMLHttpRequest();

}

var livectx = document.getElementById(‘live-chart’).getContext(‘2d’);

var chartData = [];

function updateChart( newVal ) {

  chartData.push( parseInt(newVal) );

  if (chartData.length > width) {

    chartData.shift();

  }

  var maxVal=height;

  for (var i=0; i<chartData.length; i++)

    if (chartData[i] > maxVal) maxVal=chartData[i];

  // Draw Border

  livectx.beginPath();

  livectx.clearRect(0,0,width,height);

  livectx.rect(0,0,width,height);

  // Go to Starting point

  livectx.moveTo(0,height-(height*chartData[0]/maxVal));

  for (var i=1; i<chartData.length; i++) {

    // Draw Line

    livectx.lineTo( i, height-(height*chartData[i]/maxVal) );

  }

  livectx.stroke();

}

function getStats() {

xmlhttp.open(“GET”, g_urlsingle, true);

xmlhttp.onreadystatechange=function() {

  if (xmlhttp.readyState==4) {

   updateChart( scrapper.exec(xmlhttp.responseText)[1] );

   document.f.users.value = scrapper.exec(xmlhttp.responseText)[1];

   setTimeout(‘getStats()’, 120000 );

  }

}

xmlhttp.send(null)

}

// Load 24h XML

var xml = new JKL.ParseXML( g_url24h );

var data = xml.parse();

for (var i=0; i < data.sdnusers.users.length; i++) {

  chartData.push( parseInt(data.sdnusers.users[i]) );

  if (chartData.length > width) {

    chartData.shift();

  }

}

getStats();

</script>

</body>

</html>

</pre>

Upload JKL.ParseXML

Before you can run the BSP Application you have to upload the

JKL.ParseXML

as a mime-object. Then you need Firefox 1.5  (http://www.mozilla.com/firefox/) to run the application. It will look like:

!https://weblogs.sdn.sap.com/weblogs/images/2345/UsersOnline.jpg|height=288|alt=image|width=573|src=https://weblogs.sdn.sap.com/weblogs/images/2345/UsersOnline.jpg|border=0!</body>

To report this post you need to login first.

Be the first to leave a comment

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

Leave a Reply