Compare commits

..

26 Commits

Author SHA1 Message Date
Dima Kogan
fa7082b242 version bump 2015-11-13 11:08:30 -08:00
Dima Kogan
c61e58da0a added --equation 2015-11-13 11:07:18 -08:00
Dima Kogan
c19dc4aa2a slighly fancier histogram recipe 2015-11-01 13:03:52 -08:00
Dima Kogan
238a0c1943 version bump 2015-11-01 12:55:09 -08:00
Dima Kogan
42a8218fbe removed unneeded if()
This looks like a large patch, but it's 99% re-indentation
2015-11-01 12:46:30 -08:00
Dima Kogan
4cfcf0fc35 removed threading stuff
It's now all in one thread with a select() loop. Much nicer
2015-11-01 12:44:55 -08:00
Dima Kogan
0e7f51f3f7 comment 2015-11-01 01:05:32 -08:00
Dima Kogan
01971c2434 whitespace 2015-11-01 01:02:51 -08:00
Dima Kogan
104accdd0d More sophisticated handling of termination conditions
no --stream and no --exit:
  When input exhausted, keep interactive plot up, keep shell busy until user ^C

no --stream and --exit:
  When input exhausted, keep non-interactive plot up, make shell available
  immediately

--stream and no --exit:
  When input exhausted, keep interactive plot up, keep shell busy until user ^C.
  A user ^C before the input is exhausted is blocked from killing
  C<feedgnuplot>, but allows the data input process to be killed, so it looks
  like an input exhaustion condition.

--stream and --exit:
  When input exhausted or user ^C, shut down all plots, make shell available
  immediately. A user ^C is respected immediately, and C<feedgnuplot> is killed
2015-11-01 01:02:51 -08:00
Dima Kogan
605158b391 replaced a 'say' with 'print' 2015-11-01 01:45:55 -07:00
Dima Kogan
0c32afacfd fixed typo 2014-08-22 17:17:18 -07:00
Dima Kogan
1688496f34 an "exit" command now has effect even with triggered-only replotting 2014-05-28 02:34:39 -07:00
Dima Kogan
498047e785 version bump 2014-05-14 00:45:49 -07:00
Dima Kogan
72adba82f7 Declaring feedgnuplot as a package to pacify the MetaCPAN indexer
Hopefully this is sufficient. We'll see

https://github.com/dkogan/feedgnuplot/pull/16
https://github.com/CPAN-API/metacpan-web/issues/1148
https://github.com/CPAN-API/metacpan-web/issues/1170
https://github.com/CPAN-API/metacpan-web/issues/994
2014-05-14 00:43:13 -07:00
Corey Putkunz
539b2035d8 Fix for "Use of implicit split to @_ is deprecated at /d/home/coreyp/bin/feedgnuplot line 377" 2014-04-07 10:20:57 +08:00
Dima Kogan
9b3cbc13be version bump 2014-02-06 23:17:29 -08:00
Dima Kogan
a65abc6095 fixed incorrect plotting of --timefmt --rangesize plots 2014-02-06 23:16:48 -08:00
Dima Kogan
5db86810b5 the rangesizes are now precomputed and easily assessed 2014-02-06 23:16:44 -08:00
Dima Kogan
d75b572875 version bump 2014-02-05 13:58:01 -08:00
Dima Kogan
6cb1574e2b tests use some of the nicer new syntax 2014-02-05 13:53:34 -08:00
Dima Kogan
4fd1c390ff added --rangesize and --rangesizeall
--rangesizeall is a different way to express --extraValuesPerPoint. --rangesize
is per-curve however
2014-02-05 13:53:16 -08:00
Dima Kogan
4163e24956 Simplified data parsing.
Instead of complicated regexes, I now simply do splits and joins. This paves the
way for per-curve extraValuesPerPoint
2014-02-05 02:54:00 -08:00
Dima Kogan
13268a1fa8 fixed typo 2014-01-26 12:13:38 -08:00
Dima Kogan
08fa97fdb5 version bump 2014-01-25 20:51:45 -08:00
Dima Kogan
e19bdf51c4 changelog bump 2014-01-25 20:51:45 -08:00
Dima Kogan
a9af1925e2 test suite now requires gawk
Previously I assumed that some 'awk' existed, but machines with just mawk were
producing test error complaining about strftime()
2014-01-25 20:51:45 -08:00
16 changed files with 581 additions and 332 deletions

53
Changes
View File

@@ -1,10 +1,59 @@
feedgnuplot (1.30) unstable; urgency=low
feedgnuplot (1.36)
* Added --equation to plot symbolic equations
-- Dima Kogan <dima@secretsauce.net> Fri, 13 Nov 2015 11:08:26 -0800
feedgnuplot (1.35)
* replaced a 'say' with 'print'. Should work better with ancient perls
* an "exit" command now has effect even with triggered-only replotting
* More sophisticated handling of termination conditions:
- Without --exit, we always end up with an interactive plot when the
input data is exhausted or when the user sends a ^C to the pipeline
- When streaming, the first ^C does not kill feedgnuplot
* Removed threading
-- Dima Kogan <dima@secretsauce.net> Sun, 01 Nov 2015 12:50:33 -0800
feedgnuplot (1.34)
* Fix for "Use of implicit split to @_ is deprecated". Thanks to Corey
Putkunz
* Declaring feedgnuplot as a package to let MetaCPAN index this
distribution
-- Dima Kogan <dima@secretsauce.net> Wed, 14 May 2014 00:45:24 -0700
feedgnuplot (1.33)
* fixed incorrect plotting of --timefmt --rangesize plots
-- Dima Kogan <dima@secretsauce.net> Thu, 06 Feb 2014 23:17:21 -0800
feedgnuplot (1.32)
* Added --rangesize and --rangesizeall. Different curves can now plot
different-size tuples
-- Dima Kogan <dima@secretsauce.net> Wed, 05 Feb 2014 13:57:58 -0800
feedgnuplot (1.31)
* Test suite requires gawk to get strftime()
-- Dima Kogan <dima@secretsauce.net> Sat, 25 Jan 2014 20:49:38 -0800
feedgnuplot (1.30)
* Added --with, --set, --unset, --style, --styleall
-- Dima Kogan <dima@secretsauce.net> Fri, 24 Jan 2014 15:38:07 -0800
feedgnuplot (1.29) unstable; urgency=low
feedgnuplot (1.29)
* added CPAN meta-data to require IPC::Run at build time

View File

