Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

I had been interested in trying out some new JavaScript libraries particularly related to the area of data visualization. I felt that some of these offered very promising complementary functionality to the standard BSP user interface building blocks. I plumped for D3.js as it seems to have gained some popularity and I liked what I saw. To test it out I decided to add a simple bar chart to a BSP application using D3.js.

For this purpose I created a small stateful BSP application. I then fetched some test data from into a static public table of the BSP application class YCL_TEST2=>DATA and created a main page set as initial BSP page containing a htmlb:tableView to display this data.  Finally, I set selectionMode to SINGLESELECT and saved the currently selected row number to YCL_TEST2=>SELECTEDROWINDEX so it is available to the window which will contain the d3 created bar chart and will be called via a window.open statement when the user clicks on a htmlb:button at the top of the page.

The test data used for this demonstration in YCL_TEST2=>DATA takes the form of total cost of labour and subcontracted activities in warranty claims by customer and month. The concept of this demonstration BSP is that when the user selects a line and hits the button at the top of the page a popup with the a bar chart showing the total value claimed each month by the customer of the selected line.

To begin building the bar chart I downloaded the d3.js library and uploaded it to the BSP application. As this was done purely for research in a development environment, I used the non minified version of the library.

To be able to use the data in our table we need to convert it from the internal ABAP to a more JavaScript friendly format. I chose to convert our data to a json file format contained in a public string attribute of our application class. This was done in the OnInitialization event of the popup window with some ABAP code that once it has extracted the vendor of the line highlighted in the main window it then generates a JSON formatted string with the two attributes month and value containing the relevant information.

And finally I created the layout of my BSP page which also contains in the head my JavaScript code using D3 that generates my bar chart as well some CSS formatting. To learn a bit about D3 and to guide me in creating I used a few resources but I should particularly credit http://bost.ocks.org/mike/bar/, https://www.dashingd3js.com/, https://gist.github.com/jasondavies/2300078/ and http://jsfiddle.net/robdodson/KWRxW/.


<!doctype html>
<html lang=
"en">
<head>
<meta charset=
"utf-8">
<title>Claims by
<%= parnr %> </title>

<style>
.chart {
background-color: #eee;
}

.chart rect {
stroke: white;
fill: steelblue;
}

.axis {
shape-rendering: crispEdges;
}

.x.axis line {
stroke: black;
}

.y.axis line {
stroke: black;
}

.axis
text {
font-size: 12px;
}
</style>

<script type=
"text/javascript" src="d3.js"></script>
<script type=
"text/javascript">

function load() {
var results,
data = [],
chart,
bars,
margin = 100,
w = 50,
h = 500,
x, y,
xAxis, yAxis;

var json = <%= ycl_test2=>json %>;
results = d3.map( json );
results.forEach( function( key, val ) {
var result = {};
result.month = new Date(2010, ( parseInt( val.Month.slice(4,6),
10 ) - 1 ), 15);
result.value = parseInt( val.Value.replace( /,/g,
'' ), 10 );
data.push( result );
} );

chart = d3.select(
'body' ).append( 'svg' )
.attr(
'class', 'chart' )
.attr(
'width', 800 )
.attr(
'height', h )
.append(
'g');

d3.select(
'svg g')
.attr(
'transform', 'translate(50, 50)');

x = d3.time.scale()
.domain( [new Date(2010, 0, 1), new Date(2010, 11, 31)] )
.range( [0, ( w *
12 )] );

y = d3.scale.linear()
.domain( [0, d3.max( data, function( d ) { return d.value; } )] )
.rangeRound( [0, h - margin] );

// Bars
bars = chart.append(
'g')
.attr(
'class', 'bars');

bars.selectAll(
'rect' )
.data(
data )
.enter().append(
'rect' )
.attr(
'x', function( d, i ) { return x( d.month ) - 23; } )
.attr(
'y', function( d ) { return (h - margin) - y( d.value ) } )
.attr(
'width', w )
.attr(
'height', function( d ) { return y( d.value ) } )
.append(
'g');

//
Axis
xAxis = d3.svg.axis()
.scale(x)
.ticks(d3.time.month)
.tickSize(6, 3, 1)
.tickPadding(10);

yAxis = d3.svg.axis()
.scale(d3.scale.linear().domain( [0, d3.max( data, function( d ) { return d.value; } )] ).rangeRound( [h - margin, 0] ))
.tickSize(6, 3, 1)
.orient(
'right');

chart.append(
'g')
.attr(
'class', 'x axis')
.attr(
'transform', 'translate(0, ' + (h - margin) + ')')
.call(xAxis);

chart.append(
'g')
.attr(
'class', 'y axis')
.attr(
'transform', 'translate(' + x.range()[1] + ')')
.call(yAxis);

};
</script>
</head>
<body onload=
"load()">
</body>
</html>

And here’s the end result. As described above when the user selects a line from the main page they are shown a bar chart of the customers from that line’s claims over.

So there we go. A little rough around the edges but good enough for a first attempt destined for a non production environment and there’s might be something in there that others could find useful.

I found this an interesting learning exercise and I’m still enthusiastic about the possibilities of enhancing the capabilities of BSP by incorporating open source JavaScript libraries. Specifically in respect to D3.js I really liked the easy with which SVG and other screen elements could be manipulated and the approach to binding to screen elements seems particularly well suited to creating visualization of data. On the downside I found the learning a bit steeper than expected (in fact I had originally planned to create various different type of graph for the same data set but ran out of time because it took me longer than I thought to get my code working) but this is obviously only an initial hurdle. I also felt that although I liked the flexibility of d3.js there were more steps than I would have expected for data visualisation library to such a standard task as creating a bar chart. I can see why this is but this draw back made me quite interested in the NVD3.js project which “to build re-usable charts and chart components for d3.js without taking away the power that d3.js gives you”. But that will have to wait for another time.

4 Comments
Labels in this area