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

I'm trying to use the Perl module Tk::Graph. I have researched this extensivley, but cannot find the right information. The problem is, I need to generate a graph from a two dimensional hash, but all the tutorial and documentation that I read about the module is all showing examples of static graphs, where you put static values in for the data. This is my code, but it will only generate a one bar graph. It remembers the last value within the loop and only outputs that.
sub reportg{ my( $userjobcount_ref, $userjobcpu_ref, $queuejobsystem_ref, $userjobt +ime_ref, $queue_cpu_summary_ref, $total_ref, $count) = @_; my( $total, $avg, $month_or_day,$user, $queue, $system_cpu); $MW = MainWindow->new; foreach $month_or_day (sort keys %{$queue_cpu_summary_ref}) { foreach $queue (sort keys %{$queue_cpu_summary_ref->{$month_or_day}}) { $usage=sprintf ("%.3f", $$queue_cpu_summary_ref{$month_or_day}{$queue} + / $total * 100); $data = { $queue => $usage }; $ca = $MW->Graph( -type => 'BARS', -ylabel => 'percentage', -xlabel => 'queue', )->pack( -expand => 1, -fill => 'both', ); $ca->configure(-variable => $data); # bind to data
All I get is the last value and key from the hash. Please help it's driving me insane.

2006-09-27 Retitled by planetscape, as per Monastery guidelines: one-word (or module-only) titles hinder site navigation

( keep:0 edit:27 reap:0 )

Original title: 'Tk:: Graph'

Replies are listed 'Best First'.
Re: Using Tk::Graph to graph two-dimensional data
by liverpole (Monsignor) on Sep 26, 2006 at 11:11 UTC
    Hi wishartz,

    Please provide a more complete code example.  The subroutine you gave doesn't contain a closing brace "}", nor does it contain the closing brace for either of your foreach statements.

    Since the problem you're having appears to be related to how much of the data is formatted for use by the Tk::Graph object, knowing the code to the end of the loops is fairly important.  You should also strongly consider reformatting your indentation to give visual clues about which code belongs in which block; without which your code is pretty difficult to follow.

    I will take a guess, though, and assume that the loops both terminate past after the code you showed.  According to the CPAN documentation for Tk::Graph, an example of its usage is:

    my $data = { Sleep => 51, Work => 135, Access => 124, mySQL => 5 }; my $ca = $mw->Graph( -type => 'BARS', )->pack( -expand => 1, -fill => 'both', ); $ca->configure(-variable => $data); # bind to data # or ... $ca->set($data); # set data

    However, you appear to be calling Tk::Graph multiple times within your foreach loops, and each time assigning only a single pair of data (which I've reformatted here to make immensely more readable):

    $data = { $queue => $usage }; $ca = $MW->Graph(-type => 'BARS', -ylabel => 'percentage', -xlabel + => 'queue'); $ca->pack(-expand => 1, -fill => 'both');

    It would appear that a partial fix to your problem might involve moving the construction of the Tk::Graph object outside of the inner loop, and within the loop changing the assignment of $data to:

    $data->{$queue} = $usage;

    so as not to overwrite its previous key/value pairs.

    If this doesn't get you past the problem, please consider submitting the entire subroutine.


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
      Sorry about my messy code. The good news is $data->{$queue} = $usage; worked I was overwriting the contents each time. Thanks a lot for the help guys.
Re: Using Tk::Graph to graph two-dimensional data
by zentara (Cardinal) on Sep 26, 2006 at 10:57 UTC
    I'm not sure exactly what you are trying to do, dynamically update a graph? I'm not very familiar with Tk::Graph, and a full working example would be helpful, so we don't have to flesh out your code to test it.

    In the mean time, here is a basic dynamic bar graph using only the canvas.

    #!/usr/bin/perl use warnings; use strict; use Tk; my $w=20; my $x=0; my $y=0; my %colors = ( 0 => ['black','yellow'], 1 => ['yellow','black'], 2 => ['white','green'], 3 => ['green','white'], 4 => ['grey','red'], 5 => ['red','grey'], 6 => ['blue','white'], 7 => ['white','blue'], 8 => ['orange','grey45'], 9 => ['grey45','orange'], ); my %bardata = ( 0 => rand 200, 1 => rand 200, 2 => rand 200, 3 => rand 200, 4 => rand 200, 5 => rand 200, 6 => rand 200, 7 => rand 200, 8 => rand 200, 9 => rand 200, ); my %bars; my $mw=tkinit; my $c = $mw->Canvas->pack; for (0..9) { $bars{$_} = $c->createRectangle($x,$y,$x+20,$bardata{$_}, -fill=> ${$colors{$_}}[0], ); my $text = $c->createText($x+10,$y+10, -anchor=>'center', -fill => ${$colors{$_}}[1], -text => $_ ); $x+=20; } $mw->Button( -text => "Save", -command => [sub { $c->update; my @capture=(); my ($x0,$y0,$x1,$y1)=$c->bbox('all'); @capture=('-x'=>$x0,'-y'=>$y0,-height=>$y1-$y0,-width=>$x1-$x +0); $c -> postscript(-colormode=>'color', -file=>$0.'.ps', -rotate=>90, -width=>800, -height=>500, @capture); } ] )->pack; $mw->repeat(2000, sub{ &update }); MainLoop; ########################################################## sub update{ $x=0; $y=0; %bardata = ( 0 => rand 200, 1 => rand 200, 2 => rand 200, 3 => rand 200, 4 => rand 200, 5 => rand 200, 6 => rand 200, 7 => rand 200, 8 => rand 200, 9 => rand 200, ); for (0..9) { $c->delete( $bars{$_} ); $bars{$_} = $c->createRectangle($x,$y,$x+20,$bardata{$_}, -fill=> ${$colors{$_}}[0], ); my $text = $c->createText($x+10,$y+10, -anchor=>'center', -fill => ${$colors{$_}}[1], -text => $_ ); $x+=20; } }

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: Using Tk::Graph to graph two-dimensional data
by robot_tourist (Hermit) on Sep 26, 2006 at 10:30 UTC

    Are you sure your perl is OK? I tend to find that if something is only remembering the last thing from a loop, I am either overwriting the data each time or not storing it at all, so have another look at your loop and how the values are stored.

    How can you feel when you're made of steel? I am made of steel. I am the Robot Tourist.
    Robot Tourist, by Ten Benson