@@ -1,19 +1,20 @@
#!/usr/bin/perl
package feedgnuplot; # for the metacpan indexer
use strict;
use warnings;
use Getopt::Long;
use Time::HiRes qw( usleep gettimeofday tv_interval );
use IO::Handle;
use IO::Select;
use List::Util qw( first );
use Scalar::Util qw( looks_like_number );
use Text::ParseWords;
use threads;
use threads::shared;
use Thread::Queue;
use Text::ParseWords; # for shellwords
use Pod::Usage;
use Time::Piece;
my $VERSION = 1.30;
my $VERSION = 1.36;
my %options;
interpretCommandline();
@@ -26,16 +27,11 @@ interpretCommandline();
# with --xlen, the offsets are preserved by using $curve->{datastring_offset} to
# represent the offset IN THE ORIGINAL STRING of the current start of the
# datastring
my @curves = ();
# list mapping curve names to their indices in the @curves list
my %curveIndices = ();
# now start the data acquisition and plotting threads
my $dataQueue;
# Whether any new data has arrived since the last replot
my $haveNewData;
@@ -45,39 +41,16 @@ my $last_replot_time = [gettimeofday];
# whether the previous replot was timer based
my $last_replot_is_from_timer = 1;
my $streamingFinished : shared = undef;
if($options{stream})
{
$dataQueue = Thread::Queue->new();
my $addThr = threads->create(\&mainThread);
my $prev_timed_replot_time = [gettimeofday];
my $this_replot_is_from_timer;
my $stdin = IO::Handle->new();
die "Couldn't open STDIN" unless $stdin->fdopen(fileno(STDIN),"r");
my $selector = IO::Select->new( $stdin );
# spawn the plot updating thread. If I'm replotting from a data trigger, I don't need this
my $plotThr = threads->create(\&plotUpdateThread) if $options{stream} > 0;
while(<>)
{
chomp;
last if /^exit/;
# place every line of input to the queue, so that the plotting thread can process it. if we are
# using an implicit domain (x = line number), then we send it on the data queue also, since
# $. is not meaningful in the plotting thread
if(!$options{domain})
{
$_ .= " $.";
}
$dataQueue->enqueue($_);
}
$streamingFinished = 1;
$plotThr->join() if defined $plotThr;
$addThr->join();
}
else
{ mainThread(); }
mainThread();
@@ -116,20 +89,25 @@ sub interpretCommandline
$options{extracmds} = [];
$options{set} = [];
$options{unset} = [];
$options{equation} = [];
$options{curvestyleall} = '';
$options{styleall} = '';
$options{with} = '';
$options{rangesize} = [];
GetOptions(\%options, 'stream:s', 'domain!', 'dataid!', '3d!', 'colormap!', 'lines!', 'points!',
'circles', 'legend=s{2}', 'autolegend!', 'xlabel=s', 'ylabel=s', 'y2label=s', 'zlabel=s',
'title=s', 'xlen=f', 'ymin=f', 'ymax=f', 'xmin=s', 'xmax=s', 'y2min=f', 'y2max=f',
'zmin=f', 'zmax=f', 'y2=s@',
'style=s{2}', 'curvestyle=s{2}', 'curvestyleall=s', 'styleall=s', 'with=s', 'extracmds=s@', 'set=s@', 'unset=s@',
'square!', 'square_xy!', 'hardcopy=s', 'maxcurves=i', 'monotonic!', 'timefmt=s',
'equation=s@',
'histogram=s@', 'binwidth=f', 'histstyle=s',
'terminal=s',
'extraValuesPerPoint=i', 'help', 'dump', 'exit', 'version',
'rangesize=s{2}', 'rangesizeall=i', 'extraValuesPerPoint=i',
'help', 'dump', 'exit', 'version',
'geometry=s') or pod2usage( -exitval => 1,
-verbose => 1, # synopsis and args
-output => \*STDERR );
@@ -176,7 +154,7 @@ sub interpretCommandline
# arrays in order to preserve the ordering. I parse both of these into hashes
# because those are useful to have later. After this I can access individual
# legends with $options{legend_hash}{curveid}
for my $listkey (qw(legend curvestyle))
for my $listkey (qw(legend curvestyle rangesize))
{
$options{"${listkey}_hash"} = {};
@@ -193,11 +171,37 @@ sub interpretCommandline
exit -1;
}
if ( defined $options{rangesizeall} && defined $options{extraValuesPerPoint} )
{
print STDERR "Only one of --rangesizeall and --extraValuesPerPoint may be given\n";
exit -1;
}
# I now set up the rangesize to always be
# $options{rangesize_hash}{$id} // $options{rangesize_default}
if ( $options{rangesizeall} )
{
$options{rangesize_default} = $options{rangesizeall};
}
else
{
$options{rangesize_default} = 1;
$options{rangesize_default} += $options{extraValuesPerPoint} if ($options{extraValuesPerPoint});
$options{rangesize_default}++ if ($options{colormap});
$options{rangesize_default}++ if ($options{circles} );
}
# parse stream option. Allowed only numbers >= 0 or 'trigger'. After this code
# $options{stream} is
# -1 for triggered replotting
# >0 for timed replotting
# undef if not streaming
#
# Note that '0' is not allowed, so !$options{stream} will do the expected
# thing
if(defined $options{stream})
{
# if no streaming period is given, default to 1Hz.
@@ -345,10 +349,8 @@ sub interpretCommandline
$options{timefmt} =~ s/^\s*//;
$options{timefmt} =~ s/\s*$//;
my $Nfields = scalar split( ' ', $options{timefmt});
my $Nfields = () = split /\s+/, $options{timefmt}, -1;
$options{timefmt_Ncols} = $Nfields;
my $regex_str = join( '\s+', ('\S+') x $Nfields );
$options{timefmt_regex} = qr/$regex_str/;
# make sure --xlen is an integer. With a timefmt xlen goes through strptime
# and strftime, and those are integer-only
@@ -356,7 +358,7 @@ sub interpretCommandline
{
if( $options{xlen} - int($options{xlen}) )
{
say STDERR "When streaming --xlen MUST be an integer. Rounding up to the nearest second";
print STDERR "When streaming --xlen MUST be an integer. Rounding up to the nearest second\n";
$options{xlen} = 1 + int($options{xlen});
}
}
@@ -377,19 +379,6 @@ sub getGnuplotVersion
return $gnuplotVersion;
}
sub plotUpdateThread
{
while(! $streamingFinished)
{
usleep( $options{stream} * 1e6 );
# indicate that the timer was the replot source
$dataQueue->enqueue('replot timertick');
}
$dataQueue->enqueue(undef);
}
sub sendRangeCommand
{
my ($name, $min, $max) = @_;
@@ -425,21 +414,64 @@ sub makeDomainNumeric
return $domain0;
}
sub getNextLine
{
while(1)
{
$this_replot_is_from_timer = undef;
# if we're not streaming, or we're doing triggered-only replotting, simply
# do a blocking read
return $stdin->getline()
if (! $options{stream} || $options{stream} < 0);
my $now = [gettimeofday];
my $time_remaining = $options{stream} - tv_interval($prev_timed_replot_time, $now);
if ( $time_remaining < 0 )
{
$prev_timed_replot_time = $now;
$this_replot_is_from_timer = 1;
return 'replot';
}
if ($selector->can_read($time_remaining))
{
return $stdin->getline();
}
}
}
sub mainThread
{
my $valuesPerPoint = 1;
if($options{extraValuesPerPoint}) { $valuesPerPoint += $options{extraValuesPerPoint}; }
if($options{colormap}) { $valuesPerPoint++; }
if($options{circles} ) { $valuesPerPoint++; }
local *PIPE;
my $dopersist = '';
if( !$options{stream} && getGnuplotVersion() >= 4.3)
if( getGnuplotVersion() >= 4.3 && # --persist not available before this
# --persist is needed for the "half-alive" state (see documentation for
# --exit). This state is only used with these options:
!$options{stream} && $options{exit})
{
$dopersist = '--persist';
}
# We trap SIGINT to kill the data input, but keep the plot up. see
# documentation for --exit
if ($options{stream} && !$options{exit})
{
$SIG{INT} = sub
{
print STDERR "$0 received SIGINT. Send again to quit\n";
$SIG{INT} = undef;
};
}
if(exists $options{dump})
{
*PIPE = *STDOUT;
@@ -573,16 +605,6 @@ sub mainThread
setCurveAsHistogram( $_ ) foreach (@{$options{histogram}});
# regexp for a possibly floating point, possibly scientific notation number
my $numRE = '-?\d*\.?\d+(?:[Ee][-+]?\d+)?';
my $domainRE = $options{timefmt_regex} || $numRE;
# a point may be preceded by an id
my $pointRE = $options{dataid} ? '(\S+)\s+' : '()';
$pointRE .= '(' . join('\s+', ($numRE) x $valuesPerPoint) . ')';
$pointRE = qr/$pointRE/;
# set all the axis ranges
# If a bound isn't given I want to set it to the empty string, so I can communicate it simply to
# gnuplot
@@ -616,8 +638,7 @@ sub mainThread
# number of seconds since the UNIX epoch.
my $domain0_numeric;
# I should be using the // operator, but I'd like to be compatible with perl 5.8
while( $_ = (defined $dataQueue ? $dataQueue->dequeue() : <>))
while( defined ($_ = getNextLine()) )
{
next if /^#/o;
@@ -631,89 +652,104 @@ sub mainThread
if(/^replot/o )
{
# /timertick/ determines if the timer was the source of the replot
replot( $domain0_numeric, /timertick/ );
replot( $domain0_numeric );
next;
}
# /exit/ is handled in the data-reading thread
last if /^exit/o;
}
if(! /^replot/o)
# parse the incoming data lines. The format is
# x id0 dat0 id1 dat1 ....
# where idX is the ID of the curve that datX corresponds to
#
# $options{domain} indicates whether the initial 'x' is given or not (if not, the line
# number is used)
# $options{dataid} indicates whether idX is given or not (if not, the point order in the
# line is used)
# 3d plots require $options{domain}, and dictate "x y" for the domain instead of just "x"
my @fields = split;
if($options{domain})
{
# parse the incoming data lines. The format is
# x id0 dat0 id1 dat1 ....
# where idX is the ID of the curve that datX corresponds to
#
# $options{domain} indicates whether the initial 'x' is given or not (if not, the line
# number is used)
# $options{dataid} indicates whether idX is given or not (if not, the point order in the
# line is used)
# 3d plots require $options{domain}, and dictate "x y" for the domain instead of just "x"
if($options{domain})
if( $options{timefmt} )
{
/($domainRE)/go or next;
$domain[0] = $1;
$domain0_numeric = makeDomainNumeric( $domain[0] );
# no point if doing anything unless I have at least the domain and
# 1 piece of data
next if @fields < $options{timefmt_Ncols}+1;
if($options{'3d'})
{
/($numRE)/go or next;
$domain[1] = $1;
}
elsif( $options{monotonic} )
{
if( defined $latestX && $domain0_numeric < $latestX )
{
# the x-coordinate of the new point is in the past, so I wipe out
# all the data and start anew. Before I wipe the old data, I
# replot the old data
replot( $domain0_numeric );
clearCurves();
$latestX = undef;
}
else
{ $latestX = $domain0_numeric; }
}
$domain[0] = join (' ', splice( @fields, 0, $options{timefmt_Ncols}) );
$domain0_numeric = makeDomainNumeric( $domain[0] );
}
elsif(!$options{'3d'})
{
# no point if doing anything unless I have at least the domain and
# 1 piece of data
next if @fields < 1+1;
$domain[0] = $domain0_numeric = shift @fields;
}
else
{
# since $. is not meaningful in the plotting thread if we're using the data queue, we pass
# $. on the data queue in that case
if(defined $dataQueue)
# no point if doing anything unless I have at least the domain and
# 1 piece of data
next if @fields < 2+1;
@domain = splice(@fields, 0, 2);
}
if( $options{monotonic} )
{
if( defined $latestX && $domain0_numeric < $latestX )
{
s/ ([\d]+)$//o;
$domain[0] = $1;
# the x-coordinate of the new point is in the past, so I wipe out
# all the data and start anew. Before I wipe the old data, I
# replot the old data
replot( $domain0_numeric );
clearCurves();
$latestX = undef;
}
else
{ $latestX = $domain0_numeric; }
}
}
else
{
$domain[0] = $.;
$domain0_numeric = makeDomainNumeric( $domain[0] );
}
my $id = -1;
while(@fields)
{
if($options{dataid})
{
$id = shift @fields;
}
else
{
$domain[0] = $.;
$id++;
}
$domain0_numeric = makeDomainNumeric( $domain[0] );
}
my $id = -1;
while (/$pointRE/go)
{
if($1 ne '') {$id = $1;}
else {$id++; }
# I'd like to use //, but I guess some people are still on perl 5.8
my $rangesize = exists $options{rangesize_hash}{$id} ?
$options{rangesize_hash}{$id} :
$options{rangesize_default};
last if @fields < $rangesize;
pushPoint(getCurve($id),
"@domain $2\n", $domain0_numeric);
}
join(' ',
@domain,
splice( @fields, 0, $rangesize ) ) . "\n",
$domain0_numeric);
}
}
# if we were streaming, we're now done!
if( $options{stream} )
{
return;
}
# finished reading in all. Plot what we have
plotStoredData();
plotStoredData() unless $options{stream};
if ( defined $options{hardcopy})
{
@@ -722,7 +758,7 @@ sub mainThread
# sleep until the plot file exists, and it is closed. Sometimes the output
# is still being written at this point. If the output filename starts with
# '|', gnuplot pipes the output to that process, instead of writing to a
# file. In that case I don't make sure the file exists, since there IS not
# file. In that case I don't make sure the file exists, since there IS no
# file
if( $options{hardcopy} !~ /^\|/ )
{
@@ -734,6 +770,13 @@ sub mainThread
return;
}
# data exhausted. If we're killed now, then we should peacefully die.
if($options{stream} && !$options{exit})
{
print STDERR "Input data exhausted\n";
$SIG{INT} = undef;
}
# we persist gnuplot, so we shouldn't need this sleep. However, once
# gnuplot exits, but the persistent window sticks around, you can no
# longer interactively zoom the plot. So we still sleep
@@ -777,7 +820,9 @@ sub plotStoredData
my @nonemptyCurves = grep { $_->{datastring} } @curves;
my @extraopts = map {$_->{options}} @nonemptyCurves;
my $body = join(', ' , map({ "'-' $_" } @extraopts) );
my $body = join('', map { "$_," } @{$options{equation}});
$body .= join(', ' , map({ "'-' $_" } @extraopts) );
if($options{'3d'}) { print PIPE "splot $body\n"; }
else { print PIPE "plot $body\n"; }
@@ -824,7 +869,19 @@ sub updateCurveOptions
my $usingoptions = '';
if( $options{timefmt} )
{
$usingoptions = "using 1:" . ($options{timefmt_Ncols}+1);
# with --timefmt I need an explicit 'using' specification. I specify the
# columns as 1:2:3..... I need the right number of columns (this is given
# as 1 + rangesize). I also need to start the range at the first column
# past the timefmt
# I'd like to use //, but I guess some people are still on perl 5.8
my $rangesize = exists $options{rangesize_hash}{$id} ?
$options{rangesize_hash}{$id} :
$options{rangesize_default};
my @rest = map {$_ + $options{timefmt_Ncols}} (1..$rangesize);
$usingoptions = "using 1:" . join(':', @rest);
}
$curve->{options} = "$histoptions $usingoptions $titleoption $curve->{extraoptions} $curvestyleall";
@@ -919,7 +976,7 @@ sub replot
# }
my ($domain0_numeric, $replot_is_from_timer) = @_;
my ($domain0_numeric) = @_;
my $now = [gettimeofday];
@@ -929,7 +986,7 @@ sub replot
# if the last replot was timer-based, but this one isn't, force a replot.
# This makes sure that a replot happens for a domain rollover shortly
# after a timer replot
!$replot_is_from_timer && $last_replot_is_from_timer ||
!$this_replot_is_from_timer && $last_replot_is_from_timer ||
# if enough time has elapsed since the last replot, it's ok to replot
tv_interval ( $last_replot_time, $now ) > 0.8*$options{stream} )
@@ -955,7 +1012,7 @@ sub replot
# update replot state
$last_replot_time = $now;
$last_replot_is_from_timer = $replot_is_from_timer;
$last_replot_is_from_timer = $this_replot_is_from_timer;
}
}
@@ -1112,17 +1169,24 @@ conjunction with C<--dataid>.
=head3 Multi-value style support
Depending on how gnuplot is plotting the data, more than one value may be needed
to represent a single point. For example, the script has support to plot all the
data with C<--circles>. This requires a radius to be specified for each point in
addition to the position of the point. Thus, when plotting with C<--circles>, 2
numbers are read for each data point instead of 1. A similar situation exists
with C<--colormap> where each point contains the position I<and> the color.
There are other gnuplot styles that require more data (such as error bars), but
none of these are directly supported by the script. They can still be used,
though, by specifying the specific style with C<--style>, and specifying how
many extra values are needed for each point with C<--extraValuesPerPoint extra>.
C<--extraValuesPerPoint> is ONLY needed for the styles not explicitly supported;
supported styles set that variable automatically.
to represent the range of a single point. Basic 2D plots have 2 numbers
representing each point: 1 domain and 1 range. But if plotting with
C<--circles>, for instance, then there's an extra range value: the radius. A
similar situation exists with C<--colormap> where each point contains the
position I<and> the color. There are other gnuplot styles that require more data
(such as error bars), but none of these are directly supported by the script.
They can still be used, however, by specifying the specific style with
C<--style>, and specifying how many values are needed for each point with
C<--rangesizeall> or C<--rangesize> or C<--extraValuesPerPoint>. Those options
that specify the range size are required I<only> for styles not explicitly
supported by feedgnuplot; supported styles do the right thing automatically.
More examples: if making a 2d plot of y error bars where gnuplot expects a
(x,y,ydelta) tuple for each point, you want C<--rangesizeall 2> because you have
one domain value (x) and 2 range values (y,ydelta). Gnuplot can also plot
lopsided y errorbars by giving a tuple (x,y,ylow,yhigh). This is similar as
before, but you want C<--rangesizeall 3> instead.
=head3 3D data
@@ -1157,7 +1221,7 @@ C<--xmin> and C<--xmax> I<must> use the format passed in to C<--timefmt>
Using this option changes both the way the input is parsed I<and> the way the
x-axis tics are labelled. Gnuplot tries to be intelligent in this labelling, but
it doesn't always to what the user wants. The labelling can be controlled with
it doesn't always do what the user wants. The labelling can be controlled with
the gnuplot C<set format> command, which takes the same type of format string as
C<--timefmt>. Example:
@@ -1365,8 +1429,7 @@ Interpret the X data as a time/date, parsed with the given format
C<--colormap>
Show a colormapped xy plot. Requires extra data for the color. zmin/zmax can be
used to set the extents of the colors. Automatically increments
C<--extraValuesPerPoint>
used to set the extents of the colors. Automatically sets the C<--rangesize>.
=item
@@ -1394,8 +1457,7 @@ Do [not] draw points
C<--circles>
Plot with circles. This requires a radius be specified for each point.
Automatically increments C<--extraValuesPerPoint>). C<Not> supported for 3d
plots.
Automatically sets the C<--rangesize>. C<Not> supported for 3d plots.
=item
@@ -1552,6 +1614,34 @@ times.
=item
C<--equation xxx>
Gnuplot can plot both data and symbolic equations. C<feedgnuplot> generally
plots data, but with this option can plot symbolic equations /also/. This is
generally intended to augment data plots, since for equation-only plots you
don't need C<feedgnuplot>. C<--equation> can be passed multiple times for
multiple equations. The given strings are passed to gnuplot directly without any
thing added or removed, so styling and such should be applied in the string. A
basic example:
seq 100 | awk '{print $1/10, $1/100}' |
feedgnuplot --with 'lines lw 3' --domain --ymax 1
--equation 'sin(x)/x' --equation 'cos(x)/x with lines lw 4'
Here I plot the incoming data (points along a line) with the given style (a line
with thickness 3), /and/ I plot two damped sinusoids on the same plot. The
sinusoids are not affected by C<feedgnuplot> styling, so their styles are set
separately, as in this example. More complicated example:
seq 360 | perl -nE '$th=$_/360 * 3.14*2; $c=cos($th); $s=sin($th); say "$c $s"' |
feedgnuplot --domain --square
--set parametric --set "trange [0:2*3.14]" --equation "sin(t),cos(t)"
Here the data I generate is points along the unit circle. I plot these as
points, and I /also/ plot a true circle as a parametric equation.
=item
C<--square>
Plot data with aspect ratio 1. For 3D plots, this controls the aspect ratio for
@@ -1599,13 +1689,32 @@ replotted before being purged
=item
C<--rangesize curveID xxx>
The options C<--rangesizeall>, C<--rangesize> and C<--extraValuesPerPoint> set
the number of values are needed to represent each point being plotted (see
L</"Multi-value style support"> above). These options are I<only> needed if
unknown styles are used, with C<--styleall> or C<--with> for instance.
C<--rangesize> is used to set how many values are needed to represent the range
of a point for a particular curve. This overrides any defaults that may exist
for this curve only.
=item
C<--rangesizeall xxx>
Like C<--rangesize>, but applies to I<all> the curves.
C<--extraValuesPerPoint xxx>
How many extra values are given for each data point. Normally this is 0, and
does not need to be specified, but sometimes we want extra data, like for colors
or point sizes or error bars, etc. feedgnuplot options that require this
(colormap, circles) automatically set it. This option is ONLY needed if unknown
styles are used, with C<--styleall> or C<--with> for instance
Like C<--rangesizeall>, but instead of overriding the default, adds to it. For
example, if plotting non-lopsided y errorbars gnuplot wants (x,y,ydelta) tuples.
These can be specified both with C<--rangesizeall 2> (because there are 2 range
values) or C<--extraValuesPerPoint 1> (because there's 1 more value than usual).
This option is I<only> needed if unknown styles are used, with C<--styleall> or
C<--with> for instance.
=item
@@ -1618,10 +1727,80 @@ is possible to send the output produced this way to gnuplot directly.
C<--exit>
Terminate the feedgnuplot process after passing data to gnuplot. The window will
persist but will not be interactive. Without this option feedgnuplot keeps
running and must be killed by the user. Note that this option works only with
later versions of gnuplot and only with some gnuplot terminals.
This controls the details of what happens when the input data is exhausted, or
when some part of the C<feedgnuplot> pipeline is killed. This option does
different things depending on whether C<--stream> is active, so read this
closely.
With interactive gnuplot terminals (qt, x11, wxt), the plot windows live in a
separate process from the main C<gnuplot> process. It is thus possible for the
main C<gnuplot> process to exit, while leaving the plot windows up (a caveat is
that such decapitated windows aren't interactive). To be clear, there are 3
possible states:
=over
=item Alive: C<feedgnuplot>, C<gnuplot> alive, plot window process alive, no
shell prompt (shell busy with C<feedgnuplot>)
=item Half-alive: C<feedgnuplot>, C<gnuplot> dead, plot window process alive
(but non-interactive), shell prompt available
=item Dead: C<feedgnuplot>, C<gnuplot> dead, plot window process dead, shell
prompt available
=back
The C<--exit> option controls the details of this behavior. The possibilities
are:
=over
=item No C<--stream>, input pipe is exhausted (all data read in)
=over
=item default; no C<--exit>
Alive. Need to Ctrl-C to get back into the shell
=item C<--exit>
Half-alive. Non-interactive prompt up, and the shell accepts new commands.
Without C<--stream> the goal is to show a plot, so a Dead state is not useful
here.
=back
=item C<--stream>, input pipe is exhausted (all data read in) or the
C<feedgnuplot> process terminated
=over
=item default; no C<--exit>
Alive. Need to Ctrl-C to get back into the shell
=item C<--exit>
Dead. No plot is shown, and the shell accepts new commands. With C<--stream> the
goal is to show a plot as the data comes in, which we have been doing. Now that
we're done, we can clean up everything.
=back
=back
Note that one usually invokes C<feedgnuplot> as a part of a shell pipeline:
$ write_data | feedgnuplot
If the user terminates this pipeline with ^C, then I<all> the processes in the
pipeline receive SIGINT. This normally kills C<feedgnuplot> and all its
C<gnuplot> children, and we let this happen unless C<--stream> and no C<--exit>.
If C<--stream> and no C<--exit>, then we ignore the first ^C. The data feeder
dies, and we behave as if the input data was exhausted. A second ^C kills us
also.
=item
@@ -1675,10 +1854,12 @@ in a Thinkpad.
$ while true; do cat /proc/acpi/ibm/thermal | awk '{$1=""; print}' ; sleep 1; done |
feedgnuplot --stream --xlen 100 --lines --autolegend --ymax 100 --ymin 20 --ylabel 'Temperature (deg C)'
=head2 Plotting a histogram of file sizes in a directory
=head2 Plotting a histogram of file sizes in a directory, granular to 10MB
$ ls -l | awk '{print $5/1e6}' |
feedgnuplot --histogram 0 --with boxes --ymin 0 --xlabel 'File size (MB)' --ylabel Frequency
feedgnuplot --histogram 0 --with boxes
--binwidth 10 --set 'style fill solid'
--ymin 0 --xlabel 'File size (MB)' --ylabel Frequency
=head1 ACKNOWLEDGEMENT

View File

@@ -15,6 +15,8 @@ complete -W \
--dump \
--exit \
--extraValuesPerPoint \
--rangesizeall \
--rangesize \
--extracmds \
--set \
--unset \

View File

@@ -37,7 +37,9 @@ _arguments -S
'--hardcopy[Plot to a file]:filename' \
'--maxcurves[The maximum allowed number of curves]:number of curves' \
'(--3d)--monotonic[Resets plot if an X in the past is seen]' \
'--extraValuesPerPoint[How many extra values are given for each data point]:N'\
'(--rangesizeall)--extraValuesPerPoint[How many extra values are given for each data range]:N'\
'(--extraValuesPerPoint)--rangesizeall[How many values are given for each data range]:N'\
'*--rangesize[How many values comprise a data range in this curve]:curve id: :N:' \
'--dump[Instead of printing to gnuplot, print to STDOUT]' \
'--geometry[The X11 geometry string]:geometry string:' \
'*--curvestyle[Additional styles for a curve]:curve id: :style:' \

58
debian/changelog vendored
View File

@@ -1,58 +0,0 @@
feedgnuplot (1.30-1) unstable; urgency=low
* made the VCS links canonical
* added --set, --unset, --with, --style, --styleall
-- Dima Kogan <dima@secretsauce.net> Fri, 24 Jan 2014 15:50:03 -0800
feedgnuplot (1.28-1) unstable; urgency=low
* Upstream update:
- Removed example debianization
- Removed unreliable unit tests from automated testing (Closes: #731080)
* gnuplot dependency now favors graphical gnuplot packages
* Removed Anton Gladky from the Uploaders
-- Dima Kogan <dima@secretsauce.net> Wed, 04 Dec 2013 02:05:08 -0800
feedgnuplot (1.26-1) unstable; urgency=low
[ Dima Kogan ]
* Minor POD update
* Added test suite
* Added initial support for --timefmt. Currently time/date data is
supported only at the x-axis domain
* Added --exit option for force feedgnuplot to return even if gnuplot
may not yet be done rendering (patch by Eric Schulte)
* Reformatted the documentation
* y2-axis curves no longer have a thicker line by default
* --hardcopy now handles piped output (gnuplot 'set output |process'
syntax)
[ Anton Gladky ]
* Add libipc-run-perl to Build-Depends to execute tests
-- Dima Kogan <dima@secretsauce.net> Sun, 20 Oct 2013 01:19:51 -0700
feedgnuplot (1.24-2) unstable; urgency=low
* Now building the html documentation from the correct POD source
-- Dima Kogan <dima@secretsauce.net> Sun, 28 Apr 2013 17:42:52 -0700
feedgnuplot (1.24-1) unstable; urgency=low
* Fixed regression in --monotonic. This works again now
* moved POD back into the main source file. This fixes the broken usage
messages
* added --version
* fixed watchfile to work with newer github pages
* priority now optional
-- Dima Kogan <dima@secretsauce.net> Fri, 08 Feb 2013 02:01:32 -0800
feedgnuplot (1.23-2) unstable; urgency=low
* Initial Debian release (Closes: #686413)
-- Dima Kogan <dima@secretsauce.net> Tue, 30 Oct 2012 11:14:01 -0700

1
debian/compat vendored
View File

@@ -1 +0,0 @@
9

19
debian/control vendored
View File

@@ -1,19 +0,0 @@
Source: feedgnuplot
Section: science
Priority: optional
Build-Depends: debhelper (>= 9), libstring-shellquote-perl, perl, gawk, gnuplot, libipc-run-perl
Maintainer: Debian Science Maintainers <debian-science-maintainers@lists.alioth.debian.org>
Uploaders: Dima Kogan <dima@secretsauce.net>
Standards-Version: 3.9.4
Homepage: https://github.com/dkogan/feedgnuplot
Vcs-Git: git://anonscm.debian.org/debian-science/packages/feedgnuplot.git
Vcs-Browser: http://anonscm.debian.org/gitweb/?p=debian-science/packages/feedgnuplot.git
Package: feedgnuplot
Architecture: all
Depends: ${misc:Depends}, ${perl:Depends}, gnuplot-qt | gnuplot-x11 | gnuplot
Description: Pipe-oriented frontend to Gnuplot
Flexible, command-line-oriented frontend to Gnuplot. Creates plots from data
coming in on STDIN or given in a filename passed on the commandline. Various
data representations are supported, as is hardcopy output and streaming display
of live data.

24
debian/copyright vendored
View File

@@ -1,24 +0,0 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://github.com/dkogan/feedgnuplot
Upstream-Contact: Dima Kogan, <dima@secretsauce.net>
Upstream-Name: feedgnuplot
Files: *
Copyright: 2011, Dima Kogan <dima@secretsauce.net>
License: Artistic or GPL-1+
License: Artistic
This program is free software; you can redistribute it and/or modify
it under the terms of the Artistic License, which comes with Perl.
.
On Debian GNU/Linux systems, the complete text of the Artistic License
can be found in `/usr/share/common-licenses/Artistic'.
License: GPL-1+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
.
On Debian GNU/Linux systems, the complete text of version 1 of the
General Public License can be found in `/usr/share/common-licenses/GPL-1'.

View File

@@ -1,9 +0,0 @@
Document: feedgnuplot
Title: Feedgnuplot Manual
Author: Dima Kogan
Abstract: Formatted manpage for feedgnuplot
Section: Science/Data Analysis
Format: HTML
Index: /usr/share/doc/feedgnuplot/feedgnuplot.html
Files: /usr/share/doc/feedgnuplot/feedgnuplot.html

View File

@@ -1 +0,0 @@
feedgnuplot.html

View File

@@ -1,2 +0,0 @@
completions/bash/feedgnuplot /etc/bash_completion.d/
completions/zsh/_feedgnuplot /usr/share/zsh/vendor-completions

4
debian/gbp.conf vendored
View File

@@ -1,4 +0,0 @@
[DEFAULT]
debian-branch = debian
upstream-tag = v%(version)s
pristine-tar = True

12
debian/rules vendored
View File

@@ -1,12 +0,0 @@
#!/usr/bin/make -f
%:
dh $@
override_dh_auto_build:
dh_auto_build
pod2html --title=feedgnuplot bin/feedgnuplot > feedgnuplot.html
override_dh_auto_clean:
rm -rf feedgnuplot.html pod2htm*
dh_auto_clean

View File

@@ -1 +0,0 @@
3.0 (quilt)

4
debian/watch vendored
View File

@@ -1,4 +0,0 @@
version=3
opts=uversionmangle=s/(\d)[_\.\-\+]?((RC|rc|pre|dev|beta|alpha|b|a)\d*)$/$1~$2/,dversionmangle=s/\+(debian|dfsg|ds|deb)\d*$// \
https://github.com/dkogan/feedgnuplot/tags .*/v?(\d.*)\.(?:tgz|tbz2|txz|tar\.(?:gz|bz2|xz))
# Bart Martens <bartm@debian.org> Sat, 22 Dec 2012 12:54:18 +0000

202
t/plots.t
View File

@@ -17,14 +17,20 @@ BEGIN {
exit(0);
}
open(my $pipe, 'gnuplot --version |');
if( !$pipe )
my $gawkversion = `gawk -V`;
if( !$gawkversion || $@ )
{
print("1..0 # Skip: gawk is required for strftime() in the test suite. Skipping tests.\n");
exit(0);
}
my $gnuplotVersion = `gnuplot --version`;
if( !$gnuplotVersion || $@)
{
print("1..0 # Skip: gnuplot not installed. Tests require ver. 4.6.4; feedgnuplot works with any.\n");
exit(0);
}
my $gnuplotVersion = <$pipe>;
chomp $gnuplotVersion;
if ($gnuplotVersion ne "gnuplot 4.6 patchlevel 4")
{
@@ -33,7 +39,7 @@ BEGIN {
}
}
use Test::More tests => 52;
use Test::More tests => 58;
use File::Temp 'tempfile';
use IPC::Run 'run';
use String::ShellQuote;
@@ -320,7 +326,7 @@ tryplot( testname => 'basic line plot with bounds, square aspect ratio',
EOF
tryplot( testname => 'lines on both axes with labels, legends, titles',
cmd => q{seq 5 | awk '{print 2*$1, $1*$1}'},
cmd => q{seq 5 | gawk '{print 2*$1, $1*$1}'},
options => [qw(--lines --points),
'--legend', '0', 'data 0',
'--title', "Test plot",
@@ -369,7 +375,7 @@ tryplot( testname => 'lines on both axes with labels, legends, titles',
EOF
tryplot( testname => 'lines on both axes with labels, legends, titles; different styles',
cmd => q{seq 5 | awk '{print 2*$1, $1*$1}'},
cmd => q{seq 5 | gawk '{print 2*$1, $1*$1}'},
options => ['--legend', '0', 'data 0',
'--title', "Test plot",
qw(--y2 1 --y2label y2 --xlabel x --ylabel y --y2max 30),
@@ -419,7 +425,7 @@ tryplot( testname => 'lines on both axes with labels, legends, titles; different
EOF
tryplot( testname => 'domain plot',
cmd => q{seq 5 | awk '{print 2*$1, $1*$1}'},
cmd => q{seq 5 | gawk '{print 2*$1, $1*$1}'},
options => [qw(--lines --points), '--domain'],
refplot => <<'EOF' );
@@ -465,7 +471,7 @@ tryplot( testname => 'domain plot',
EOF
tryplot( testname => 'dataid plot',
cmd => q{seq 5 | awk '{print 2*$1, $1*$1}'},
cmd => q{seq 5 | gawk '{print 2*$1, $1*$1}'},
options => [qw(--lines --points),
qw(--dataid --autolegend)],
refplot => <<'EOF' );
@@ -512,7 +518,7 @@ tryplot( testname => 'dataid plot',
EOF
tryplot( testname => '3d spiral with bounds, labels',
cmd => q{seq 50 | awk '{print 2*cos($1/5), sin($1/5), $1}'},
cmd => q{seq 50 | gawk '{print 2*cos($1/5), sin($1/5), $1}'},
options => [qw(--lines --points),
qw(--3d --domain --zmin -5 --zmax 45 --zlabel z),
'--extracmds', 'set view 60,30'],
@@ -560,7 +566,7 @@ tryplot( testname => '3d spiral with bounds, labels',
EOF
tryplot( testname => '3d spiral with bounds, labels, square xy aspect ratio',
cmd => q{seq 50 | awk '{print 2*cos($1/5), sin($1/5), $1}'},
cmd => q{seq 50 | gawk '{print 2*cos($1/5), sin($1/5), $1}'},
options => [qw(--lines --points),
qw(--3d --domain --zmin -5 --zmax 45 --zlabel z),
'--extracmds', 'set view 60,30', '--square_xy'],
@@ -608,7 +614,7 @@ tryplot( testname => '3d spiral with bounds, labels, square xy aspect ratio',
EOF
tryplot( testname => 'Monotonicity check',
cmd => q{seq 10 | awk '{print (NR-1)%5,NR}'},
cmd => q{seq 10 | gawk '{print (NR-1)%5,NR}'},
options => [qw(--lines --points --domain --monotonic)],
refplot => <<'EOF' );
@@ -655,7 +661,7 @@ EOF
tryplot( testname => 'basic --timefmt plot',
cmd => q{seq 5 | awk '{print strftime("%d %b %Y %T",1382249107+$1,1),$1}'},
cmd => q{seq 5 | gawk '{print strftime("%d %b %Y %T",1382249107+$1,1),$1}'},
options => ['--domain', '--timefmt', '%d %b %Y %H:%M:%S'],
refplot => <<'EOF' );
@@ -701,7 +707,7 @@ tryplot( testname => 'basic --timefmt plot',
EOF
tryplot( testname => '--timefmt plot with bounds',
cmd => q{seq 5 | awk '{print strftime("%d %b %Y %T",1382249107+$1,1),$1}'},
cmd => q{seq 5 | gawk '{print strftime("%d %b %Y %T",1382249107+$1,1),$1}'},
options => ['--domain', '--timefmt', '%d %b %Y %H:%M:%S',
'--xmin', '20 Oct 2013 06:05:00',
'--xmax', '20 Oct 2013 06:05:20'],
@@ -749,7 +755,7 @@ tryplot( testname => '--timefmt plot with bounds',
EOF
tryplot( testname => '--timefmt plot with --monotonic',
cmd => q{seq 10 | awk '{x=(NR-1)%5; print strftime("%d %b %Y %T",1382249107+x,1),$1}'},
cmd => q{seq 10 | gawk '{x=(NR-1)%5; print strftime("%d %b %Y %T",1382249107+x,1),$1}'},
options => ['--domain', '--timefmt', '%d %b %Y %H:%M:%S',
'--monotonic'],
refplot => <<'EOF' );
@@ -795,10 +801,57 @@ tryplot( testname => '--timefmt plot with --monotonic',
EOF
tryplot( testname => '--timefmt with custom rangesize',
cmd => q{seq 5 | gawk '{print strftime("%d %b %Y %T",1382249107+$1,1),$1,$1/10}'},
options => ['--domain', '--timefmt', '%d %b %Y %H:%M:%S',
qw(--with errorbars --rangesizeall 2)],
refplot => <<'EOF' );
5.5 ++---------+-----------+----------+----------+----------+-----------+----------+---------**
+ + + + + + + + *
| *
5 ++ +A
| *
| *
| *
4.5 ++ **
| *** |
| * |
4 ++ A ++
| * |
| * |
| *** |
3.5 ++ ++
| *** |
| * |
3 ++ A ++
| * |
| * |
| *** |
2.5 ++ ++
| |
| *** |
2 ++ A ++
| * |
| *** |
| |
1.5 ++ ++
| |
| |
1 A* ++
** |
| |
+ + + + + + + + +
0.5 ++---------+-----------+----------+----------+----------+-----------+----------+---------++
05:08 05:08 05:09 05:09 05:10 05:10 05:11 05:11 05:12
EOF
tryplot( testname => 'Error bars (using extraValuesPerPoint)',
cmd => q{seq 5 | awk '{print $1,$1,$1/10}'},
cmd => q{seq 5 | gawk '{print $1,$1,$1/10}'},
options => [qw(--domain),
qw(--extraValuesPerPoint 1 --curvestyle 0), 'with errorbars'],
qw(--extraValuesPerPoint 1 --with errorbars)],
refplot => <<'EOF' );
@@ -843,6 +896,103 @@ tryplot( testname => 'Error bars (using extraValuesPerPoint)',
EOF
tryplot( testname => 'Error bars (using rangesizeall)',
cmd => q{seq 5 | gawk '{print $1,$1,$1/10}'},
options => [qw(--domain),
qw(--rangesizeall 2 --with errorbars)],
refplot => <<'EOF' );
5.5 ++---------+-----------+----------+----------+----------+-----------+----------+---------**
+ + + + + + + + *
| *
5 ++ +A
| *
| *
| *
4.5 ++ **
| *** |
| * |
4 ++ A ++
| * |
| * |
| *** |
3.5 ++ ++
| *** |
| * |
3 ++ A ++
| * |
| * |
| *** |
2.5 ++ ++
| |
| *** |
2 ++ A ++
| * |
| *** |
| |
1.5 ++ ++
| |
| |
1 A* ++
** |
| |
+ + + + + + + + +
0.5 ++---------+-----------+----------+----------+----------+-----------+----------+---------++
1 1.5 2 2.5 3 3.5 4 4.5 5
EOF
tryplot( testname => 'Error bars (using rangesize, rangesizeall)',
cmd => q{seq 5 | gawk '{print $1,"vert",$1,$1/10,"horiz",5-$1,$1-$1/5,$1+$1/20}'},
options => [qw(--domain --dataid),
qw(--rangesize vert 2 --rangesizeall 3 --with xerrorbars --style vert), 'with errorbars',
qw(--xmin 1 --xmax 5 --ymin 0.5 --ymax 5.5)],
refplot => <<'EOF' );
+-----------+----------+-----------+----------+-----------+----------+-----------+---------**
+ + + + + + + + *
| *
5 ++ +A
| *
| *
| *
| **
| *** |
## * |
4 B# A ++
## * |
| * |
| *** |
| |
| *** |
| # # * |
3 ++ #########B## A ++
| # # * |
| * |
| *** |
| |
| |
| *** # # |
2 ++ A ##############B### ++
| * # # |
| *** |
| |
| |
| |
| # # |
1 A* ##################B##### ++
** # # |
| |
+ + + + + + + + +
+-----------+----------+-----------+----------+-----------+----------+-----------+----------+
1 1.5 2 2.5 3 3.5 4 4.5 5
EOF
SKIP:
{
@@ -860,7 +1010,7 @@ skip "Skipping unreliable tests. Set RUN_ALL_TESTS environment variable to run t
tryplot( testname => 'Histogram plot',
cmd => q{seq 50 | awk '{print $1*$1}'},
cmd => q{seq 50 | gawk '{print $1*$1}'},
options => [qw(--lines --points),
qw(--histo 0 --binwidth 50 --ymin 0 --curvestyleall), 'with boxes'],
refplot => <<'EOF' );
@@ -907,7 +1057,7 @@ tryplot( testname => 'Histogram plot',
EOF
tryplot( testname => 'Cumulative histogram',
cmd => q{seq 50 | awk '{print $1*$1}'},
cmd => q{seq 50 | gawk '{print $1*$1}'},
options => [qw(--lines --points),
qw(--histo 0 --histstyle cum --binwidth 50 --ymin 0 --curvestyleall), 'with boxes'],
refplot => <<'EOF' );
@@ -954,7 +1104,7 @@ tryplot( testname => 'Cumulative histogram',
EOF
tryplot( testname => 'Circles',
cmd => q{seq 5 | awk '{print $1,$1,$1/10}'},
cmd => q{seq 5 | gawk '{print $1,$1,$1/10}'},
options => [qw(--circles --domain)],
refplot => <<'EOF' );
@@ -1008,7 +1158,7 @@ note( "Starting to run streaming tests. These will take several seconds each" );
# points, and then "exit", so I should have two frames worth of data plotted. I
# pre-send a 0 so that the gnuplot autoscaling is always well-defined
tryplot( testname => 'basic streaming test',
cmd => q{seq 500 | awk 'BEGIN{ print 0; } {print (NR==3)? "exit" : $0; fflush(); system("sleep 1.2");}'},
cmd => q{seq 500 | gawk 'BEGIN{ print 0; } {print (NR==3)? "exit" : $0; fflush(); system("sleep 1.2");}'},
options => [qw(--lines --points --stream)],
refplot => <<'EOF' );
@@ -1094,7 +1244,7 @@ tryplot( testname => 'basic streaming test',
EOF
tryplot( testname => 'basic streaming test, twice as fast',
cmd => q{seq 500 | awk 'BEGIN{ print 0; } {print (NR==3)? "exit" : $0; fflush(); system("sleep 0.6");}'},
cmd => q{seq 500 | gawk 'BEGIN{ print 0; } {print (NR==3)? "exit" : $0; fflush(); system("sleep 0.6");}'},
options => [qw(--lines --points --stream 0.4)],
refplot => <<'EOF' );
@@ -1181,7 +1331,7 @@ EOF
tryplot( testname => 'streaming with --xlen',
cmd => q{seq 500 | awk 'BEGIN{ print 0; } {print (NR==3)? "exit" : $0; fflush(); system("sleep 0.6");}'},
cmd => q{seq 500 | gawk 'BEGIN{ print 0; } {print (NR==3)? "exit" : $0; fflush(); system("sleep 0.6");}'},
options => [qw(--lines --points --stream 0.4 --xlen 1.1)],
refplot => <<'EOF' );
@@ -1267,7 +1417,7 @@ tryplot( testname => 'streaming with --xlen',
EOF
tryplot( testname => 'streaming with --monotonic',
cmd => q{seq 500 | awk '{if(NR==11) {print "exit";} else {x=(NR-1)%5; if(x==0) {print -1,-1;} print x,NR;}; fflush(); system("sleep 0.6");}'},
cmd => q{seq 500 | gawk '{if(NR==11) {print "exit";} else {x=(NR-1)%5; if(x==0) {print -1,-1;} print x,NR;}; fflush(); system("sleep 0.6");}'},
options => [qw(--lines --points --stream 0.4 --domain --monotonic)],
refplot => <<'EOF' );
@@ -1673,7 +1823,7 @@ tryplot( testname => 'streaming with --monotonic',
EOF
tryplot( testname => '--timefmt streaming plot with --xlen',
cmd => q{seq 5 | awk 'BEGIN{ print strftime("%d %b %Y %T",1382249107-1,1),-4;} {if(NR==3) {print "exit";} else{ print strftime("%d %b %Y %T",1382249107+$1,1),$1;} fflush(); system("sleep 0.6")}'},
cmd => q{seq 5 | gawk 'BEGIN{ print strftime("%d %b %Y %T",1382249107-1,1),-4;} {if(NR==3) {print "exit";} else{ print strftime("%d %b %Y %T",1382249107+$1,1),$1;} fflush(); system("sleep 0.6")}'},
options => ['--points', '--lines',
'--domain', '--timefmt', '%d %b %Y %H:%M:%S',
qw(--stream 0.4 --xlen 3)],
@@ -1761,7 +1911,7 @@ tryplot( testname => '--timefmt streaming plot with --xlen',
EOF
tryplot( testname => '--timefmt streaming plot with --monotonic',
cmd => q{seq 10 | awk '{x=(NR-1)%5; if(x==0) {print strftime("%d %b %Y %T",1382249107-1,-4),-4;} print strftime("%d %b %Y %T",1382249107+x,1),NR; fflush(); system("sleep 0.6")}'},
cmd => q{seq 10 | gawk '{x=(NR-1)%5; if(x==0) {print strftime("%d %b %Y %T",1382249107-1,-4),-4;} print strftime("%d %b %Y %T",1382249107+x,1),NR; fflush(); system("sleep 0.6")}'},
options => ['--points', '--lines',
'--domain', '--timefmt', '%d %b %Y %H:%M:%S',
qw(--stream 0.4 --monotonic)],
@@ -2177,7 +2327,7 @@ sub tryplot
my %args = @_;
my @options = ('--exit',
'--extracmds', 'unset grid',
qw(--unset grid),
'--terminal', 'dumb 100,40');
unshift @options, @{$args{options}};