#!/usr/bin/perl -w use strict; use warnings; use Goo::Canvas; use Gtk2 '-init'; use Glib qw(TRUE FALSE); use Gtk2::Gdk::Keysyms; my $scale = 1; my $window = Gtk2::Window->new('toplevel'); $window->signal_connect('delete_event' => sub { Gtk2->main_quit; }); $window->set_size_request(800, 600); my $swin = Gtk2::ScrolledWindow->new; $swin->set_shadow_type('in'); $window->add($swin); my ($cwidth,$cheight)= (1200,1200); my $canvas = Goo::Canvas->new(); $canvas->set_size_request(800, 650); $canvas->set_bounds(0, 0, $cwidth, $cheight); my $black = Gtk2::Gdk::Color->new (0x0000,0x0000,0x0000); my $white = Gtk2::Gdk::Color->new (0xFFFF,0xFFFF,0xFFFF); $canvas->modify_base('normal',$white ); $swin->add($canvas); my $root = $canvas->get_root_item(); my ($margin_x,$margin_y) = (100,100); my $g = Goo::Canvas::Group->new($root); $g->scale(1,-1); #reverse direction of y axis, so graphing will be normal cartesian $g->translate(0 + $margin_x, -1200 + $margin_y); #notice translations are reversed $canvas->scroll_to(0,$cheight); # add a background rect filling $g, so button press will be detected # otherwise $g will be invisible to button-press-event my $rect = Goo::Canvas::Rect->new( $g, 0, 0, $cwidth,$cheight, 'line-width' => 1, 'stroke-color' => 'white', #invisible on white bg 'fill-color' => 'white', # must be filled for mouse event sensitivity ); # some key help my $markup = " Keys: 'Z' zoom in, 'z' zoom out, 's' save a PDF "; my $text = Goo::Canvas::Text->new( $g, $markup, -80 , 80 , -1, 'w', 'use markup' => 1, ); $text->scale(1,-1); $g->signal_connect('button-press-event', \&on_g_button_press); $canvas->signal_connect_after('key_press_event', \&on_key_press); $canvas->can_focus(TRUE); $canvas->grab_focus($root); &set_axis(); &plot(); $window->show_all(); Gtk2->main; sub set_axis{ # x axis my $xline = Goo::Canvas::Polyline->new( $g, TRUE, [0,0,900,0], 'stroke-color' => 'black', 'line-width' => 3, ); #label my $markup = " X axis Label "; my $text = Goo::Canvas::Text->new( $g, $markup, 450 , 80 , -1, 'center', 'use markup' => 1, ); $text->scale(1,-1); for my $x (0..900){ if ($x % 100 == 0){ my $xtick = Goo::Canvas::Polyline->new( $g, TRUE, [$x,0,$x,-25], 'stroke-color' => 'black', 'line-width' => 3, ); $markup = " $x "; $text = Goo::Canvas::Text->new( $g, $markup, $x-1 , 10 , 1, 'north-east', 'use markup' => 1, 'wrap' => 'char'); $text->scale(1,-1); }elsif ($x % 10 == 0){ my $xtick = Goo::Canvas::Polyline->new( $g, TRUE, [$x,0,$x,-15], 'stroke-color' => 'red', 'line-width' => 1, ); my $markup = " $x "; my $text = Goo::Canvas::Text->new( $g, $markup, $x-1 , 6 , 1, 'north-east', 'use markup' => 1, 'wrap' => 'char'); $text->scale(1,-1); } } # y axis my $yline = Goo::Canvas::Polyline->new( $g, TRUE, [0,0,0,900], 'stroke-color' => 'black', 'line-width' => 3, ); #label $markup = " Y axis Label "; $text = Goo::Canvas::Text->new( $g, $markup, -70 ,-450 , -1, 'center', 'use markup' => 1, ); $text->scale(1,-1); $text->rotate(-90,-70,-450); for my $y (0..900){ if ($y % 100 == 0){ my $ytick = Goo::Canvas::Polyline->new( $g, TRUE, [0,$y,-25,$y], 'stroke-color' => 'black', 'line-width' => 3, ); $markup = " $y "; $text = Goo::Canvas::Text->new( $g, $markup, -25 , -$y -8 , -1, 'north-east', 'use markup' => 1, ); $text->scale(1,-1); }elsif ($y % 10 == 0){ my $ytick = Goo::Canvas::Polyline->new( $g, TRUE, [0,$y,-15,$y], 'stroke-color' => 'red', 'line-width' => 1, ); my $markup = " $y "; my $text = Goo::Canvas::Text->new( $g, $markup, -16 , -$y - 6 , -1, 'north-east', 'use markup' => 1, ); $text->scale(1,-1); } } } sub plot{ my @points; for my $x (0..900){ push @points,$x, 300 + 100*sin( $x /5); } my $poly = Goo::Canvas::Polyline->new( $g, FALSE, \@points, 'stroke-color' => 'green', 'line-width' => 2, ); } sub on_g_button_press { #print "@_\n"; my ( $group, $widget, $event ) = @_; print $widget ,' ',$event->type, ' ','button',' ',$event->button,"\n"; my ($x,$y) = ($event->x,$event->y); print "$x $y\n"; return 0; } sub on_key_press { # print "@_\n"; my ( $canvas, $event ) = @_; # print $event->type,"\n"; if ( $event->keyval == $Gtk2::Gdk::Keysyms{Z} ) { $scale += .1; $canvas->set_scale($scale); $canvas->scroll_to(0,$cheight); } if ( $event->keyval == $Gtk2::Gdk::Keysyms{z} ) { $scale -= .1; $canvas->set_scale($scale); $canvas->set_scale($scale); $canvas->scroll_to(0,$cheight); } if ( $event->keyval == $Gtk2::Gdk::Keysyms{s} ) { write_pdf($canvas); } # print "key was ", chr( $event->keyval ), "\n"; return 0; } sub write_pdf { #print "@_\n"; my $canvas = shift; print "Write PDF...\n"; my $scale = $canvas->get_scale; print "scale->$scale\n"; my $surface = Cairo::PdfSurface->create("$0-$scale.pdf", $scale*$cwidth, $scale*$cheight); my $cr = Cairo::Context->create($surface); # needed to save scaled version $cr->scale($scale, $scale); $canvas->render($cr, undef, 1); $cr->show_page; print "done\n"; return TRUE; } __END__