user6238907
user6238907

Reputation:

Perl GD::Graph Invalid data set: 0 at (pie)

i am trying to make a little PERL-Script (i am an beginner!)

I took an example Code and editet it to my needs.

So the task is to read data from a csv file put them into an html-table and also to show a diagram in pie form.

The table already works, only the pie diagram is my problem. I already looked and tried many changes within the diagram part in the code but not win bringing.

Here is my code:

#!C:\Perl64\bin\perl.exe -w
### Variablendeklarationen und Moduleinbindungen ###
use strict;

use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser);
use DBI;
my $DBH = DBI->connect('DBI:CSV:');
my $STH;
use CGI::Carp 'fatalsToBrowser';

### Statement-Vorbereitung ###
$DBH->{'csv_tables'}->{'daten'} = { 'file' => 'daten.csv'}
    or die "Konnte Datenbank nicht oeffnen:$!";
$STH = $DBH->prepare("SELECT * FROM daten")
    or die "Konnte SQL-Statement nicht ausfuehren:$!";

$STH->execute()
    or die "Ausfuehren der Datenbankabfrage nicht moeglich:$!";

print <<HERE_TEXT;
Content-type:text/html

<html>
<head>
<title>Datenanzeige CSV-File</title>
</head>

<body>
<center>
<h1>Folgende Umsatzdaten sind ausgelesen worden:</h1>
<hr>
<table border>
<tr>
    <td width="200"><b>Filiale:</b></td>
    <td width="100"><b>Leiter:</b></td>
    <td width="200"><b>Mitarbeiter:</b></td>
    <td width="100"><b>Umsatz:</b></td>
</tr>

HERE_TEXT

my @data;
my @diagarray;

while (@data = $STH->fetchrow_array()) {
    my $filiale = $data[0];
    my $leiter = $data[1];
    my $mitarbeiter = $data[2];
    my $umsatz = $data[3];

push (@diagarray, $umsatz);
print qq§<tr>\n<td><b>$filiale</b></td>\n<td>$leiter</td>\n<td>$mitarbeiter</td>\n<td>$umsatz</td>\n</tr>\n§;
}
print ("<br><br>");

use GD::Graph::pie;
my $graph = GD::Graph::pie->new(300, 300);

    $graph->set(
    title => 'Umsatzverteilung Filialen',
    ) or die $graph->error;

#my @diagram = (\@data,\@diagarray);

#Debug
#my $diagram;
#   foreach $diagram(@diagram)
#       {
#           print ("$diagram\n");
#       }

my $gd = $graph->plot(\@diagarray) or die $graph->error;

    my $format = $graph->export_format;
    print header("image/$format");
    binmode STDOUT;
    print $graph->plot(\@diagarray)->$format();

Would be great if anyone could give me the last needed hint. Greetings

Upvotes: 0

Views: 271

Answers (2)

Chris Turner
Chris Turner

Reputation: 8142

Getting two array refs into @diagarray isn't any different to how you're pushing a scalar in to it.

push(@diagarray,\@labels);
push(@diagarray,\@values);

But you want that to happen outside of the while-loop. Inside the while-loop is where you'd populate @labels and @values. Both arrays have to be the same size.

Also your script is trying to output the HTML and piechart in one go which won't work as your browser will just treat it all as just one lump of HTML. Your HTML needs to have an "img" tag in it that points at another URL. That URL can be the same script but with a different query string. For example

use CGI
my $query=new CGI;
if($query->param("piechart")) {
   # print out the graph
} else {
   print "<img src=\"",$ENV{"SCRIPT_NAME"},"?piechart=1\"/>";
}

Or alternatively you could split the piechart code into an entirely separate script, but that makes it less easy to maintain as you'd have to update two scripts if the code for reading in the data ever changed.

Upvotes: 0

Sebastian
Sebastian

Reputation: 2550

When debugging, always confirm your data and script flow, never assume anything to be correct.

Try

use Data::Dumper; # at the top of your script
[...]
print Dumper(\@diagarray); # just before your $graph->plot call

You'll probably notice that your data format differs from what is shown on http://search.cpan.org/~ruz/GDGraph-1.52/Graph.pm#USAGE

You're passing an ArrayRef to ->plot while the sample shows an ArrayRef of ArrayRefs:

[
  ['Desc1','Desc2'],
  [250000, 350000],
]

I suggest to extract the drawing part and try it with static data until you get a working result. Then copy it back into your script and replace the static data with your data, for example:

#!/usr/bin/perl
use GD::Graph::pie;
my $graph = GD::Graph::pie->new(300, 300);
    $graph->set(
    title => 'Umsatzverteilung Filialen',
    ) or die $graph->error;
my @diagarray = (
    ['Title1', 'Title2', ],
    [ 100, 200 ],
);
my $gd = $graph->plot(\@diagarray) or die $graph->error;
my $format = $graph->export_format;
print header("image/$format");
binmode STDOUT;
print $graph->plot(\@diagarray)->$format();

Also check the line reported in the error message. Each of your ->plot calls may be the reason.

Two additional remarks:

  1. No(!) code should be within the use lines of your script as they're processed at compile time while code runs at run time. Mixing doesn't harm your script, but looks like my $DBH = DBI->connect('DBI:CSV:'); would run before use CGI::Carp.
  2. print'ing HTML source from a script is ok for testing and learning, but shouldn't be done in productive environments as it makes maintenance harder. Try using Template::Toolkit or something.

Upvotes: 1

Related Questions