Specifying Graph Data Through the setTabularData Method

The BI Beans graph supports a simple DataSource implementation for displaying data. You can pass data to this simple DataSource through the setTabularData method of the oracle.dss.graph.Graph class. For example, you can call setTabularData, for example, to set JDBC data on the graph, or to set data from a file of tab-separated values.

Structure of the data in the DataSource

Any DataSource implementation presents data to the BI Beans graph in a grid shape. This includes the internal, local DataSource that setTabularData constructs. By default, each row of the grid represents a series of data in the graph. Each column or set of columns represents a group of data in the graph.

For example, consider the following graph. It has three groups, represented by a set of two bars each: 1999, 2000, and 2001. This graph also has two series, whose labels appear in the legend: SHOES and BOOTS.

simple bar graph; described in text

The following table shows the data grid for this graph.

empty cell; date column 1999-01-01 2000-01-01 2001-01-01
SHOES 100000 120000 150000
BOOTS 125000 130000 190000

Using setTabularData to pass data

The setTabularData method takes a List of three-member Object arrays. Each array specifies one data value in the grid of data that the method constructs. The members of each array are as follows:

For each unique String that you pass in the first member of an array, the setTabularData method creates a new column in the grid. For each unique String that you pass in the second member of an array, the setTabularData method creates a new row in the grid. You can also pass java.sql.Date objects, to have the graph treat the group axis as a time axis.

Order is important. The first label that setTabularData encounters as a column label identifies the first column in the grid. The second label identifies the second column, and so on.

The DataSource that setTabularData creates has only one layer of metadata for each edge. If you want to specify two dimensions on an edge, you can combine the key column values to make a single label, such as "Shoes-Boston". This ensures a separate column or row in the grid for each combination of dimension members.

Example: Passing data from a tab-separated file

Suppose that you have data like that shown in the following table. The table identifies the year and the product in key columns. The third column is a fact column. The headers are included only for clarity. The code example does not account for headers in the source data file.

Year Product Data
1999-01-01 SHOES 100000
1999-01-01 BOOTS 125000
2000-01-01 SHOES 120000
2000-01-01 BOOTS 130000
2001-01-01 SHOES 150000
2001-01-01 BOOTS 190000

The following code sample shows how to construct an ArrayList of data from the file. This sample assumes that you have located the file and have read it into a BufferedReader. This sample also assumes a graph that is named graph.


// you will pass this ArrayList to the graph private ArrayList data = new ArrayList(); // reader is a BufferedReader while ((line = reader.readLine()) != null && !line.equals("")){ // create a 3-member array Object[] rowItems = new Object[3]; StringTokenizer tokens = new StringTokenizer(line, "\t"); for (int i = 0; i < 3; i++){ // for each item in the row switch (i){ case 0: // put Dates in the array, as column labels rowItems[i] = java.sql.Date.valueOf(tokens.nextToken()); break; case 1: // put Strings in the array, as row labels rowItems[i] = tokens.nextToken(); break; case 2: // third item in the array is the data value rowItems[i] = new Double(tokens.nextToken()); break; default: System.out.println("Too many tokens in line"); } // switch } // for each item // add the array to the ArrayList data.add(rowItems); } // while still reading // pass the ArrayList to the graph graph.setTabularData(data);

Troubleshooting

As you work with the setTabularData method, you might see the following error:


PROBLEM: In oracle.dss.graph.Graph::setTabularData: duplicate data at (row,column) = (MAY01,SHANGHAI COSTS)

This error indicates that more than one data value has been specified for a cell in the grid. Two common causes of this error are:

You might see "Insufficient Data" errors if the grid that setTabularData creates does not have enough rows or columns for the specified graph type. Check to see if you have enough unique column or row labels.

You might see "Inappropriate Data" messages if the data is not appropriate for the specified graph type. For example, for an open-high-low-close stock graph, the first column label that you pass is for the opening price. You must then pass a unique column label for the High column, then another unique label for the Low column, and then another unique label for the Close column. The opening values and the closing values must fall between the high and low values. If you see a message about open or close values out of range, then you probably have a problem with the order in which the columns are defined.

Handling Problems in Graph Data
Data Series and Groups
Data Requirements for Different Kinds of Graphs