CS302 -- Lab 3


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 done writing this lab you will think that object-oriented programming is a good way to create graphical interfaces.

Problem Statement

Your program is going to read a file containing historical price information for a stock and produce a graphical chart with tickmarks showing the high, low, and close for each month of data. data shows an example input file. chart is a compiled binary that you can run to see what your output should look like. For example, copy data from the cs302/labs/lab3 directory and then try:
/ruby/homes/ftp/pub/bvz/classes/cs302/bin/chart data
Notice that the program takes an input file as a parameter.


Setting Up

You should copy the following files from the /ruby/homes/ftp/pub/bvz/classes/cs302/labs/lab3 directory to your directory:

In order to make the graphics package work, you will need to type the following two commands in every window in which you run your program (or you can place them in your .cshrc file):

setenv AMULET_DIR /sunshine/homes/bvz/amulet/amulet3/
setenv AMULET_VARS_FILE Makefile.vars.gcc.Solaris
If you have certain types of protections, you may also 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., cetus4a).


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 chart 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:

  1. The y-axis is labeled with prices and the x-axis is labeled with months.

  2. 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.

  3. 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.

  4. The largest price tick on the x-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 x-axis. If the highest price tick is a multiple of 10, for example 50, then the largest price tick on the x-axis should be the next highest multiple of 10, for example 60.

  5. There should be one tick mark for each month. Each tick mark consists of two lines:

  6. The label and the tickmark for the month with the maximum high should be colored red.

  7. 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).

  8. The following spacing values should be used:


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.cc. 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 and the string "Hello World".

Now place the cursor over the "Hello World" string and press the F1 button. An "inspector" window should pop up that displays the properties of this text object. You will not recognize many of the properties, but you should recognize LEFT, TOP, and TEXT. You may also notice that the top line says that you are inspecting "my text". If you look at sample.cc, you will see that we passed the string "my text" to the constructor for the "Hello World" text object. This string allows you to match an object created in your program with an object appearing in the inspector window. You will also notice that you can edit properties by placing the cursor over a property's value and editing it. In general you can use the inspector window to determine whether objects' properties are what you expect them to be and to play around with the positioning of objects.

You can quit the application in one of three ways:

  1. Type Ctrl-C in the window in which you started sample.

  2. Go to the Objects menu in the inspector window, pull it down, and select Quit Application.

  3. Go to the window and type Alt-Shift-F1 (the Alt and Shift buttons must be held down before you type F1).

The class definitions for the graphical objects can be found in the CS302 include directory (/ruby/homes/ftp/pub/bvz/classes/notes/include) 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

The window object supports the following methods:

  1. setLeft(int), setTop(int): Set the left and top of the window respectively.

  2. setWidth(int), setHeight(int): Set the width and height of the window respectively.

  3. 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.

  • setLineStyle(Am_Style): Sets the line style of the line to the desired line style. For this lab, the available line styles are Am_Red, Am_Blue, Am_Black and Am_Dotted_Line. Each of these line styles is an object that can be passed as a parameter to the setLineStyle method.

    Text Object

    The text object supports the following methods:

    1. setLeft(int), setTop(int): Set the left and top of the text object respectively.

    2. setLineStyle(Am_Style): Sets the line style of the string's characters to the desired line style. For this lab, the available line styles are Am_Red, Am_Blue, Am_Black and Am_Dotted_Line. Each of these line styles is an object that can be passed as a parameter to the setLineStyle method.

    3. 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.cc. 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. In the next lab you will learn how to make your own.

    Two other files that you have been provided are called StockRecordArray.h and StockRecordArray.cc. You should not have to modify these files but you can if you want. These two files declare and define an extendible array that stores pointers to objects of type StockRecord. In StockRecordArray.h you will find a class called StockRecord that is capable of storing a line from an input file. You should use the Fields class to read in lines of data and then transfer the line to a StockRecord object. You can use the extendible array to store pointers to these StockRecords.

    Notice that you have not been given the objects.h file. That file is in the CS302 include directory. Also notice that it has already been included for you in chart.cc.


    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 Hand In

    You should mail to your TA a file created by /sunshine/homes/bvz/courses/302/bin/302submit. The file should be named username.lab where username is your username. For example, if I were submitting the lab, the file would be named bvz.lab. You will be sending your TA the makefile, chart.cc file, StockRecord.h and StockRecord.cc files.