Re: create arrays for GD::Graph::lines
- From: dermot@xxxxxxxxxxxxxxxx (Beginner)
- Date: Thu, 23 Nov 2006 15:51:23 -0000
On 22 Nov 2006 at 17:35, Rob Dixon wrote:
Beginner wrote:
On 22 Nov 2006 at 15:14, Beginner wrote:[snip]
[snip]
The number of years can vary so you might get data from 2006->1990.
The data looks like it is suited to a hash but GD::lines wants the
data passed to in as arrays references (\@array). That is one array
with all the "ancode_n" and foreach code, an array of all the yearly
values. I have managed to get my data into this type of structure
'ADV ' => [
'117216',
'104776',
]
'BAP ' => [
'0',
'270',
],
But I am stuck trying to get it out into n number of arrays that I
can pass to GD. I don't want to pre-declare n number of arrays as the
number may vary and because I am using strict, I don't know how I can
pass the data out of whatever loop I use to get to the values.
OK that should work, you've got your codes into a list of legends now. There's
no need for the reverse if you use unshift instead of push to add the values to
the array. And what are you doing for a list of x-values (the years)?
I understood you to mean that there may be gaps in the data, which is another
reason why I said you needed to store hashes of data relating to the years. It
also looked from your code like the data wasn't very well behaved, as you had
allowed for a given year being repeated in some cases. If it's always complete
and in reverse-year order then things are a lot easier. This program keeps your
original data format and produces the same output as my previous effort.
use strict;
use warnings;
use GD::Graph::lines;
use CGI qw/:standard/;
my $q = new CGI;
my %years;
my %values;
foreach my $par ($q->param) {
my $val = $q->param($par);
$val =~ s/\s+$//;
if ($par =~ /(\w{3})_(\d{4})/ ) {
my ($ancode, $yr) = ($1, $2);
$years{$yr}++;
unshift @{$values{$ancode}}, $val;
}
}
my @ancodes = sort keys %values;
my $gdata = [
[sort keys %years],
@values{@ancodes},
];
my $graph = GD::Graph::lines->new(600, 400);
$graph->set_legend(@ancodes);
my $gd = $graph->plot($gdata);
I have come unstuck. I showed the results to the MD and he said
"perhaps it would look better if all the years were sorted" ,highest
to lowest based on the current year. So i began tinkering with Rob's
last post so I had a hash with the keys as the ancode (ADV) and their
values are a hash of the years and their values. It looks a bit like
this:
$VAR1 = {
'ADV' => {,
'2005' => '104776',
'2004' => '85515',
'2006' => '117619',
'2003' => '117007',
},
'PRO' => {,
'2005' => '49684',
'2004' => '39446',
'2006' => '49876',
'2003' => '45674',
},
which I got with this
use strict;
use warnings;
...snip
my $current_year;
my $year_counter = 0;
foreach my $par ($q->param) {
++$year_counter;
my $val = $q->param($par);
$val =~ s/\s+$//;
if ($par =~ /(\w{3})_(\d{4})/ ) {
my ($ancode, $yr) = ($1, $2);
($current_year) = $yr if ($year_counter == 2 ); # current year is
always 2nd param.
$values{$ancode}{$yr} = $val;
}
}
print STDERR "Current year is $current_year\n";
So I need to sort all the code values based on 2006 and then output
the codes in that order.
This seems to sort all the codes in order based on 2006:
my @ancodes = keys %values;
my @sorted_crnt_year = sort { $values{$a}{$current_year} <=>
$values{$b}{$current_year} } @ancodes;
What I can work out of how to pass the data to GD::Graph::Data. What
I have at the moment gives me all the values for a given code
together, rather than separated by years.
my $gdata = new GD::Graph::Data;
foreach my $code (@sorted_crnt_year) {
foreach my $y (keys %years) {
print STDERR "Code=$code,YR=$y,
Val=",$values{$code}{$y},"\n";
$gdata->add_point($code,$values{$code}{$y});
}
}
Can anyone help me with mapping the add_point so that the data is
segragated into years, but keeping the order of @sorted_crnt_year?
TIA.
Dp.
========= As it stands ===========
use strict;
use warnings;
use GD::Graph::bars;
use GD::Graph::Data;
use CGI qw/:standard/;
use Data::Dumper;
my $q = new CGI;
my %values;
my %years;
my $values;
my @param_names = $q->param;
my $current_year;
my $year_counter = 0;
foreach my $par ($q->param) {
++$year_counter;
my $val = $q->param($par);
$val =~ s/\s+$//;
if ($par =~ /(\w{3})_(\d{4})/ ) {
my ($ancode, $yr) = ($1, $2);
($current_year) = $yr if ($year_counter == 2 );
$years{$yr}++;
$values{$ancode}{$yr} = $val;
}
}
print STDERR "Current year is $current_year\n";
my @ancodes = sort keys %values;
# Sort the values of the current year nad store the code
my @sorted_crnt_year = sort { $values{$b}{$current_year} <=>
$values{$a}{$current_year} } @ancodes;
my $gdata = new GD::Graph::Data;
foreach my $code (@sorted_crnt_year) {
foreach my $y (keys %years) {
print STDERR "Code=$code,YR=$y,
Val=",$values{$code}{$y},"\n";
$gdata->add_point($code,$values{$code}{$y});
}
}
#open my $fh, '> plot.gif' or die $!;
#binmode $fh;
#print $fh $gd->gif;
#close $fh;
my $format = $graph->export_format;
print header("image/$format");
binmode STDOUT;
print $graph->plot($gdata)->$format or die $graph->error;
======================
.
- References:
- create arrays for GD::Graph::lines
- From: Beginner
- Re: create arrays for GD::Graph::lines
- From: Beginner
- Re: create arrays for GD::Graph::lines
- From: Rob Dixon
- create arrays for GD::Graph::lines
- Prev by Date: postgres insert
- Next by Date: Free Perl Editor
- Previous by thread: Re: create arrays for GD::Graph::lines
- Next by thread: Re: create arrays for GD::Graph::lines
- Index(es):
Relevant Pages
|
|