The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
#!/usr/bin/perl -w

use lib qw(blib/lib blib/arch);

use Imager;
use Imager::Plot;
use Time::Local;

Imager::Font->priorities(qw(w32 ft2 tt t1));

$plot = Imager::Plot->new(Width  => 700,
			  Height => 350,
			  GlobalFont => get_font() );


sub ym_to_time {
  my $x = shift;
  my ($y, $m) = ($x =~ /(\d+)\.(\d+)/);
  $y -= 1900;
  return timegm(0, 0, 0, 15,$m-1,$y);
}

my $cnt = @data/2;
my @time = map { ym_to_time($_) } @data[map { $_*2 } 0..$cnt-1];
my @rate = @data[map { 1+$_*2 } 0..$cnt-1];




$plot->AddDataSet(X  => \@time, Y => \@rate, style=>{line=>{antialias=>1, color=>'blue'},
						     code=>{
							    ref=>\&magic_marker,
							    opts=>undef
							   }});



$img = Imager->new(xsize=>750, ysize => 400);
$img->box(filled=>1, color=>'white');

$Axis = $plot->GetAxis();

# this is mighty handy for time formating

$Axis->{YgridNum} = 8;
$Axis->{XgridNum} = 10;
$Axis->{Border} = "";


$Axis->{make_xgridlist} = sub {
  my $self = shift;
  my ($min, $max) = @{$self->{XRANGE}};
  my ($miny, $maxy) =( (gmtime($min))[5], (gmtime($max))[5] );

  my $d = int(0.5+($maxy-$miny)/$self->{XgridNum});

  if ($d<1) { $d = 1; }

  $c = int( ($miny+$maxy)/2+.5 );
  while($c >= $miny) { unshift(@rc, $c); $c-=$d; }
  $c = int( ($miny+$maxy)/2+.5 )+$d;
  while($c <= $maxy) { push(@rc, $c); $c+=$d; }

  $self->{XGRIDLIST} = [map { timelocal(00,00,00, 1, 5, $_) } @rc];
};



$Axis->{Xformat} = \&tformat;

$plot->{'Ylabel'} = 'Exchange rate';
$plot->{'Xlabel'} = 'Date';
$plot->{'Title'} = 'USD vs Austrian Schilling';


sub tformat {
  my $t = shift;
  my @mn = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
    gmtime($t);
  $year = sprintf("%02d", $year % 100);
  return $mn[$mon]."'".$year;
};


sub magic_marker {
  my ($DataSet, $xr, $yr, $Xmapper, $Ymapper, $img, $opts) = @_;

  my @x = @$xr;
  my @y = @$yr;
  my $font = get_font();
  my $c = 0;

  for (0..$#x) {
    if ($c+50< $_ && rand()>.8) {
      $c = $_;
      $img->circle(x=>$x[$_], y=>$y[$_], r=>3, color=>'red', aa=>1);
      my $t = $DataSet->{X}->[$_];
      my $r = $DataSet->{Y}->[$_];
      my $tt = sprintf("%.2f @ %s",$r, tformat($t));
      $img->string(font=>$font,
		   x=>$x[$_]-30,
		   y=>$y[$_]+30,
		   text=>$tt,
		   color=>Imager::Color->new(150,0,0));
    }
  }
}


$plot->Render(Image => $img, Xoff => 40, Yoff => 370);

mkdir("sampleout", 0777) unless -d "sampleout";
$img->write(file => "sampleout/sample6.ppm");





