On 22 Nov 2006 at 17:35, Rob Dixon wrote:

> Beginner wrote:
> > On 22 Nov 2006 at 15:14, Beginner wrote:
> >>
> [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 ([EMAIL PROTECTED]). 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.
> [snip]
> 
> 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],
>   @[EMAIL PROTECTED],
> ];
> 
> 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;

======================


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to