http://users.softlab.ntua.gr/~ttsiod/gnuplotStreaming.html
[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 @gnuplots;
67     my @buffers;
68     my @xcounters;
69     shift @ARGV; # number of streams
70     for(my $i=0; $i<$numberOfStreams; $i++) {
71         shift @ARGV; # sample size
72         shift @ARGV; # title
73         shift @ARGV; # geometry
74         local *PIPE;
75         my $geometry = "";
76         if (-1 != $#geometries) {
77             $geometry = " -geometry ".$geometries[$i];
78         }
79         open PIPE, "|gnuplot $geometry " || die "Can't initialize gnuplot number ".($i+1)."\n";
80         select((select(PIPE), $| = 1)[0]);
81         push @gnuplots, *PIPE;
82         print PIPE "set xtics\n";
83         print PIPE "set ytics\n";
84         print PIPE "set style data linespoints\n";
85         print PIPE "set grid\n";
86         if ($numberOfStreams == 1) {
87             print PIPE "set terminal $terminal title '".$titles[0]."' noraise\n";
88         } else {
89             print PIPE "set terminal $terminal noraise\n";
90         }
91         print PIPE "set autoscale\n";
92         my @data = [];
93         push @buffers, @data;
94         push @xcounters, 0;
95     }
96     my $streamIdx = 0;
97     select((select(STDOUT), $| = 1)[0]);
98     while(<>) {
99         chomp;
100         my @parts = split /:/;
101         $streamIdx = $parts[0];
102         my $buf = $buffers[$streamIdx];
103         my $pip = $gnuplots[$streamIdx];
104         my $xcounter = $xcounters[$streamIdx];
105         my $title = $titles[$streamIdx];
106
107         # data buffering (up to stream sample size)
108         push @{$buf}, $parts[1];
109         #print "stream $streamIdx: ";
110         print $pip "set xrange [".($xcounter-$sampleSizes[$streamIdx]).":".($xcounter+1)."]\n";
111         if ($numberOfStreams == 1) {
112             print $pip "plot \"-\"\n";
113         } else {
114             print $pip "plot \"-\" title '$title'\n";
115         }
116         my $cnt = 0;
117         for my $elem (reverse @{$buf}) {
118             #print " ".$elem;
119             print $pip ($xcounter-$cnt)." ".$elem."\n";
120             $cnt += 1;
121         }
122         #print "\n";
123         print $pip "e\n";
124         if ($cnt>=$sampleSizes[$streamIdx]) {
125             shift @{$buf};
126         }
127         $xcounters[$streamIdx]++;
128     }
129     for(my $i=0; $i<$numberOfStreams; $i++) {
130         my $pip = $gnuplots[$i];
131         print $pip "exit;\n";
132         close $pip;
133     }
134 }
135
136 main;