#!/usr/bin/perl use strict; use warnings; use List::Util qw(min max); use Text::CSV_XS; use GD::Graph::bars; use Data::Dumper; my $csv = Text::CSV_XS->new(); my @keys; my @wanted; my %data; open my $csv_fh, '<', 'Latency.csv' or die; while ( my $row = $csv->getline($csv_fh) ) { if ( !@keys ) { @keys = @$row; @wanted = grep { /^<=\d+/ } @keys; next; } my %row; @row{@keys} = @$row; #next if $row{kernel} ne 'bsd.sp'; #next if $row{arch} ne 'AMD64'; #next if $row{size} ne '384'; my $graph = join ' ', 'Latency Distribution', @row{qw{ kernel size }}, 'Byte Frames'; my $item = join ' ', @row{qw{ arch nic }}; for (my $i = 0; $i < @wanted; $i++) { my $d; if ($row{TxFrames}) { $d = $row{ $wanted[$i] } / $row{TxFrames} * 100; } $data{$graph}[$i]{rate} = $wanted[$i]; $data{$graph}[$i]{data}{$row{load}}{$item} = $d; } } close $csv_fh; #print Dumper \%data; exit; foreach my $graph ( keys %data ) { my @d; my @k = map { $_->{rate} } @{ $data{$graph} }; my @l; my @m; my $seen_l; foreach my $item (@{ $data{$graph} }) { my $d = $item->{data}; my @rate_d; foreach my $size (sort { $a <=> $b } keys %{ $d }) { if (@rate_d) { push @l, '' if !$seen_l; push @rate_d, undef; } if (!@m) { @m = sort keys %{ $d->{$size} }; } for ( my $i = 0; $i < @m; $i++ ) { push @l, sprintf('%d%%', $size) if !$seen_l; push @rate_d, $d->{$size}{$m[$i]}; } } $seen_l = 1; push @d, \@rate_d; } make_graph( [ $graph, join(' | ', @m) ], \@k, \@l, \@d ); } sub make_graph { my ( $title, $legend, $labels, $data ) = @_; #print Dumper \@_; exit; my @all_points = grep { defined $_ } map {@$_} @$data; my $min_point = min @all_points; my $max_point = max @all_points; my $x_label_skip = @{ $labels } / @{ $data } - 1; my $graph = GD::Graph::bars->new( 800, 400 ); $graph->set( title => $title->[0], transparent => 0, cumulate => 'true', x_label => 'Percent Load - ' . $title->[1], x_label_skip => $x_label_skip, x_tick_offset => $x_label_skip / 4, y_label => "Percent of Frames", dclrs => [ qw/ cyan lblue lgreen lyellow orange lred red lgray / ], #y_min_value => $min_point * 0.9, #y_max_value => $max_point * 1.1, y_min_value => 0, y_max_value => 100, y_number_format => \&make_human_readable, ) or warn $graph->error; #$graph->set( #) or warn $graph->error; $graph->set_legend(@$legend) or warn $graph->error; my $gd = $graph->plot( [ $labels, @$data ] ) or die $graph->error; $title->[0] =~ s/\s+/_/g; open my $fh, '>', $title->[0] . '.png' or die $!; print $fh $gd->png; close $fh; } sub make_human_readable { my ($v) = @_; my @suffix = ( '', 'K', 'M', 'G', ); my $i = 0; while ( $v > 1000 ) { $v /= 1000; $i++; } $v = sprintf "%0.2f" . $suffix[$i], $v; return $v; }