GD: Graph Data Array Issue


C

Chad Thomson

Hi All.

I'm relatively new to Perl, and have been somewhat successful using
the GD::Graph and Graph3d modules.

I'm using this procedure as a CGI app to generate graphs.
I've got an issue where, I'm setting up the @data array and when my
image renders in the browser, it has a width, and height, but still
appears as a broken link.

I've tried CARP and multiple other techniques to figure out what's
happening. Obviously unsuccessful.

I believe the issue is directly related to the @data array, and/or
it's reference.

I've attached a "scaled-down" snipped of what I'm working with, any
advice is appreciated.

Chad.

<snip>

use CGI ':standard';
use GD::Graph::bars3d;

# Create CGI Object
my $q = new CGI;

my $alpha = "abcdefghijklmnopqrstuvwxyz";
my $ii = 0;
my $paramname;

# a sample url would be:
# ?xlabels=this,that,theother&groups=joe,ed,frank&a=1,2,3&b=4,5,6&c=7,8,9

# get X labels
my @labels = [ split (/\,/, $q->param ("xlabels")) ];

# get data groups
my @datagroups = split (/\,/, $q->param("groups"));

# @data is supplied to the generator @plot-time
my @data = ( @labels );

# get data sets
# data is on query string as: a=1,2,3&b=4,5,6
my @datasets;
foreach (@datagroups) {
$paramname = substr $alpha, $ii, 1;
push @datasets, [ split ( /\,/ , $q->param($paramname) ) ];
$ii++;
}
# @datasets should have a structure like this now.
# @datasets = ( [ 12,15,20 ]
# ,[ 30,10,25 ]
# ,[ 15,25,55 ]
# );

=DEBUGcomments
need to transpose datasets into @data:
@data = ( [ labels ]
,[ 12,30,15 ]
,[ 15,10,25 ]
,[ 15,25,55 ]
);
=cut

foreach (@datasets) {
# will have an array here

# get each entry in the array
# add/push it to an array on @data
for ($i=0;$i<= $#{$_}; $i++) {
push @{$data[$i+1]}, $_->[$i];
carp @{$data[$i+1]};
}
}

my $my_image = $my_graph->plot(\@data) or die $my_graph->error;

print "Content-type: image/png\n\n";
binmode ( STDOUT );
print $my_image->png;

</snip>
 
Ad

Advertisements

M

Martien Verbruggen

Hi All.

I'm relatively new to Perl, and have been somewhat successful using
the GD::Graph and Graph3d modules.

I'm using this procedure as a CGI app to generate graphs.
I've got an issue where, I'm setting up the @data array and when my
image renders in the browser, it has a width, and height, but still
appears as a broken link.

Renders in the browser? How do you mean, and what is the URL to the
script below you use?
I've tried CARP and multiple other techniques to figure out what's
happening. Obviously unsuccessful.

Have you also checked the web server logs for error messages?
use CGI ':standard';
use GD::Graph::bars3d;

# Create CGI Object
my $q = new CGI;

my $alpha = "abcdefghijklmnopqrstuvwxyz";
my $ii = 0;
my $paramname;

# a sample url would be:
# ?xlabels=this,that,theother&groups=joe,ed,frank&a=1,2,3&b=4,5,6&c=7,8,9

# get X labels
my @labels = [ split (/\,/, $q->param ("xlabels")) ];

# get data groups
my @datagroups = split (/\,/, $q->param("groups"));

# @data is supplied to the generator @plot-time
my @data = ( @labels );

# get data sets
# data is on query string as: a=1,2,3&b=4,5,6
my @datasets;
foreach (@datagroups) {
$paramname = substr $alpha, $ii, 1;
push @datasets, [ split ( /\,/ , $q->param($paramname) ) ];
$ii++;
}

It looks here like you're use $ii and $alpha to get an alphabetically
incrementing letter, right? Perl's automagical increment can do this
for you:

my $paramname = "a";
foreach my $dg (@datagroups)
{
push @datasets, [split /,/ , $q->param($paramname)];
$paramname++;
}
# @datasets should have a structure like this now.
# @datasets = ( [ 12,15,20 ]
# ,[ 30,10,25 ]
# ,[ 15,25,55 ]
# );

And the number of labels should be the same as the number of array
references in @datasets here, right?

So, each column here represents a set of data that will become a line
or bar group in the chart?
=DEBUGcomments
need to transpose datasets into @data:
@data = ( [ labels ]
,[ 12,30,15 ]
,[ 15,10,25 ]
,[ 15,25,55 ] ^^
20?

);
=cut

[ I wish you hadn't chosen a three-by-three data set. It's easier to
visualise this sort of stuff with non-square sets ]

But, given this, it looks like for each @datagroup, you're reading in
the values for the three data sets that at that point need to be
appended to the sets. The GD::Graph::Data module that prepares data
sets for GD::Graph has an "add_point" method for this.

I'd probably do something like:

use GD::Graph::Data;

my $dataset = GD::Graph::Data->new();

my $paramname = "a";
foreach my $dg (@datagroups)
{
$dataset->add_point("dummy", split /,/ , $q->param($paramname));
$paramname++;
}
for my $i (0 .. $#labels)
{
$dataset->set_x($i, $labels[$i]);
}

And then use $dataset instead of \@data. It's quite easy to lose track
of how to work with those data structures.
my $my_image = $my_graph->plot(\@data) or die $my_graph->error;

This probably generates an error. Check your web server log.

Alternatively, if you use the fatalsToBrowser argument with CGI, you
should see the error messages in your browser.
print "Content-type: image/png\n\n";

Use the CGI methods for this, since you've loaded the module anyway.

print $q->header(-type => "image/png");
binmode ( STDOUT );

You should use the binmode as the first thing you do on STDOUT, before
the above print even.

Without really deconstructing what you did with that data set, I can't
tell whether that is what is wrong. I'd advise you to get check the
GD::Graph::Data module, which can help with this particular structure,
and maybe use Data::Dumper to dump out the structure to your browser,
so you can see what it looks like.

Also, for testing, don't use square data sets. It's much easier to
debug a non-square one.

Martien
 
Ad

Advertisements

G

Gregory Toomey

Chad Thomson said:
Hi All.

I'm relatively new to Perl, and have been somewhat successful using
the GD::Graph and Graph3d modules.

I'm using this procedure as a CGI app to generate graphs.
I've got an issue where, I'm setting up the @data array and when my
image renders in the browser, it has a width, and height, but still
appears as a broken link.

I've tried CARP and multiple other techniques to figure out what's
happening. Obviously unsuccessful.

I believe the issue is directly related to the @data array, and/or
it's reference.

I've attached a "scaled-down" snipped of what I'm working with, any
advice is appreciated.

Chad.

I do the same sort of thing & a superficial look at your code shows no
obvious errors. CARP will not work as you are not generating HTML.

I suggest opening a file (in / tmp if necessary) and writing debugging
messages there. As you have a broken link you may not even be calling the
program.
You can try writing your png file to disk (as 'test.png') instead of stdout
and try to load test.png in the browser.

You might want to look at the HTML I have at www.ipo-australia.com to
generate graphs.

gtoomey
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top