NAME

PostScript::Graph::Bar - draw a bar chart on a postscript file

SYNOPSIS

Simplest

Take labels and values from a csv file and output as a bar chart on a postscript file.

use PostScript::Graph::Bar;

my $bar = new PostScript::Graph::Bar();
$bar->build_chart("survey.csv");
$bar->output("survey");

Typical

    use PostScript::Graph::Bar;

    my $bar = new PostScript::Graph::Bar(
	    file   => {
		paper      => 'A4',
		landscape  => 1,
	    },
	    layout => {
		background => [1, 1, 0.9],
		heading    => 'Test results',
	    },
	    y_axis => {
		smallest   => 4,
	    },
	    style  => {
		auto       => [qw(green blue red)],
	    }
	);

    $bar->series_from_file( 'data.csv' );
    $bar->build_chart();
    $bar->output( 'results' );

The file 'data.csv' has a row of headings followed by 4 rows of 10 items. This produces a bar chart with four groups of ten bars each. The groups are labelled with the first value in each row. The bars in each group are coloured ranging from brown through green and then shades of blue. A Key links the row of headings to each colour. In addition, the background is beige, a heading is placed above the chart and the y axis is not too crowded.

All options

    use PostScript::Graph::Bar;

    my $bar = new PostScript::Graph::Bar(
	file   => {
	    # Paper size, orientation etc
	    # See PostScript::File
	},
	layout => {
	    # General proportions, headings
	    # See PostScript::Graph::Paper
	},
	x_axis => {
	    # All settings for X axis
	    # See PostScript::Graph::Paper
	},
	y_axis => {
	    # All settings for Y axis
	    # See PostScript::Graph::Paper
	},
	style  => {
	    # Appearance of bars
	    # See PostScript::Graph::Style
	},
	key    => {
	    # Settings for any Key area
	    # See PostScript::Graph::Key
	},
	show_key   => 1,
	labels_row => 1,
    );
    

DESCRIPTION

This is a top level module in the PostScript::Graph series. It produces bar charts from CSV files. There are three basic variants, depending on the structure of the data.

Independent values

A CSV file with just a label and a single value on each line produces the most basic form of bar chart. All the bars are the same colour, all standing alone.

File 1

Months,	Sales
March,	671
April,	944
May,	867
June,	851

If the first entry in the second column cannot be interpreted as a number it is assumed that the first line of data contains headings for each column. The first column heading becomes the X axis title and the second column heading goes into the Key box alongside the colour of the bars.

Multiple series

The CSV file can have more than one column of values. The columns for each row are shown as different coloured bars next to each other. There is then a gap and data for the next row is displayed using the same sequence of coloured bars. The following data would be shown as four groups with two bars in each.

File 2

Months, Joe,    Jim
March,  344,    327
April,  489,    455
May,    437,    430
June,   369,    482

The groups (months) are labelled across the X axis and each comprise a column for Joe and a column for Jim. A Key shows which coloured bar represents each salesman.

Single series

If the CSV file is just a row of numbers, this is interpreted as a single series, so each number is represented as a different coloured bar, and the bars are adjacent to each other. A Key shows the labels associated with each colour. These can either come from the first line of data or passed as a seperate array.

File 3

Months, March,  April,  May,    June
Sales,  671,    1044,   867,    2851

Additional data

Series

It is possible to have several series_from_file calls, each adding more data. The simplest case is where the labels shown across the X axis (rows in the file) are the same for all data sets. Each new set just adds an additional series to the labels.

Example 1

use PostScript::Graph::Bar;
my $b = new PostScript::Graph::Bar();

$b->series_from_file( "joe_sales.csv" );
$b->series_from_file( "jim_sales.csv" );

Each file here would be just two columns like File 1. But the end result would be the same as for File 2.

Labels

Data can also be extended by adding more items (labels) within a series. Care should be taken with this, as any duplicate data will be overwritten.

File 4

Months, Joe,    Jim
July,   392,    404
August, 401,    438

Example 2

my $b = new PostScript::Graph::Bar();

$b->series_from_file( "file_2.csv" );
$b->series_from_file( "file_4.csv", 0 );

The sales data for both Joe and Jim would now cover months March to August. Note that the new_series flag must be set to '0' for this behaviour.

Both

If the new_series flag is not 0, the new data is added as new series, regardless of whether series with the same name already exist. It is possible for new labels to be added at the same time. Of course this means that some data slots will have no value and these are just set to zero.

File 5

Months, Fred
June,   288
July,   302
August, 378
Sept,   421

Example 3

my $b = new PostScript::Graph::Bar();

$b->series_from_file( "file_2.csv" );
$b->series_from_file( "file_4.csv", 0 );
$b->series_from_file( "file_5.csv" );

The data would now be as follows:

Months, Joe,    Jim,    Fred
March,  344,    327,    0
April,  489,    455,    0
May,    437,    430,    0
June,   369,    482,    288    
July,   392,    404,    302
August, 401,    438,    378
Sept,   0,	    0,	    421

Styles

Each series has a PostScript::Graph::Style object associated with it, managing the colour, outline and so on. These objects are created with different values by default, and how these vary is controlled by a StyleSequence. This allows the colours to be controlled as closely (or as loosely) as you like. Each colour could be set up seperately as in Example 4, or they could be generated as in Example 5. See PostScript::Graph::Style for all the style settings.

Example 4

    use PostScript::Graph::Style;
    my $s1 = new PostScript::Graph::Style(
	    auto => 'none',
	    bar => {
		color => [0.5, 0.2, 0.3],
	    },
	);

