diff --git a/TimeSeries.pm b/TimeSeries.pm index e673b0c..fd8fcdf 100644 --- a/TimeSeries.pm +++ b/TimeSeries.pm @@ -27,7 +27,7 @@ use Data::Dumper; use HTTP::Date qw(parse_date); use Time::Local qw(timegm_nocheck); -$VERSION = do { my @r=(q$Revision: 1.11 $=~/\d+/g);sprintf "%d."."%02d"x$#r,@r}; +$VERSION = do { my @r=(q$Revision: 1.12 $=~/\d+/g);sprintf "%d."."%02d"x$#r,@r}; =head2 new(%opts) @@ -192,6 +192,21 @@ sub log_y { return $oldlog_y; } +=head2 stacked([$stacked]) + +If $stacked is non-zero, the timeseries are stacked. + +The return value is the old value of this setting. + +=cut + +sub stacked { + my ($self, $stacked) = @_; + my $oldstacked = $self->{stacked}; + $self->{stacked} = $stacked if (defined($stacked)); + return $oldstacked; +} + =head2 output_format([$output_format]) Sets a new output format if $output_format is given. In any case the old @@ -301,14 +316,22 @@ sub plot { my ($self) = @_; #print Dumper($self); - my ($datafh, $datafn) = tempfile(); + my ($datafh, $datafn) = tempfile("tsplotXXXXXXXX", UNLINK => 0); for my $i (@{$self->{data}}) { my $time = $i->[0]; my $data = $i->[1]; print $datafh $time; - for my $j (@$data) { - print $datafh "\t", $j + 0; + if ($self->{stacked}) { + my $v = 0; + for my $j (@$data) { + $v += ($j || 0); + print $datafh "\t", $v; + } + } else { + for my $j (@$data) { + print $datafh "\t", ($j || 0) + 0; + } } print $datafh "\n"; } diff --git a/top_n b/top_n new file mode 100755 index 0000000..1630e63 --- /dev/null +++ b/top_n @@ -0,0 +1,42 @@ +#!/usr/bin/perl -w +use strict; + +my $n = shift; +my $f = shift; +my $v = shift; + +my @data; +my %s; +while (<>) { + chomp; + my @a = split(/\t/); + push @data, [@a]; + $s{$a[$f]} += $a[$v]; +} + +my @top_n = (sort { $s{$b} <=> $s{$a} } keys %s )[ 0 .. $n - 1 ]; +my %top_n = map { $_ => 1 } @top_n; + +my %index; + +for my $i (0 .. $#data) { + unless ($top_n{$data[$i][$f]}) { + my $val = $data[$i][$v]; + $data[$i][$v] = 0; + $data[$i][$f] = 'UNKNOWN'; + my $k = join("\t", @{$data[$i]}); + if (defined($index{$k})) { + $data[$index{$k}][$v] += $val; + $data[$i][$v] = undef; + } else { + $data[$i][$v] = $val; + $index{$k} = $i; + } + } +} + +for (@data) { + if (defined($_->[$v])) { + print join("\t", @$_), "\n"; + } +} diff --git a/tsplotv b/tsplotv new file mode 100755 index 0000000..80fa693 --- /dev/null +++ b/tsplotv @@ -0,0 +1,41 @@ +#!/usr/bin/perl -w + +=head1 NAME + +tsplotv - plot time series given in vertical format + +=head1 DESCRIPTION + +This program expects time series data in vertical format, I.e., +each line contains a tripel . + +=cut + +use strict; +use TimeSeries; + +binmode STDOUT, ':raw'; + +my %series; +my $ns; +my %data; + +my $ts = TimeSeries->new(); +while (<>) { + chomp; + my ($timestamp, $series, $value) = split(/\t/); + $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("below"); +$ts->stacked(1); +for my $timestamp (sort keys %data) { + my %d = %{$data{$timestamp}}; + my @values = @d{@series}; + $ts->add_timestring($timestamp, @values); +} + +my $g = $ts->plot(); +print $g