A Chart Library

Author(s): Isabel Martín García.

This library is intended to eaose the task of displaying some graphical results. This library allows the programmer to visualize different graphs and tables without knowing anything about specific graphical packages.

You need to install the BLT package in your computer. BLT is an extension to the Tk toolkit and it does not require any patching of the Tcl or Tk source files. You can find it in http://www.tcltk.com/blt/index.html

Basically, when the user invokes a predicate, the library (internally) creates a bltwish interpreter and passes the information through a socket to display the required widget. The interpreter parses the received commands and executes them.

The predicates exported by this library can be classified in four main groups, according to the types of representation they provide.

  • bar charts

  • line graphs

  • scatter graphs

  • tables

To represent graphs, the Cartesian coordinate system is used. I have tried to show simple samples for every library exported predicate in order to indicate how to call them.

Bar charts

In this section we shall introduce the general issues about the set of barchart predicates. By calling the predicates that pertain to this group a bar chart for plotting two-dimensional data (X-Y coordinates) can be created. A bar chart is a graphic means of comparing numbers by displaying bars of lengths proportional to the y-coordinates they represented. The barchart widget has many configurable options such as title, header text, legend and so on. You can configure the appearance of the bars as well. The bar chart widget has the following components:

Header text

The text displayed at the top of the window. If it is no text will be displayed.

Save button
The button placed below the header text. Pops up a dialog box for the user to select a file to save the graphic in PostScript format.

Note: Limitation: Some printers can have problems if the PostScript file is too complex (i.e. too many points/lines appear in the picture).

Bar chart title
The title of the graph. It is displayed at the top of the bar chart graph. If text is no title will be displayed.

X axis title
X axis title. If text is no x axis title will be displayed.

Y axis title
Y axis title. If text is no y axis title will be displayed.

X axis
X coordinate axis. The x axis is drawn at the bottom margin of the bar chart graph. The x axis consists of the axis line, ticks and tick labels. Tick labels can be numbers or plain text. If the labels are numbers, they could be displayed at uniform intervals (the numbers are treated as normal text) or depending on its x-coodinate value. You can also set limits (maximum and minimum) for the x axis, but only if the tick labels are numeric.

Y axis
Y coordinate axis. You can set limits (maximum and minimum) for the y axis. The y axis is drawn at the right margin of the bar chart graph.The y axis consists of the axis line, ticks and tick labels. The tick labels are numeric values determined from the data and are drawn at uniform intervals.

Bar chart graph
This is the plotting area, placed in the center of the window and surrounded by the axes, the axis titles and the legend (if any). The range of the axes controls what region of the data is plotted. By default, the minimum and maximum limits are determined from the data, but you can set them (as mentioned before). Data points outside the minimum and maximum value of the axes are not plotted.

Legend
The legend displays the name and symbol of each bar. The legend is placed in the right margin of the Bar chart graph.

Footer text
Text displayed at the lower part of the window. If text is no header text will be displayed.

Quit button
Button placed below the footer text. Click it to close the window.

All of them are arranged in a window. However you can, for example, show a bar chart window without legend or header text. Other configuration options will be explained later.

In addition to the window appearance there is another important issue about the bar chart window, namely its behaviour in response to user actions. The association user actions to response is called bindings. The main bindings currently specified are the following:

Default bindings
Those are well known by most users. They are related to the frame displayed around the window. As you know, you can interactively move, resize, close, iconify, deiconify, send to another desktop etc. a window.

Bindings related to bar chart graph and its legend
Clicking the left mouse key over a legend element, the corresponding bar turns out into red. After clicking again, the bar toggles to its original look. In addition, you can do zoom-in by pressing the left mouse key over the bar chart graph and dragging to select an area. To zoom out simply press the right mouse button.

When the pointer passes over the plotting area the cross hairs are drawn. The cross hairs consists of two intersecting lines (one vertical and one horizontal). Besides, if the pointer is over a legend element, its background changes.

Bindings related to buttons
There are two buttons in the main widget. Clicking the mouse on the Save button a "Save as" dialog box is popped up. The user can select a file to save the graph. If the user choose a file that already exists, the dialog box prompts the user for confirmation on whether the existing file should be overwritten or not. Furthermore, you can close the widget by clicking on the Quit button.

When the pointer passes over a button the button color changes.

The predicates that belong to this group are those whose names begin with barchart and genmultibar. If you take a look at the predicate names that pertain to this group, you will notice that they are not self-explanatory. It would have been better to name the predicates in a way that allows the user to identify the predicate features by its name, but it would bring about very long names (i.e barchart_WithoutLegend_BarsAtUniformIntervals_RandomBarsColors). For this reason I decided to simply add a number after barchart to name them.

Line graphs

It is frequently the case that several datasets need to be displayed on the same plot. If so, you may wish to distinguish the points in different datasets by joining them by lines of different color, or by plotting with symbols of different types. This set of predicates allows the programmer to represent two-dimensional data (X-Y coordinates). Each dataset contains x and y vectors containing the coordinates of the data. You can configure the appearance of the points and the lines which the points are connected with. The configurable line graph components are:

