Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re: Creating Pie chart based graph network

by kcott (Archbishop)
on Sep 25, 2013 at 13:52 UTC ( [id://1055687]=note: print w/replies, xml ) Need Help??


in reply to Creating Pie chart based graph network

G'day KuntalBhusan,

For creating pie charts in a Tk::Canvas, you'll probably want to use $canvas->createArc(...) with various options, including -style => 'pieslice'. See Tk::Canvas: ARC ITEMS.

I'm not really sure what you have in mind with respect to a "graph network". Tk::Canvas: LINE ITEMS seems like the obvious choice; however, you're also talking about cross-linking, so perhaps that's not what you want. You'll need to clarify what you mean in this regard.

-- Ken

Replies are listed 'Best First'.
Re^2: Creating Pie chart based graph network
by KuntalBhusan (Acolyte) on Sep 26, 2013 at 06:03 UTC

    Dear Ken,

    To put it in a more simpler way I need to get the output of the code below in form of a pie. Probably this will be a subroutine with the shown inputs that will be taken dynamically.can you help me in getting the values for $x1, $x2, $y1, $y2 in the code dynamically.

    use strict; use Tk; my $mw = new MainWindow(-title => 'Test'); my $canvas = $mw->Canvas(-width => 512, -height => 512)->pack; ## input ######################### my $start_x = 0; my $stary_y = 0; my $radius = 10; my @data = (4,5,2,6,8); ######################### my $slices = $data; my $slice_angle = 360/$slices; foreach my $this_value (@data) { my $x1 = ?; ## need to get dynamically my $y1 = ?; ## need to get dynamically my $x2 = ?; ## need to get dynamically my $y2 = ?; ## need to get dynamically $canvas->createArc( $x1, $y2, $x2, $y2, -start => 0, -extent => $slice +_angle, -style => 'pieslice', ); } MainLoop;

      Here's a working script that produces pie charts. See the notes at the end (which will probably make more sense after you've read the code and run the script).

      #!/usr/bin/env perl use strict; use warnings; use Tk; use List::Util 'sum'; my $pie_slice_colours = [ map { '#' . $_ } qw{ff0000 ffff00 00ff00 00ffff 0000ff ff00ff} + ]; my @pie_data = ( { centre_x => 50, centre_y => 150, radius => 40, values => [ 1, 2, 5, 3 ], fills => $pie_slice_colours, }, { centre_x => 220, centre_y => 105, radius => 100, values => [ 1, 8, 16, 4, 2 ], fills => $pie_slice_colours, }, { centre_x => 420, centre_y => 75, radius => 75, values => [ 1, 1, 2, 3, 5, 8 ], fills => $pie_slice_colours, }, { centre_x => 60, centre_y => 40, radius => 50, values => [ 32, 16, 8, 4, 2, 1 ], fills => $pie_slice_colours, }, ); my $mw = MainWindow->new; my $ctrl_F = $mw->Frame->pack(-side => 'bottom'); $ctrl_F->Button(-text => 'Quit', -command => sub { exit })->pack; my $canv_F = $mw->Frame->pack(-side => 'top', -fill => 'both', -expand + => 1); my $sc = $canv_F->Scrolled(Canvas => -scrollbars => 'osoe', -bg => '#ffffff', -width => 500, -height => 220, -scrollregion => [0, 0, 500, 220], ); $sc->pack(-fill => 'both', -expand => 1); my $canvas = $sc->Subwidget('canvas'); draw_pie(\$canvas, $_) for @pie_data; MainLoop; sub draw_pie { my ($c_ref, $data) = @_; my @coords = @{_get_pie_coords($c_ref, $data)}; $$c_ref->createArc(@coords, %$_) for @{_get_pie_slices($data)}; return; } sub _get_pie_coords { my ($c_ref, $data) = @_; my ($x, $y, $r) = @$data{qw{centre_x centre_y radius}}; my $h = $$c_ref->cget('-height'); return [$x - $r, $h - $y + $r, $x + $r, $h - $y - $r]; } sub _get_pie_slices { my $data = shift; my @values = @{$data->{values}}; my @fills = @{$data->{fills}}; my $total_values = sum @values; my $start = 90; return [ map { my $extent = 360 * $values[$_] / $total_values; $start -= $extent; +{ -extent => $extent, -start => $start, -fill => $fills[$ +_] } } 0 .. $#values ]; }

      Notes:

      • The Tk::Canvas coordinate system is an upside-down version of Cartesian coordinates. I personally don't like this: mainly because I find it counter-intuitive (x increases along the x-axis but y decreases along the y-axis). _get_pie_coords() takes (x,y) Cartesian coordinates for the centre of the pie chart, as well as the radius for the pie chart, and returns the coordinates required by createArc(). Feel free to revert to the Tk::Canvas coordinate system; however, you'll still need a function like this unless you're happy to specify (x1, y1, x2, y2) for every pie chart (and note those coordinates are outside the pie chart).
      • The placement of the pie slices is also somewhat counter-intuitive (at least, in my opinion). If you take the defaults, -start is called 0° (but, on a compass, it would be east, i.e. 90°); and -extent (whose default value is 90°) increases in an anticlockwise direction such that adding 90° to east results in north (on a compass, that would be south). Anyway, _get_pie_slices() works all that out for you: the first slice starts at 0° (north) and extends proportionally in a clockwise fashion; subsequent slices continue to be added in the same manner.
      • Unless you have a particular reason not to, you probably want (at least optional) scrollbars. Note that Scrolled(Canvas => ...) is actually a composite widget and the Tk::Canvas widget is a component of this accessed with Subwidget('canvas').
      • I've added six colours ($pie_slice_colours) and reused them for each pie chart. You may need more colours. You may not want the same colours for every chart: set the value of the fills key how you want it.
      • Everything else should either be fairly straightforward Perl or documented via links already supplied.

      -- Ken

Log In?
Username:
Password:

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

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

    No recent polls found