NAME
PostScript::Graph::Paper - prepare blank graph for a postscript file
SYNOPSIS
Simplest
Let the module create its own postscript file:
use PostScript::Graph::Paper;
my $pg = new PostScript::Graph::Paper(
file => { landscape => 1 },
layout => { title => "Blank grid" } );
$pg->output("testfile");
Typical
Add the chart to an existing postscript file:
use PostScript::Graph::Paper;
use PostScript::File;
my $ps = new PostScript::File(
left => 40,
right => 40,
top => 30,
bottom => 30,
landscape => 1,
errors => 1 );
new PostScript::Graph::Paper(
file => $ps,
layout => { title =>
"Experimental results" },
x_axis => { high => 10,
title =>
"Control variable" },
y_axis => { low => 23.6,
high => 24.95,
title =>
"Dependent variable" });
$ps->output("testfile");
Create a bar chart layout:
use PostScript::Graph::Paper;
new PostScript::Graph::Paper(
layout => { title =>
"Survey" },
x_axis => { labels => [
"Men", "Women",
"Boys", "Girls", ], },
y_axis => { low => 8,
high => 37, } );
$ps->output("testfile");
All options
new PostScript::Graph::Paper(
file => $ps_file,
layout => {
bottom_edge => 30,
top_edge => 30,
left_edge => 30,
right_edge => 30,
spacing => 4,
top_margin => 10,
right_margin => 10,
key_width => 0,
sub_divisions => 4,
dots_per_inch => 600,
font => 'Helvetica',
font_color => 0,
font_size => 10,
heading => 'My Graph',
heading_font => 'Times-Bold',
heading_font_color => 0.9,
heading_font_size => 20,
heading_height => 30,
background => [ 0.9, 0.95, 0.85 ],
color => [ 0, 0, 0.7 ],
heavy_color => [0, 0, 0.4],
mid_color => [0.6, 0.6, 1],
light_color => 0.8,
heavy_width => 1,
mid_width => 0.8,
light_width => 0.25,
no_drawing => 0,
},
x_axis => {
low => 74.25,
high => 74.9,
width => 200,
height => 450,
label_gap => 50,
labels => [qw(this that other)],
labels_req => 7,
font => 'Helvetica',
font_color => 0,
font_size => 10,
title => 'X axis',
color => 0.5,
heavy_color => [0, 0, 0.4],
mid_color => [0.6, 0.6, 1],
light_color => 0.8,
heavy_width => 1,
mid_width => 0.8,
light_width => 0.25,
mark_min => 2,
mark_max => 8,
smallest => 8,
center => 1,
offset => 1,
rotate => 1,
draw_fn => "myxdraw",
},
y_axis => {
# as x_axis
},
);
DESCRIPTION
This module is designed as a supporting part of the PostScript::Graph suite. For top level modules that output something useful, see
PostScript::Graph::Bar
PostScript::Graph::Stock
PostScript::Graph::XY
An area of graph paper is created on a postscript page. X and Y axes are labelled and there are facilities to add a title and key. This is written to a PostScript::File object (automatically created if not supplied) which can then be output. It is intended to be a static object - once the parameters are set there is little point in changing them - so all options are set in the contructor.
CONSTRUCTOR
new( [options] )
The labelling and layout of the graph is quite flexible, but that level of control inevitably requires many options. If no options are given, graph paper labelled 0 to 100 along each axis fills an A4 page (apart from a half-inch border all round). It is up to the user how much this is altered. Either labels or high and low values will probably need to be given for each axis, with titles, a heading and perhaps some space for a key.
options
can either be a list of hash keys and values or a hash reference. In either case, the hash is expected to have the same structure. There are a few primary keys, each of which point to sub-hashes which hold options for that group.
For every option listed here there is a corresponding function returning its value. For example, the label printed at the top of the y axis is set with the option x_axis =
{ title => '...' }>. x_axis_title()
would return the string given and the option would be documented as axis_title
.
Example 1
my $gp = new PostScript::Graph::Paper(
layout => {
title => "Bar chart",
right_edge => 500,
key_width => 100,
},
x_axis => {
labels => [ "First bar",
"Second bar",
"Third bar" ],
},
y_axis => {
low => 123,
high => 456.7,
title => "Readings",
},
);
This would prepare graph paper for a
bar chart with 3 vertical bars and a key.
Example 2
my $gp = new PostScript::Graph::Paper(
file => {
landscape => 1,
errors => 1,
},
layout => {
font_color => 1,
heading_height => 0,
left_axis_font_size => 0,
bottom_axis_height => 0,
left_axis_width => 0,
mark_min => 0,
mark_max => 0,
},
x_axis => {
smallest => 72,
},
y_axis => {
smallest => 72,
},
);
This fills an A4 page with a plain grid of
squares no smaller than 1 inch big, with
no axes, marks, labels, heading or key.
PostScript Options
The PostScript::File object which recieves the grid may either be an existing one or the module can create one for you. Use file
to declare a pre-existing object, or file
to control how the new one is created.
file
This may be either a PostScript::File object or a options in hash key/value format. If options are given, a new PostScript::File object is created.
Example 1
$psf = new PostScript::File();
$pg = new PostScript::Graph::Paper(
file => $psf );
Then $psf == $pg->file();
Example 2
my $ch = new PostScript::Graph::Paper(
file => {
landscape => 1,
clipping => 1,
clipcmd => "stroke",
debug => 2,
errors => 1,
} );
Chart Options
These are all set within a layout
option given to the constructor. Remove the initial layout_
to get the option name. All values are in PostScript native units (72 = 1 inch).
Example
$pg = new PostScript::Graph::Paper(
layout => { right_edge => 600,
heavy_color => [0, 0, 0.8],
light_color => 0.6,
font => "Courier",
title_font_size => 14,
right_margin => 20,
spacing => 4 } );
$pg->layout_font() would return "Courier".
layout_bottom_edge
The bottom boundary of the whole chart area.
layout_background
Background color.
layout_color
Default colour for all grid lines. All colours can be either a greyscale value or an array of RGB values. All values vary from 0 = black to 1 = brightest. (Default: 0.5)
Example
layout => { background => [ 0.95, 0.95, 0.85 ],
color => [ 0, 0.2, 0.8 ],
light_color => 0.85 }
Grid lines will be a blue shade on a beige background,
except the lightest lines which will be light grey.
layout_dots_per_inch
Marks are spaced at a multiple of this value. If this does not match the physical output device, the appearance can be somewhat ragged. (Default: 300)
layout_font
Default font for everything except titles. (Default: "Helvetica")
layout_font_color
Default colour for all fonts. (Default: 0)
layout_font_size
Default font size for everything except the title font. (Default: 10)
layout_heading
The title above the grid. (Default: "")
layout_heading_font
Font for the main heading above the graph. (Default: "Helvetica-Bold")
layout_heading_font_color
Colour for main heading. (Defaults to font_color
)
layout_heading_font_size
Size for main heading. (Default: 12)
layout_heading_height
Size of area above the graph holding the main title and the y axis title. (Defaults to just enough space)
layout_heavy_color
The colour of the major, labelled, lines. (Defaults to color
)
layout_heavy_width
Width of the labelled lines. (Default: 0.75)
layout_key_width
Width of box at the right of the graph, allocated for the key. If this is 0, no key box is drawn. (Default: 0)
The key is drawn by a seperate PostScript::Graph::Key object. This merely allocates space within the chart edges.
layout_left_edge
The left boundary of the whole paper area.
layout_light_color
Colour of the minor, unlabelled, lines. (Defaults to color
)
layout_light_width
Width of the lightest lines. (Default: 0.25)
layout_mid_color
A scale of 10 will be divided into two lots of 5 seperated by a slightly heavier line at the 5 mark. This is the 'mid' line. (Defaults to color
)
layout_mid_width
Width of the mid-lines, see </mid_color>. (Default: 0.75)
no_drawing
If true, the call to draw_scales
is not carried out in the constructor, allowing some tinkering with labels etc. before comitting to postscript. The only way to do this is to access the objects data directly. Use with caution. (Default: 0)
layout_right_edge
The right boundary of the whole chart area.
layout_right_margin
Space at the right hand side of the graph area, taken up by part of the last label. (Default: 15)
layout_spacing
Increasing this value seperates out the various parts of the chart, like leading added to text. (Default: 0)
layout_sub_divisons
Used by PostScript::Graph::Bar to signal the number of series per label. Not appropriate for anything else.
layout_top_edge
The top boundary of the whole chart area.
layout_top_margin
Space above the graph area taken up by part of the topmost y label. (Default: 5)
Axis Options
The axis_
entries below refer to four things: x_axis and y_axis options and x_axis_ and y_axis_ functions which return those values. Remove the axis_
prefix to get the option name, and prepend x_
or y_
to get the relevant function name. The options belong within hashes indexed by either x_axis
or y_axis
.
Example
Options documentated as:
axis_low
axis_high
Would be set by:
$pg = new PostScript::Graph::Paper(
x_axis => { low => 1,
high => 12,
},
y_axis => { low => 247,
high => 980,
} );
And inspected by:
$pg->x_axis_low() == 1
$pg->x_axis_high() == 14
$pg->y_axis_low() == 200
$pg->y_axis_high() == 1000
Note that the original values have been
adjusted as the scales were calculated.
axis_center
By default, any labels given to axis_labels
are placed centrally between the lines. Setting this to 0 puts the labels in the normal 'number' position, next to the major lines.
axis_color
Colour for grid lines on one axis. See "layout_color". (Defaults to layout_color
).
axis_draw_fn
The string given here should be the name of a PostScript function which will draw the axis, lines and labels. See the code for the /xdraw
and /ydraw
functions which provide the defaults.
axis_font
Font for labels and title on the axis. (Defaults to font
)
axis_font_color
Colour for axis title and labels. (Defaults to font_color
)
axis_font_size
Size for title and labels on the axis. (Defaults to font_size
)
axis_heavy_color
The colour of the major, labelled, lines. (Defaults to layout_heavy_color
)
axis_heavy_width
Width of the labelled lines. (Defaults to layout_heavy_width
)
axis_height
For x: space beneath the x axis. (Defaults to just enough space for the labels and x axis title)
For y: should not be changed. (Defaults to full height of chart area, baring top and bottom space)
axis_high
The highest number required to appear on the axis. This will be rounded up to suit the chosen scale. (Default: 100)
axis_label_gap
The space between the start of each label. The effect is for the program to choose more or fewer labels on the x axis. Although available to the y axis, the spacing between labels is rarely an issue. (Default: 30)
axis_labels
This should be a reference to a list of strings. If a list of labels is provided, the axes uses these, ignoring axis_high
and axis_low
.
The functions x_axis_labels
and y_axis_labels
are unusual in that they set as well as return their value. Note that any alterations made after new
and before draw_scales
, must have all strings enclosed in '()' for postscript. The number of labels must NOT be changed.
axis_labels_req
An indication of the number of major (labelled) marks wanted along the axis. The program overrides this if it is not suitable. (Default derived from axis_label_gap
)
axis_light_color
Colour of the minor, unlabelled, lines. (Defaults to layout_light_color
)
axis_light_width
Width of the lightest lines. (Defaults to layout_light_width
)
axis_low
The lowest number required to appear on the axis. This will be rounded down to suit the chosen scale. (Default: 0)
axis_mid_color
A scale of 10 will be divided into two lots of 5 seperated by a slightly heavier line at the 5 mark. This is the 'mid' line. (Defaults to layout_mid_color
)
axis_mid_width
Width of the mid-lines, see </axis_mid_color>. (Defaults to layout_mid_width
)
axis_mark_gap
The gap between smallest marks. This is a calculated value and cannot be set, although it may be controlled with axis_smallest.
axis_mark_min
The smallest mark on the axis. (Defaults to layout_mark_min
)
axis_mark_max
The tallest mark on the axis. (defaults to layout_mark_max
)
axis_rotate
Setting this to 1 rotates the axis labels 90 degrees right. (Defaults to 1 on the x axis when labels are provided, 0 otherwise)
axis_smallest
This is the smallest allowable gap between axis marks. Setting this controls how many subdivisions the program generates. It would be wise to set this as a multiple of layout_dots_per_inch
. (Defaults to 3 dots)
axis_si_shift
The number of 0's removed at a time when adjusting the axis labels, e.g. 3 for thousands, 2 for hundreds or 0 for no adjustment. (Default: 3)
axis_title
The text printed at the top of the y axis and below the right of the x axis. (Default: "")
axis_width
For x: should not be changed. (Defaults to width between y axis and key area)
For y: width allocated for y axis marks and labels. (Default: 36)
OBJECT METHODS
Methods are provided which access the option values given to the constructor. Those are file, and all layout_, x_axis_ and y_axis_ methods documented under "CONSTRUCTOR".
The most common PostScript::File methods are also provided as members of this class.
However, the most useful methods are those which give access to the layout calculations including conversion functions.
Convenience methods
A few methods of the underlying PostScript::File object are provided for convenience. The others can be called via the file() function. The following both do the same thing.
$pg->newpage();
$pg->file()->newpage();
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.
Result methods
These fall into three groups according to their return value. _area methods return an array of four values representing the physical coordinates of (left, bottom, right, top). _point methods return an array again, but this time representing an (x, y) value. The underlying constants are also accessable.
graph_area
Return an array holding (x0, y0, x1, y1), the bounding box of the graph area.
key_area
Return an array holding (x0, y0, x1, y1), the bounding box of the area allocated for the key, if any.
vertical_bar_area
Return the physical coordinates of a barchart bar. Use as:
@area = vertical_bar_area( $bar )
@area = vertical_bar_area( $bar, $y )
Where $bar
is the 0 based number of the bar and $y
is an optional coordinate indicating the top of the bar.
horizontal_bar_area
Return the physical coordinates of a barchart bar. Use as:
@area = horizontal_bar_area( $bar )
@area = horizontal_bar_area( $bar, $x )
Where $bar
is the 0 based number of the bar and $x
is an optional coordinate indicating the 'top' of the bar.
physical_point( x, y )
Return the physical, native postscript, coordinates corresponding to the logical point (x, y) on the graph.
logical_point( px, py )
Return the logical, graph, coordinates corresponding to a point on the postscript page.
px
Use as physical_x = $gp->ps( logical_x )
py
Use as physical_y = $gp->ps( logical_y )
lx
Use as logical_x = $gp->ps( physical_x )
py
Use as logical_y = $gp->ps( physical_y )
POSTSCRIPT CODE
There should be no reason to access this under normal use. However, as the purpose of this module is to make drawing graphs for postscript easier. Therefore the main graph-drawing function is documented here, along with the variables and functions that may be useful elsewhere.
drawgpaper
The principal function requires 62 settings. To make this more manageable there are a number of functions which merely accept and store a small group of these. After these have been executed, drawgpaper is then called with no parameters.
Usage is given below with the functions indented after their parameters. Each function remove all its parameters from the stack. All functions and variables are within the gpaperdict dictionary. It is written out as it would appear within a perl 'here' document, with perl variables for each parameter. The '/' in front of font names, and '()' around text are required by postscript.
gpaperdict begin
$graph_left
$graph_bottom
$graph_right
$graph_top
graph_area
$heavy_width
$heavy_color
$mid_width
$mid_color
$light_width
$light_color
graph_colors
$heading_left
$heading_bottom
$heading_right
$heading_top
heading_area
/$heading_font
$heading_font_size
$heading_font_color
($heading_text)
heading_labels
$x_axis_left
$x_axis_bottom
$x_axis_right
$x_axis_top
x_axis_area
$x_axis_mark_min
$x_axis_mark_multiplier
$x_axis_mark_max
$x_axis_mark_gap
xaxis_marks
$x_axis_factors_array_as_string
$x_axis_labels_array_as_string
$x_axis_label_depth
$x_axis_flags
/$x_axis_font
$x_axis_font_size
$x_axis_font_color
($x_axis_text)
xaxis_labels
$y_axis_left
$y_axis_bottom
$y_axis_right
$y_axis_top
y_axis_area
$y_axis_mark_min
$y_axis_mark_multiplier
$y_axis_mark_max
$y_axis_mark_gap
yaxis_marks
$y_axis_factors_array_as_string
$y_axis_labels_array_as_string
$y_axis_label_depth
$y_axis_flags
/$y_axis_font
$y_axis_font_size
$y_axis_font_color
($y_axis_text)
yaxis_labels
drawgpaper
end % gpaperdict
Most of these are self explanatory or relate to options documented elsewhere, but a few might need some explanation.
x_axis_flags
indicate how the labels are to be printed.
Bit Action if true
0 rotate text
1 centre text between marks
x_axis_labels_array_as_string
means a list of all the labels to be printed on the x axis, written out as a postscript array, such as:
"[ (label1) (label2) (label3) ]"
"[ 0 0.5 1 1.5 2 ]"
x_axis_factors_array_as_string
has the same format. However, the contents refer to the nesting of the axis marks. For example, the x axis goes from 400 to 800 in units of 100. Each 100 is subdivided into 2 and then 5, so the smallest divisions are worth 10 each. Labels are placed at the 100 and 50 marks. The factor array would be as follows.
[ 4 2 5 ]
x_axis_label_depth
would be 1 in the previous example (postscript arrays are zero based).
x_axis_mark_min
is the size of the smallest mark - the 10's above.
x_axis_mark_max
is the size of the largest mark - the 100's above.
x_axis_mark_multiplier
is the size added for each decreas in factor depth.
px
Convert a logical x value to a postscript x value. It is probably faster to use physical_point() to do any conversions and write postscript values into the postscript code. PostScript interpreters seem to use much slower processors.
py
Convert a logical y value to a postscript y value.
gpapercolor
Set the drawing color. This expects a single parameter which may be an array of RGB values or a grayscale value.
0.5 gpapercolor
[ 1 0.8 0 ] gpapercolor
gpaperfont
Select a font for subsequent text. It expects three parameters - a font name, size and colour. The font name should evaluate to a literal name as used by findfont
. The size is stored in the variable fontsize
for reference later, and the color is just passed to gpapercolor
.
/Helvetica 12 0 gpaperfont
/$fontname $fontsize [ $r $g $b ] gpaperfont
fillbox
Fill and outlines a box. Use as follows. The colours are passed to gpapercolor
.
$left $bottom $right $top
$fill_color
$outline_color $outline_width
fillbox
drawbox
Draw an unfilled box. Use as follows. The colours are passed to gpapercolor
.
$left $bottom $right $top
$outline_color $outline_width
drawbox
centered
Show text horizontally centred about the coordinated given. Use as:
$message $x $y centered
rjustify
Show right justified text, ending at the point given. Use as:
$message $x $y rjustified
rotated
Show text rotated 90 degrees right, starting at the point given. Use as:
$message $x $y rotated
copy_array
Do a deep copy of an array so that one can be changed without affecting the other. This works differently from the others. It requires an array, and exits leaving both copies on the stack. The variable array_max
is also set to the highest index allowed.
gpaperdict variables
Here are some of the variables in the gpaperdict dictionary which might need to be accessed directly.
array_max largest index into copied array
bgnd background colour for grid
boxc colour of box outline
boxw width of box outline
fillc fill colour of box
fontsize height of most recent gpaperfont
gx0 graph left (same as xx0)
gy0 graph bottom (same as yy0)
gx1 graph right (same as xx1)
gy1 graph top
hcol font colour used on heading
hfont font name used on heading
hsize font size used on heading
hx0 head left
hx1 head right
hy0 head bottom
hy1 head top
xlc constant for logical x
xlm multiplier for logical x
xmarkcen width for centering label
ylc constant for logical y
ylm multiplier for logical y
ymarkcen width for centering label
draw_scales()
Commits to postscript the settings collected and calculted by new
. Under normal circumstances this should not need to be called. It is only necessary if the layout option no_drawing
has been specified.
BUGS
Very likely. This is still alpha software and has been tested in fairly limited conditions.
AUTHOR
Chris Willmot, chris@willmot.org.uk
SEE ALSO
PostScript::File, PostScript::Graph::Style and PostScript::Graph::Key for the other modules in this suite.
PostScript::Graph::Bar, PostScript::Graph::XY and Finance::Shares::Chart for modules that use this one.