BEGIN {

@data = qw(
1971.01    25.863
1971.02    25.873
1971.03    25.869
1971.04    25.842
1971.05    25.209
1971.06    24.987
1971.07    24.975
1971.08    24.837
1971.09    24.484
1971.10    24.236
1971.11    24.225
1971.12    23.638
1972.01    23.471
1972.02    23.198
1972.03    23.072
1972.04    23.129
1972.05    23.107
1972.06    23.030
1972.07    22.897
1972.08    23.004
1972.09    23.066
1972.10    23.201
1972.11    23.221
1972.12    23.163
1973.01    23.147
1973.02    21.829
1973.03    20.495
1973.04    20.691
1973.05    20.380
1973.06    19.086
1973.07    17.209
1973.08    17.892
1973.09    17.956
1973.10    17.899
1973.11    18.995
1973.12    19.552
1974.01    20.700
1974.02    19.996
1974.03    19.383
1974.04    18.749
1974.05    17.971
1974.06    18.155
1974.07    18.191
1974.08    18.552
1974.09    18.877
1974.10    18.496
1974.11    18.021
1974.12    17.493
1975.01    16.816
1975.02    16.559
1975.03    16.490
1975.04    16.849
1975.05    16.658
1975.06    16.573
1975.07    17.495
1975.08    18.185
1975.09    18.512
1975.10    18.321
1975.11    18.338
1975.12    18.523
1976.01    18.416
1976.02    18.306
1976.03    18.389
1976.04    18.194
1976.05    18.338
1976.06    18.472
1976.07    18.349
1976.08    17.971
1976.09    17.680
1976.10    17.254
1976.11    17.144
1976.12    16.933
1977.01    16.994
1977.02    17.108
1977.03    17.001
1977.04    16.877
1977.05    16.797
1977.06    16.766
1977.07    16.211
1977.08    16.450
1977.09    16.563
1977.10    16.243
1977.11    15.987
1977.12    15.450
1978.01    15.223
1978.02    14.952
1978.03    14.660
1978.04    14.691
1978.05    15.146
1978.06    14.989
1978.07    14.805
1978.08    14.393
1978.09    14.266
1978.10    13.429
1978.11    13.928
1978.12    13.776
1979.01    13.547
1979.02    13.604
1979.03    13.640
1979.04    13.916
1979.05    14.041
1979.06    13.877
1979.07    13.400
1979.08    13.372
1979.09    12.955
1979.10    12.894
1979.11    12.766
1979.12    12.494
1980.01    12.394
1980.02    12.529
1980.03    13.248
1980.04    13.434
1980.05    12.803
1980.06    12.591
1980.07    12.411
1980.08    12.684
1980.09    12.672
1980.10    13.041
1980.11    13.619
1980.12    13.979
1981.01    14.233
1981.02    15.147
1981.03    14.937
1981.04    15.304
1981.05    16.205
1981.06    16.808
1981.07    17.176
1981.08    17.558
1981.09    16.527
1981.10    15.788
1981.11    15.621
1981.12    15.852
1982.01    16.066
1982.02    16.588
1982.03    16.711
1982.04    16.853
1982.05    16.275
1982.06    17.114
1982.07    17.342
1982.08    17.431
1982.09    17.597
1982.10    17.797
1982.11    17.947
1982.12    16.994
1983.01    16.783
1983.02    17.076
1983.03    16.940
1983.04    17.176
1983.05    17.368
1983.06    17.974
1983.07    18.209
1983.08    18.799
1983.09    18.754
1983.10    18.305
1983.11    18.901
1983.12    19.383
1984.01    19.815
1984.02    19.028
1984.03    18.285
1984.04    18.630
1984.05    19.316
1984.06    19.226
1984.07    19.998
1984.08    20.268
1984.09    21.293
1984.10    21.557
1984.11    21.075
1984.12    21.803
1985.01    22.267
1985.02    23.190
1985.03    23.248
1985.04    21.717
1985.05    21.868
1985.06    21.532
1985.07    20.446
1985.08    19.632
1985.09    19.949
1985.10    18.569
1985.11    18.237
1985.12    17.658
1986.01    17.151
1986.02    16.389
1986.03    15.976
1986.04    15.965
1986.05    15.667
1986.06    15.699
1986.07    15.117
1986.08    14.502
1986.09    14.349
1986.10    14.111
1986.11    14.251
1986.12    13.996
1987.01    13.087
1987.02    12.833
1987.03    12.905
1987.04    12.734
1987.05    12.574
1987.06    12.793
1987.07    12.996
1987.08    13.041
1987.09    12.765
1987.10    12.674
1987.11    11.843
1987.12    11.500
1988.01    11.635
1988.02    11.920
1988.03    11.767
1988.04    11.744
1988.05    11.912
1988.06    12.380
1988.07    12.991
1988.08    13.281
1988.09    13.135
1988.10    12.777
1988.11    12.307
1988.12    12.359
1989.01    12.904
1989.02    13.022
1989.03    13.148
1989.04    13.161
1989.05    13.691
1989.06    13.912
1989.07    13.308
1989.08    13.570
1989.09    13.733
1989.10    13.140
1989.11    12.860
1989.12    12.240
1990.01    11.904
1990.02    11.803
1990.03    12.005
1990.04    11.862
1990.05    11.699
1990.06    11.843
1990.07    11.520
1990.08    11.044
1990.09    11.044
1990.10    10.719
1990.11    10.451
1990.12    10.539
1991.01    10.616
1991.02    10.416
1991.03    11.341
1991.04    11.977
1991.05    12.104
1991.06    12.538
1991.07    12.562
1991.08    12.267
1991.09    11.910
1991.10    11.887
1991.11    11.408
1991.12    11.003
1992.01    11.108
1992.02    11.391
1992.03    11.693
1992.04    11.620
1992.05    11.422
1992.06    11.067
1992.07    10.499
1992.08    10.199
1992.09    10.214
1992.10    10.436
1992.11    11.168
1992.12    11.130
1993.01    11.368
1993.02    11.556
1993.03    11.586
1993.04    11.234
1993.05    11.305
1993.06    11.637
1993.07    12.071
1993.08    11.920
1993.09    11.402
1993.10    11.540
1993.11    11.958
1993.12    12.025
1994.01    12.252
1994.02    12.200
1994.03    11.896
1994.04    11.948
1994.05    11.651
1994.06    11.446
1994.07    11.027
1994.08    11.010
1994.09    10.904
1994.10    10.695
1994.11    10.838
1994.12    11.063
1995.01    10.769
1995.02    10.573
1995.03     9.898
1995.04     9.720
1995.05     9.912
1995.06     9.854
1995.07     9.765
1995.08    10.168
1995.09    10.270
1995.10     9.954
1995.11     9.974
1995.12    10.142
1996.01    10.296
1996.02    10.321
1996.03    10.391
1996.04    10.580
1996.05    10.782
1996.06    10.755
1996.07    10.576
1996.08    10.435
1996.09    10.610
1996.10    10.748
1996.11    10.640
1996.12    10.923
1997.01    11.289
1997.02    11.785
1997.03    11.931
1997.04    12.050
1997.05    11.998
1997.06    12.158
1997.07    12.620
1997.08    12.946
1997.09    12.568
1997.10    12.360
1997.11    12.181
1997.12    12.510
1998.01    12.765
1998.02    12.735
1998.03    12.852
1998.04    12.760
1998.05    12.491
1998.06    12.615
1998.07    12.650
1998.08    12.574
1998.09    11.955
1998.10    11.524
1998.11    11.840
1998.12    11.746
1999.01    11.872
1999.02    12.283
1999.03    12.640
1999.04    12.859
1999.05    12.945
1999.06    13.260
1999.07    13.269
1999.08    12.975
1999.09    13.109
1999.10    12.853
1999.11    13.323
1999.12    13.611
2000.01    13.582
2000.02    13.993
2000.03    14.270
2000.04    14.563
2000.05    15.190
2000.06    14.477
2000.07    14.660
2000.08    15.213
2000.09    15.826
2000.10    16.141
2000.11    16.090
2000.12    15.318
2001.01    14.676
2001.02    14.949
2001.03    15.150
2001.04    15.418
2001.05    15.721
2001.06    16.132
2001.07    15.972
2001.08    15.265
2001.09    15.098
2001.10    15.205
2001.11    15.491
2001.12    15.440
);

}


sub get_font {
  my %opts = (size=>12, color=>Imager::Color->new('black'));

  my $font = Imager::Font->new(file=>"ImUgly.ttf", %opts)
    || Imager::Font->new(file=>"./dcr10.pfb", %opts);
  die "Couldn't load any font!\n" unless $font;

  return $font;
}