timeseries/tsplotvsql

141 lines
3.6 KiB
Plaintext
Raw Normal View History

#!/usr/bin/perl
2016-08-08 13:21:54 +02:00
=head1 NAME
tsplotv - plot time series given in vertical format
=head1 SYNOPSIS
tsplotv
2019-02-10 15:03:08 +01:00
[--dbname dbname]
2016-08-08 13:21:54 +02:00
[--finalresolution dpi]
[--legend-position pos]
[--log-y]
[--output-format format ]
[--stacked]
[--style style]
[--time_t]
[--colors rgb-list]
[--configfile yaml]
[--yrange min:max]
2019-02-10 15:03:08 +01:00
[query ...]
2016-08-08 13:21:54 +02:00
=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;
2016-08-08 13:21:54 +02:00
use Getopt::Long;
use Pod::Usage;
use YAML qw(LoadFile);
2016-08-08 13:21:54 +02:00
use DBIx::SimpleConnect;
use TimeSeries;
2016-08-08 13:21:54 +02:00
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;
2016-08-08 13:21:54 +02:00
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,
2016-08-08 13:21:54 +02:00
'time_t' => \$time_t,
'colors=s' => \$colors,
'dbname=s' => \$dbname,
'configfile=s' => \$configfile,
'yrange=s' => \$yrange,
2016-08-08 13:21:54 +02:00
) or pod2usage(2);
pod2usage(1) if $help;
my $config = LoadFile($configfile) if $configfile;
2016-08-08 13:21:54 +02:00
binmode STDOUT, ':raw';
my $ns = 0;
2016-08-08 13:21:54 +02:00
my %data;
$config->{timeseries} //= {};
for (keys $config->{timeseries}->%*) {
$ns = $config->{timeseries}{$_}{order} if ($config->{timeseries}{$_}{order} // 0) > $ns;
}
2016-08-08 13:21:54 +02:00
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});
2016-08-08 13:21:54 +02:00
$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);
2016-08-08 13:21:54 +02:00
$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);
2016-08-08 13:21:54 +02:00
}
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