CS302 -- Lab -- Stock Charts
Lab Objective
The objective of this lab is to give you experience using objects in
a setting where objects are natural, graphical interfaces. In particular,
you will create instances of graphical objects and manipulate their
properties, such as size, position, and line style, using methods that
are provided by the objects. Hopefully when you are finished writing this
lab you will think that object-oriented programming is a good way to
create graphical interfaces.
Setting Up
You should copy the following files from the
/home/bvz/courses/302/labs/lab1/ directory to your directory:
| Filename | Description |
| chartex | Sample binary of correct solution |
| chart.cpp | program shell you will add code to |
| objects.h | GTK include file |
| objects.cpp | GTK interface code |
| makefile |   |
| StockRecord.h | defines the data structure you should use for
storing stock records |
| data | sample input file |
| sample.cpp | sample program that demonstrates how to use GTK. |
| README | helpful hints on using GTK |
Problem Statement
Your program is going to read a file from stdin
that contains historical price information
for a stock and it is going to
produce a graphical chart with tickmarks showing the
high, low, and close for each month of data. data
shows an example input file. chartex is a compiled binary
that you can run to see what your output should look like. For example,
try:
./chartex < data
If you have certain types of protections, you may get a
message saying that your display could not be opened when you
run your program. If this happens, type the following command:
xhost +machine_name
where machine_name is the name of your machine (e.g., cetus4).
Notes
- You should use the vector class from the Standard Template
Library to store the data records for this lab. Since you do not know in
advance how large your data file will be, it is poor form to try to declare
a fixed size array that is capable of holding all of the possible
input. If you pick what seems like an incredibly large number, then you
can easily waste space when the input file is small and cause your program
to take up unnecessary space in main memory. Conversely, even if you pick
an incredibly large number the data file might still be bigger than you
expect and in that case your program will seg fault when it ultimately
overflows the fixed size array. It is much better to use the vector class
which can dynamically expand to accommodate additional entries.
- Use cin to read data into your program.
- You will note that I've declared the data members of StockRecord to
be public. Sometimes you really do want a class to act like a
simple record and allow your program to access the data fields. This
is one of those cases. Feel free to have cin read directly into the
data fields and also feel free to directly access these data fields
from your program.
- This lab will be using GTK and GDK. GTK is a toolkit for the X
Window System intended for creating graphical user interfaces. GDK is an
intermediate library between the X server and GTK. It handles basic rendering
such as drawing primitives, bitmaps, etc., as well as handling window
events. You don't need to understand more than this to use GTK and GDK.
The shell program (chart.cpp) and makefile you are provided set up the
appropriate linkages to this toolkit in order for you to program this lab.
- Students wanting to work on this lab remotely will need to have an Xserver installed and running in the
background. Directions for how to do this under Windows can be found at
http://www.cs.utk.edu/~cs302/hints/Xhelp.html. The directions contain instructions for users of both
Putty and SSH Secure Shell.
Format of the Input File
The format of an input file is:
month low close high
(string) (int) (int) (int)
An example input file can be found in data. You
cannot make any assumptions about how many lines of data are in the
input file.
Output
You may want to run the chartex program while you read this section,
so you can compare the output specifications with an actual output example.
Your program should read in the stock data from the specified file and
produce a graphical chart with the following characteristics:
- The y-axis is labeled with prices and the x-axis is labeled with
months.
- There are 10 non-zero price ticks on the y-axis. A tick is denoted
by a dotted line that stretches from the y-axis to the right edge
of the x-axis. Each price label is centered with respect to this
dotted line.
- There is one
tickmark on the x-axis for each month of data. The month labels
are centered with respect to their tick marks. The
tickmarks are placed at "half" intervals. For example,
if the horizontal spacing between tick marks is 40, the first
tick mark is placed at 20, the next at 60 and so on, rather than
at 40, 80, etc. (Note, however, that this "tickmark" is exactly the
tickmark referred to in item 5 below. "Tickmark" in this case
refers to location where the data in item 5 appears.) Also note
that the months should be displayed in the order in which they
appear in the input file. You should not try to sort these into
chronological order. (We'll assume that the input file is already
in chronological order. You don't have to confirm this, though.)
- The largest price tick on the y-axis should be the lowest multiple
of 10 that is greater than the maximum high in the price file.
For example, the maximum high in the data file is 67 so 70 is
the largest price tick on the y-axis. If the highest price tick
is a multiple of 10, for example 50, then the largest price tick
on the y-axis should be the next highest multiple of 10, for example 60.
- There should be one tick mark for each month. Each tick mark consists
of two lines:
- a vertical line that stretches from the low for the month to
the high for the month, and
- a horizontal line that marks the close for the month and which
is 7 pixels long. Notice that the horizontal line starts at
the vertical line and extends for 7 pixels to the right.
- The label and the tickmark for the month with the maximum high should
be colored red.
- The label and the tickmark for the month with the minimum low should
be colored blue. If the month with the maximum high and minimum low
coincide, the label and the tickmark should be red (the high
wins over the low).
- The following spacing values should be used:
- vertical spacing between tick marks on the y-axis: 30 pixels.
- horizontal spacing between tick marks on the x-axis: 40 pixels.
- horizontal spacing between the x-axis and the left edge of
the window: 40 pixels.
- horizontal spacing between the x-axis and the
right edge of the window: 40 pixels.
- vertical spacing between the y-axis and the top edge of the
window: 40 pixels.
- vertical spacing between the y-axis and the bottom edge of the
window: 40 pixels.
Materials
You will be using a graphics package for this lab that allows you to
create three types of graphical objects: windows, lines, and text objects.
If you want to display a line or a string of text, you will allocate a line or
text object and then add it to a window object (of course you will first
have to create a window object). A simple program that illustrates the
creation of each type of object can be found in
sample.cpp. This program creates a blue line and
a text object that displays the string "Hello World". Notice how
the program sets various graphical properties in each of the objects
by calling the appropriate methods.
Compile the sample program using the provided makefile and then
type sample. A window should appear on the screen displaying
a blue line, a dotted line, and the string "Hello World".
You can quit the application by typing
Ctrl-C in the window in which you started sample.
The class definitions for the graphical objects
can be found in
objects.h. For the sake of efficiency, the
definitions of the methods have been included with the declarations.
This can be done when the methods are very short, such as one or
two lines. Do not worry about how the methods are implemented.
Coordinate Systems
The X window system which you are using starts its coordinate system
at the upper, left corner of the screen. In other words, the
coordinate (0,0) occurs at the upper left corner of the screen. Since
we normally think of the coordinate (0,0) as occuring at the bottom
left corner this will take some getting use to. If you set a window's
coordinates to be (100, 50), then it will appear 100 pixels from the left
edge of the screen and 50 pixels from the top of the screen.
Within a window, the coordinate positions of objects are relative to
the upper, left corner of the window. For example, when we set the
coordinates of the "Hello World" text object to be (80, 20), the
top, left corner of the string is displayed 80 pixels from the left
edge of the window and 20 pixels from the top of the window.
Window Object
You create a new window object using new Window(s, l, t, w, h),
where s is a string giving the name of the window, and l, t, w, h
are integers giving the left, top, width, and height of window,
respectively. This constructor returns a pointer to an object of the
Window class. (You can also create a window without passing any
parameters, which will use default values. Or, you can just give it a
name. Your code for this lab will want to pass all 5 parameters.)
The window object supports the following methods:
- setLeft(int), setTop(int): Set the left and top of
the window respectively.
- setWidth(int), setHeight(int): Set the width and height
of the window respectively.
- addObject(GraphicalObject *): Adds a line object or a text
object to the window.
Line Object
The line object supports the following methods:
setX1(int), setY1(int), setX2(int), setY2(int): Sets the
two endpoints of the line.
setColor(String color): Sets the line to the desired color. The
string names you will need for this lab are "Red", "Blue", and
"Black".
setLineStyle(lineStyle_t style): Sets the line style of the line to
the desired line style. For this lab, the available line styles
are:
- SOLID
- DASHED
- DOUBLE_DASHED
For example, you might write:
my_line.setLineStyle(SOLID);
Text Object
The text object supports the following methods:
- setLeft(int), setTop(int): Set the left and top of
the text object respectively.
- setColor(String color): Sets the text string to the desired color.
The string names you will need for this lab are "Red", "Blue", and
"Black".
- setText(string): Sets the string to be displayed.
You cannot set the width or height of a text object since the width
and height are computed automatically from the string.
Writing the Program
One of the files that you copied from the lab3 directory is called
chart.cpp. This file contains a skeleton that you need to
flesh out. It already contains commands to initialize the graphics
package and to shut it down when you are finished. You need to
write the code for your chart program and place it at the location
labeled "Your Code Goes Here".
You have also been provided a makefile for this lab. Use it.
One other file that you have been provided is called StockRecord.h.
You should not have to modify this file but
you can if you want.
In StockRecord.h you will find a class called StockRecord that is
capable of storing a line from an input file. You should read in lines of data and then store the data from each line in
a StockRecord object.
Notice that objects.h has already been
included for you in chart.cpp.
Things to Ask Yourself
After you have designed and implemented the program, you should ask
yourself how easy it would be to change the horizontal or vertical
spacing of the tickmarks, the number of tick marks on the y-axis,
or the positioning of the chart in the window. If you hardcoded
these values into your program at each spot where they were needed,
then your program may not be easy to change. In fact you are
guaranteed to run into problems because several of the spacing parameters
are 40 pixels. Therefore you will have to find each instance of 40
and determine whether it should be changed. Can you think of a better
way to code the spacing parameters so that you would only have to
change them in one place?
What to Submit
You should submit the following files:
- chart.cpp
- StockRecord.h
- makefile
Remember, you submit labs using the submission procedure described on the
TA web site.