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

Hi all,

I'm writing some code in perl/TK that talks to a data base and returns a new view for my application called a circle view. The problem that I have is that I typically have 20,000+ items returned from my query, these items have discrete lengths, some are short, shor are long, etc. and they click together in a certain order. I have one view in my application were the items are displayed linearaly but I now want to add a view where the items are displayed as a cirle. My first attempt below allows me to draw a circle but and the view comes out right but the elements are overlapping and it's only because of that, that things look right. I also want to be able to select each item, which makes for even more problems. Any ideas and how I can better draw distinct elements on a circle.

Here's the very early code I have so far:

use Cwd; use DBI; use Digest::MD5 qw(md5_hex); use LWP::Simple; use Text::Wrap; use lib 'lib'; use lib 'vg/lib'; use lib '../lib'; use Tk; use Tk::LabEntry; use Tk::Dialog; use Tk::DialogBox; use Tk::TableMatrix; use Tk::ProgressBar; use Tk::ROText; use Tk::Optionmenu; use Win32; use Win32::Process; use stricts; use warnings; my $mw = MainWindow->new(); $mw ->title("Circular Genome View"); my $canvas = $mw->Canvas(-height=>200, -width=> 200, -background=> 'wh +ite')->pack(); my ($x1,$y1,$x2,$y2,$x_center,$y_center); $x_center= 25; $y_center = 25; $x1 = $x_center; $y1 = $y_center; $x2 = $x_center + 150; $y2 = $y_center + 150; $canvas->createArc($x1,$y1,$x2,$y2, -width=> 5, -fill=> 'purple',-outl +ine=> 'purple',-style=> 'arc', -extent=> 359.59); $canvas->createArc($x1,$y1,$x2,$y2, -width=> 5, -fill=> 'blue', -outl +ine=> 'blue', -style=> 'arc', -extent=> 300); $canvas->createArc($x1,$y1,$x2,$y2, -width=> 5, -fill=> 'red', -outl +ine=> 'red', -style=> 'arc', -extent=> 270); $canvas->createArc($x1,$y1,$x2,$y2, -width=> 5, -fill=> 'green', -outl +ine=> 'green', -style=> 'arc', -extent=> 120); $canvas->createText($x_center+75, $y_center+75, -fill => 'black', -tex +t => 'Foo Genome'); $canvas->createText($x_center+75, $y_center+90, -fill => 'black', -tex +t => '25,632 bp'); #$canvas->createLine($x_center,$y_center,$x_center+20,$y_center, -widt +h=>'2',-arrow=>'last'); #$canvas->configure(-scrollregion=> [$canvas->bbox("all")]); $mw->deiconify(); $mw->raise(); MainLoop;

Thanks, Mark

edited by ybiC: balanced <code> tags instead of HTML formatting for code. <br>s are eeeevil ;^) Balanced <readmore> tags at Elian's suggestion as well

Replies are listed 'Best First'.
Re: Drawing Circles with distinct elements on them..
by Anonymous Monk on Aug 20, 2003 at 23:48 UTC
    As far as I could get it from the docs (Tk::Canvas), and as I tried, the following should work: Substitute the canvas->createArc(...); lines by
    $canvas->createArc($x1,$y1,$x2,$y2, -width=> 5, -fill=> 'purple',-outl +ine=> 'purple',-style=> 'arc', -extent=> 59.59, -start => 300); $canvas->createArc($x1,$y1,$x2,$y2, -width=> 5, -fill=> 'blue', -outl +ine=> 'blue', -style=> 'arc', -extent=> 30, -start => 270); $canvas->createArc($x1,$y1,$x2,$y2, -width=> 5, -fill=> 'red', -outl +ine=> 'red', -style=> 'arc', -extent=> 150, -start => 120); $canvas->createArc($x1,$y1,$x2,$y2, -width=> 5, -fill=> 'green', -outl +ine=> 'green', -style=> 'arc', -extent=> 120, -start => 0); $canvas->createText($x_center+75, $y_center+75, -fill => 'black', -tex +t => 'Foo Genome'); $canvas->createText($x_center+75, $y_center+90, -fill => 'black', -tex +t => '25,632 bp');
    Note the additional -start items.
    To your second question: Have a look at the example at the end of The Perl/Tk User's Guide.
    Hope this helped.
      Thanks to all. This has me on the right track. -Mark
Re: Drawing Circles with distinct elements on them..
by graff (Chancellor) on Aug 21, 2003 at 01:23 UTC
    Are you talking about drawing 20,000+ elements as arc segments on one circle? No, that can't really be what you mean -- there would never be that many pixels to draw them all distinctly.

    Anyway, the previous reply takes care of drawing the arc segments without having them overlap each other (using the "-start" attribute together with the "-extent"), and with that, assigning a tag to each segment so that you can identify one that is clicked on.

    Note that when assigning colors to arc segments, you may need to alternate light and dark shades (and reserve a "medium" shade in case you have to draw an odd number of segments) -- otherwise, it might be hard to see where the segment boundaries are.