This blog features the Yahoo's UI library and how it can be best used with BW Web applications. It will help us use the standard table control and converts into Flash based chart with animation.
Presently, I have used BW 3.5 Web templates for YUI integration. Now many of you might ask question why you are still using BW 3.5 web templates. But after extensively testing 3.5 and 7.0 web templates, we found that 3.5 templates are really stable and have much better performance. They have very simple HTML/JavaScript and very easy to use.
YUI - Often known as "yooyey", aka Yahoo! UI Library - It's an extensive library of good looking UI elements based on HTML/JavaScript/JSON/CSS. Yahoo has given nice documentation and APIs to create their UI elements easily using HTML/JavaScript.
Why is it needed?
BW 3.5 Web application designer offers standard chart UI element. It has many options to customize it to almost any requirement. It is very well integrated with the BW data and has nice jump functionality with rich context menu. But still it's not very pretty in this era of RIAs. For some dashboarding applications we would like to have Flex like charts with animation rather than statis image based charts that standard BW offers.
YUI offers Flash Chart object with Animation effect. It accepts data source in simple JavaScript/JSON array. Therefore, I decided to convert any of the BW standard table into a data source that is acceptable to YUI charts. The following code is based on YUI library which should make charting applications more powerful with the flavor of RIA.
Here's how it looks:
Steps in nutshell:
This is how your standard table should look like. Key figures should be in columns as shown:
| Net Revenue | Plan Revenue | Target Revenue |
Client-1 | $ 100 | $ 160 | $ 150 |
Client-2 | $ 200 | $ 200 | $ 210 |
Let's directly get into the code:
Imports:
Main Script:
/*
Author: Abhijeet Jangam
Input Parameters:
sourceTable : div/span ID of the DIV surrounding the source table (MANDATORY)
destinationChart: div/span ID of the destination..This DIV/SPAN should be blank. (MANDATORY)
Column_no_line_chart: column number which should appear as line chart (OPTIONAL)
Output:
A Flex like chart should appear in the destiinationChart div/SPAN
*/
function createColumnChart(sourceTable, destinationChart, column_no_line_chart)
{
//This is the div/span surrounding the standard BW table which we are converting into flex like chart
var outside_table=document.getElementById(sourceTable);
//Standard BW table has few nested tables ..this is to reach the innermost table
var inside_table = outside_table.getElementsByTagName("TABLE");
//We know its always the 5th item to get the innermost table...after studying HTML J
var rows = inside_table.item(5).getElementsByTagName("TR");
//Counter start from one since we have to skip the header row..in order to just get data rows
var column_headers = rows.item(0).getElementsByTagName("TD");
var count = rows.length-1;
if (count <= 1) count = 0; //Avoiding condition where there are no data rows in table
var row_ar = new Array(count); //This is our final array which will be bound to Chart
//This loop runs through all the rows...Skipping header row as it doesn't have data
for (var p = 1 ; p< rows.length ; p++) {
var columns = rows.item(p).getElementsByTagName("TD"); //Finding number of columns by tag TD
var col_ar = new Array(columns.length + 1);
var p1 = "";
var p2 = "";
var p3 = "";
var p4 = "";
var p5 = "";
//This loop runs through all the columns
for (var q = 0 ; q < columns.length ; q++)
{
if (q==0) //This will form the text for the columns
p1 = columns.item(q).innerText;
else //This will form the actual value of the column
{
//Following code is to clean up the number..YUI accepts only pure number. We need to remove commas and dollar signs.
var clean = "";
clean = columns.item(q).innerText.replace(/\,/g,'') ;
if (columns.item(q).innerText.indexOf("$") != -1) clean = clean.substr(2,clean.length -2 );
eval("p" + (q+1) + "= clean");
}
}
//now values of three columns are captured...created object
var myobject = new createObject(p1, p2, p3,p4,p5);
row_ar[p-1] = myobject; //since p starts from 1..i need to decreament it
}
//This is blank SWF file ..you can host it in your environment
YAHOO.widget.Chart.SWFURL =
"http://yui.yahooapis.com/2.5.2/build/charts/assets/charts.swf";
//Assigning the data source that we just built
var myDataSource = new YAHOO.util.DataSource(row_ar );
//Setting its type to JS array
myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
//Configuring number of columns. These names should be same as the attributes in object
myDataSource.responseSchema =
{
fields: [ "par1","par2", "par3","par4","par5"]
};
//Creating series: number of series = total number of data rows
var seriesDef = new Array(column_headers.length-1);
//column_no_line_chart parameter holds the number of the column which should appear as line chart
for (var x=1 ; x <column_headers.length ; x++)
{
if (x == column_no_line_chart)
seriesDef[x-1] = { displayName: column_headers.item(x).innerText , yField: "par" + (x+1) , type: "line" };
else
seriesDef[x-1] = { displayName: column_headers.item(x).innerText , yField: "par" + (x+1) };
}
//Finally creating chart
var myChart = new YAHOO.widget.ColumnChart( destinationChart, myDataSource,
{
xField: "par1",
series: seriesDef,
style:
{
legend:
{
display: "right"
}
}
});
}
//This is helper function which creates objects...Note that this is restricted to 5 parameters limiting us to 5 key figures in table but can be extended by adding more parameters
function createObject(par1, par2, par3,par4, par5)
{
this.par1 = par1;
this.par2 = par2;
this.par3 = par3;
this.par4 = par4;
this.par5 = par5;
}
How to call this script?
// ‘tbl' is the ID of surrounding DIV of source table
// ‘myCountainer' is the ID of the target DIV where we need chart to be displayed
// 3 ==> 3rd Key Figure (4th Column) of the table should appear as line chart, all other key figures as bar chart
createColumnChart('tbl' , 'myContainer', 3);
//The very first chart has object tag with ID as 'yuigen0'. All subsequent will have 'yuigen1', 'yuigen2' and so on
var chart_object = document.getElementById('yuigen0');
//Setting the size of chart
chart_object.style["height"] = "50%";
chart_object.style["width"] = "50%";
Advantages:
Limitations:
Future Work:
References: