#!/usr/bin/perl -w
#
# $Id: barchart.pl,v 1.2 2000/01/28 16:07:37 kjc Exp $
#
# usage: barchart.pl < tcpdstat_output
# barchart.pl reads the output of tcpdstat from stdin, and then,
# create a png bartchart.
# the name of the output png file is "<id>.png", <id> is extracted
# from the "Id:" field of the input file.
# input file format:
# Id: <id>
# [<level>] name (<dontcare>) (<percent>)
#
$outfile = "date.png";
$infile = "fly.temp";
$scale=3;
$xoff = 8;
$yoff = 6;
$hight = 8;
$xmax = (100 + $xoff*2) * $scale;
$ymax = (($yoff + $hight) * 3 + $hight) * $scale;
# char size:
# tiny(5x8) small(6x12) medium(7x13,bold), large(8x16), giant(9x15,bold)
$chartype = "small";
$charhight = 12;
$charwidth = 6;
# color
$r = 80;
$g = 140;
$b = 255;
$toolpath = ".";
if ($0 =~ /(.*)\/.*/) {
$toolpath = $1;
}
$flyprog = "$toolpath/../bin/fly";
sub validcolor ($) {
my $val = shift;
if ($val < 0) {
$val = 0;
}
if ($val > 255) {
$val = 255;
}
return $val;
}
sub drawbox ($$$$$$$$$) {
my ($x1, $y1, $x2, $y2, $name, $val, $r, $g, $b) = @_;
my ($sx1, $sx2, $sy1, $sy2, $cx, $cy, $r0, $g0, $b0, $strval);
$sx1 = $x1 + 6;
$sx2 = $x2 + 6;
$sy1 = $y1 - 4;
$sy2 = $y2 - 4;
$r0 = validcolor($r);
$g0 = validcolor($g);
$b0 = validcolor($b);
print FLY "frect $x1,$y1,$x2,$y2,$r0,$g0,$b0\n";
print FLY "rect $x1,$y1,$x2,$y2,0,0,0\n";
$r0 = validcolor($r - 30);
$g0 = validcolor($g - 30);
$b0 = validcolor($b - 30);
print FLY "fpoly $r0,$g0,$b0,$x1,$y1,$sx1,$sy1,$sx2,$sy1,$x2,$y1\n";
print FLY "poly 0,0,0,$x1,$y1,$sx1,$sy1,$sx2,$sy1,$x2,$y1\n";
$r0 = validcolor($r - 60);
$g0 = validcolor($g - 60);
$b0 = validcolor($b - 60);
print FLY "fpoly $r0,$g0,$b0,$x2,$y1,$sx2,$sy1,$sx2,$sy2,$x2,$y2\n";
print FLY "poly 0,0,0,$x2,$y1,$sx2,$sy1,$sx2,$sy2,$x2,$y2\n";
$cx = ($x1 + $x2) / 2 - length($name) * $charwidth / 2;
if ($cx < $x1) {
$cx = $x1;
}
$cy = ($y1 + $y2) / 2 - $charhight;
print FLY "string 0,0,0,$cx,$cy,$chartype,$name\n";
if ($val > 0) {
$strval = sprintf("%d%%", $val + 0.5);
$cx = ($x1 + $x2) / 2 - length($strval) * $charwidth / 2;
if ($cx < $x1) {
$cx = $x1;
}
$cy = ($y1 + $y2) / 2;
print FLY "string 0,0,0,$cx,$cy,$chartype,$strval\n";
}
}
while (<>) {
# find Id
if (/^Id:\s*(\w+)/) {
$outfile = $1 . ".png";
last;
}
}
unless ($_) { die "Can't find Id info!\n"; }
open(FLY,"> $infile");
print FLY "new\n";
print FLY "size $xmax,$ymax\n";
print FLY "fill 1,1,255,255,255\n";
$cur_level = 0;
$x1 = $xoff * $scale;
$x2 = $x1 + 100 * $scale;
$y1 = 0 - $hight * $scale;
$y2 = $y1 + $hight * $scale;
while (<>) {
# find "[$level] $name (xxx) ($val)"
if (/^\[(\d+)\]\s+(\w+).*\(.*\).*\(\s*(\d+\.\d+)%\)/) {
$level = $1;
$name = $2;
$val = $3;
# don't draw level 0
next if ($level == 0);
# skip entries less than 5%
next if ($val < 4.5);
# XXX: ignore entries named "other" or "frag".
# this should be done by preprocessing.
next if ($name eq "other");
next if ($name eq "frag");
if ($level == $cur_level) {
# draw a box on the right side
$x1 = $x2;
$x2 = $x1 + $val * $scale;
$r += 20; $g += 20; $b += 20;
drawbox($x1, $y1, $x2, $y2, $name, $val, $r, $g, $b);
}
elsif ($level > $cur_level) {
# go down and draw a box
push @stack, $x1;
push @stack, $x2;
$x2 = $x1 + $val * $scale;
$y1 = $y2 + $yoff * $scale;
$y2 = $y1 + $hight * $scale;
drawbox($x1, $y1, $x2, $y2, $name, $val, $r, $g, $b);
}
else {
# draw an "other" box and restore $x1, $x2
while ($level < $cur_level) {
$x1 = $x2;
$x2 = pop @stack;
drawbox($x1, $y1, $x2, $y2, "", -1, 200, 200, 200);
$x1 = pop @stack;
$y1 = $y1 - ($hight + $yoff) * $scale;
$y2 = $y1 + $hight * $scale;
$cur_level--;
}
$x1 = $x2;
$x2 = $x1 + $val * $scale;
$r += 20; $g += 20; $b += 20;
drawbox($x1, $y1, $x2, $y2, $name, $val, $r, $g, $b);
}
$cur_level = $level;
}
}
# draw "other" boxes
while (0 < $cur_level) {
$x1 = $x2;
$x2 = pop @stack;
drawbox($x1, $y1, $x2, $y2, "", -1, 200, 200, 200);
$x1 = pop @stack;
$y1 = $y1 - ($hight + $yoff) * $scale;
$y2 = $y1 + $hight * $scale;
$cur_level--;
}
close(FLY);
open(FOO,"$flyprog -q -i $infile -o $outfile |");
while( <FOO> ) {print;}
close(FOO);
unlink($infile);
exit 0;
syntax highlighted by Code2HTML, v. 0.9.1