#! perl -slw use strict; use GD::Graph::lines; use GD::Graph::colour qw(:colours :lists :files :convert); use Data::Dump qw[ pp ]; use List::Util qw[ sum ]; our $MOVES ||= 4; our $SRAND ||= 1; srand $SRAND; ## Allow consistancy between runs for testing my $y = 30 * int rand 6; ## A base level for the random data my @data = map[], 1..4; my @moving; ## to hold the last $MOVING values for averaging ## Every 3 minutes throughout a day for my $x ( 0 .. (24 * 20 -1 ) ) { ## Generate Y values varies randomly around the current transition level ## (which varies randomly see below) my $actualY = $y + -30 + int( rand 60 ); push @{ $data[ 0 ] }, $x / 20; ## X values in decimal hours push @{ $data[ 1 ] }, $y; ## display the random baseline in red push @{ $data[ 2 ] }, $actualY; ## The actual values in green ## Store the LAST $MOVES values push @moving, $actualY; shift @moving if $#moving >= $MOVES ; ## Calculate the moving average my $ave = sum( @moving ) / $MOVES; ## and round it to the nearest transition level $ave = 30 * ( int( ( $ave + 15 ) / 30 ) ); push @{ $data[ 3 ] }, $ave; ## display it in blue ## Make a random change to the base level 20% of the time next if rand > 0.2; $y = ( int( $y / 30 ) + ( -1 + int rand 3 ) ) * 30; $y = 30 if $y < 30; $y = 150 if $y > 150; } #pp \@data; <>; my $file = '789655.png'; my $graph = GD::Graph::lines->new(3000, 768); $graph->set( 'bgclr' => 'white', 'transparent' => 0, 'interlaced' => 1, title => 'Some simple graph', x_label => 'X Label', x_max_value => 24, x_min_value => 0, x_tick_number => 24, y_label => 'Y label', y_max_value => 180, y_min_value => 0, y_tick_number => 12, y_label_skip => 2, ) or die $graph->error; my $gd = $graph->plot(\@data) or die $graph->error; open IMG, '>', $file or die $!; binmode IMG; print IMG $gd->png; close IMG; system $file; ## Load the graph into the local default image viewer __END__ Usage: 789655.pl -MOVES=5 ##(less than 3 or > 10 not good )