Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: A 2D layout of graphs in Perl/Tk

by rcseege (Pilgrim)
on Oct 12, 2006 at 07:09 UTC ( [id://577760]=note: print w/replies, xml ) Need Help??


in reply to A 2D layout of graphs in Perl/Tk

I'm still not 100% sure on what you're looking for, but Zentara is right about zoom and Tk::Zinc, it's capabilities far outmatch Tk::Canvas.

Unfortunately, you would have to adapt one of the Canvas charting modules for use on Zinc if you decided to use it. I'm not aware of any charting modules that use Zinc as a base.

Here is a quick and dirty example I threw together using Pane and 16 Scrolled Canvas widgets. Aside from plotting (I just threw some random blocks in), is this something like you were looking to do? It's a start if nothing else. Something I didn't do that you might want to consider is to adjust the scrollregion for the canvas as you are zooming in/out.

use strict; use Tk; use Tk::Pane; my $mw = MainWindow->new; my $sPane = $mw->Scrolled("Pane", -scrollbars => 'se', -sticky => 'nsew', -bg => 'black', -width => 300, -height => 300 )->pack(qw/-expand 1 -fill both/); my $container = $sPane->Subwidget('scrolled'); foreach my $row (0 .. 3) { foreach my $col (0 .. 3) { createTile($container, $row, $col); } } foreach my $i (0 .. 3) { $container->gridRowconfigure($i, -weight => 1); $container->gridColumnconfigure($i, -weight => 1); } MainLoop; ## Each 'Tile' is a Frame containing a Scrolled Canvas + ## another Frame containing zoom controls. sub createTile { my ($parent, $x, $y) = @_; my $tileColor = "black"; my $tile = $parent->Frame(-bg => $tileColor)->grid( -padx => 5, -pady => 5, -row => $x, -column => $y, -sticky => 'nsew' ); my $sc = $tile->Scrolled('Canvas', -scrollbars => 'osoe', -scrollregion => [0, 0, 200, 200], -width => 125, -height => 125, -background => randColor() )->pack(qw/-fill both -side top -expand 1/); my $count = int(rand(6)) + 2; foreach my $i (1 .. $count) { my ($x, $y) = (randNumber(), randNumber()); my $size = randNumber(); $sc->createRectangle($x, $y, $x+$size, $y+$size, -fill => randColor(), -outline => 'black', -width => 2 ); } my $bFrame = $tile->Frame(-bg => $tileColor)->pack(qw/-side top/); $bFrame->Button( -text => " Zoom Out ", -command => sub { $sc->scale(qw/all 0 0 .5 .5/); } )->pack(qw/-side left -padx 5/); $bFrame->Button( -text => " Zoom In", -command => sub { $sc->scale(qw/all 0 0 2 2/); } )->pack(qw/-side right -padx 5/); } sub randColor { my @colors = qw(red yellow blue orange green purple); return $colors[rand($#colors + 1)]; } sub randNumber { my ($max, $min) = (100, 10); my $size = int(rand($max)); $size += $min if $size < $min; return $size; }

Rob

Replies are listed 'Best First'.
Re^2: A 2D layout of graphs in Perl/Tk
by tcarmeli (Beadle) on Oct 12, 2006 at 09:25 UTC
    Thanks, that's an excellent demonstration!
    In fact, the zooming you implemented is excellent for me so I guess moving to Zinc is not required.
    I will change it a bit to have a set of zoom in/out buttons per each column, not per each Tile.

    I know my question was a bit generelized but what I wanted to know is if my idea in general is feasible. Knowing that packing each canvas in a frame may save me some problems is very valuable.

      As for packing each Canvas inside a frame, I think I was off in my first comment. It wasn't as bad as I remembered it being. I must have been remembering how it used to be before a patch was put in Pane some time back. It doesn't make any difference if you put the Canvas in a frame or not.

      The only reason I put each Cavas in a frame in the example was so that I could put controls along with the Canvas, and correctly manage resizing. In terms of the example, there's actually a benefit of not having each Canvas in a Frame (Aside from the Scrolled Frame). Typically, when you create something like this, you have to either store a variable pointing to each Canvas so that you can directly access it later. You can still do this, but if each Canvas has been gridded, then you can use grid methods to access a row, column, one cell, or all of the gridded widgets. The way I currently have it, this is inconvenient because the easy access is to the frame. It would simplify things a bit if you modified createTile to something like this:

      sub createTile { my ($parent, $x, $y) = @_; my $sc = $parent->Scrolled('Canvas', -scrollbars => 'osoe', -scrollregion => [0, 0, 200, 200], -width => 125, -height => 125, -background => randColor() )->pack( -padx => 5, -pady => 5, -row => $x, -column => $y, -sticky => 'nsew' ); my $count = int(rand(6)) + 2; foreach my $i (1 .. $count) { my ($x, $y) = (randNumber(), randNumber()); my $size = randNumber(); $sc->createRectangle($x, $y, $x+$size, $y+$size, -fill => randColor(), -outline => 'black', -width => 2 ); } }

      Now access to each Canvas is a bit easier using gridSlaves or gridLocation.

      As an aside, the interface choice seems a little odd to me. The zooming part strikes me as a bit user unfriendly. It probably makes sense for your problem, but it seems frustrating to me that the views are separated into so many small boxes that I can only resize so far. Zooming only exasperates the problem - Now I have more information that I can potentially look at, but I have to scroll more to see it all.

      Why not pack as much information as is useful within the size constraints for each Canvas in the grid. And then have a way of drilling down or at least temporarily hide the others using gridForget, and allow the user to focus on one Canvas with an expanded information set and zooming capabilities? Anyway... just a few random thoughts.

      Rob

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://577760]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (4)
As of 2024-04-23 20:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found