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


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,
    );

=head1 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 C<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 the PostScript::Graph::Style manpage 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 the PostScript::File manpage 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 the PostScript::Graph::Paper manpage for the options controlling how the various parts of the chart are laid out.

x_axis

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

y_axis

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

key

See the PostScript::Graph::Key manpage 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 the PostScript::Graph::Styles manpage 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 the PostScript::File manpage.

newpage( [page] )

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

add_function( name, code )

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

add_to_page( [page], code )

Add postscript code to the underlying PostScript::File object. See add_to_page in the PostScript::File manpage 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

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

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