theravadamonk has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks, I am having a problem with show_values => 1, while drawing a bar graph with variables. My file is below

#!/usr/bin/perl use CGI; use CGI qw(:standard); use strict; use warnings; use GD; use GD::Graph; use GD::Graph::bars; use GD::Graph::Data; $ENV{"PATH"} = "/usr/sbin:/usr/bin:/sbin:/bin"; print "Content-type: text/html\n\n"; print "<body bgcolor=\"#95B8DB\">"; print "<br />"; print "<h1 align=center>\n"; print "Global Mail Statistics\n"; print "</h1>\n"; print "<br />"; print "<br />"; #Passed CLEAN - Clean Mails my $clean_total = qx(sudo grep -Ec 'amavis.*Passed CLEAN' /var/log/mai +llog); print "clean tatal $clean_total"; #Blocked SPAM - Spam Mails my $spam_total = qx(sudo grep -Ec 'amavis.*Blocked SPAM' /var/log/mail +log); #Blocked INFECTED - Virus Mails my $virus_total = qx(sudo grep -Ec 'amavis.*Blocked INFECTED' /var/log +/maillog); #Blocked BANNED - Banned Mails exe,scr etc. my $banned_total = qx(sudo grep -Ec 'amavis.*Blocked BANNED' /var/log/ +maillog); #BAD-HEADER- - Bad Header Mails my $badheader_total = qx(sudo grep -Ec 'amavis.*BAD-HEADER-' /var/log/ +maillog); #REJECT - REJECT Mails my $reject_total = qx(sudo grep -c 'reject' /var/log/maillog); print "<br />"; my $data = GD::Graph::Data->new([ ["Cleaned","Spam","Virus","Banned","BadHeader","Rejected"], [ $clean_total, $spam_total, $virus_total, $banned_to +tal, $badheader_total, $reject_total], ]) or die GD::Graph::Data->error; my $graph = GD::Graph::bars->new(900,400); $graph->set( x_label => 'Category', y_label => 'Count', title => 'Global Mail Statistics', # Show values on top of each bar show_values => 1, #y_max_value => 7, y_tick_number => 8, #y_label_skip => 3, #x_labels_vertical => 1, #show_values => 1, #values_vertical => 1, #values_space=> 4, bar_spacing => 10, shadow_depth => -4, shadowclr => 'dred', transparent => 0, ) or die $graph->error; $graph->set_title_font("/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf",1 +4); $graph->set_x_axis_font("/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf", +8); $graph->set_y_axis_font("/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf", +8); $graph->set_x_label_font("/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf" +,12); $graph->set_y_label_font("/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf" +,12); $graph->plot($data) or die $graph->error; my $file = 'bars.png'; open(my $out, '>', "../../../tmp/$file") or die "Cannot open '$file' f +or write: $!"; binmode $out; print $out $graph->gd->png; close $out; system("sudo /bin/cp -pf /tmp/$file /var/www/html/"); print "<img src=../$file><p>\n"; print "<br />"; print "</body>"; print "</html>\n";

Graph is drawn. But Show values don't apper in a proper way on top of each bar. This is the code where I have the issue

my $data = GD::Graph::Data->new([ ["Cleaned","Spam","Virus","Banned","BadHeader","Rejected"], [ $clean_total, $spam_total, $virus_total, $banned_to +tal, $badheader_total, $reject_total], ]) or die GD::Graph::Data->error;

If I change the variables to their actual values. Show vaules appear in proper way. this below code is OK

my @data = (['Cleaned', 'Spam', 'Virus', 'Banned', 'BadHeader', 'Rejec +ted' ], [10, 36, 0, 0, 0, 937]);

Pls help me to solve this

