mirror of
https://github.com/dkogan/feedgnuplot.git
synced 2025-05-06 06:21:16 +08:00
timefmt plots now work with streaming and with --xlen
This commit is contained in:
parent
d76f163be4
commit
c169330fca
122
bin/feedgnuplot
122
bin/feedgnuplot
@ -11,6 +11,7 @@ use threads;
|
|||||||
use threads::shared;
|
use threads::shared;
|
||||||
use Thread::Queue;
|
use Thread::Queue;
|
||||||
use Pod::Usage;
|
use Pod::Usage;
|
||||||
|
use Time::Piece;
|
||||||
|
|
||||||
my $VERSION = 1.24;
|
my $VERSION = 1.24;
|
||||||
|
|
||||||
@ -355,6 +356,21 @@ sub sendRangeCommand
|
|||||||
print PIPE $cmd;
|
print PIPE $cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub makeDomainNumeric
|
||||||
|
{
|
||||||
|
my ($domain0) = @_;
|
||||||
|
|
||||||
|
if ( $options{timefmt} )
|
||||||
|
{
|
||||||
|
my $timepiece = Time::Piece->strptime( $domain0, $options{timefmt} )
|
||||||
|
or die "Couldn't parse time format. String '$domain0' doesn't fit format '$options{timefmt}'";
|
||||||
|
|
||||||
|
return $timepiece->epoch();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $domain0;
|
||||||
|
}
|
||||||
|
|
||||||
sub mainThread
|
sub mainThread
|
||||||
{
|
{
|
||||||
my $valuesPerPoint = 1;
|
my $valuesPerPoint = 1;
|
||||||
@ -406,18 +422,6 @@ sub mainThread
|
|||||||
print PIPE "set terminal $options{terminal}\n" if $options{terminal};
|
print PIPE "set terminal $options{terminal}\n" if $options{terminal};
|
||||||
print PIPE "set output \"$outputfile\"\n" if $outputfile;
|
print PIPE "set output \"$outputfile\"\n" if $outputfile;
|
||||||
|
|
||||||
|
|
||||||
# If a bound isn't given I want to set it to the empty string, so I can communicate it simply to
|
|
||||||
# gnuplot
|
|
||||||
print PIPE "set xtics\n";
|
|
||||||
if($options{y2})
|
|
||||||
{
|
|
||||||
print PIPE "set ytics nomirror\n";
|
|
||||||
print PIPE "set y2tics\n";
|
|
||||||
# if any of the ranges are given, set the range
|
|
||||||
sendRangeCommand( "y2range", $options{y2min}, $options{y2max} );
|
|
||||||
}
|
|
||||||
|
|
||||||
# set up plotting style
|
# set up plotting style
|
||||||
my $style = '';
|
my $style = '';
|
||||||
if($options{lines}) { $style .= 'lines';}
|
if($options{lines}) { $style .= 'lines';}
|
||||||
@ -427,11 +431,6 @@ sub mainThread
|
|||||||
$options{curvestyleall} = "with circles $options{curvestyleall}";
|
$options{curvestyleall} = "with circles $options{curvestyleall}";
|
||||||
}
|
}
|
||||||
|
|
||||||
# if any of the ranges are given, set the range
|
|
||||||
sendRangeCommand( "xrange", $options{xmin}, $options{xmax} );
|
|
||||||
sendRangeCommand( "yrange", $options{ymin}, $options{ymax} );
|
|
||||||
sendRangeCommand( "zrange", $options{zmin}, $options{zmax} );
|
|
||||||
|
|
||||||
print PIPE "set style data $style\n" if $style;
|
print PIPE "set style data $style\n" if $style;
|
||||||
print PIPE "set grid\n";
|
print PIPE "set grid\n";
|
||||||
|
|
||||||
@ -459,13 +458,8 @@ sub mainThread
|
|||||||
print(PIPE "set view equal xy\n");
|
print(PIPE "set view equal xy\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if($options{colormap})
|
|
||||||
{
|
|
||||||
sendRangeCommand( "cbrange", $options{zmin}, $options{zmax} );
|
|
||||||
}
|
|
||||||
|
|
||||||
# For the specified values, set the legend entries to 'title "blah blah"'
|
# For the specified values, set the legend entries to 'title "blah blah"'
|
||||||
if(@{$options{legend}})
|
if(defined $options{legend} && @{$options{legend}})
|
||||||
{
|
{
|
||||||
# @{$options{legend}} is a list where consecutive pairs are (curveID,
|
# @{$options{legend}} is a list where consecutive pairs are (curveID,
|
||||||
# legend). I use $options{legend} here instead of $options{legend_hash}
|
# legend). I use $options{legend} here instead of $options{legend_hash}
|
||||||
@ -480,7 +474,7 @@ sub mainThread
|
|||||||
}
|
}
|
||||||
|
|
||||||
# add the extra curve options
|
# add the extra curve options
|
||||||
if(@{$options{curvestyle}})
|
if(defined $options{curvestyle} && @{$options{curvestyle}})
|
||||||
{
|
{
|
||||||
# @{$options{curvestyle}} is a list where consecutive pairs are (curveID,
|
# @{$options{curvestyle}} is a list where consecutive pairs are (curveID,
|
||||||
# style). I use $options{curvestyle} here instead of
|
# style). I use $options{curvestyle} here instead of
|
||||||
@ -495,9 +489,12 @@ sub mainThread
|
|||||||
}
|
}
|
||||||
|
|
||||||
# For the values requested to be printed on the y2 axis, set that
|
# For the values requested to be printed on the y2 axis, set that
|
||||||
foreach (@{$options{y2}})
|
if( defined $options{y2} )
|
||||||
{
|
{
|
||||||
addCurveOption($_, 'axes x1y2 linewidth 3');
|
foreach (@{$options{y2}})
|
||||||
|
{
|
||||||
|
addCurveOption($_, 'axes x1y2 linewidth 3');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# timefmt
|
# timefmt
|
||||||
@ -508,7 +505,7 @@ sub mainThread
|
|||||||
}
|
}
|
||||||
|
|
||||||
# add the extra global options
|
# add the extra global options
|
||||||
if($options{extracmds})
|
if(defined $options{extracmds})
|
||||||
{
|
{
|
||||||
foreach (@{$options{extracmds}})
|
foreach (@{$options{extracmds}})
|
||||||
{
|
{
|
||||||
@ -517,13 +514,16 @@ sub mainThread
|
|||||||
}
|
}
|
||||||
|
|
||||||
# set up histograms
|
# set up histograms
|
||||||
$options{binwidth} ||= 1; # if no binwidth given, set it to 1
|
if( defined $options{histogram} )
|
||||||
print PIPE
|
|
||||||
"set boxwidth $options{binwidth}\n" .
|
|
||||||
"histbin(x) = $options{binwidth} * floor(0.5 + x/$options{binwidth})\n";
|
|
||||||
foreach (@{$options{histogram}})
|
|
||||||
{
|
{
|
||||||
setCurveAsHistogram( $_ );
|
$options{binwidth} ||= 1; # if no binwidth given, set it to 1
|
||||||
|
print PIPE
|
||||||
|
"set boxwidth $options{binwidth}\n" .
|
||||||
|
"histbin(x) = $options{binwidth} * floor(0.5 + x/$options{binwidth})\n";
|
||||||
|
foreach (@{$options{histogram}})
|
||||||
|
{
|
||||||
|
setCurveAsHistogram( $_ );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# regexp for a possibly floating point, possibly scientific notation number
|
# regexp for a possibly floating point, possibly scientific notation number
|
||||||
@ -536,6 +536,26 @@ sub mainThread
|
|||||||
$pointRE .= '(' . join('\s+', ($numRE) x $valuesPerPoint) . ')';
|
$pointRE .= '(' . join('\s+', ($numRE) x $valuesPerPoint) . ')';
|
||||||
$pointRE = qr/$pointRE/;
|
$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
|
||||||
|
print PIPE "set xtics\n";
|
||||||
|
|
||||||
|
if($options{y2})
|
||||||
|
{
|
||||||
|
print PIPE "set ytics nomirror\n";
|
||||||
|
print PIPE "set y2tics\n";
|
||||||
|
# if any of the ranges are given, set the range
|
||||||
|
sendRangeCommand( "y2range", $options{y2min}, $options{y2max} );
|
||||||
|
}
|
||||||
|
|
||||||
|
# if any of the ranges are given, set the range
|
||||||
|
sendRangeCommand( "xrange", $options{xmin}, $options{xmax} );
|
||||||
|
sendRangeCommand( "yrange", $options{ymin}, $options{ymax} );
|
||||||
|
sendRangeCommand( "zrange", $options{zmin}, $options{zmax} );
|
||||||
|
sendRangeCommand( "cbrange", $options{zmin}, $options{zmax} ) if($options{colormap});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# latest domain variable present in our data
|
# latest domain variable present in our data
|
||||||
@ -544,6 +564,10 @@ sub mainThread
|
|||||||
# The domain of the current point
|
# The domain of the current point
|
||||||
my @domain;
|
my @domain;
|
||||||
|
|
||||||
|
# The x-axis domain represented as a number. This is exactly the same as
|
||||||
|
# $domain[0] unless the x-axis domain uses a timefmt. Then this is the
|
||||||
|
# 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
|
# I should be using the // operator, but I'd like to be compatible with perl 5.8
|
||||||
while( $_ = (defined $dataQueue ? $dataQueue->dequeue() : <>))
|
while( $_ = (defined $dataQueue ? $dataQueue->dequeue() : <>))
|
||||||
@ -556,7 +580,7 @@ sub mainThread
|
|||||||
elsif( $options{stream} && /^replot/o )
|
elsif( $options{stream} && /^replot/o )
|
||||||
{
|
{
|
||||||
# /timertick/ determines if the timer was the source of the replot
|
# /timertick/ determines if the timer was the source of the replot
|
||||||
replot( $domain[0], /timertick/ );
|
replot( $domain0_numeric, /timertick/ );
|
||||||
}
|
}
|
||||||
elsif(! /^replot/o)
|
elsif(! /^replot/o)
|
||||||
{
|
{
|
||||||
@ -574,6 +598,8 @@ sub mainThread
|
|||||||
{
|
{
|
||||||
/($domainRE)/go or next;
|
/($domainRE)/go or next;
|
||||||
$domain[0] = $1;
|
$domain[0] = $1;
|
||||||
|
$domain0_numeric = makeDomainNumeric( $domain[0] );
|
||||||
|
|
||||||
if($options{'3d'})
|
if($options{'3d'})
|
||||||
{
|
{
|
||||||
/($numRE)/go or next;
|
/($numRE)/go or next;
|
||||||
@ -581,17 +607,17 @@ sub mainThread
|
|||||||
}
|
}
|
||||||
elsif( $options{monotonic} )
|
elsif( $options{monotonic} )
|
||||||
{
|
{
|
||||||
if( defined $latestX && $domain[0] < $latestX )
|
if( defined $latestX && $domain0_numeric < $latestX )
|
||||||
{
|
{
|
||||||
# the x-coordinate of the new point is in the past, so I wipe out
|
# 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
|
# all the data and start anew. Before I wipe the old data, I
|
||||||
# replot the old data
|
# replot the old data
|
||||||
replot( $domain[0] );
|
replot( $domain0_numeric );
|
||||||
clearCurves();
|
clearCurves();
|
||||||
$latestX = undef;
|
$latestX = undef;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ $latestX = $domain[0]; }
|
{ $latestX = $domain0_numeric; }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -608,6 +634,7 @@ sub mainThread
|
|||||||
{
|
{
|
||||||
$domain[0] = $.;
|
$domain[0] = $.;
|
||||||
}
|
}
|
||||||
|
$domain0_numeric = makeDomainNumeric( $domain[0] );
|
||||||
}
|
}
|
||||||
|
|
||||||
my $id = -1;
|
my $id = -1;
|
||||||
@ -617,7 +644,7 @@ sub mainThread
|
|||||||
else {$id++; }
|
else {$id++; }
|
||||||
|
|
||||||
pushPoint(getCurve($id),
|
pushPoint(getCurve($id),
|
||||||
"@domain $2\n", $domain[0]);
|
"@domain $2\n", $domain0_numeric);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -645,8 +672,7 @@ sub mainThread
|
|||||||
|
|
||||||
sub pruneOldData
|
sub pruneOldData
|
||||||
{
|
{
|
||||||
my ($x, $xlen) = @_;
|
my ($oldestx) = @_;
|
||||||
my $oldestx = $x - $xlen;
|
|
||||||
|
|
||||||
foreach my $curve (@curves)
|
foreach my $curve (@curves)
|
||||||
{
|
{
|
||||||
@ -815,7 +841,7 @@ sub replot
|
|||||||
# }
|
# }
|
||||||
|
|
||||||
|
|
||||||
my ($domain0, $replot_is_from_timer) = @_;
|
my ($domain0_numeric, $replot_is_from_timer) = @_;
|
||||||
|
|
||||||
my $now = [gettimeofday];
|
my $now = [gettimeofday];
|
||||||
|
|
||||||
@ -834,9 +860,15 @@ sub replot
|
|||||||
if ( defined $options{xlen} )
|
if ( defined $options{xlen} )
|
||||||
{
|
{
|
||||||
# we have an --xlen, so we need to clean out the old data
|
# we have an --xlen, so we need to clean out the old data
|
||||||
pruneOldData( $domain0, $options{xlen} );
|
pruneOldData( $domain0_numeric - $options{xlen} );
|
||||||
|
|
||||||
my ($xmin, $xmax) = ($domain0 - $options{xlen}, $domain0);
|
my ($xmin, $xmax) = ($domain0_numeric - $options{xlen}, $domain0_numeric);
|
||||||
|
if ( defined $options{timefmt} )
|
||||||
|
{
|
||||||
|
# if we're using a timefmt, I need to convert my xmin range from
|
||||||
|
# seconds-since-the-epoch BACK to the timefmt. Sheesh
|
||||||
|
($xmin, $xmax) = map {Time::Piece->strptime( $_, '%s' )->strftime( $options{timefmt} ) } ($xmin, $xmax);
|
||||||
|
}
|
||||||
sendRangeCommand( "xrange", $xmin, $xmax );
|
sendRangeCommand( "xrange", $xmin, $xmax );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -852,10 +884,10 @@ sub replot
|
|||||||
# function to add a point to the plot. Assumes that the curve indexed by $idx already exists
|
# function to add a point to the plot. Assumes that the curve indexed by $idx already exists
|
||||||
sub pushPoint
|
sub pushPoint
|
||||||
{
|
{
|
||||||
my ($curve, $datastring, $domain0) = @_;
|
my ($curve, $datastring, $domain0_numeric) = @_;
|
||||||
|
|
||||||
push @{$curve->{datastring_meta}}, { offset_start => length( $curve->{datastring} ) + $curve->{datastring_offset},
|
push @{$curve->{datastring_meta}}, { offset_start => length( $curve->{datastring} ) + $curve->{datastring_offset},
|
||||||
domain => $domain0 };
|
domain => $domain0_numeric };
|
||||||
$curve->{datastring} .= $datastring;
|
$curve->{datastring} .= $datastring;
|
||||||
|
|
||||||
$haveNewData = 1;
|
$haveNewData = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user