# $Id: Line.pm 6839 2000-05-05 21:32:07Z rousskov $ package ReportGen::Line; use strict; # # Wrapper for gnuplot-like plot "lines" # # order must match what plotter expects my @DataOpts = qw( index every thru using smooth ); my @KnownOptions = ( @DataOpts, qw(axes title with) ); sub new { my ($proto) = @_; my $type = ref($proto) || $proto; my $this = bless({}, $type); $this -> {theData} = ''; $this -> {theOpt} = {}; $this -> {theLineCount} = undef; # cache return $this; } sub clone { my ($this) = @_; my $clone = bless({}, ref($this)); $clone -> {theData} = $this -> {theData}; $clone -> {theOpt} = { map { $_ => $this -> {theOpt} -> {$_} } keys %{$this -> {theOpt}} }; $clone -> {theLineCount} = $this -> {theLineCount}; return $clone; } sub data { my ($this, $d) = @_; $this -> {theData} = $d; $this -> {theLineCount} = undef; } sub image { my ($this) = @_; my $image = ''; my $data = $this -> {theData} || ''; if ($data =~ /^\S*\(/) { # a function $image .= $data; } else { $image .= "\"$data\""; } $image .= ' '; foreach (@KnownOptions) { my $opt = $this->{theOpt}->{$_}; $image .= " $_ $opt" if $opt; $image .= " no$_" if defined $opt && $opt eq ''; } return $image; } sub using { my ($this, @fields) = @_; $this->{theOpt}->{'using'} = join(':', map { "($_)" } @fields); } sub title { my ($this, $title) = @_; $this->{theOpt}->{'title'} = sprintf('"%s"', $title) if defined $title; } # pipes already set data through a given filter # %y in the filter string is replaced with y-column number from 'using' sub filter { my ($this, $filter) = @_; my $y = $this->ycolumn(); $filter =~ s/\%y/$y/g; if ($this->{theData} =~ /^</) { # already a pipe $this->data($this->{theData} . "| $filter"); } else { $this->data("<$filter < " . $this->{theData}); } } sub ycolumn { my $this = shift; my $opt = $this->{theOpt}->{'using'}; die("line->ycolumn called for a line with no 'using' option") unless $opt; my @columns = split /:/, $opt; die("cannot parse 'using' option in '$opt'") unless @columns; my $res = defined $columns[1] ? $columns[1] : $columns[0]; $res =~ s/^\(|\)$//g; die("y-column specs are too complex in $res\n") unless $res =~ /^\d+$/; return $res; } sub lineCount { my $this = shift; my $cmd = $this->{theData}; die("lineCount called for the line with no data!") unless $cmd; my ($lc) = ($cmd =~ s/^<//) ? (`$cmd | wc -l` =~ /\b(\d+)\b/) : (`wc -l $cmd` =~ /\b(\d+)\b/); die("failed to count lines in $cmd") unless $lc; $this->{theLineCount} = $lc; return $lc; } use vars qw($AUTOLOAD); sub AUTOLOAD { my $this = shift; my $A = $AUTOLOAD; $A =~ s/ReportGen::Line:://; return undef if $A eq 'DESTROY'; my $opt = lc $A; die("unknown line option '$A', stopped") unless grep { /^$opt$/ } @KnownOptions; # die("no args for line option '$A', stopped") unless @_; $this -> {theOpt} -> {$opt} = @_ ? join(' ', @_) : undef(); } 1;