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

Folks, I am using perl GD to plot png file onto Mozilla. Although I can view the graph, and save it as png file, there seems to be something wrong with png format. I cannot view it using png viewer and also import it into MS word. Is there something I am missing? Thanks for your help. Perlmonks is great and a helpful resource. Regards, Rakhee
#!/usr/bin/perl -w # # # This is the HTML form for selecting projects for QA Metrics # use lib qw(/tools/local/lib/perl5); use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); use DBI; use GD::Graph::linespoints; $cgi= new CGI; my @timedata = localtime(time); #print "Content-type: text/html\n\n"; #print "@timedata[0]\n, @timedata[1]\n, @timedata[2]\n,@timedata[3]\n, +@timedata[4]\n,@timedata[5]\n,@timedata[6]"; $day = @timedata[3]; $month = @timedata[4] + 1; $year = 1900 + @timedata[5]; $def_start_date = '31/3/2009'; $today_date = join('/',$day,$month,$year); $def_end_date = $today_date; #print "Content-type: text/html\n\n"; #print "$def_end_date"; if (!$cgi->param) { print $cgi->header; print $cgi->start_html(-title=>'Project Selection', -style => {'src'=> +'http://wwwin.telegent.com/sqametrics/style1.css'}); print $cgi->startform; print $cgi->h3('Select Project to view QA Metrics'); print $cgi->br; print $cgi->br; print "<em><b>Enter Start Date [dd/mm/yyyy]</b></em><br>"; print $cgi->textfield(-name=>'start_date', -default=>$def_start_date, -size=>9, -maxlength=>80); print $cgi->br; print $cgi->br; print "<em><b>Enter End Date [dd/mm/yyyy]</b></em><br>"; print $cgi->textfield(-name=>'end_date', -default=>$def_end_date, -override=>true, -size=>9, -maxlength=>80); print $cgi->br; print $cgi->br; print $cgi->br; print "<b>Select Project and DataType to View QA Metrics </b><br>" +; print $cgi->br; print $cgi->scrolling_list(-name=>'Projects', -value=>[ 'ARES', 'POSEIDON_SW', 'DEIMOS', 'MIMAS', 'JUPITER', 'POSEIDON', 'DIONYSUS'], -size=>7, -multiple=>'false', -default=>'ARES'); print $cgi->br; print $cgi->br; print $cgi->br; print "<b>Select Check Box for Plotting Verified, Closed Bug Data< +/b><br>"; print $cgi->br; print $cgi->checkbox(-name=>'verified_closed', -checked=>0, -value=> 'verified-closed'); print $cgi->br; print $cgi->br; print "<b>Select from P1, P2, or P1+P2 Bugs Data</b><br>"; print $cgi->br; print $cgi->radio_group(-name=>'P1P2_bugs', -values=> ['P1', 'P2','P1-P2','Daily-Snapshot'], -default=>['P1'], -linebreak=>'true'); print $cgi->br; print $cgi->submit(-value=>'Submit Project'); print $cgi->endform; print $cgi->end_html; } else { my $start_date = param('start_date'); my $end_date = param('end_date'); my $error_msg = ""; my $error_msg = &validate_date($start_date, $end_date, $today_date); #print "Content-type: text/html\n\n"; #print $today_date; # my $error_msg = ""; # if (!$start_date){ # $error_msg1 = "The Start Date Field is Blank. Please use Browser +Back button and enter a Valid Start Date</BR>"}; # if (!$end_date){ # $error_msg2 = "The End Date Field is Blank. Please use Browser Ba +ck button and enter a Valid End Date</BR>"}; # if(!$error_msg) { #my $start_date_newfrmt = &date_format($start_date); my @date_array = split(/\//, $start_date); my $start_date_newfrmt = join('-', @date_array[2], @date_array[1], @da +te_array[0]); my @date_array1 = split(/\//, $end_date); my $end_date_newfrmt = join('-', @date_array1[2], @date_array1[1], @da +te_array1[0]); my @selected = param('Projects'); my $turned_on = param('verified_closed'); #print "Content-type: text/html\n\n"; #print $turned_on; my $which_radio_button = param('P1P2_bugs'); # #Decide the rec_type based on the Radio button selection if ($which_radio_button eq 'P1') { $rec_type= '3'; $y_label = 'Open P1 Bugs'; } elsif ($which_radio_button eq 'P2') { $rec_type = '4'; $y_label = 'Open P2 Bugs'; } elsif ($which_radio_button eq 'P1-P2') { $rec_type = '2'; $y_label = 'Open P1-P2 Bugs'; } elsif ($which_radio_button eq 'Daily-Snapshot') { $rec_type = '1'; $y_label = 'Daily-Snapshot'; }; my $project_name1 = @selected[0]; my $num_selected = @selected; # # Check what data types are selcted and set flags for plotting the dat +a # #print "Content-type: text/html\n\n"; #print @selected[0],@turned_on[0], $new_flag, $open_flag, $reopen_flag +, $closed_flag; my $dbh = DBI->connect('dbi:mysql:bugz:bugzilla.telegent.com:3306', 's +wqa', 'sImANten') or die "Connection Error: $DBI::errstr\n"; my $sql = "Select log_date, new_cnt, open_cnt, reopen_cnt, fixed_cnt, +verified_cnt, closed_cnt from swqa.Poseidon where product like '%$pro +ject_name1%' and rec_type='$rec_type' and log_date between '$start_da +te_newfrmt' and '$end_date_newfrmt'"; my $sth = $dbh->prepare($sql); $sth->execute or die "SQL Error: $DBI::errstr\n"; my @log_date = (); my @new_bugs = (); my @open_bugs = (); my @reopen_bugs = (); my @fixed_bugs = (); my @verified_bugs = (); my @closed_bugs = (); while (my @row = $sth->fetchrow_array) { # print "<tr><td>$row[0]</tr></td><tr><td>$row[1]</td></tr><tr>< +td>$row[2]</tr></td>\n"; push @log_date, $row[0]; push @new_bugs, $row[1]; push @open_bugs, $row[2]; push @reopen_bugs, $row[3]; push @fixed_bugs, $row[4]; push @verified_bugs, $row[5]; push @closed_bugs, $row[6]; } # print @log_date; # print @deimos_open_bugs; $dbh->disconnect; #print "Content-type: text/html\n\n"; #print $new_flag, $open_flag, $reopen_flag, $fixed_flag; # if($turned_on eq 'verified-closed') { @data = (\@log_date, \@new_bugs, \@open_bugs, \@reopen_bugs, \@fix +ed_bugs, \@verified_bugs, \@closed_bugs); } else { @data = (\@log_date, \@new_bugs, \@open_bugs, \@reopen_bugs, \@fix +ed_bugs ); }; print $cgi->header( -type => 'image/png'); my $title = "Open Bugs for $project_name1"; my $mygraph = GD::Graph::linespoints->new(600, 400); #my @legend_keys = qw(new_bugs open_bugs reopen_bugs fixed_bugs verifi +ed_bugs ); my @legend_keys = qw(new_bugs open_bugs reopen_bugs fixed_bugs verifie +d_bugs closed_bugs); $mygraph->set( x_label => 'Log_Date', y_label => $y_label, x_label_skip => 30, x_labels_vertical => true, title => $title, legend_placement => 'BL', legend_marker_height => 12, dclrs => [ qw(green blue red yellow brown orange) ], ) or warn $mygraph->error; $mygraph->set_legend(@legend_keys); $mygraph->set_title_font(GD::gdGiantFont); $mygraph->set_x_label_font(GD::gdLargeFont); $mygraph->set_y_label_font(GD::gdLargeFont); my $myimage = $mygraph->plot(\@data) or die $mygraph->error; binmode STDOUT; print $myimage->png; #my $mygraph #print $cgi->end_html; } else { print "Content-type: text/html\n\n"; print $cgi->h3('Error Message'); print $cgi->h3($error_msg); } } sub date_format($date){ my @date_array = split(/\//, $date); print @date_array; my $new_date = join('-', @date_array[2], @date_array[1], @date_arr +ay[0]); return $new_date; } sub validate_date { my $start_date = $_[0]; my $end_date = $_[1]; my $today_date = $_[2]; my @start_date_array = split(/\//, $start_date); my @end_date_array = split(/\//, $end_date); my @today_date_array = split(/\//, $today_date); my $yyyymmdd_start_date = join("",@start_date_array[2],@start_date +_array[1],@start_date_array[0]); # print "Content-type: text/html\n\n"; # print $yyyymmdd_start_date; my $error_msg = ""; if (!$start_date || !$end_date){ $error_msg = "Blank Field in Date field. Please Use Browser Back b +utton and Enter Date Field"; } elsif (($start_date !~ m[^\d+\/\d+\/\d{4}$]) || ($end_date !~ m[ +^\d+\/\d+\/\d{4}$])){ $error_msg = "Invalid Characters in Date. Please Use Browser Back +button and Enter Start Date"; } else { my $error_msg = ""; } return $error_msg; }

Replies are listed 'Best First'.
Re: cannot view png file from Graph::GD module
by ww (Archbishop) on Apr 07, 2010 at 19:38 UTC

    Please --

    • cut your script down to the minimum (not more than a few dozen lines) that displays the problem (we usually don't need to see the un-related parts of the script that's giving you grief).
      ...and
    • Clarify your problem statement

    You appear to be contradicting yourself:

    Although I can view the graph, and save it as png file... I cannot view it using png viewer...

    Do you mean that it renders well in a browser so you can "view" it there, but not in a standalone graphics program? And how does " ...and also import it into MS word" relate? Is that meant to be part of a compound negative -- I can't view it with a png viewer and I can't insert it into M$ word?

      Sorry for posting the full program. I will follow your suggestions next time. Thanks for the advise.
Re: cannot view png file from Graph::GD module
by toolic (Bishop) on Apr 07, 2010 at 20:10 UTC
    #!/usr/bin/perl -w
    It appears from your shebang line that you have enabled warnings. If that is the case, then you are ignoring the warning messages which are generated when your code runs. For example, these 3 lines generate warnings:
    $day = @timedata[3]; $month = @timedata[4] + 1; $year = 1900 + @timedata[5];

    This may have nothing to do with your problem, but I wonder if you are ignoring some important warnings. It is also a good practice to use strict; (see use strict and warnings).

      Off-topic: Will -w cause perl to fire warnings for CGI.pm code? I thought that was one reason the warnings pragma is considered a better choice.

      Elda Taluta; Sarks Sark; Ark Arks

        From the CGI documentation:
        If you use the -w switch, you will be warned that some CGI.pm argument names conflict with built-in Perl functions. The most frequent of these is the -values argument, used to create multi-valued menus, radio button clusters and the like. To get around this warning, you have several choices:
      Hi Monk, Actually after playing with the image for a while I found that the "Save Image" is actually saving my HTML from the form from previous page which invokes the Graph. So, actually save image is not saving a png file. Any clues to what I am doing wrong? Also, is this a perl GD limitation? Thanks for any suggestions. Regards, Rakhee
        the "Save Image" is actually saving my HTML

        So you're trying to debug your browser "Save Image" functionality? Wrong forum.

