#!/usr/bin/perl -w
require 5.003;
use strict;
# plots traces labeled with label_results
# see also: label_results, report_results
if (`pwd` =~ 'ReportGen') {
use lib '..';
}
use ReportGen::Opts;
use ReportGen::Globs;
use ReportGen::ObjDbase;
require ReportGen::Plot;
require ReportGen::Line;
# Configuration
my %Opts = (
out_name => undef(),
sort_by => undef(),
plot_title => undef(),
plotter_terminal => undef(),
plotter => undef(),
plotter_opts => undef(),
);
my %SavedOpts = %Opts;
# globals
my $Meas; # what measurement to plot
my $IFName;
my ($MeasPos, $MeasType);
my ($SortPos);
my (@LineLabels, @LineTypes, @LineNames);
my $LabelWidthMax = -10;
my $Plot;
&init();
exit(&main());
sub main {
&scanLineLabels();
$Plot = new ReportGen::Plot(join(' ', $0, @ARGV));
&setXLabel();
&setYLabel();
&setXTics();
&setTitle();
&setOther();
&addLines();
&setTerminal($Opts{plotter_terminal});
&setOutput($Opts{out_name});
&plot();
return 0;
}
sub scanLineLabels {
my @lines = ();
my %vendors = ();
my $typeCount = 0;
#system("jove $IFName") if $Opts{plot_title} =~ /Median/;
my $IF = new FileHandle("<$IFName") or die("$0: cannot open $IFName; $!\n");
while (<$IF>) {
next if /^\#/;
next if /^\s*$/;
chomp;
my ($fields, $name) = ($_ =~ /^\s*(.*)\s*\"([^\"]*)\"$/);
die("$0: cannot parse line: `$_', stopped") unless defined $fields && defined $name;
my ($vendor) = ($name =~ /^([^-]+)/);
die($name) unless defined $vendor;
$vendors{$vendor} = &VendType($vendor) unless defined $vendors{$vendor};
my @fields = split /\s+/, $fields;
push @lines, [ @fields, $vendors{$vendor}, $name ];
$LabelWidthMax = length($fields[0]) if length($fields[0]) > $LabelWidthMax;
}
@lines = sort cmpLines grep { knownLine($_) } @lines if defined $SortPos;
@LineLabels = map { $_->[0] } @lines;
@LineTypes = map { $_->[$#{$_}-1] } @lines;
@LineNames = map { $_->[$#{$_}] } @lines;
}
sub setXLabel {
$Plot->xlabel_qw('');
}
sub setYLabel {
$Plot->ylabel_qw($MeasType);
}
sub setXTics {
$Plot->xtics('rotate') if @LineLabels > 5;
$Plot->tics('x',
map { $LineNames[$_], $_ } 0 .. $#LineNames);
}
sub setTitle {
my $title = $Opts{plot_title};
$Plot->title($title) if defined $title;
}
sub setOther {
$Plot->range('x', -1, scalar @LineLabels);
$Plot->range('y', 0);
$Plot->set('size 1,0.85');
$Plot->set("bmargin $LabelWidthMax/2") if @LineLabels > 5;
$Plot->data('style boxes');
$Plot->set('boxwidth 0.75');
$Plot->grid();
#$Plot->timestamp();
}
sub addLines {
# plot each line separately so that they appear in different colors
my $count = 0;
for (my $li = 0; $li <= $#LineLabels; ++$li) {
my $llabel = $LineLabels[$li];
my $lt = $LineTypes[$li];
my $line = new ReportGen::Line;
my $filter = "grep '^$llabel\[[:space:]]' $IFName";
$line->data("<$filter");
$line->using($count, "\$$MeasPos");
$line->with("boxes lt $lt");
$line->title('');
$Plot->line($line);
$count++;
}
}
sub setTerminal {
my $term = shift;
$Plot->terminal($term) if $term;
}
sub setOutput {
my $fname = shift;
$Plot->output($fname) if defined $fname;
}
sub plot {
if (my $fname = $Plot->ofile()) {
warn("$0: plotting: `$fname'\n");
}
#warn($Plot->image());
$Plot->plot();
}
sub cmpLines {
die('cmpLines') unless defined $SortPos;
return cmpFields($a->[$SortPos-1], $b->[$SortPos-1]);
}
sub knownLine {
my $line = shift;
die('knownLines') unless defined $SortPos;
return $line->[$SortPos-1] =~ /^\d/;
}
sub cmpFields($$) {
my ($x, $y) = @_;
return $x <=> $y if $x =~ /^\d/ && $y =~ /^\d/;
return $x cmp $y;
}
sub getObjPos {
my ($fname, $name) = @_;
open(IF, "<$fname") or die("$0: cannot open `$fname': $!\n");
my $firstLine = <IF>;
close(IF);
my @names = split(/\s+/, $firstLine);
die("$0: `$fname' has unknown file format\n")
unless @names && $names[0] =~ s/^#//;
my $pos = 1;
foreach my $n (@names) {
return $pos if $n eq $name;
$pos++;
}
#die("$0: `$fname' has no object named `$name'\n");
return undef();
}
sub init {
my @params = ();
die(&usage()) unless &ParseOpts(\%Opts, \@params, @ARGV) && @params == 2;
die("plotter must be specified\n" . &usage()) unless $Opts{plotter};
$ReportGen::Plot::Plotter = $Opts{plotter};
$ReportGen::Plot::Plotter .= ' ' . $Opts{plotter_opts}
if $Opts{plotter_opts};
($Meas, $IFName) = @params;
$MeasType = &ObjName2Type($Meas);
die("$0: unknown object `$Meas'\n") unless $MeasType;
$MeasPos = getObjPos($IFName, $Meas);
die("$0: `$IFName' has no object named `$Meas'\n") unless defined $MeasPos;
my $sortField = $Opts{'sort_by'};
if (defined $sortField) {
$SortPos = getObjPos($IFName, $sortField);
die("$0: cannot sort by `$sortField', not in `$IFName'\n") unless defined $SortPos && $SortPos > 0;
}
}
sub usage {
return "usage: $0 [options] <object> <file_name>\n" . &Opts2Str(\%SavedOpts);
}
syntax highlighted by Code2HTML, v. 0.9.1