#!/usr/bin/perl -w #TITLE: Chart demo #REQUIRES: Gtk # chart-demo.pl # # Gtk+/Perl chart demo. # # 19980813 PMC Created. # # Coding and mathematics are horrible, but this is just to demonstrate # the use of colors and graphics contexts. #use strict; use Gtk; init Gtk; $pixmapChart = undef; $width = 600; $height = 240; sub do_chart_expose { my ( $widget, $event ) = @_; my ( $event_area ); $event_area = ${$event}{'area'}; $widget->window->draw_pixmap( $widget->style->fg_gc('normal'), $pixmapChart, ${$event_area}[0], ${$event_area}[1], ${$event_area}[0], ${$event_area}[1], ${$event_area}[2], ${$event_area}[3] ); 0; } sub draw_chart { my ( $widget ) = @_; my ( $margin, $axemargin ) = ( 20, 20 ); my ( $xticks, $yticks, $tickwidth ) = ( 10, 24, 5 ); my $steps = 90; my ( $step ); my ( $tick); my $red_gc = new Gtk::Gdk::GC ( $widget->window ); my $green_gc = new Gtk::Gdk::GC ( $widget->window ); my $blue_gc = new Gtk::Gdk::GC ( $widget->window ); my $red_color = $widget->window->get_colormap->color_alloc( { red => 65000, green => 0, blue => 0 } ); my $green_color = $widget->window->get_colormap->color_alloc( { red => 0, green => 65000, blue => 0 } ); my $blue_color = $widget->window->get_colormap->color_alloc( { red => 0, green => 0, blue => 65000 } ); $red_gc->set_foreground( $red_color ); $green_gc->set_foreground( $green_color ); $blue_gc->set_foreground( $blue_color ); $pixmapChart = new Gtk::Gdk::Pixmap ( $widget->window, $width, $height, -1 ); # clear the pixmap to white $pixmapChart->draw_rectangle( $widget->style->white_gc, 1, 0, 0, $width, $height ); $pixmapChart->draw_line( $blue_gc, $margin, $height - $margin - $axemargin, $width - $margin, $height - $margin - $axemargin ); $pixmapChart->draw_line( $blue_gc, $margin + $axemargin, $margin, $margin + $axemargin, $height - $margin ); $tickstep = ( $height - ( $margin * 2 ) - ( $axemargin * 2 ) ) / $xticks; for $tick ( 1 .. $xticks ) { $pixmapChart->draw_line( $red_gc, $margin + $axemargin - $tickwidth, $height - $margin - $axemargin - ( $tick * $tickstep ), $margin + $axemargin, $height - $margin - $axemargin - ( $tick * $tickstep ) ); } $tickstep = ( $width - ( $margin * 2 ) - ( $axemargin * 2 ) ) / $yticks; for $tick ( 1 .. $yticks ) { $pixmapChart->draw_line( $red_gc, $margin + $axemargin + ( $tick * $tickstep ), $height - $margin - $axemargin, $margin + $axemargin + ( $tick * $tickstep ), $height - $margin - $axemargin + $tickwidth ); } $range = $width - 2 * $margin - 2 * $axemargin; $center = $height / 2; $old = $center; for $step ( 1 .. $range ) { $new = 3.14 / ( $range / 2 - $step + 0.000000001 ) * 20 + $center; if ( $new > ( $height - $margin - $axemargin ) ) { $new = $margin + $axemargin; } $pixmapChart->draw_line( $green_gc, $margin + $axemargin + $step, $old, $margin + $axemargin + $step + 1, $new ); $old = $new; } } # main my ( $windowMain, $vboxMain, $dareaChart ); $windowMain = new Gtk::Window( 'toplevel' ); $windowMain->signal_connect( 'destroy', sub { Gtk::main_quit( Gtk ); } ); $windowMain->set_title( 'Chart drawing' ); $windowMain->border_width( 0 ); $vboxMain = new Gtk::VBox ( 0, 0 ); $vboxMain->border_width( 10 ); $windowMain->add( $vboxMain ); $vboxMain->show; $dareaChart = new Gtk::DrawingArea; $dareaChart->signal_connect( 'expose_event', \&do_chart_expose ); $dareaChart->size( $width, $height ); $vboxMain->pack_start( $dareaChart, 1, 1, 0 ); $dareaChart->set_events( [ 'exposure_mask' ] ); $dareaChart->show; $dareaChart->realize; draw_chart ( $dareaChart ); $windowMain->show; Gtk::main( Gtk ); # end