Archive for the ‘Xcelsius’ Category

Play the pie chart Dreidel

Published by Ron Keler in BI At Large, Xcelsius on December 6th, 2012 | No Comments »

This Saturday is the first night of Chanukah, the Jewish “festival of lights” holiday. One of the games kids play during this holiday is called Dreidel. The Dreidel is essentially a top that has four Hebrew letters marked on four sides. To play the game, kids spin the Dreidel and while it spins, they pick a letter from the four possible options. When the Dreidel stops, whoever picked the letter the Dreidel landed on, wins. In the spirit of the holiday, and since I have been working with Xcelsius SP5 and some of its new mobile features, I created a simple pie chart Dreidel game… Enjoy and happy holidays!

Get Xcelsius EIC connection to work properly in IE9

Published by Ron Keler in Xcelsius on September 18th, 2012 | No Comments »

The EIC (External Interface Connection), is a key feature of Xcelsius that allows the creation of sophisticated integrated dashboard. It’s a programmatic way to pass information through javascript to and from the html container that embeds the Xcelsius swf object. If you never used it, be sure to check off this capability and at least understand it, so you can have a fuller picture of the product.
Xcelsius ships with some EIC connectivity samples that are used throughout as the base for implementation in projects. These samples represent best practice, and i typically start my coding with them. Well, recently, i ran into problems with teh EIC connectivity, especially with modern browsers, and particularly with IE9. With the invaluable help of my colleague Robert Blackburn (whose outstanding blog, http://rwblackburn.com/ is a tremendous resource) , we were able to narrow down the EIC connectivity issues to the javascript function used to call the swf object in the EIC samples, get Movie(). The getMovie() function is used in the EIC sample code as a utility function to obtain a reference to the swf object that you are working with. However, this function was written some years ago, and some of the js and html standards that existed at the time it was written have changed, in particular, IE9 is breaking some new grounds with its support (or non support) for functionality that is widely used and accepted in other browsers, such as firefox or chrome. In any case, we were able to identify the root cause for the EIC failures in the getMovie function and fix it. So, if you are having any problems with EIC values not working properly in IE, simply replace the getMovie() function with the one below:
function getMovie(movieName) {
var movie = undefined;
if (navigator.appName.indexOf(“Microsoft”) != -1) {
movie = document.getElementById(movieName);
} else {
movie = document[movieName];
}
return movie;
}

Control the dashboard size in SAP BI Launchpad 4.0

Xcelsius dashboards developers who leverage the BI 4.0 BI Launchpad as the content portal for delivering their work, have long suffered from the sloppy interface between Xcelsius and the portal.
First (and foremost), when you publish an Xcelsius or dashboard object (the .swf) into the BI Launchpad (or InfoView for that matter), you lose control over the canvas size. This means that the dashboard will open in a window the size allowed by the user browser and preferences. The impact on the dashboard design can be devastating, rendeing completely unusable in some extreme situation, or at a minimum less then professional looking, as fonts get “squashed” components overlap, and graphics degrade as they stretch or slim down.
This is nothing new, and has been the same situation since XIR2, through 3.1, and now, with 4.0, the problems still remain.
To have complete control over your dashboard presentation, you really should consider hosting it in a different portal, but that is not always feasible. If you are “stuck” with the BI Launchpad, you can use the following technique to address the problem described above, as well as another, less common problem, related to flash crossdomain restrictions. If your dashboard has live data and is making connections to a web service or xml feed, the web service url will have to be fully qualified in the xlf file. The problem will hit you if any of your users use a variation on the host name you used in your web services url. For example, if you use http://myboserver:8080 and your users use a fully qualified name, or even an IP address to get to the server (http://myboserver.mycompany.com:8080), they will end up with a crossdomain error instead of a working dashboard. To overcome this problem, you need to use a dynamic host name, based on the client request.
To address both problems, you can do the following:
First, add a flash variable connection in your xlf. In my example, I called mine host. Use this host flash variable to create a formula in your model that will concatenate the flash variable value with the rest of your web service url. Flash variables are populated on the swf initialization, and the values will be passed to the model before the web service connections are made.
Next, create a directory on your BO web server (tomcat in most cases) and place a .jsp file in it with the following code:

<%
//Initialize var
String host = "";
//Get the host name from the http request
host = request.getServerName();
//Construct an openDoc URL and pass the host name to the swf. Use this url as the content src of the iframe, where you can set the specific height and width
String url = "http://"+host+"/BOE/OpenDocument/opendoc/openDocument.jsp?iDocID=Abvx6T2dOeZNiF8bWJ11Qfk&sIDType=CUID&lsShost="+host;
%>
<iframe src="<%=url%>" height=630 width=1030 marginheight=0 marginwidth=0 frameborder=0></iframe>

 
Now, create a hyperlink in the BI Launchpad to this file (for example, if your file is called link.jsp, which resides in a folder called links and you wanted to use a relative path, your url would look like this: ../../../../../../links/link.jsp)
That’s it! Your swf is still safely secured in the BO repository, openDoc will only work if the user has logged in properly (or prompt the user to logon if not), so any universe security built into your connection will remain intact, and your dashboard will open using the width and height specified, regardless of the host name the users end up using.

Xcelsius Flight Seat Order models visualized

Published by Ron Keler in Xcelsius on March 25th, 2012 | No Comments »

On a recent international flight I had a chance to ponder how much the order of seating passengers really impact the amount of time it takes to get all the passengers seated. On one flight, the crew called passengers to board the plane by row number. Starting from the back of the plane and working their way to the front, row by row, passengers were called to board. On another flight, general boarding commenced immediately. Between passengers who do ignore the ground crew directions regarding which rows are boarding, and the many other variables that impact seating airplane passengers, does it really matter that much? While I do not have enough data to make a call either way, I was able to come up with a visualization exercise for this problem that combines several Xcelsius modeling techniques, such as combining the player selector with a history component to get a staggered dynamic visibility effect (the rows appear in order, and stay painted). Enjoy the XLF here.

Randomize seating order

Dynamically resizing images in Xcelsius

Published by Ron Keler in Xcelsius on March 8th, 2012 | No Comments »

It is sometime useful o be able to dynamically change an image size in Xcelsius, based on user inputs for example, or on a data variable that changes live, or as a result of user input. Xcelsius components, except for charts, are typically fixed in size and position, and there is no way to move or resize components on the fly. However, using the following technique, you can dynamically change the size of images in your Xcelsius swf to fit your data visualization needs.
To accomplish this effect, i used the slideshow component, and bind it to a url that is constructed dynamically based on the user input in the width or height sliders. The url is pointing to a php file that streams the image and changes it’s size based on the width and height variables supplied over the url (using PHP GD library). You can find all the source files (.php, .xlf) here. Enjoy!

 

Xcelsius bubbles

Published by Ron Keler in Xcelsius on March 1st, 2012 | 2 Comments »

Not much to say about this one, i just really like bubbles… Using bubble charts in Xcelsius can be very appealing.

 

Bookmark Xcelsius Dashboard

Published by Ron Keler in Xcelsius on February 23rd, 2012 | 4 Comments »

The other day, my colleague Josh Tapley (http://data-ink.com) and I had a conversation about being able to “bookmark” an Xcelsius dashboard. Basically, the idea would be to “save” the user context on the dashboard and be able to return to the same context. Well, below is an example of such an implementation. The dashboard is embedded in a php page. The Bookmark button on the dashboard is a text label with html code to trigger a javascript ajax function that takes the user context in the dashboard selectors, assigns them an id, and saves them in a database table. When the id is passed back to the embedding page, the proper values are retrieved and are used to initialize the dashboard. Enjoy!

Medicare Advantage Enrollment Dashboard

About a month ago, my colleague, Josh Tapley (http://data-ink.com/) and I set out to build an Xcelsius based BI application. Our goals were to demonstrate the capabilities of the technology, when combined with some fundamental data warehousing and BI techniques and great design principals.

We started our quest by looking for a large, publically available, dataset that will be interesting to analyze. We wanted to use a data set that can produce valuable insights by applying analytics and data visualization techniques to it. Josh suggested we use the government center for Medicare and Medicaid services which publishes monthly national Medicare enrollment numbers each month. The data is published as text and excel files and is proliferated across the site. It is a classical example of large amounts of data, published in raw format for users to wrestle with and with no information or insight in sight.

We proceeded to create a data repository (data warehouse of sorts), essentially coming up with a process for collecting the multitude of data files across the various sources it is published in, and loading the data into a database, using ETL techniques. The most granular fact table in our database of Medicare records contain 588846 records as of Feb 2012, it grows at a rate of approx 30-50K records a month. Not bad for a publically available data set.

We applied an aggregate strategy to our database to assure the queries we perform on it to support our application are adequately fast and users experience minimal delays as they navigate this rich data set.

With all the data on hand, we set out to design our application. We used simple, clean and intuitive design principals to highlight the analytics, and allow users to easily understand enrollment trends across several key factors. We wanted to tell a story, paint a picture, and not require users to struggle and stumble through complex interfaces and data layouts to get a gleam of information.

With our design at hand, we created a series of xml feeds that query the database on the fly and return result sets that meet our application layout needs.

The result is what we consider to be both a useful and informative analytical tools for anyone in the healthcare industry and beyond, as well as a good showcase of BI Happiness.. Please be sure to checkout our Medicare Advantage Enrollment Dashboard.

Enjoy!

SAP Dashboards (Xcelsius) autocomplete input text

Published by Ron Keler in Xcelsius on January 12th, 2012 | 5 Comments »

Autocomplete has become a standard in modern application, when users are asked to type in inputs. In the example below, I implemented autocomplete functionality into an Xcelsius input text component. Start typing any zip code starting with 0 and hit the enter key to get the all the zip codes that match the starting numbers you typed in. (zip code list sourced from http://www.quine.org/zip-all-00001.html, not all zip codes represented, and accuracy of list is unknown)

To get this to work, I used an ajax technique. The Xcelsius file contains two eic variables, one for the value inserted in the text box, and one for the query results array presented in the spreadsheet component. The html page that embeds the swf contains a javascript functions that listens to changes in the value of the input eic. On change, it makes a call to a php file that uses the user input as part of a sql where clause, and gets the list of matching zip codes from a mySql database.
Since there are no native inpu text components in Xcelsius that write to the model while users type, users still need hit enter; ce la vie. Also, I limit the query results to 100 rows from the database, so you don’t get all 5600 zip codes that start with 0 as you type 0 and hit enter…
Using BusinessObjects native connectivity methods, such as BI Services, QaaWS or Live Office can eliminate the need for the ajax approach and basically trigger connections on change from within Xcelsius. All the source files for this example can be found here. Enjoy!

BI Services Run Time Configuration Explained

SAP BusinessObjects BI Services are a class of web services that can be easily created by converting web intelligence (webi) report blocks into web services. A simple GUI wizard guides the report developer through a few simple steps that publish the report block as a web service and provide a WSDL that can be used to interact with the report block data. As i wrote in an older post, the BI Services combine the power of Live Office in leveraging webi full capabilities (using variables, filters, formulas, cross tabs, etc) with the power of QaaWS web services (good caching capabilities for enhanced performance).
The BI Services publish with two default methods. A GetReportBlock method and a Drill method. For this post, i will examine the GetReportBlock configuration and describe some of the refinements you can apply to the web service as you consume it in your application.
First, a word about the difference between prompts and filters: BI Services introduce a powerful concept of filters. Basically, any object in the report can be used as a filter in the web service. Filters can be applied at the database level during query time, or to a saved report instance data. Prompts are only applicable at the database level and cannot be applied to saved instances.
Next, there are two main input parameters that control the GetReportBlock behavior with regards to filtering and running against the DB vs running against saved reports instances: refresh and getFromLastDocumentInstance (or getFromUserInstance in “bursting” schedules scenarios). All these parameters are boolean types and setting them to true or false will result in different behavior from the web service during consumption time. Here are some example:
The initial setup is a simple report that returns the Years object from the e-Fashion universe. The report has an optional prompt on the Year object. The simple report block was published as a BI Service. When we run the report, it looks like so in webi:

 We can test the web service configuration right from within webi

In our first test, we set the refresh parameter to true and send the request. This is because we set the report to refresh, we did not specify a prompt value, and since our prompt is optional, it was ignored, and we did not specify any filter value.

In the second test, we still use the refresh parameter to hit the database, but this time we specify a prompt value. We get back the year row we expect.


 
To demonstrate the interoperability of the filter and the prompt in a refresh scenario, we clear out the prompt value and use a filter that is set to equal a different year now.

Now, let’s try review what options are available when we schedule the report and save it with data. Let’s schedule our report with two years (rows) of data: 2004 and 2005.

This time, when we go to test our web service, let’s use the saved report instance, and see what happens. First, let’s change our test settings to use the getFromLastDocumentInstance instead of refresh, and leave the filter value empty (since we are working with a saved instance, the prompt value will be ignored even we if we try to use it). This time, we will get the saved instance results, just two rows of data.

If we apply a filter for say, year 2005, we get the data from the report instance

We will not hit the database, so even if we try to filter for a value we know to exist in the DB, such as 2006, since we are only getting data from the saved report, we will not get any result back.

 

Also, if during testing you lose the state of your service between cached and non-cached versions, or need to reset the service state for any other reason, you can set the resetState parameter to true.

So all in all, the BI Services provide a lot of configuration options to address a wide range of reporting use cases from all saved data to no saved data used.

© BI HAPPY
CyberChimps