PostScript-Graph

 view release on metacpan or  search on metacpan

Graph/XY.pm  view on Meta::CPAN

C<options> may be either a list of hash keys and values or a hash reference.  Either way, the hash should have the
same structure - made up of keys to several sub-hashes.  Only one (chart) holds options for this module.  The
other sections are passed on to the appropriate module as it is created.

    Hash Key	Module
    ========	======
    file	PostScript::File
    layout	PostScript::Graph::Paper
    x_axis	PostScript::Graph::Paper
    y_axis	PostScript::Graph::Paper
    style	PostScript::Graph::Style
    key		PostScript::Graph::Key
    chart	this one, see below 

=head3 data

This may be either an array or the name of a CSV file.  See B<line_from_array> or B<line_from_file> for details.
If data is given here, the chart is built automatically.  There is no opportunity to add extra lines (they should
be included in this data) but there is no need to call B<build_chart> explicitly as the chart is ready for output.

=head3 show_key

Set to 0 if key panel is not required.  (Default: 1)

=head3 show_lines

Set to 0 to hide lines and make a scatter graph.  (Default: 1)

=head3 show_points

Set to 0 to hide points.  (Default: 1)

All the settings are optional and the defaults work reasonably well.  See the other PostScript manpages for
details of their options.

=head1 OBJECT METHODS

=cut

sub line_from_array {
    my $o = shift;
    my ($data, $style, $opts, $label);
    foreach my $arg (@_) {
	$_ = ref($arg);
	CASE: {
	    if (/ARRAY/)                    { $data  = $arg; last CASE; }
	    if (/HASH/)                     { $opts  = $arg; last CASE; }
	    if (/PostScript::Graph::Style/) { $style = $arg; last CASE; }
	    $label = $arg;
	}
    }
    die "add_line() requires an array\nStopped"  unless (defined $data);
    $o->{ylabel} = $label                        unless (defined $o->{ylabel});
    
    ## create style object
    $opts = $o->{opt}{style}                     unless (defined $opts);
    $opts->{line} = {}				 unless (defined $opts->{line});
    $opts->{point} = {}				 unless (defined $opts->{point});
    $style = new PostScript::Graph::Style($opts) unless (defined $style); 
    
    ## split multi-columns into seperate lines
    my $name = $o->{default}++;
    my ($first, @rest) = split_data($data);
    foreach my $column (@rest) {
	$o->line_from_array($column, $opts);
    }
    
    ## identify axis titles
    $o->{line}{$name}{xtitle} = "";
    my $line = $o->{line}{$name};
    $line->{ytitle} = $label || "";
    $line->{style} = $style;
   
    my $number = qr/^\s*[-+]?[0-9.]+(?:[Ee][-+]?[0-9.]+)?\s*$/;
    unless ($first->[0][1] =~ $number) {
	my $row = shift(@$first);
	$line->{xtitle} = $$row[0];
	$line->{ytitle} = $$row[1];
    }
    $o->{ylabel} = $line->{ytitle} unless (defined $o->{ylabel});
    
    ## find min and max for each axis
    my @coords;
    my ($xmin, $ymin, $xmax, $ymax);
    foreach my $row (@$first) {
	my ($x, $y) = @$row;
	if ($x =~ $number) {
	    $xmin = $x if (not defined($xmin) or $x < $xmin);
	    $xmax = $x if (not defined($xmax) or $x > $xmax);
	}
	if ($y =~ $number) {
	    $ymin = $y if (not defined($ymin) or $y < $ymin);
	    $ymax = $y if (not defined($ymax) or $y > $ymax);
	}
    }
    $line->{data} = $first;
    $line->{last} = 2 * ($#$first + 1) - 1;
    $line->{xmin} = $xmin;
    $line->{xmax} = $xmax;
    $line->{ymin} = $ymin;
    $line->{ymax} = $ymax;
}

=head2 line_from_array( data [, label | opts | style ]... )

=over 8

=item data

An array reference pointing to a list of positions.  

=item label

A string to represent this line in the Key.

=item opts

This should be a hash reference containing keys and values suitable for a PostScript::Graph::Style object.  If present,
the object is created with the options specified.

=item style



( run in 3.496 seconds using v1.01-cache-2.11-cpan-71847e10f99 )