#!/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 ".png", is extracted # from the "Id:" field of the input file. # input file format: # Id: # [] name () () # $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( ) {print;} close(FOO); unlink($infile); exit 0;