line graph
This is the plotting area, placed in the center of the window and surrounded by the axes, the axes titles and the legend (if any). The range of the axes controls what region of the data is plotted. By default, the minimum and maximum limits are determined from the data, but you can set them. Data points outside the minimum and maximum value of the axes are not plotted. You can specify how connecting line segments joining successive datapoints are drawn by setting the Smooth argument. Smooth can be either linear, step, natural and quadratic. Furthermore, you can select the appearance of the points and lines.

Legend
The legend displays the name and symbol of each line. The legend is placed in the right margin of the graph.

The elements header, footer, quit and save buttons, the titles and the axes are quite similar to those in barchart graphs, except in that the tick labels will be numbers. All of them are arranged in a window by the geometry manager. However you can, as we mentioned in the above paragraphs, show a line graph window without any titles or footer text. Other configuration options will be explained later in this section or in the corresponding modules.

Related to the behaviour of the widgets in response to user actions (bindings) we will remark the following features:

Bindings related to line graph and its legend
Clicking the left mouse key over a legend element, the corresponding line turns out into blue. Repeating the action reverts the line to its original color. Moreover, you can do zoom-in by clicking the left mouse key over the bar chart graph and dragging a rectangle defining the area you want to zoom in. To zoom out simply press the right mouse button.

When the pointer passes over the plotting area the cross hairs are drawn. The cross hairs consists of two intersecting lines (one vertical and one horizontal). Besides, if the pointer is over a legend element, its background changes.

Other bindings
The default bindings and the bindings related to the save and quit buttons are similar to those in the bar chart graphs.

The predicates that belong to this group are those whose names begin with graph_.

Scatter graphs

The challenge of this section is to introduce some general aspects about the scatter graph predicates group. By invoking the scatter graph predicates the user can represent two-dimensional point datasets. Often you need to display one or several point datasets on the same plot. If so, you may wish to distinguish the points that pertain to different datasets by using plotting symbols of different types, or by displaying them in different colors. This set of predicates allows you to represent two-dimensional data (X-Y coordinates). Each dataset contains x and y vectors containing the coordinates of the data. You can configure the appearance of the points. The configurable scatter graph components are:

scatter graph
This is the plotting area, placed in the center of the window and surrounded by the axes, the axes titles and the legend (if any). The range of the axes controls what region of the data is plotted. By default, the minimum and maximum limits are determined from the data, but you can set them (as we mentioned before). Data points outside the minimum and maximum value of the axes are not plotted. The user can select the appearance of the points.

Legend
The legend displays the name and symbol of each point dataset. The legend is drawn in the right margin of the graph.

The elements header, footer, quit and save buttons, the titles and the axes are similar to those in barchart graphs except for that, as in line graphs, the tick labels will be numbers. All of them are arranged in a window by the geometry manager. However you can, for example, show a scatter graph window without titles or footer text, as we mentioned before. Other configuration options will be explained later, in the corresponding modules.

Related to the behaviour of the widgets in response to user actions (bindings) the following features are:

Bindings related to scatter graph and its legend
Clicking the left mouse key over a legend element, the points which belong to the corresponding dataset turn out into blue. Repeating the action toggles the point dataset to its original color. Moreover, you can do zoom-in by clicking the left mouse key over the bar chart graph and dragging a rectangle defining the area you want to zoom-in on. To do zoom-out simply press the right mouse button.

When the pointer passes over the plotting area the cross hairs are drawn. The cross hairs consists of two intersecting lines (one vertical and one horizontal). Besides, if the pointer is over a legend element, its background changes.

Other bindings
The default bindings and the bindings related to the save and quit buttons are similar to those in the bar chart graphs.

The predicates that belong to this group are those whose names began with scattergraph_.

Tables

The purpose of this section is to allow the user to display results in a table. A table is a regular structure in which:

  • Every row has the same number of columns, or

  • Every column has the same number of rows.

The widget configurable components are as follows:

Title

Title of the widget, it is displayed centered at the top of the canvas. If text is no title will be displayed.

Header text

Left centered text displayed bellow the title. If text is no header text will be displayed.

Table

Is placed in the center of the window. The table is composed by cells ordered in rows and columns. The cell values can be either any kind of text or numbers and they can be empty as well (see the type definition in the corresponding chapter module). A table is a list of lists. Each sublist is a row, so every sublist in the table must contain the same number of alements.

Footer text

Left centered text displayed at the lower part of the window. If text is no header text will be displayed.

Quit button

Button placed below the footer text. You can click it to close the window.

If the arguments are not in a correct format an exception will be thrown. Moreover, these widgets have the default bindings and the binding related to the quit button:

The set of predicates that belongs to this group are those which names begin with table_widget.

Overview of widgets

Although you don't have to worry about how to arrange the widgets, here is an overview of how Tcl-tk, the underlying graphical system currently used by chartlib, performs this task. Quoting from the book Tcl and Tk toolkit, John K. Ousterhout.

