4 use List::Util qw( max sum );
5 use open qw( :std :utf8 );
9 use Getopt::Long '2.33', qw( :config gnu_getopt );
10 sub podexit { require Pod::Usage; Pod::Usage::pod2usage(-exitval => 0, @_) }
15 'usage|h' => sub { podexit() },
16 'help' => sub { podexit(-verbose => 2) },
17 ) or exit 64; # EX_USAGE
18 $opt{width} ||= $ENV{COLUMNS} || 80;
21 my @lines = readline or exit;
23 my @values = map { s/^\h* ( -? [0-9]* (?:\.[0-9]+)? )//x and $1 } @lines;
24 my @order = sort { $b <=> $a } grep { length } @values;
25 my $maxval = $order[0];
26 my $minval = min $order[-1], 0;
28 my $lenval = max map { length } @order;
29 my $len = 1 + max map { length } @lines; # left padding
30 my $size = ($maxval - $minval) &&
31 ($opt{width} - $lenval - $len) / ($maxval - $minval); # bar multiplication
34 if ($opt{markers} // 1) {
35 sub orderpos { (($order[$_[0]] + $order[$_[0] + .5]) / 2 - $minval) * $size }
36 $barmark[ (sum(@order) / @order - $minval) * $size ] = '='; # average
37 $barmark[ orderpos($#order / 2) ] = '+'; # mean
38 $barmark[ -$minval * $size ] = '|' if $minval < 0; # zero
39 defined and $opt{color} and $_ = "\e[36m$_\e[0m" for @barmark;
42 for my $nr (0 .. $#lines) {
43 my $val = $values[$nr];
45 my $color = !$opt{color} ? 0 :
46 $val == $order[0] ? 32 : # max
47 $val == $order[-1] ? 31 : # min
49 printf "\e[%sm", $color if $color;
50 printf "%*s", $lenval, $val;
51 print "\e[0m" if $color;
53 printf '%-*s', $len, $lines[$nr];
54 print $barmark[$_] // '-' for 1 .. (($val || 0) - $minval) * $size;
62 graph - append bar chart to input numbers
66 B<graph> [<options>] [<input>]
70 Each line starting with a number is given a bar to visualise relative sizes.
78 Disable colored output of values and bar markers.
82 Statistical positions to indicate on bars.
83 Cannot be customized yet,
84 only disabled by providing an empty argument.
86 Any value enables all marker characters:
93 the sum of all values divided by the number of counted lines.
98 the middle value or average between middle values.
102 =item -w, --width=<columns>
104 Override the maximum number of columns to use.
105 Appended graphics will extend to fill up the entire screen.
111 Commonly used after counting, such as users on the current server:
113 users | sed 's/ /\n/g' | sort | uniq -c | graph
115 Letter frequencies in text files:
117 cat /usr/share/games/fortunes/*.u8 |
118 perl -CO -nE 'say for grep length, split /\PL*/, uc' |
119 sort | uniq -c | graph
121 Memory usage of user processes:
123 ps xo %mem,pid,cmd | graph -l40
125 Sizes (in megabytes) of all root files and directories:
129 Number of HTTP requests per day:
131 cat log/access.log | cut -d\ -f4 | cut -d: -f1 | uniq -c | graph
133 Any kind of database query with leading counts:
135 echo 'SELECT count(*),schemaname FROM pg_tables GROUP BY 2' |
138 Git statistics, such commit count by year:
140 git log --pretty=%ci | cut -b-4 | uniq -c | graph
142 Or the most frequent authors:
144 git shortlog -sn | graph | head -3
148 Mischa POSLAWSKY <perl@shiar.org>