Example 5

    use PostScript::Graph::Style;
    my $seq = new StyleSequence;
    $seq->setup('red',   [0.5, 0.9]);
    $seq->setup('green', [0.2, 0.8]);
    $seq->setup('blue',  [0.3]);
    
    my $opts = { sequence => $seq,
		 auto => [ 'red', 'green' ],
		 bar => {} };
    
    my $s1 = new PostScript::Graph::Style($opts);
    my $s2 = new PostScript::Graph::Style($opts);
    my $s3 = new PostScript::Graph::Style($opts);
    my $s4 = new PostScript::Graph::Style($opts);

The fill colour for each style would be as follows.

$s1	    [0.5, 0.2, 0.3]	a dull dark red
$s2	    [0.9, 0.2, 0.3]	a bright red
$s3	    [0.5, 0.8, 0.3]	an orange yellow
$s4	    [0.9, 0.8, 0.3]	light orange cream

These could then be used to specify colours for each data series added to the chart.

Example 6

my $b = new PostScript::Graph::Bar();

$b->series_from_file( "joe.csv",  $s1 );
$b->series_from_file( "jim.csv",  $s2 );
$b->series_from_file( "fred.csv", $s3 );
$b->series_from_file( "alan.csv", $s4 );

CONSTRUCTOR

new( [options] )

options can either be a list of hash keys and values or a hash reference, or omitted altogether. In either case, the hash is expected to have the same structure. A couple of the primary keys are simple values but most point to sub-hashes which hold options or groups themselves. See the All options section of "SYNOPSIS" for the complete structure.

All color options can take either monochrome or colour format values. If a single number from 0 to 1.0 inclusive, this is interpreted as a shade of grey, with 0 being black and 1 being white. Alternatively an array ref holding three such values is read as holding red, green and blue values - again 1 is the brightest possible value.

Value	    Interpretation
=====	    ==============
0		    black
0.5		    grey
1		    white
[1, 0, 0]	    red
[0, 1, 0]	    green
[0, 0, 1]       blue
[1, 1, 0.9]	    light cream
[0, 0.8, 0.6]   turquoise

Other numbers are floating point values in PostScript native units (72 per inch).

file

This may be either a PostScript::File object or a hash ref holding options for it. See PostScript::File for details. Options within this group include the paper size, orientation, debugging features and whether it is an EPS or a normal PostScript file.

labels_row

Although an attempt is made to automatically detect labels in the top row of each CSV file, it sometimes fails. Giving a value here forces the module to either use (1) or not use (0) the first row for labels instead of data. (Default: undefined)

layout

See "layout" in PostScript::Graph::Paper for the options controlling how the various parts of the chart are laid out.

x_axis

See "x_axis" in PostScript::Graph::Paper for configuring the X axis sizes, font etc.

y_axis

See "y_axis" in PostScript::Graph::Paper for configuring the appearance of the Y axis.

key

See PostScript::Graph::Key for configuring the appearance of the Key showing what the colours mean.

show_key

If set to 0, the Key is hidden. (Default: 1)

style

The settings given here control how the colours for each series are generated. See "Styles" and PostScript::Graph::Styles for further information.

OBJECT METHODS

series_from_array( data [, style | labels | new_series ]... )

data

An array ref pointing to a list of array refs. Each sub-array hold the data for one CSV row - a list comprising one label followed by one or more numbers.

style

An optional hash ref. This should contain settings for the PostScript::Graph::Style objects which will be associated with each column of data. If present, the whole hash ref overrides any 'style' hash ref given to new.

labels

An optional array ref. This list of series names will appear in the Key, replacing the column headings, if given, as the first data line.

new_series

A flag indicating whether the columns constitute new series to be added. Set to 0 to force merging of data with existing series of the same name. (Default: 1)

Add one or more series of data to whatever is already collected. This can be used in place of series_from_file, which is merely a useful front end for it.

Example

    my $b = new PostScript::Graph::Bar();
    $b->series_from_array( 
	    [ [ March,  344, 327 ],
	      [ April,  489, 455 ],
	      [ May,    437, 430 ],
	      [ June,   369, 482 ], ],
	    { auto => ['red'] },
	    [ 'Joe', 'Jim' ],
      );

series_from_file( file [, style | labels | new_series ]... )

Read in the named CSV file then pass it and any other arguments to series_from_array.

build_chart([ data | file [, style | labels | new_series ]... ])

The optional arguments are passed direct to series_from_array or series_from_file depending on whether the first is an array ref. This just provides a convenient way of providing a single data set.

If a PostScript::File object has not been given to new, it is created along with the PostScript::Graph::Paper and PostScript::Graph::Key objects. The postscript code to draw these is generated with bars and key entries superimposed.

SUPPORTING METHODS

file

Return the underlying PostScript::File object.

graph_key

Return the underlying PostScript::Graph::Key object. Only available after a call to build_chart.

graph_paper

Return the underlying PostScript::Graph::Paper object. Only available after a call to build_chart.

sequence()

Return the style sequence being used. This is only required when you wish to alter the ranges used by the auto style feature.

output( file [, dir] )

Output the chart as a file. See "output" in PostScript::File.

newpage( [page] )

Start a new page in the underlying PostScript::File object. See "newpage" in PostScript::File and "set_page_label" in PostScript::File.

add_function( name, code )

Add functions to the underlying PostScript::File object. See "add_function" in PostScript::File for details.

add_to_page( [page], code )

Add postscript code to the underlying PostScript::File object. See "add_to_page" in PostScript::File for details.

BUGS

When reading from a CSV file, the first line is only recognized as a label line if both the first and SECOND entries are unable to be read as a number. Putting quotes around them no longer works.

AUTHOR

Chris Willmot, chris@willmot.co.uk

SEE ALSO

PostScript::File, PostScript::Graph::Style, PostScript::Graph::Key, PostScript::Graph::Paper, PostScript::Graph::XY, Finance::Shares::Chart.