posible auto sample size?
[cheali-logview-gnuplot] / driveGnuPlots.pl
1 #!/usr/bin/perl -w
2 use strict;
3
4 sub usage {
5     print "Usage: $0 <options>\n";
6     print <<OEF;
7 where options are (in order):
8
9   NumberOfStreams                         How many streams to plot (windows)
10   Stream1_WindowSampleSize <Stream2...>   This many window samples for each stream
11   Stream1_Title <Stream2_Title> ...       Title used for each stream
12   (Optional) Stream1_geometry <Stream2_geometry>...  X and Y position in pixels from the top left
13
14 The last parameters (the optionally provided geometries of the gnuplot windows) 
15 are of the form: 
16   WIDTHxHEIGHT+XOFF+YOFF
17 OEF
18     exit(1);
19 }
20
21 sub Arg {
22     if ($#ARGV < $_[0]) {
23         print "Expected parameter missing...\n\n";
24         usage;
25     }
26     $ARGV[int($_[0])];
27 }
28
29 sub main {
30     my $argIdx = 0;
31     my $numberOfStreams = Arg($argIdx++);
32     print "Will display $numberOfStreams Streams (in $numberOfStreams windows)...\n";
33     my @sampleSizes;
34     for(my $i=0; $i<$numberOfStreams; $i++) {
35         my $samples = Arg($argIdx++);
36         push @sampleSizes, $samples;
37         print "Stream ".($i+1)." will use a window of $samples samples\n";
38     }
39     my @titles;
40     for(my $i=0; $i<$numberOfStreams; $i++) {
41         my $title = Arg($argIdx++);
42         push @titles, $title;
43         print "Stream ".($i+1)." will use a title of '$title'\n";
44     }
45     my @geometries;
46     if ($#ARGV >= $argIdx) {
47         for(my $i=0; $i<$numberOfStreams; $i++) {
48             my $geometry = Arg($argIdx++);
49             push @geometries, $geometry;
50             print "Stream ".($i+1)." will use a geometry of '$geometry'\n";
51         }
52     }
53     my $terminal = "";
54     open GNUPLOT_TERM, "echo 'show terminal;' | gnuplot 2>&1 |";
55     while (<GNUPLOT_TERM>) {
56         if (m/terminal type is (\w+)/) {
57             $terminal=$1;
58         }
59     }
60     close GNUPLOT_TERM;
61
62     # unfortunately, the wxt terminal type does not support positioning. 
63     # hardcode it...
64     $terminal  = "x11";
65
66         my $x_start = 10;
67         my $y_start = 30;
68         my $x_space = 5; # gnuplot needs some space
69         my $y_space = 15;
70         my $w = 320;
71         my $h = 200;
72         my $x = $x_start;
73         my $y = $y_start;
74
75         my ($x_size, $y_size) = ( 1,1 );
76         my $vertical = 1;
77         foreach my $title (@titles) {
78                 if ( $title =~ m/,$/ ) {
79                         $y_size = $vertical if $vertical > $y_size;
80                         $vertical = 1;
81                         $x_size++;
82                 } else {
83                         $vertical++;
84                 }
85         }
86         $vertical--;
87         $y_size = $vertical if $vertical > $y_size;
88         print "# grid $x_size x $y_size\n";
89
90         my $info = `xwininfo -root`;
91         if ( $info =~ m/-geometry (\d+)x(\d+)/ ) {
92                 my ( $x_screen, $y_screen ) = ( $1, $2 );
93                 $w = int( ( $x_screen - ( 2 * $x_start ) - ( ($x_size-1) * $x_space ) ) / $x_size );
94                 $h = int( ( $y_screen - ( 2 * $y_start ) - ( ($y_size-1) * $y_space ) ) / $y_size );
95                 print "# graph size $w x $h\n";
96         }
97
98         #@sampleSizes = ( $w x $numberOfStreams );
99
100     my @gnuplots;
101     my @buffers;
102     my @xcounters;
103     shift @ARGV; # number of streams
104     for(my $i=0; $i<$numberOfStreams; $i++) {
105         shift @ARGV; # sample size
106         shift @ARGV; # title
107         shift @ARGV; # geometry
108         local *PIPE;
109
110         my $geometry = "${w}x${h}+${x}+${y}";
111         $geometries[$i] = $geometry;
112         print "# $i $titles[$i] $geometry\n";
113         $geometry = " -geometry $geometry";
114
115         if ( $titles[$i] =~ s/,$// ) {
116                 $x += $w + $x_space;
117                 $y  = $y_start;
118         } else {
119                 $y += $h + $y_space;
120         }
121
122         open PIPE, "|gnuplot $geometry " || die "Can't initialize gnuplot number ".($i+1)."\n";
123         select((select(PIPE), $| = 1)[0]);
124         push @gnuplots, *PIPE;
125         print PIPE "set xtics\n";
126         print PIPE "set ytics\n";
127 #       print PIPE "set style data linespoints\n";
128         print PIPE "set style data lines\n";
129         print PIPE "set grid\n";
130         if ($numberOfStreams == 1) {
131             print PIPE "set terminal $terminal title '".$titles[0]."' noraise\n";
132         } else {
133             print PIPE "set terminal $terminal noraise\n";
134         }
135         print PIPE "set autoscale\n";
136         my @data = [];
137         push @buffers, @data;
138         push @xcounters, 0;
139     }
140     my $streamIdx = 0;
141     select((select(STDOUT), $| = 1)[0]);
142     while(<>) {
143         chomp;
144         my @parts = split /:/;
145         $streamIdx = $parts[0];
146         my $buf = $buffers[$streamIdx];
147         my $pip = $gnuplots[$streamIdx];
148         my $xcounter = $xcounters[$streamIdx];
149         my $title = $titles[$streamIdx];
150
151         # data buffering (up to stream sample size)
152         push @{$buf}, $parts[1];
153         #print "stream $streamIdx: ";
154         print $pip "set xrange [".($xcounter-$sampleSizes[$streamIdx]).":".($xcounter+1)."]\n";
155         if ($numberOfStreams == 1) {
156             print $pip "plot \"-\"\n";
157         } else {
158             print $pip "plot \"-\" title '$title'\n";
159         }
160         my $cnt = 0;
161         for my $elem (reverse @{$buf}) {
162             #print " ".$elem;
163             print $pip ($xcounter-$cnt)." ".$elem."\n";
164             $cnt += 1;
165         }
166         #print "\n";
167         print $pip "e\n";
168         if ($cnt>=$sampleSizes[$streamIdx]) {
169             shift @{$buf};
170         }
171         $xcounters[$streamIdx]++;
172     }
173     for(my $i=0; $i<$numberOfStreams; $i++) {
174         my $pip = $gnuplots[$i];
175         print $pip "exit;\n";
176         close $pip;
177     }
178 }
179
180 main;