This example shows how to set data from a tab-delimited file on a high-low-close stock graph. You can modify this example to work with open-close stock graphs, candle open-high-low-close stock graphs, open-high-low-close stock graphs, and all stock graphs that also show volume. All stock graphs have the same kind of data. The only difference is the number of data points that each group requires.
This example uses
the setTabularData
method of the graph. The file that supplies
data for the graph can have two different forms.
Single fact column -- The file might have a single fact column of data values, with key columns that identify the measures to which the fact values belong.
Multiple fact column -- The file might have a fact column for each measure that you want to display in the graph.
The setTabularData
method creates a simple DataSource
from the data that you pass. This grid is the same for both forms of source
data, and the graph is the same. The following figure shows the graph that this
example creates.
The following table shows the grid of data for this graph.
![]() |
2002-06-03 | 2002-06-03 Low | 2002-06-03 Close | 2002-06-04 | 2002-06-04 Low | 2002-06-04 Close | 2002-06-05 | 2002-06-05 Low | 2002-06-05 Close | 2002-06-06 | 2002-06-06 Low | 2002-06-06 Close | 2002-06-07 | 2002-06-07 Low | 2002-06-07 Close |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
VGE | 9 | 7.5 | 8.5 | 9.5 | 8 | 8.75 | 10 | 7.75 | 8 | 9.25 | 7.25 | 8.75 | 10 | 8 | 9.25 |
OKA | 24 | 21.5 | 23 | 23.5 | 21 | 21.75 | 22 | 19.75 | 20.75 | 21.25 | 19.5 | 20 | 21 | 19 | 20.5 |
Notice that this grid has three columns for June 1, three for June 2, and so
on. The "2002-06-03" label identifies the unique column for the high
values for June 1. (The "High" part is omitted to prevent its appearing
in the graph). The "2002-06-03 Low" and "2002-06-03 Close"
are different labels, ensuring the appropriate three-column group of data for
June 1 for a high-low-close stock graph. This example passes java.sql.Date
objects to the graph, so that the graph has a time axis.
Note: This grid is appropriate if the getDataRowShownAsASeries
method of the graph returns true
. If you map columns as series,
then the grid should have three distinct rows for each day.
In an OLAP data source, you could simply place the Time and Measure dimensions
on the column edge, and the data source would create a grid that has two layers
of metadata on the column edge. The simple data source that setTabularData
creates supports only one layer on the column edge, so you must provide distinct
labels for each column. In a stock graph, the first label for the group appears
as the group label. The other labels do not appear anywhere in the graph.
Notice, also, that the High, Low, and Close columns always occur in that order. The high stock price must be first. It must be followed by the low stock price, and the closing stock price must be last in the group. The closing value must fall between the high and low values.
The following table shows the data that is in the source file that has a single fact column. In the file, this data would be separated by tabs or commas. Also, it would not have headers. The headers are included here for clarity.
Note that the "High" measure value must appear first, then the "Low" value and then the "Close" value. If you have an open-high-low-close stock graph, then the "Open" value must appear before "High." In stock graphs that show volume, the "Volume" measure value must appear last.
Stock | Date | Measure | Data |
---|---|---|---|
VGE | 2002-06-03 | High | 9 |
VGE | 2002-06-03 | Low | 7.5 |
VGE | 2002-06-03 | Close | 8.5 |
VGE | 2002-06-04 | High | 9.5 |
VGE | 2002-06-04 | Low | 8 |
VGE | 2002-06-04 | Close | 8.75 |
VGE | 2002-06-05 | High | 10 |
VGE | 2002-06-05 | Low | 7.75 |
VGE | 2002-06-05 | Close | 8 |
VGE | 2002-06-06 | High | 9.25 |
VGE | 2002-06-06 | Low | 7.25 |
VGE | 2002-06-06 | Close | 8.75 |
VGE | 2002-06-07 | High | 10 |
VGE | 2002-06-07 | Low | 8 |
VGE | 2002-06-07 | Close | 9.25 |
OKA | 2002-06-03 | High | 24 |
OKA | 2002-06-03 | Low | 21.50 |
OKA | 2002-06-03 | Close | 23 |
OKA | 2002-06-04 | High | 23.5 |
OKA | 2002-06-04 | Low | 21 |
OKA | 2002-06-04 | Close | 21.75 |
OKA | 2002-06-05 | High | 22 |
OKA | 2002-06-05 | Low | 19.75 |
OKA | 2002-06-05 | Close | 20.75 |
OKA | 2002-06-06 | High | 21.25 |
OKA | 2002-06-06 | Low | 19.5 |
OKA | 2002-06-06 | Close | 20 |
OKA | 2002-06-07 | High | 21 |
OKA | 2002-06-07 | Low | 19 |
OKA | 2002-06-07 | Close | 20.5 |
This example retrieves the data from the source file that has a single fact
column. The file is set as a command-line argument. This example uses a StringTokenizer
to take the data from the file and put in an ArrayList
of object
arrays, which it then passes to setTabularData
.
This code assumes that you have the full file name, including the path, and that you have a graph.
// declared earlier // you will pass this ArrayList to the graph ArrayList data = new ArrayList(); // code omitted here to get full file name try{ BufferedReader reader = new BufferedReader (new FileReader(fullFilename)); String line = ""; // read rows from a tab-delimited file // while there are rows of data to read while ((line = reader.readLine()) != null && !line.equals("")){ StringTokenizer tokens = new StringTokenizer(line, "\t"); String stock = tokens.nextToken(); // first token // pass Date objects for time axis java.sql.Date day = java.sql.Date.valueOf(tokens.nextToken()); // second token String measure = tokens.nextToken(); // third token; open or close Double value = new Double(tokens.nextToken()); // fourth token; data value // create a 3-member Object array Object[] rowItems = new Object[3]; // first element is the column label in the grid // for first measure, you just want the day label if (measure.equals("High")) rowItems[0] = day; // for low and close, add the measure name to the day // to ensure three separate columns in the grid else // low or close rowItems[0] = day + " " + measure; // second element in array is the row label in the grid rowItems[1] = stock; // always // third element is the data value rowItems[2] = value; data.add(rowItems); } // while still reading } catch (IOException e){ System.out.println("IO problem reading " + fullFilename); e.printStackTrace(); } // catch IO exception reading file // pass the ArrayList to setTabularData graph.setTabularData(data); // set the graph type graph.setGraphType(Graph.STOCK_HILO_CLOSE);
The following table shows the data that is in the source file that has more than one fact column. In the file, this data would be separated by tabs or commas. Also, it would not have headers. The headers are included here for clarity.
Stock | Date | High | Low | Close |
---|---|---|---|---|
VGE | 2002-06-03 | 9 | 7.5 | 8.5 |
VGE | 2002-06-04 | 9.5 | 8 | 8.75 |
VGE | 2002-06-05 | 10 | 7.75 | 8 |
VGE | 2002-06-06 | 9.25 | 7.25 | 8.75 |
VGE | 2002-06-07 | 10 | 8 | 9.25 |
OKA | 2002-06-03 | 24 | 21.50 | 23 |
OKA | 2002-06-04 | 23.5 | 21 | 21.75 |
OKA | 2002-06-05 | 22 | 19.75 | 20.75 |
OKA | 2002-06-06 | 21.25 | 19.5 | 20 |
OKA | 2002-06-07 | 21 | 19 | 20.5 |
This example retrieves the data from the source file that has more than one
fact column. The file is set as a command-line argument. This example uses a
StringTokenizer
to take the data from the file and put in an ArrayList
of object arrays, which it then passes to setTabularData
. As is
the case when you pass a file with multiple fact columns to a simple graph,
this code iterates over each row value three times, in order to make three separate
columns in the grid of data for the graph.
This code assumes that you have the full file name, including the path, and that you have a graph.
// declared earlier // you will pass this ArrayList to the graph ArrayList data = new ArrayList(); // code omitted here to get full file name try{ BufferedReader reader = new BufferedReader (new FileReader(fullFilename)); String line = ""; // create an array of measure names // first string null because the first column is the // tick label String[] measures = new String[] {"", "Low", "Close"}; // read rows from a tab-delimited file // while there are rows of data to read while ((line = reader.readLine()) != null && !line.equals("")){ StringTokenizer tokens = new StringTokenizer(line, "\t"); String stock = tokens.nextToken(); // first token // pass Date objects for time axis java.sql.Date day = java.sql.Date.valueOf(tokens.nextToken()); // second token Double highPrice = new Double(tokens.nextToken()); // third token Double lowPrice = new Double(tokens.nextToken()); // fourth token Double closePrice = new Double(tokens.nextToken()); // fifth token Double[] dataValues = new Double[]{highPrice, lowPrice, closePrice}; // for each fact column for (int i = 0; i < measures.length; i++){ // create a 3-member Object array Object[] rowItems = new Object[3]; // first member is the column label in the grid // concatenate the day and the measures // to ensure that there are three separate columns rowItems[0] = day + " " + measures[i]; // second member is the row label in the array rowItems[1] = stock; // same for each column // third member is the data value rowItems[2] = dataValues[i]; // add the array to the ArrayList data.add(rowItems); } // for each column of data } // while still reading } catch (IOException e){ System.out.println("IO problem reading " + fullFilename); e.printStackTrace(); } // catch IO exception reading file // pass the ArrayList to setTabularData graph.setTabularData(data); // set the graph type graph.setGraphType(Graph.STOCK_HILO_CLOSE);
Specifying
Graph Data Through the setTabularData Method
Data Requirements for
Different Kinds of Graphs
Handling Problems
in Graph Data
Stock Graphs