Compare commits

..

No commits in common. "d3af2e6a5b3960d05dbaa8774c59e4e82012a74c" and "6d6400d3ebbd946420bea4f5ae3284bc63349abd" have entirely different histories.

2 changed files with 59 additions and 197 deletions

108
tsplotsql
View File

@ -1,42 +1,30 @@
#!/usr/bin/perl #!/usr/bin/perl -w
use v5.24;
use warnings;
use Getopt::Long;
use Pod::Usage;
use DBIx::SimpleConnect;
use TimeSeries;
=head1 NAME =head1 NAME
tsplot - plot time series in column format tsplotv - plot time series given in vertical format
=head1 SYNOPSIS =head1 SYNOPSIS
tsplot tsplotv
[--dbname dbname] [--dbname dbname]
[--finalresolution dpi] [--finalresolution dpi]
[--legend-position pos] [--legend-position pos]
[--log-y]
[--output-format format ] [--output-format format ]
[--stacked] [--stacked]
[--style style] [--style style]
[--time_t]
[--yrange min max]
[query ...] [query ...]
=head1 DESCRIPTION =head1 DESCRIPTION
This program expects time series data in column format, I.e., This program expects time series data in vertical format, I.e.,
each line contains a timestamp and the values for each series, except each line contains a tab-separated tripel <time, series, value>.
the first one which contains the column headers, which are used for the
legend. Columns are separated by any amount of whitespace unless the
--tsv option is given which enables tab-separated columns.
The default legend position is "top right", same as with gnuplot. The default legend position is "top right", same as with gnuplot.
Another frequently useful position (especially if you have lots of series) Another frequently useful position (especially if you have lots of series)
is "below". Note that positions which consist of several words (such as is "below". Note that positions which consist of several words (such as
"top right") need to be passed to tsplotv as a single argument, so the "top right" need to be passed to tsplotv as a single argument, so the
space needs to be hidden from the shell by use of quotes or a backslash. space needs to be hidden from the shell by use of quotes or a backslash.
The default output format is "png", the default style is "lines". The default output format is "png", the default style is "lines".
@ -47,62 +35,76 @@ output formats, and styles.
The --stacked option causes the time series to be stacked on top of each The --stacked option causes the time series to be stacked on top of each
other. other.
The --time_t option specifies that the timestamps are in seconds since
the epoch. Otherwise they are parsed by add_timestring function (which
in turn uses the parse_date function of the HTTP::Date module).
=cut =cut
use strict;
use TimeSeries;
use Getopt::Long;
use Pod::Usage;
use DBIx::SimpleConnect;
my $help;
my $legend_position = 'top right';
my $output_format = 'png'; my $output_format = 'png';
my $log_y =0;
my $time_t =0;
my $style = "lines";
my $tsv = 0;
my $stacked = 0; my $stacked = 0;
my @yrange; my $style = "lines";
my $keeptempfiles; my $log_y = 0;
my $finalresolution; my $finalresolution;
my $time_t = 0;
my $colors;
my $dbname; my $dbname;
GetOptions('output_format|output-format=s' => \$output_format, GetOptions('help|?' => \$help,
'log_y|log-y' => \$log_y, 'legend_position|legend-position=s' => \$legend_position,
'time_t' => \$time_t, 'output_format|output-format=s' => \$output_format,
'style=s' => \$style,
'tsv' => \$tsv,
'stacked' => \$stacked, 'stacked' => \$stacked,
'yrange=s{2}' => \@yrange, 'style:s' => \$style,
'keeptempfiles' => \$keeptempfiles, 'log_y|log-y' => \$log_y,
'finalresolution=i' => \$finalresolution, 'finalresolution=i' => \$finalresolution,
'time_t' => \$time_t,
'colors=s' => \$colors,
'dbname=s' => \$dbname, 'dbname=s' => \$dbname,
) ) or pod2usage(2);
or pod2usage(verbose => 0); pod2usage(1) if $help;
my $sep = $tsv ? qr/\t/ : ' ';
binmode STDOUT, ':raw'; binmode STDOUT, ':raw';
my %series;
my $ns;
my %data;
my $ts = TimeSeries->new(output_format => $output_format); my $ts = TimeSeries->new(output_format => $output_format);
$ts->{keeptempfiles} = 1 if $keeptempfiles;
my $dbh = DBIx::SimpleConnect->connect($dbname); my $dbh = DBIx::SimpleConnect->connect($dbname);
my $sth = $dbh->prepare($ARGV[0]);
$sth->execute();
my @legend = $sth->{NAME}->@*;
shift @legend;
$ts->legend(@legend);
while (my (@r) = $sth->fetchrow_array) { for my $q (@ARGV) {
my ($timestamp, @values) = @r; my $qdata = $dbh->selectall_arrayref($q);
for my $r (@$qdata) {
my ($timestamp, $series, $value) = @$r;
$series{$series} = ++$ns unless ($series{$series});
$data{$timestamp}{$series} = $value;
}
}
my @series = sort { $series{$a} <=> $series{$b} } keys %series;
$ts->legend(@series);
$ts->legend_position($legend_position);
$ts->stacked($stacked);
$ts->style($style);
$ts->log_y($log_y);
$ts->finalresolution($finalresolution) if $finalresolution;
if ($colors) {
$ts->colors(split(/,/, $colors));
}
for my $timestamp (sort keys %data) {
my %d = %{$data{$timestamp}};
my @values = @d{@series};
if ($time_t) { if ($time_t) {
$ts->add($timestamp, @values); $ts->add($timestamp, @values);
} else { } else {
$ts->add_timestring($timestamp, @values); $ts->add_timestring($timestamp, @values);
} }
} }
$ts->log_y($log_y);
$ts->style($style);
$ts->stacked($stacked);
$ts->yrange(@yrange);
$ts->finalresolution($finalresolution) if $finalresolution;
my $g = $ts->plot(); my $g = $ts->plot();
print $g print $g

View File

@ -1,140 +0,0 @@
#!/usr/bin/perl
=head1 NAME
tsplotv - plot time series given in vertical format
=head1 SYNOPSIS
tsplotv
[--dbname dbname]
[--finalresolution dpi]
[--legend-position pos]
[--log-y]
[--output-format format ]
[--stacked]
[--style style]
[--time_t]
[--colors rgb-list]
[--configfile yaml]
[--yrange min:max]
[query ...]
=head1 DESCRIPTION
This program expects time series data in vertical format, I.e.,
each line contains a tab-separated tripel <time, series, value>.
The default legend position is "top right", same as with gnuplot.
Another frequently useful position (especially if you have lots of series)
is "below". Note that positions which consist of several words (such as
"top right" need to be passed to tsplotv as a single argument, so the
space needs to be hidden from the shell by use of quotes or a backslash.
The default output format is "png", the default style is "lines".
See L<TimeSeries> for a description of possible legend positions,
output formats, and styles.
The --stacked option causes the time series to be stacked on top of each
other.
=cut
use v5.24;
use warnings;
use Getopt::Long;
use Pod::Usage;
use YAML qw(LoadFile);
use DBIx::SimpleConnect;
use TimeSeries;
my $help;
my $legend_position = 'top right';
my $output_format = 'png';
my $stacked = 0;
my $style = "lines";
my $log_y = 0;
my $finalresolution;
my $time_t = 0;
my $colors;
my $dbname;
my $configfile;
my $yrange;
GetOptions('help|?' => \$help,
'legend_position|legend-position=s' => \$legend_position,
'output_format|output-format=s' => \$output_format,
'stacked' => \$stacked,
'style:s' => \$style,
'log_y|log-y' => \$log_y,
'finalresolution=i' => \$finalresolution,
'time_t' => \$time_t,
'colors=s' => \$colors,
'dbname=s' => \$dbname,
'configfile=s' => \$configfile,
'yrange=s' => \$yrange,
) or pod2usage(2);
pod2usage(1) if $help;
my $config = LoadFile($configfile) if $configfile;
binmode STDOUT, ':raw';
my $ns = 0;
my %data;
$config->{timeseries} //= {};
for (keys $config->{timeseries}->%*) {
$ns = $config->{timeseries}{$_}{order} if ($config->{timeseries}{$_}{order} // 0) > $ns;
}
my $dbh = DBIx::SimpleConnect->connect($dbname);
for my $q (@ARGV) {
my $qdata = $dbh->selectall_arrayref($q);
for my $r (@$qdata) {
my ($timestamp, $series, $value) = @$r;
$config->{timeseries}{$series}{order} = ++$ns unless ($config->{timeseries}{$series}{order});
$data{$timestamp}{$series} = $value;
}
}
my @series = sort { $config->{timeseries}{$a}{order} <=> $config->{timeseries}{$b}{order} }
keys $config->{timeseries}->%*;
if ($colors) {
my @colors = split(/,/, $colors);
while (my ($i, $c) = each(@colors)) {
$config->{timeseries}{$series[$i]}{color} = $c;
}
}
my $ts = TimeSeries->new(output_format => $output_format);
$ts->legend(@series);
$ts->legend_position($legend_position);
$ts->stacked($stacked);
$ts->style($style);
$ts->log_y($log_y);
$ts->finalresolution($finalresolution) if $finalresolution;
$ts->colors(map $config->{timeseries}{$_}{color}, @series);
if ($yrange) {
$yrange =~s /^\[(.*)\]$/$1/; # remove optional brackets
my ($min, $max) = $yrange =~ /^(\*|[-+0-9E.]+):(\*|[-+0-9E.]+)$/;
$ts->yrange($min, $max);
}
for my $timestamp (sort keys %data) {
my %d = %{$data{$timestamp}};
my @values = @d{@series};
if ($time_t) {
$ts->add($timestamp, @values);
} else {
$ts->add_timestring($timestamp, @values);
}
}
my $g = $ts->plot();
print $g