Replies are listed 'Best First'.
Re: problem with show_values => 1, while drawing a bar graph with variables
by poj (Abbot) on Mar 15, 2018 at 08:11 UTC
    This is the code where I have the issue

    Write a test cgi for that part and use Dumper to inspect the result. You may see line endings \n on your grep results

    #!/usr/bin/perl use strict; use warnings; use CGI qw(:standard); use CGI::Carp 'fatalsToBrowser'; # only use for testing use GD::Graph; use Data::Dumper; my $clean_total = qx(sudo grep -Ec 'amavis.*Passed CLEAN' /var/log/ma +illog); my $spam_total = qx(sudo grep -Ec 'amavis.*Blocked SPAM' /var/log/ma +illog); my $virus_total = qx(sudo grep -Ec 'amavis.*Blocked INFECTED' /var/lo +g/maillog); my $banned_total = qx(sudo grep -Ec 'amavis.*Blocked BANNED' /var/log/ +maillog); my $badheader_total = qx(sudo grep -Ec 'amavis.*BAD-HEADER-' /var/log/ +maillog); my $reject_total = qx(sudo grep -c 'reject' /var/log/maillog); my $data = GD::Graph::Data->new([ ["Cleaned","Spam","Virus","Banned","BadHeader","Rejected"], [$clean_total, $spam_total, $virus_total, $banned_total, $badheade +r_total, $reject_total], ]) or die GD::Graph::Data->error; print header('text/plain'); print Dumper $data;
    poj
      your code shows in this way. $VAR1 = bless( [ [ 'Cleaned', 'Spam', 'Virus', 'Banned', 'BadHeader', 'Rejected' ], [ '10 ', '36 ', '0 ', '0 ', '0 ', '975 ' ] ], 'GD::Graph::Data' );

      when I added below code instead. it shows in this way. It works as expected

      my $data = GD::Graph::Data->new([ ["Cleaned","Spam","Virus","Banned","BadHeader","Rejected"], [10, 36, 0, 0, 0, 974], ]) or die GD::Graph::Data->error; $VAR1 = bless( [ [ 'Cleaned', 'Spam', 'Virus', 'Banned', 'BadHeader', 'Rejected' ], [ 10, 36, 0, 0, 0, 974 ] ], 'GD::Graph::Data' );

      I think grep results with variables has UNWANTED Stuffs. How can avoid them? I tried, but no success. Pls discard my last mail since it has formatting issues.

        You could chomp($clean_total) all the values, but I would try to avoid shelling out to grep and just use perl.

        #!/usr/bin/perl use strict; use warnings; use CGI qw(:standard); use GD::Graph; use CGI::Carp 'fatalsToBrowser'; use Data::Dumper; my $logfile = '/var/log/maillog'; open $fh, '<', $logfile or die "Could not open $logfile : $!"; my %count=(); while (<$fh>){ if (/amavis.*(Passed|Blocked) (CLEAN|SPAM|INFECTED|BANNED)/){ ++$count{$2}; } elsif (/amavis.*(BAD-HEADER)-/) { ++$count{$1}; } elsif (/reject/){ ++$count{'REJECTED'}; } } close $fh; my @data = map{ $count{$_} || 0 } qw(CLEAN SPAM INFECTED BANNED BAD-HE +ADER REJECTED); my $data = GD::Graph::Data->new([ ["Cleaned","Spam","Virus","Banned","BadHeader","Rejected"], [@data], ]) or die GD::Graph::Data->error; print header('text/plain'); print Dumper $data;
        poj
        Pls discard my last mail since it has formatting issues.

        It was good of you to notice and to create a new post to correct them. However, it would generally be better in future just to fix the original post and thus avoid duplication. See How do I change/delete my post? for the details.

      Hi, Many thanks for your code. I cheeked your code. it gives below output to my web browser $VAR1 = bless( [ 'Cleaned', 'Spam', 'Virus', 'Banned', 'BadHeader', 'Rejected' , '10 ', '36 ', '0 ', '0 ', '0 ', '975 ' ], 'GD::Graph::Data' );

      Then, I wrote another code by manually adding data to it in this ways

      #!/usr/bin/perl use strict; use warnings; use CGI qw(:standard); use CGI::Carp 'fatalsToBrowser'; # only use for testing use GD::Graph; use Data::Dumper; my $clean_total = qx(sudo grep -Ec 'amavis.*Passed CLEAN' /var/log/ma +illog); my $spam_total = qx(sudo grep -Ec 'amavis.*Blocked SPAM' /var/log/ma +illog); my $virus_total = qx(sudo grep -Ec 'amavis.*Blocked INFECTED' /var/lo +g/maillog); my $banned_total = qx(sudo grep -Ec 'amavis.*Blocked BANNED' /var/log/ +maillog); my $badheader_total = qx(sudo grep -Ec 'amavis.*BAD-HEADER-' /var/log/ +maillog); my $reject_total = qx(sudo grep -c 'reject' /var/log/maillog); my $data = GD::Graph::Data->new([ ["Cleaned","Spam","Virus","Banned","BadHeader","Rejected"], [10, 36, 0, 0, 0, 974], ]) or die GD::Graph::Data->error; print header('text/plain'); print Dumper $data;

      Then, it gives below output to my web browser

      $VAR1 = bless( [ 'Cleaned', 'Spam', 'Virus', 'Banned', 'BadHeader', 'Rejected' , 10, 36, 0, 0, 0, 974 ], 'GD::Graph::Data' );

      The above works as expected. But I need to go with variables. Could you pls help me to write my grep results with variables properly? I tried but I still can't get it done? I think I will have to avoid line break..