home *** CD-ROM | disk | FTP | other *** search
-
- <HTML>
- <HEAD>
- <TITLE>Chart - a series of charting modules</TITLE>
- <LINK REL="stylesheet" HREF="../../Active.css" TYPE="text/css">
- <LINK REV="made" HREF="mailto:">
- </HEAD>
-
- <BODY>
- <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
- <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
- <STRONG><P CLASS=block> Chart - a series of charting modules</P></STRONG>
- </TD></TR>
- </TABLE>
-
- <A NAME="__index__"></A>
- <!-- INDEX BEGIN -->
-
- <UL>
-
- <LI><A HREF="#name">NAME</A></LI><LI><A HREF="#supportedplatforms">SUPPORTED PLATFORMS</A></LI>
-
- <LI><A HREF="#synopsis">SYNOPSIS</A></LI>
- <LI><A HREF="#description">DESCRIPTION</A></LI>
- <UL>
-
- <LI><A HREF="#useing chart">use-ing Chart</A></LI>
- <LI><A HREF="#getting an object">Getting an object</A></LI>
- <LI><A HREF="#setting different options">Setting different options</A></LI>
- <LI><A HREF="#gifgraph.pmstyle api">GIFgraph.pm-style API</A></LI>
- <LI><A HREF="#graph.pmstyle api">Graph.pm-style API</A></LI>
- <LI><A HREF="#imagemap support">Imagemap Support</A></LI>
- </UL>
-
- <LI><A HREF="#to do">TO DO</A></LI>
- <LI><A HREF="#bugs">BUGS</A></LI>
- <LI><A HREF="#author">AUTHOR</A></LI>
- <LI><A HREF="#maintainer">MAINTAINER</A></LI>
- <LI><A HREF="#copyright">COPYRIGHT</A></LI>
- </UL>
- <!-- INDEX END -->
-
- <HR>
- <P>
- <H1><A NAME="name">NAME</A></H1>
- <P>Chart - a series of charting modules</P>
- <P>
- <HR>
- <H1><A NAME="supportedplatforms">SUPPORTED PLATFORMS</A></H1>
- <UL>
- <LI>Linux</LI>
- <LI>Windows</LI>
- </UL>
- <HR>
- <H1><A NAME="synopsis">SYNOPSIS</A></H1>
- <PRE>
- use Chart::type;</PRE>
- <PRE>
- $obj = Chart::type->new;
- $obj = Chart::type->new ( $gif_width, $gif_height );
- </PRE>
- <PRE>
-
- $obj->set ( $key_1, $val_1, ... ,$key_n, $val_n );
- $obj->set ( $key_1 => $val_1,
- ...
- $key_n => $val_n );
- $obj->set ( %hash );</PRE>
- <PRE>
- # GIFgraph.pm-style API
- @data = ( \@x_tick_labels, \@dataset1, ... , \@dataset_n );
- $obj->gif ( "filename", \@data );
- $obj->gif ( $filehandle, \@data );
- $obj->gif ( FILEHANDLE, \@data );
- $obj->cgi_gif ( \@data );</PRE>
- <PRE>
- # Graph.pm-style API
- $obj->add_pt ($label, $val_1, ... , $val_n);
- $obj->add_dataset ($val_1, ... , $val_n);
- $obj->gif ( "filename" );
- $obj->gif ( $filehandle );
- $obj->gif ( FILEHANDLE );
- $obj->cgi_gif ();</PRE>
- <PRE>
- # Retrieve imagemap information
- $obj->set ( 'imagemap' => 'true' );
- $imagemap_ref = $obj->imagemap_dump ();</PRE>
- <P>
- <HR>
- <H1><A NAME="description">DESCRIPTION</A></H1>
- <P>This module is an attempt to build a general purpose graphing module
- that is easily modified and expanded. I borrowed most of the API
- from Martien Verbruggen's GIFgraph module. I liked most of GIFgraph,
- but I thought it was to difficult to modify, and it was missing a few
- things that I needed, most notably legends. So I decided to write
- a new module from scratch, and I've designed it from the bottom up
- to be easy to modify. Like GIFgraph, Chart uses Lincoln Stein's GD
- module for all of its graphics primitives calls.</P>
- <P>
- <H2><A NAME="useing chart">use-ing Chart</A></H2>
- <P>Okay, so you caught me. There's really no Chart::type module.
- All of the different chart types (Points, Lines, Bars, LinesPoints, Pie,
- Composite, StackedBars, and Pareto so far) are classes by themselves, each
- inheriting a bunch of methods from the Chart::Base class. Simply replace
- the word type with the type of chart you want and you're on your way.
- For example,
- </P>
- <PRE>
-
- use Chart::Lines;</PRE>
- <P>would invoke the lines module.</P>
- <P>
- <H2><A NAME="getting an object">Getting an object</A></H2>
- <P>The new method can either be called without arguments, in which
- case it returns an object with the default image size (400x300 pixels),
- or you can specify the width and height of the image. Just remember
- to replace type with the type of graph you want. For example,</P>
- <PRE>
- $obj = Chart::Bars (600,400);</PRE>
- <P>would return a Chart::Bars object containing a 600x400 pixel
- image. New also initializes most of the default variables, which you
- can subsequently change with the set method.</P>
- <P>
- <H2><A NAME="setting different options">Setting different options</A></H2>
- <P>This is where the fun begins. Set looks for a hash of keys and
- values. You can pass it a hash that you've already constructed, like</P>
- <PRE>
- %hash = ('title' => 'Foo Bar');
- $obj->set (%hash);
- </PRE>
- <PRE>
-
- or you can try just constructing the hash inside the set call, like</PRE>
- <PRE>
- $obj->set ('title' => 'Foo Bar');</PRE>
- <P>The following are all of the currently supported options:</P>
- <DL>
- <DT><STRONG><A NAME="item_%27transparent%27">'transparent'</A></STRONG><BR>
- <DD>
- Makes the background of the image transparent if set to 'true'. Useful
- for making web page images. Default is 'false'.
- <P></P>
- <DT><STRONG><A NAME="item_%27gif_border%27">'gif_border'</A></STRONG><BR>
- <DD>
- Sets the number of pixels used as a border between the graph
- and the edges of the gif. Defaults to 10.
- <P></P>
- <DT><STRONG><A NAME="item_%27graph_border%27">'graph_border'</A></STRONG><BR>
- <DD>
- Sets the number of pixels used as a border between the title/labels
- and the actual graph within the gif. Defaults to 10.
- <P></P>
- <DT><STRONG><A NAME="item_%27text_space%27">'text_space'</A></STRONG><BR>
- <DD>
- Sets the amount of space left on the sides of text, to make it more
- readable. Defaults to 2.
- <P></P>
- <DT><STRONG><A NAME="item_%27title%27">'title'</A></STRONG><BR>
- <DD>
- Tells GD graph what to use for the title of the graph. If empty,
- no title is drawn. It recognizes '\n' as a newline, and acts accordingly.
- Default is empty.
- <P></P>
- <DT><STRONG><A NAME="item_%27sub_title%27">'sub_title'</A></STRONG><BR>
- <DD>
- Deprecated, left in for backwards-compatibility. This option will probably
- be taken out of the next release.
- <P></P>
- <DT><STRONG><A NAME="item_%27x_label%27">'x_label'</A></STRONG><BR>
- <DD>
- Tells Chart what to use for the x-axis label. If empty, no label
- is drawn. Default is empty.
- <P></P>
- <DT><STRONG><A NAME="item_%27y_label%27%2C_%27y_label2%27">'y_label', 'y_label2'</A></STRONG><BR>
- <DD>
- Tells Chart what to use for the y-axis labels. If empty, no label
- is drawn. Default is empty.
- <P></P>
- <DT><STRONG><A NAME="item_%27legend%27">'legend'</A></STRONG><BR>
- <DD>
- Specifies the placement of the legend. Valid values are 'left', 'right',
- 'top', 'bottom'. Setting this to 'none' tells chart not to draw a
- legend. Default is 'right'.
- <P></P>
- <DT><STRONG><A NAME="item_%27legend_labels%27">'legend_labels'</A></STRONG><BR>
- <DD>
- Sets the values for the labels for the different datasets. Should
- be assigned a reference to an array of labels. For example,
-
- <PRE>
-
- @labels = ('foo', 'bar');
- $obj->set ('legend_labels' => \@labels);</PRE>
- <P>Default is empty, in which case 'Dataset 1', 'Dataset 2', etc. are
- used as the labels.</P>
- <P>For a pareto graph, the first value should be the name of the set, and
- the second should be the name of the running sum of the values.</P>
- <P>For a pie graph, this option is ignored, as the values for the legend
- are taken from the array of data point labels.</P>
- <P></P>
- <DT><STRONG><A NAME="item_%27tick_len%27">'tick_len'</A></STRONG><BR>
- <DD>
- Sets the length of the x- and y-ticks in pixels. Default is 4.
- <P></P>
- <DT><STRONG><A NAME="item_%27x_ticks%27">'x_ticks'</A></STRONG><BR>
- <DD>
- Specifies how to draw the x-tick labels. Valid values are 'normal',
- 'staggered' (staggers the labels vertically), and 'vertical' (the
- labels are draw upwards). Default is 'normal'.
- <P></P>
- <DT><STRONG><A NAME="item_%27y_ticks%27">'y_ticks'</A></STRONG><BR>
- <DD>
- Sets the number of y_ticks to draw. Default is 6.
- <P></P>
- <DT><STRONG><A NAME="item_%27max_val%27">'max_val'</A></STRONG><BR>
- <DD>
- Sets the maximum y-value on the graph, overriding the normal auto-scaling.
- Default is undef.
- <P></P>
- <DT><STRONG><A NAME="item_%27min_val%27">'min_val'</A></STRONG><BR>
- <DD>
- Sets the minimum y-value on the graph, overriding the normal auto-scaling.
- Default is undef.
- <P></P>
- <DT><STRONG><A NAME="item_%27pt_size%27">'pt_size'</A></STRONG><BR>
- <DD>
- Sets the radius of the points (for Chart::Points, etc.) in pixels.
- Default is 18.
- <P></P>
- <DT><STRONG><A NAME="item_%27brush_size%27">'brush_size'</A></STRONG><BR>
- <DD>
- Sets the width of the lines (for Chart::Lines, etc.) in pixels.
- Default is 6.
- <P></P>
- <DT><STRONG><A NAME="item_%27skip_x_ticks%27">'skip_x_ticks'</A></STRONG><BR>
- <DD>
- Sets the number of x-ticks and x-tick labels to skip. (ie.
- if 'skip_x_ticks' was set to 4, Chart would draw every 4th x-tick
- and x-tick label). Default is undef.
- <P></P>
- <DT><STRONG><A NAME="item_%27custom_x_ticks%27">'custom_x_ticks'</A></STRONG><BR>
- <DD>
- Used in points, lines, linespoints, and bars charts, this option
- allows you to specify exatly which x-ticks and x-tick labels should
- be drawn. It should be assigned a reference to an array of desired
- ticks. Just remember that I'm counting from the 0th element of the
- array. (ie., if 'custom_x_ticks' is assigned [0,3,4], then the 0th,
- 3rd, and 4th x-ticks will be displayed)
- <P></P>
- <DT><STRONG><A NAME="item_%27colors%27">'colors'</A></STRONG><BR>
- <DD>
- This option lets you control the colors the chart will use. It takes
- a reference to a hash. The hash should contain keys mapped to references
- to arrays of rgb values. For instance,
- <PRE>
- $obj->set('colors' => {'background' => [255,255,255]});</PRE>
- <P>sets the background color to white (which is the default). Valid keys for
- this hash are</P>
- <PRE>
- 'background' (background color for the gif)
- 'text' (all the text in the chart)
- 'y_label' (color of the first y axis label)
- 'y_label2' (color of the second y axis label)
- 'grid_lines' (color of the grid lines)
- 'x_grid_lines' (color of the x grid lines - for x axis ticks)
- 'y_grid_lines' (color of the y grid lines - for to left y axis ticks)
- 'y2_grid_lines' (color of the y2 grid lines - for right y axis ticks)
- 'dataset0'..'dataset15' (the different datasets)
- 'misc' (everything else, ie. ticks, box around the legend)</PRE>
- <P>NB. For composite charts, there is a limit of 8 datasets per component.
- The colors for 'dataset8' through 'dataset15' become the colors
- for 'dataset0' through 'dataset7' for the second component chart.</P>
- <P></P>
- <DT><STRONG><A NAME="item_%27grey_background%27">'grey_background'</A></STRONG><BR>
- <DD>
- Puts a nice soft grey background on the actual data plot when
- set to 'true'. Default is 'true'.
- <P></P>
- <DT><STRONG><A NAME="item_%27grid_lines%27">'grid_lines'</A></STRONG><BR>
- <DD>
- Draws grid lines matching up to x and y ticks
- <P></P>
- <DT><STRONG><A NAME="item_%27spaced_bars%27">'spaced_bars'</A></STRONG><BR>
- <DD>
- Leaves space between the groups of bars at each data point when set
- to 'true'. This just makes it easier to read a bar chart. Default
- is 'true'.
- <P></P>
- <DT><STRONG><A NAME="item_%27imagemap%27">'imagemap'</A></STRONG><BR>
- <DD>
- Lets Chart know you're going to ask for information about the placement
- of the data for use in creating an image map from the gif. This information
- can be retrieved using the <CODE>imagemap_dump()</CODE> method. NB. that the
- <CODE>imagemap_dump()</CODE> method cannot be called until after the Chart has been
- generated (ie. using the <CODE>gif()</CODE> or <CODE>cgi_gif()</CODE> methods).
- <P></P>
- <DT><STRONG><A NAME="item_%27sort%27">'sort'</A></STRONG><BR>
- <DD>
- Tells Chart to sort the data before plotting it. Can be assigned
- an order ('asc' or 'desc' for ascending and descending, respectively),
- in which case it sorts numerically. Or it can also be assigned an
- array reference. The array reference should contain 3 elements: the
- order in which to search (as above), which dataset to use (remember
- that 0 is the x-tick labels), and the type of sort to do ('alpha' or 'num'
- for alphabetical or numerical sorts, respectively). For example,
- <PRE>
- $obj->set ('sort' => ['asc', 2, 'num']);</PRE>
- <P>would sort the data numerically in ascending order, sorting by the
- third dataset (second if you don't count the x-tick labels). Note that</P>
- <PRE>
- $obj->set ('sort' => ['asc', 0, 'alpha']);</PRE>
- <P>will sort the data in ascending alphabetical order by the x-tick labels.
- Defualts to undef, normally, and 'desc' for pareto.</P>
- <P></P>
- <DT><STRONG><A NAME="item_%27nosort%27">'nosort'</A></STRONG><BR>
- <DD>
- Turns off the default sort for pareto graphs. Default is undef.
- <P></P>
- <DT><STRONG><A NAME="item_%27cutoff%27">'cutoff'</A></STRONG><BR>
- <DD>
- Only used for pareto charts, this option determines where the
- cut-off point is. It then lumps everything after the highest 'cutoff'
- data points into an 'Other' entry on the chart. Default is 5.
- <P></P>
- <DT><STRONG><A NAME="item_%27nocutoff%27">'nocutoff'</A></STRONG><BR>
- <DD>
- Turns off the default 'cutoff' feature of pareto graphs. Defaut is
- undef.
- <P></P>
- <DT><STRONG><A NAME="item_%27composite_info%27">'composite_info'</A></STRONG><BR>
- <DD>
- This option is only used for composite charts. It contains the
- information about which types to use for the two component charts,
- and which datasets belonf to which component chart. It should be
- a reference to an array of array references, containing information
- like the following
- <PRE>
- $obj->set ('composite_info' => [ ['Bars', [1,2]],
- ['Lines', [3,4] ]);</PRE>
- <P>This example would set the two component charts to be a bar chart and
- a line chart. It would use the first two data sets for the bar
- chart (note that the numbering starts at 1, not zero like most of
- the other numbered things in Chart), and the second two data sets
- for the line chart. The default is undef.</P>
- <P>NB. Chart::Composite can only do two component charts.</P>
- <P></P>
- <DT><STRONG><A NAME="item_%27min_val1%27%2C_%27min_val2%27">'min_val1', 'min_val2'</A></STRONG><BR>
- <DD>
- Only for composite charts, these options specify the minimum y-value
- for the first and second components respectively. Both default to
- undef.
- <P></P>
- <DT><STRONG><A NAME="item_%27max_val1%27%2C_%27max_val2%27">'max_val1', 'max_val2'</A></STRONG><BR>
- <DD>
- Only for composite charts, these options specify the maximum y-value
- for the first and second components respectively. Both default to
- undef.
- <P></P>
- <DT><STRONG><A NAME="item_%27ylabel2%27">'ylabel2'</A></STRONG><BR>
- <DD>
- The label for the right y-axis (the second component chart) on a composite
- chart. Default is undef.
- <P></P>
- <DT><STRONG><A NAME="item_%27yticks1%27%2C_%27y_ticks2%27">'yticks1', 'y_ticks2'</A></STRONG><BR>
- <DD>
- The number of y ticks to use on the first and second y-axis on a composite
- chart. Please note that if you just set the 'y_ticks' option, both axes
- will use that number of y ticks. Both default to undef.
- <P></P>
- <DT><STRONG><A NAME="item_%27same_y_axes%27">'same_y_axes'</A></STRONG><BR>
- <DD>
- Forces both component charts in a composite chart to use the same maximum
- and minimum y-values if set to 'true'. This helps to keep the composite
- charts from being too confusing. Default is undef.
- <P></P>
- <DT><STRONG><A NAME="item_%27no_cache%27">'no_cache'</A></STRONG><BR>
- <DD>
- Adds Pragma: no-cache to the http header. Be careful with this one, as
- Netscape 4.5 is unfriendly with POST using this method.
- <P></P></DL>
- <P>
- <H2><A NAME="gifgraph.pmstyle api">GIFgraph.pm-style API</A></H2>
- <DL>
- <DT><STRONG><A NAME="item_Sending_the_image_to_a_file">Sending the image to a file</A></STRONG><BR>
- <DD>
- Invoking the gif method causes the graph to be plotted and saved to
- a file. It takes the name of the output file and a reference to the
- data as arguments. For example,
- <PRE>
- $obj->gif ("foo.gif", \@data);</PRE>
- <P>would plot the data in @data, and the save the image to foo.gif.
- Of course, this then beggars the question ``What should @data look
- like?''. Well, just like GIFgraph, @data should contain references
- to arrays of data, with the first array reference pointing to an
- array of x-tick labels. For example,</P>
- <PRE>
- @data = ( [ 'foo', 'bar', 'junk' ],
- [ 30.2, 23.5, 92.1 ] );</PRE>
- <P>would set up a graph with one dataset, and three data points in that
- set. In general, the @data array should look something like</P>
- <PRE>
- @data = ( \@x_tick_labels, \@dataset1, ... , \@dataset_n );</PRE>
- <P>And no worries, I make my own internal copy of the data, so that it doesn't
- mess with yours.</P>
- <P></P>
- <DT><STRONG><A NAME="item_CGI_and_Chart">CGI and Chart</A></STRONG><BR>
- <DD>
- Okay, so you're probably thinking, ``Do I always have to save these images
- to disk? What if I want to use Chart to create dynamic images for my
- web site?'' Well, here's the answer to that.
- <PRE>
- $obj->cgi_gif ( \@data );</PRE>
- <P>The cgi_gif method will print the chart, along with the appropriate http
- header, to stdout, allowing you to call chart-generating scripts directly
- from your html pages (ie. with a <img src=image.pl> HTML tag). The @data
- array should be set up the same way as for the normal gif method.</P>
- <P></P></DL>
- <P>
- <H2><A NAME="graph.pmstyle api">Graph.pm-style API</A></H2>
- <P>You might ask, ``But what if I just want to add a few points to the graph,
- and then display it, without all those references to references?''. Well,
- friend, the solution is simple. Borrowing the add_pt idea from Matt
- Kruse's Graph module, you simply make a few calls to the add_pt method,
- like so:</P>
- <PRE>
- $obj->add_pt ('foo', 30, 25);
- $obj->add_pt ('bar', 16, 32);</PRE>
- <P>Or, if you want to be able to add entire datasets, simply use the add_dataset
- method:</P>
- <PRE>
- $obj->add_dataset ('foo', 'bar');
- $obj->add_dataset (30, 16);
- $obj->add_dataset (25, 32);</PRE>
- <P>These methods check to make sure that the points and datasets you are
- adding are the same size as the ones already there. So, if you have
- two datasets currently stored, and try to add a data point with three
- different values, it will carp (per the Carp module) an error message.
- Similarly, if you try to add a dataset with 4 data points,
- and all the other datasets have 3 data points, it will carp an error
- message.</P>
- <P>Don't forget, when using this API, that I treat the first dataset as
- a series of x-tick labels. So, in the above examples, the graph would
- have two x-ticks, labeled 'foo' and 'bar', each with two data points.</P>
- <DL>
- <DT><STRONG><A NAME="item_Clearing_the_data">Clearing the data</A></STRONG><BR>
- <DD>
- A simple call to the clear_data method empties any values that may
- have been entered.
- <PRE>
- $obj->clear_data ();</PRE>
- <P></P>
- <DT><STRONG><A NAME="item_Getting_a_copy_of_the_data">Getting a copy of the data</A></STRONG><BR>
- <DD>
- If you want a copy of the data that has been added so far, make a call
- to the get_data method like so:
- <PRE>
- $dataref = $obj->get_data;</PRE>
- <P>It returns (you guessed it!) a reference to an array of references to
- datasets. So the x-tick labels would be stored as</P>
- <PRE>
- @x_labels = @{$dataref->[0]};</PRE>
- <P></P>
- <DT><STRONG>Sending the image to a file</STRONG><BR>
- <DD>
- If you just want to print this chart to a file, all you have to do
- is pass the name of the file to the <CODE>gif()</CODE> method.
- <PRE>
- $obj->gif ("foo.gif");</PRE>
- <P></P>
- <DT><STRONG><A NAME="item_Sending_the_image_to_a_filehandle">Sending the image to a filehandle</A></STRONG><BR>
- <DD>
- If you want to do something else with the image, you can also pass
- a filehandle (either a typeglob or a FileHandle object) to gif, and
- it will print directly to that.
- <PRE>
- $obj->gif ($filehandle);
- $obj->gif (FILEHANDLE);</PRE>
- <P></P>
- <DT><STRONG>CGI and Chart</STRONG><BR>
- <DD>
- Okay, so you're probably thinking (again), ``Do I always have to save these
- images to disk? What if I want to use Chart to create dynamic images for
- my web site?'' Well, here's the answer to that.
- <PRE>
- $obj->cgi_gif ();</PRE>
- <P>The cgi_gif method will print the chart, along with the appropriate http
- header, to stdout, allowing you to call chart-generating scripts directly
- from your html pages (ie. with a <img src=image.pl> HTML tag).</P>
- <P></P></DL>
- <P>
- <H2><A NAME="imagemap support">Imagemap Support</A></H2>
- <P>Chart can also return the pixel positioning information so that you can
- create image maps from the gifs Chart generates. Simply set the 'imagemap'
- option to 'true' before you generate the gif, then call the <CODE>imagemap_dump()</CODE>
- method afterwards to retrieve the information. You will be returned a
- data structure almost identical to the @data array described above to pass
- the data into Chart.</P>
- <PRE>
- $imagemap_data = $obj->imagemap_dump ();</PRE>
- <P>Instead of single data values, you will be passed references to arrays
- of pixel information. For Bars and StackedBars charts, the arrays will
- contain two x-y pairs (specifying the upper left and lower right corner
- of the bar), like so</P>
- <PRE>
- ( $x1, $y1, $x2, $y2 ) = @{ $imagemap_data->[$dataset][$datapoint] };</PRE>
- <P>For Lines, Points, and LinesPoints, the arrays will contain a single
- x-y pair (specifying the center of the point), like so</P>
- <PRE>
- ( $x, $y ) = @{ $imagemap_data->[$dataset][$datapoint] };</PRE>
- <P>A few caveats apply here. First of all, GD treats the upper-left corner
- of the gif as the (0,0) point, so positive y values are measured from the
- top of the gif, not the bottom. Second, these values will most likely
- contain long decimal values. GD, of course, has to truncate these to
- single pixel values. Since I don't know how GD does it, I can't truncate
- it the same way he does. In a worst-case scenario, this will result in
- an error of one pixel on your imagemap. If this is really an issue, your
- only option is to either experiment with it, or to contact Lincoln Stein
- and ask him. Third, please remember that the 0th dataset will be empty,
- since that's the place in the @data array for the data point labels.</P>
- <P>
- <HR>
- <H1><A NAME="to do">TO DO</A></H1>
- <UL>
- <LI>
- Numeric x-axes.
- <P></P>
- <LI>
- Add some 3-D graphs.
- <P></P></UL>
- <P>
- <HR>
- <H1><A NAME="bugs">BUGS</A></H1>
- <P>Probably quite a few, since it's been completely rewritten. As usual,
- please mail me with any bugs, patches, suggestions, comments, flames,
- death threats, etc.</P>
- <P>
- <HR>
- <H1><A NAME="author">AUTHOR</A></H1>
- <P>David Bonner (<A HREF="mailto:dbonner@cs.bu.edu">dbonner@cs.bu.edu</A>)</P>
- <P>
- <HR>
- <H1><A NAME="maintainer">MAINTAINER</A></H1>
- <P>Peter Clark (<A HREF="mailto:ninjaz@webexpress.com">ninjaz@webexpress.com</A>)</P>
- <P>
- <HR>
- <H1><A NAME="copyright">COPYRIGHT</A></H1>
- <P><CODE>Copyright(c)</CODE> 1997-1998 by David Bonner, 1999 by Peter Clark
- All rights reserved. This program is free software; you can
- redistribute it and/or modify it under the same terms as Perl
- itself.</P>
- <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
- <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
- <STRONG><P CLASS=block> Chart - a series of charting modules</P></STRONG>
- </TD></TR>
- </TABLE>
-
- </BODY>
-
- </HTML>
-