Re: cannot view png file from Graph::GD module
by Khen1950fx (Canon) on Apr 08, 2010 at 09:26 UTC
    I had some free time, so I fixed the errors. The first script is your corrected script; however, you'll notice that the png code won't work. I reworked the graph code for you in the second script. I'll leave it to you to integrate the two scripts. And, in the future, don't forget to use strictures:
    #!/usr/bin/perl # # # This is the HTML form for selecting projects for QA Metrics # use lib qw(/tools/local/lib/perl5); use strict; use warnings; use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); use DBI; use GD::Graph::linespoints; my $cgi = new CGI; my @timedata = localtime(time); #print "Content-type: text/html\n\n"; #print "@timedata[0]\n, @timedata[1]\n, @timedata[2]\n,@timedata[3]\n, +@timedata[4]\n,@timedata[5]\n,@timedata[6]"; my $day = $timedata[3]; my $month = $timedata[4] + 1; my $year = 1900 + $timedata[5]; my $def_start_date = '31/3/2009'; my $today_date = join( '/', $day, $month, $year ); my $def_end_date = $today_date; #print "Content-type: text/html\n\n"; #print "$def_end_date"; if ( !$cgi->param ) { print $cgi->header; print $cgi->start_html( -title => 'Project Selection', -style => { 'src' => 'http://wwwin.telegent.com/sqametrics/sty +le1.css' } ); print $cgi->startform; print $cgi->h3('Select Project to view QA Metrics'); print $cgi->br; print $cgi->br; print "<em><b>Enter Start Date [dd/mm/yyyy]</b></em><br>"; print $cgi->textfield( -name => 'start_date', -default => $def_start_date, -size => 9, -maxlength => 80 ); print $cgi->br; print $cgi->br; print "<em><b>Enter End Date [dd/mm/yyyy]</b></em><br>"; print $cgi->textfield( -name => 'end_date', -default => $def_end_date, -override => 'true', -size => 9, -maxlength => 80 ); print $cgi->br; print $cgi->br; print $cgi->br; print "<b>Select Project and DataType to View QA Metrics </b><br>" +; print $cgi->br; print $cgi->scrolling_list( -name => 'Projects', -value => [ 'ARES', 'POSEIDON_SW', 'DEIMOS', 'MIMAS', 'JUPITER', 'POSEIDON', 'DIONYSUS' ], -size => 7, -multiple => 'false', -default => 'ARES' ); print $cgi->br; print $cgi->br; print $cgi->br; print "<b>Select Check Box for Plotting Verified, Closed Bug Data< +/b><br>"; print $cgi->br; print $cgi->checkbox( -name => 'verified_closed', -checked => 0, -value => 'verified-closed' ); print $cgi->br; print $cgi->br; print "<b>Select from P1, P2, or P1+P2 Bugs Data</b><br>"; print $cgi->br; print $cgi->radio_group( -name => 'P1P2_bugs', -values => [ 'P1', 'P2', 'P1-P2', 'Daily-Snapshot' ], -default => ['P1'], -linebreak => 'true' ); print $cgi->br; print $cgi->submit( -value => 'Submit Project' ); print $cgi->endform; print $cgi->end_html; } else { my $start_date = param('start_date'); my $end_date = param('end_date'); my $error_msg = ""; $error_msg = &validate_date( $start_date, $end_date, $today_date ) +; #print "Content-type: text/html\n\n"; #print $today_date; # my $error_msg = ""; # if (!$start_date){ # $error_msg1 = "The Start Date Field is Blank. Please use Browser +Back button and enter a Valid Start Date</BR>"}; # if (!$end_date){ # $error_msg2 = "The End Date Field is Blank. Please use Browser Ba +ck button and enter a Valid End Date</BR>"}; # if ( !$error_msg ) { #my $start_date_newfrmt = &date_format($start_date); my @date_array = split( /\//, $start_date ); my $start_date_newfrmt = join( '-', $date_array[2], $date_array[1], $date_array[0] ); my @date_array1 = split( /\//, $end_date ); my $end_date_newfrmt = join( '-', $date_array1[2], $date_array1[1], $date_array1[0] + ); my @selected = param('Projects'); my $turned_on = param('verified_closed'); #print "Content-type: text/html\n\n"; #print $turned_on; my $which_radio_button = param('P1P2_bugs'); # #Decide the rec_type based on the Radio button selection if ( $which_radio_button eq 'P1' ) { my $rec_type = '3'; my $y_label = 'Open P1 Bugs'; } elsif ( $which_radio_button eq 'P2' ) { my $rec_type = '4'; my $y_label = 'Open P2 Bugs'; } elsif ( $which_radio_button eq 'P1-P2' ) { my $rec_type = '2'; my $y_label = 'Open P1-P2 Bugs'; } elsif ( $which_radio_button eq 'Daily-Snapshot' ) { my $rec_type = '1'; my $y_label = 'Daily-Snapshot'; } my $project_name1 = $selected[0]; my $num_selected = @selected; # # Check what data types are selcted and set flags for plotting the dat +a # #print "Content-type: text/html\n\n"; #print @selected[0],@turned_on[0], $new_flag, $open_flag, $reopen_flag +, $closed_flag; my $rec_type; my $dbh = DBI->connect( 'dbi:mysql:bugz:bugzilla.telegent.com: +3306', 'swqa', 'sImANten' ) or die "Connection Error: $DBI::errstr\n"; my $sql = "Select log_date, new_cnt, open_cnt, reopen_cnt, fixed_cnt, verified_c +nt, closed_cnt from swqa.Poseidon where product like '%$project_name1 +%' and 'rec_type'=$rec_type and log_date between '$start_date_newfrmt +' and '$end_date_newfrmt'"; my $sth = $dbh->prepare($sql); $sth->execute or die "SQL Error: $DBI::errstr\n"; my @log_date = (); my @new_bugs = (); my @open_bugs = (); my @reopen_bugs = (); my @fixed_bugs = (); my @verified_bugs = (); my @closed_bugs = (); while ( my @row = $sth->fetchrow_array ) { # print "<tr><td>$row[0]</tr></td><tr><td>$row[1]</td></tr><tr>< +td>$row[2]</tr></td>\n"; push @log_date, $row[0]; push @new_bugs, $row[1]; push @open_bugs, $row[2]; push @reopen_bugs, $row[3]; push @fixed_bugs, $row[4]; push @verified_bugs, $row[5]; push @closed_bugs, $row[6]; } # print @log_date; # print @deimos_open_bugs; $dbh->disconnect; #print "Content-type: text/html\n\n"; #print $new_flag, $open_flag, $reopen_flag, $fixed_flag; # if ( $turned_on eq 'verified-closed' ) { my @data = ( \@log_date, \@new_bugs, \@open_bugs, \@reopen_bugs, \@fixed_bugs, \@verified_bugs, \@closed_bugs ); } else { my @data = ( \@log_date, \@new_bugs, \@open_bugs, \@reopen_bugs, \@fixed_bugs ); } print $cgi->header( -type => 'image/png' ); my $title = "Open Bugs for $project_name1"; my $mygraph = GD::Graph::linespoints->new( 600, 400 ); #my @legend_keys = qw(new_bugs open_bugs reopen_bugs fixed_bugs verifi +ed_bugs ); my @legend_keys = qw(new_bugs open_bugs reopen_bugs fixed_bugs verified_bugs c +losed_bugs); $mygraph->set( x_label => 'Log_Date', y_label => '$y_label', x_label_skip => 30, x_labels_vertical => 'true', title => $title, legend_placement => 'BL', legend_marker_height => 12, dclrs => [qw(green blue red yellow brown or +ange)], ) or warn $mygraph->error; $mygraph->set_legend(@legend_keys); $mygraph->set_title_font(GD::gdGiantFont); $mygraph->set_x_label_font(GD::gdLargeFont); $mygraph->set_y_label_font(GD::gdLargeFont); my @data; my $myimage = $mygraph->plot( \@data ) or die $mygraph->error; binmode STDOUT; print $myimage->png; #my $mygraph #print $cgi->end_html; } else { print "Content-type: text/html\n\n"; print $cgi->h3('Error Message'); print $cgi->h3($error_msg); } } sub date_format { my $date; my @date_array = split( /\//, $date ); print @date_array; my $new_date = join( '-', $date_array[2], $date_array[1], $date_ar +ray[0] ); return $new_date; } sub validate_date { my $start_date = $_[0]; my $end_date = $_[1]; my $today_date = $_[2]; my @start_date_array = split( /\//, $start_date ); my @end_date_array = split( /\//, $end_date ); my @today_date_array = split( /\//, $today_date ); my $yyyymmdd_start_date = join( "", $start_date_array[2], $start_date_array[1], $start_date_array[ +0] ); # print "Content-type: text/html\n\n"; # print $yyyymmdd_start_date; my $error_msg = ""; if ( !$start_date || !$end_date ) { $error_msg = "Blank Field in Date field. Please Use Browser Back button and Enter D +ate Field"; } elsif (( $start_date !~ m[^\d+\/\d+\/\d{4}$] ) || ( $end_date !~ m[^\d+\/\d+\/\d{4}$] ) ) { $error_msg = "Invalid Characters in Date. Please Use Browser Back button and Enter +Start Date"; } else { my $error_msg = ""; } return $error_msg; }
    The code for your .png:
    #!/usr/bin/perl use strict; use warnings; use GD::Graph::linespoints; my $title = "Open Bugs for Buggy"; my $graph = GD::Graph::linespoints->new( 600, 400 ); my @legend_keys = qw(new_bugs open_bugs reopen_bugs fixed_bugs verified_bugs closed_bu +gs); $graph->set( x_label => 'Log_Date', y_label => '$y_label', x_label_skip => 30, x_labels_vertical => 'true', title => $title, legend_placement => 'BL', legend_marker_height => 12, ); $graph->set( dclrs => [qw(green blue red yellow brown orange)] ); $graph->set_legend(@legend_keys); $graph->set_title_font(GD::gdGiantFont); $graph->set_x_label_font(GD::gdLargeFont); $graph->set_y_label_font(GD::gdLargeFont); my @data = ( [qw( Jan Feb Mar Apr May Jun Jul Sep )], [ reverse( 4, 3, 5, 6, 3, 1.5, -1, -3, -4 ) ], ); print $graph->plot( \@data ); save_chart( $graph, 'Buggy' ); sub save_chart { my $chart = shift or die "Need a chart!"; my $name = shift or die "Need a name!"; local (*OUT); my $ext = $chart->export_format; open( OUT, ">Buggy.png" ) or die "Cannot open Buggy.png for write: + $!"; binmode OUT; print OUT $chart->gd->$ext(); close OUT; }
      Thank you Monk. Actually, what you did is very helpful. I am able to run the form and DBI query part of it. I just need to fix my png graph part. Also, during the process I learnt about Perl scoping. Extremely helpful. Thanks again. Rakhee