The X Window System provides many facilities for manipulating windows in displays. The root window may have any number of child windows, each of wich is called a top-level window. Top-level windows may have children of their own, wich may have also children, and so on. The descendants of top-level windows are called internal windows. Internal windows are usedfor individual controls such as buttons, text entries, and for grouping controls together. An X-application tipically manages several top-level windows. Tk uses X to implement a set of controls with the Motif look and feel. These controls are called widgets. Each widget is implemented using one X window, and the terms "window" and "widget" will be used interchangeably in this document. As with windows, widgets are nested in hierarchical structures. In this library top-level widgets (nonleaf or main) are just containers for organizing and arranging the leaf widgets (components). Thereby, the barchart widget is a top-level window wich contains some widget components.

Probably the most painstaking aspect of building a graphical application is getting the placement and size of the widgets just right. It usually takes many iterations to align widgets and adjust their spacing. That's because managing the geometry of widgets is simply not a packing problem, but also graphical design problem. Attributes such as alignment, symmetry, and balance are more important than minimizing the amount of space used for packing. Tk is similar to other X toolkits in that it does not allow widgets to determine their own geometries. A widget will not even appeared unless it is managed by a geometry manager. This separation of geometry management from internal widget behaviour allows multiple geometry managers to exist simultaneously and permits any widget to be used with any geometry manager. A geometry manager's job is to arrange one or more slave widgets relative to a master widgets. There are some geometry managers in Tk such as pack, place and canvas widget. We will use another one call table.

The table geometry manager arranges widgets in a table. It's easy to align widgets (horizontally and vertically) or to create empty space to balance the arrangement of the widgets. Widgets (called slaves in the Tk parlance) are arranged inside a containing widget (called the master). Widgets are positioned at row,column locations and may span any number of rows or columns. More than one widget can occupy a single location. The placement of widget windows determines both the size and arrangement of the table. The table queries the requested size of each widget. The requested size of a widget is the natural size of the widget (before the widget is shrunk or expanded). The height of each row and the width of each column is the largest widget spanning that row or column. The size of the table is in turn the sum of the row and column sizes. This is the table's normal size. The total number of rows and columns in a table is determined from the indices specified. The table grows dynamically as windows are added at larger indices.


Documentation on exports

(UNDOC_REEXPORT)
barchart1/7:
Imported from genbar1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
barchart1/9:
Imported from genbar1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
percentbarchart1/7:
Imported from genbar1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
barchart2/7:
Imported from genbar2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
barchart2/11:
Imported from genbar2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
percentbarchart2/7:
Imported from genbar2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
barchart3/7:
Imported from genbar3 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
barchart3/9:
Imported from genbar3 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
percentbarchart3/7:
Imported from genbar3 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
barchart4/7:
Imported from genbar4 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
barchart4/11:
Imported from genbar4 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
percentbarchart4/7:
Imported from genbar4 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
multibarchart/8:
Imported from genmultibar (see the corresponding documentation for details).

(UNDOC_REEXPORT)
multibarchart/10:
Imported from genmultibar (see the corresponding documentation for details).

(UNDOC_REEXPORT)
tablewidget1/4:
Imported from table_widget1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
tablewidget1/5:
Imported from table_widget1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
tablewidget2/4:
Imported from table_widget2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
tablewidget2/5:
Imported from table_widget2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
tablewidget3/4:
Imported from table_widget3 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
tablewidget3/5:
Imported from table_widget3 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
tablewidget4/4:
Imported from table_widget4 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
tablewidget4/5:
Imported from table_widget4 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
graph_b1/9:
Imported from gengraph1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
graph_b1/13:
Imported from gengraph1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
graph_w1/9:
Imported from gengraph1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
graph_w1/13:
Imported from gengraph1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
scattergraph_b1/8:
Imported from gengraph1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
scattergraph_b1/12:
Imported from gengraph1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
scattergraph_w1/8:
Imported from gengraph1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
scattergraph_w1/12:
Imported from gengraph1 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
graph_b2/9:
Imported from gengraph2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
graph_b2/13:
Imported from gengraph2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
graph_w2/9:
Imported from gengraph2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
graph_w2/13:
Imported from gengraph2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
scattergraph_b2/8:
Imported from gengraph2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
scattergraph_b2/12:
Imported from gengraph2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
scattergraph_w2/8:
Imported from gengraph2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
scattergraph_w2/12:
Imported from gengraph2 (see the corresponding documentation for details).

(UNDOC_REEXPORT)
chartlib_text_error_protect/1:
Imported from chartlib_errhandle (see the corresponding documentation for details).

(UNDOC_REEXPORT)
chartlib_visual_error_protect/1:
Imported from chartlib_errhandle (see the corresponding documentation for details).

Known bugs and planned improvements

  • Run-time checks have been reported not to work with this code. That means that either the assertions here, or the code that implements the run-time checks are erroneous.