Chart-Strip-1.08004075500017500000146000000000001165706726100116645ustar jawjawChart-Strip-1.08/t004075500017500000146000000000001165706726100121275ustar jawjawChart-Strip-1.08/t/test3.t010064400017500000146000000320001046576067700134340ustar jawjaw # test new xtic code use Chart::Strip; use strict; my $MK = 0; my $H = 3600; my $D = $H * 24; my @t; eval { # tests assume US/eastern, en_us. skip if we can't make compat. require POSIX; POSIX->import(); $ENV{TZ} = 'EST5EDT'; setlocale( LC_ALL(), "C" ); tzset(); if( localtime(1151726400) ne 'Sat Jul 1 00:00:00 2006' ){ die "tests not configured for this timezone/locale\n"; } }; if($@){ print "1..0 # Skipped: cannot make timezone/locale compatible\n"; exit; } if( localtime(1175400000) ne 'Sun Apr 1 00:00:00 2007' ){ # the US govmit changed the daylight saving time rules. # most OSes don't know that # expect the fallout from this to be much worse than y2k. print "1..0 # Skipped: OS has out of date daylight saving time rules\n"; exit; } # return xtic data for specified time range sub gen { my $t0 = shift; my $dur = shift; my $c = Chart::Strip->new(); $c->add_data( [ {time => $t0, value => 1}, {time => $t0 + $dur, value => 1}], { style => 'line' }); $c->plot(); $c->{grid}{x}; } sub test { my $t = shift; my $mk = shift; if( !ref $t ){ print "$t\n" if $mk; return 'ok'; } my $t0 = $t->{start}; my $dur = $t->{dur}; my $exp = $t->{exp}; $dur = $1 * $D if $dur =~ /(\d+)D/; $dur = $1 * $H if $dur =~ /(\d+)H/; my $res = gen( $t0, $dur ); my $err; $err = 1 if @$res != @$exp; if( $mk ){ my $pv; for my $r (@$res){ my $dt = $pv ? $r->[0] - $pv : ''; print "$t->{dur}\t$t0\t$r->[0]\t$r->[1]\t$r->[2]\t$dt\n"; $pv = $r->[0]; } print "\n"; } for my $e (@$exp){ my $terr; my $r = shift @$res; $terr = 1 unless $e->[0] == $r->[0]; $terr = 1 unless $e->[1] == $r->[1]; $terr = 1 unless $e->[2] eq $r->[2]; $err ||= $terr; print STDERR "error: @$e != @$r\n" if $terr; } $err ? 'not ok' : 'ok'; } my $pd = ''; while(){ chop; my @l = split; my $dur = $l[0]; my $t0 = $l[1]; my $exp = [@l[2,3,4,5]]; if( /^\#/ ){ # preserve comments push @t, $_; next; } next unless $dur; if($dur eq $pd){ push @{$t[-1]{exp}}, $exp; }else{ push @t, { dur => $dur, start => $t0, exp => [$exp] }; } $pd = $dur; } print "1..", scalar @t, "\n" unless $MK; my $n = 1; foreach my $t (@t){ my $r = test($t, $MK); print "$r ", $n++, "\n" unless $MK; } # duration start expected result: tic-time, redmark, label, delta(not-used) __END__ 2100D 1151726400 1167627600 0 2007 2100D 1151726400 1199163600 0 2008 31536000 2100D 1151726400 1230786000 0 2009 31622400 2100D 1151726400 1262322000 0 2010 31536000 2100D 1151726400 1293858000 0 2011 31536000 2100D 1151726400 1325394000 0 2012 31536000 1500D 1151726400 1151726400 0 01/Jul 1500D 1151726400 1167627600 0 2007 15901200 1500D 1151726400 1183262400 0 01/Jul 15634800 1500D 1151726400 1199163600 0 2008 15901200 1500D 1151726400 1214884800 0 01/Jul 15721200 1500D 1151726400 1230786000 0 2009 15901200 1500D 1151726400 1246420800 0 01/Jul 15634800 1500D 1151726400 1262322000 0 2010 15901200 1500D 1151726400 1277956800 0 01/Jul 15634800 750D 1151726400 1151726400 0 01/Jul 750D 1151726400 1159675200 0 01/Oct 7948800 750D 1151726400 1167627600 1 2007 7952400 750D 1151726400 1175400000 0 01/Apr 7776000 750D 1151726400 1183262400 0 01/Jul 7858800 750D 1151726400 1191211200 0 01/Oct 7948800 750D 1151726400 1199163600 1 2008 7952400 750D 1151726400 1207022400 0 01/Apr 7862400 750D 1151726400 1214884800 0 01/Jul 7858800 400D 1151726400 1151726400 0 01/Jul 400D 1151726400 1157083200 0 01/Sep 5356800 400D 1151726400 1162357200 0 01/Nov 5274000 400D 1151726400 1167627600 1 2007 5270400 400D 1151726400 1172725200 0 01/Mar 5097600 400D 1151726400 1177992000 0 01/May 5266800 400D 1151726400 1183262400 0 01/Jul 5270400 200D 1151726400 1151726400 0 01/Jul 200D 1151726400 1154404800 0 01/Aug 2678400 200D 1151726400 1157083200 0 01/Sep 2678400 200D 1151726400 1159675200 0 01/Oct 2592000 200D 1151726400 1162357200 0 01/Nov 2682000 200D 1151726400 1164949200 0 01/Dec 2592000 200D 1151726400 1167627600 1 2007 2678400 100D 1151726400 1151726400 0 01/Jul 100D 1151726400 1152936000 0 15/Jul 1209600 100D 1151726400 1154404800 0 01/Aug 1468800 100D 1151726400 1155614400 0 15/Aug 1209600 100D 1151726400 1157083200 0 01/Sep 1468800 100D 1151726400 1158292800 0 15/Sep 1209600 100D 1151726400 1159675200 0 01/Oct 1382400 50D 1151726400 1151726400 1 01/Jul 50D 1151726400 1152331200 0 08/Jul 604800 50D 1151726400 1152936000 0 15/Jul 604800 50D 1151726400 1153540800 0 22/Jul 604800 50D 1151726400 1154404800 1 01/Aug 864000 50D 1151726400 1155009600 0 08/Aug 604800 50D 1151726400 1155614400 0 15/Aug 604800 20D 1151726400 1151726400 1 01/Jul 20D 1151726400 1151899200 0 03/Jul 172800 20D 1151726400 1152072000 0 05/Jul 172800 20D 1151726400 1152244800 0 07/Jul 172800 20D 1151726400 1152417600 0 09/Jul 172800 20D 1151726400 1152590400 0 11/Jul 172800 20D 1151726400 1152763200 0 13/Jul 172800 20D 1151726400 1152936000 0 15/Jul 172800 20D 1151726400 1153108800 0 17/Jul 172800 20D 1151726400 1153281600 0 19/Jul 172800 12D 1151726400 1151726400 0 Sat 12D 1151726400 1151812800 1 02/Jul 86400 12D 1151726400 1151899200 0 Mon 86400 12D 1151726400 1151985600 0 Tue 86400 12D 1151726400 1152072000 0 Wed 86400 12D 1151726400 1152158400 0 Thu 86400 12D 1151726400 1152244800 0 Fri 86400 12D 1151726400 1152331200 0 Sat 86400 12D 1151726400 1152417600 1 09/Jul 86400 12D 1151726400 1152504000 0 Mon 86400 12D 1151726400 1152590400 0 Tue 86400 12D 1151726400 1152676800 0 Wed 86400 6D 1151726400 1151726400 0 Sat 6D 1151726400 1151812800 1 02/Jul 86400 6D 1151726400 1151899200 0 Mon 86400 6D 1151726400 1151985600 0 Tue 86400 6D 1151726400 1152072000 0 Wed 86400 6D 1151726400 1152158400 0 Thu 86400 3D 1151726400 1151726400 1 01/Jul 3D 1151726400 1151748000 0 6:00 21600 3D 1151726400 1151769600 0 12:00 21600 3D 1151726400 1151791200 0 18:00 21600 3D 1151726400 1151812800 1 02/Jul 21600 3D 1151726400 1151834400 0 6:00 21600 3D 1151726400 1151856000 0 12:00 21600 3D 1151726400 1151877600 0 18:00 21600 3D 1151726400 1151899200 1 03/Jul 21600 3D 1151726400 1151920800 0 6:00 21600 3D 1151726400 1151942400 0 12:00 21600 3D 1151726400 1151964000 0 18:00 21600 2D 1151726400 1151726400 1 01/Jul 2D 1151726400 1151740800 0 4:00 14400 2D 1151726400 1151755200 0 8:00 14400 2D 1151726400 1151769600 0 12:00 14400 2D 1151726400 1151784000 0 16:00 14400 2D 1151726400 1151798400 0 20:00 14400 2D 1151726400 1151812800 1 02/Jul 14400 2D 1151726400 1151827200 0 4:00 14400 2D 1151726400 1151841600 0 8:00 14400 2D 1151726400 1151856000 0 12:00 14400 2D 1151726400 1151870400 0 16:00 14400 2D 1151726400 1151884800 0 20:00 14400 18H 1151726400 1151726400 1 01/Jul 18H 1151726400 1151733600 0 2:00 7200 18H 1151726400 1151740800 0 4:00 7200 18H 1151726400 1151748000 0 6:00 7200 18H 1151726400 1151755200 0 8:00 7200 18H 1151726400 1151762400 0 10:00 7200 18H 1151726400 1151769600 0 12:00 7200 18H 1151726400 1151776800 0 14:00 7200 18H 1151726400 1151784000 0 16:00 7200 9H 1151726400 1151726400 1 01/Jul 9H 1151726400 1151730000 0 1:00 3600 9H 1151726400 1151733600 0 2:00 3600 9H 1151726400 1151737200 0 3:00 3600 9H 1151726400 1151740800 0 4:00 3600 9H 1151726400 1151744400 0 5:00 3600 9H 1151726400 1151748000 0 6:00 3600 9H 1151726400 1151751600 0 7:00 3600 9H 1151726400 1151755200 0 8:00 3600 # check near leap year (near 1Mar2004) 6H 1078106400 1078106400 0 21:00 6H 1078106400 1078110000 0 22:00 3600 6H 1078106400 1078113600 0 23:00 3600 6H 1078106400 1078117200 1 01/Mar 3600 6H 1078106400 1078120800 0 1:00 3600 6H 1078106400 1078124400 0 2:00 3600 22H 1078074000 1078074000 0 12:00 22H 1078074000 1078081200 0 14:00 7200 22H 1078074000 1078088400 0 16:00 7200 22H 1078074000 1078095600 0 18:00 7200 22H 1078074000 1078102800 0 20:00 7200 22H 1078074000 1078110000 0 22:00 7200 22H 1078074000 1078117200 1 01/Mar 7200 22H 1078074000 1078124400 0 2:00 7200 22H 1078074000 1078131600 0 4:00 7200 22H 1078074000 1078138800 0 6:00 7200 22H 1078074000 1078146000 0 8:00 7200 14D 1077512400 1077512400 0 Mon 14D 1077512400 1077598800 0 Tue 86400 14D 1077512400 1077685200 0 Wed 86400 14D 1077512400 1077771600 0 Thu 86400 14D 1077512400 1077858000 0 Fri 86400 14D 1077512400 1077944400 0 Sat 86400 14D 1077512400 1078030800 1 29/Feb 86400 14D 1077512400 1078117200 0 Mon 86400 14D 1077512400 1078203600 0 Tue 86400 14D 1077512400 1078290000 0 Wed 86400 14D 1077512400 1078376400 0 Thu 86400 14D 1077512400 1078462800 0 Fri 86400 14D 1077512400 1078549200 0 Sat 86400 14D 1077512400 1078635600 1 07/Mar 86400 20D 1077512400 1077512400 0 23/Feb 20D 1077512400 1077685200 0 25/Feb 172800 20D 1077512400 1077858000 0 27/Feb 172800 20D 1077512400 1078030800 0 29/Feb 172800 20D 1077512400 1078117200 1 01/Mar 86400 20D 1077512400 1078290000 0 03/Mar 172800 20D 1077512400 1078462800 0 05/Mar 172800 20D 1077512400 1078635600 0 07/Mar 172800 20D 1077512400 1078808400 0 09/Mar 172800 20D 1077512400 1078981200 0 11/Mar 172800 20D 1077512400 1079154000 0 13/Mar 172800 # and near non-leap year (near 1Mar2005) 6H 1109642400 1109642400 0 21:00 6H 1109642400 1109646000 0 22:00 3600 6H 1109642400 1109649600 0 23:00 3600 6H 1109642400 1109653200 1 01/Mar 3600 6H 1109642400 1109656800 0 1:00 3600 6H 1109642400 1109660400 0 2:00 3600 22H 1109610000 1109610000 0 12:00 22H 1109610000 1109617200 0 14:00 7200 22H 1109610000 1109624400 0 16:00 7200 22H 1109610000 1109631600 0 18:00 7200 22H 1109610000 1109638800 0 20:00 7200 22H 1109610000 1109646000 0 22:00 7200 22H 1109610000 1109653200 1 01/Mar 7200 22H 1109610000 1109660400 0 2:00 7200 22H 1109610000 1109667600 0 4:00 7200 22H 1109610000 1109674800 0 6:00 7200 22H 1109610000 1109682000 0 8:00 7200 14D 1109048400 1109048400 0 Tue 14D 1109048400 1109134800 0 Wed 86400 14D 1109048400 1109221200 0 Thu 86400 14D 1109048400 1109307600 0 Fri 86400 14D 1109048400 1109394000 0 Sat 86400 14D 1109048400 1109480400 1 27/Feb 86400 14D 1109048400 1109566800 0 Mon 86400 14D 1109048400 1109653200 0 Tue 86400 14D 1109048400 1109739600 0 Wed 86400 14D 1109048400 1109826000 0 Thu 86400 14D 1109048400 1109912400 0 Fri 86400 14D 1109048400 1109998800 0 Sat 86400 14D 1109048400 1110085200 1 06/Mar 86400 14D 1109048400 1110171600 0 Mon 86400 20D 1109048400 1109134800 0 23/Feb 20D 1109048400 1109307600 0 25/Feb 172800 20D 1109048400 1109480400 0 27/Feb 172800 20D 1109048400 1109653200 1 01/Mar 172800 20D 1109048400 1109826000 0 03/Mar 172800 20D 1109048400 1109998800 0 05/Mar 172800 20D 1109048400 1110171600 0 07/Mar 172800 20D 1109048400 1110344400 0 09/Mar 172800 20D 1109048400 1110517200 0 11/Mar 172800 20D 1109048400 1110690000 0 13/Mar 172800 # check near time change (2Apr) 4H 1143954000 1143954000 1 02/Apr 4H 1143954000 1143955800 0 0:30 1800 4H 1143954000 1143957600 0 1:00 1800 4H 1143954000 1143959400 0 1:30 1800 4H 1143954000 1143961200 0 3:00 1800 4H 1143954000 1143963000 0 3:30 1800 4H 1143954000 1143964800 0 4:00 1800 4H 1143954000 1143966600 0 4:30 1800 8H 1143954000 1143954000 1 02/Apr 8H 1143954000 1143957600 0 1:00 3600 8H 1143954000 1143961200 0 3:00 3600 8H 1143954000 1143964800 0 4:00 3600 8H 1143954000 1143968400 0 5:00 3600 8H 1143954000 1143972000 0 6:00 3600 8H 1143954000 1143975600 0 7:00 3600 8H 1143954000 1143979200 0 8:00 3600 2D 1143954000 1143954000 1 02/Apr 2D 1143954000 1143964800 0 4:00 10800 2D 1143954000 1143979200 0 8:00 14400 2D 1143954000 1143993600 0 12:00 14400 2D 1143954000 1144008000 0 16:00 14400 2D 1143954000 1144022400 0 20:00 14400 2D 1143954000 1144036800 1 03/Apr 14400 2D 1143954000 1144051200 0 4:00 14400 2D 1143954000 1144065600 0 8:00 14400 2D 1143954000 1144080000 0 12:00 14400 2D 1143954000 1144094400 0 16:00 14400 2D 1143954000 1144108800 0 20:00 14400 2D 1143954000 1144123200 1 04/Apr 14400 4D 1143954000 1143954000 1 02/Apr 4D 1143954000 1144036800 0 Mon 82800 4D 1143954000 1144123200 0 Tue 86400 4D 1143954000 1144209600 0 Wed 86400 4D 1143954000 1144296000 0 Thu 86400 # check near time change (29Oct) 4H 1162094400 1162094400 1 29/Oct 4H 1162094400 1162096200 0 0:30 1800 4H 1162094400 1162098000 0 1:00 1800 4H 1162094400 1162099800 0 1:30 1800 4H 1162094400 1162101600 0 1:00 1800 4H 1162094400 1162103400 0 1:30 1800 4H 1162094400 1162105200 0 2:00 1800 4H 1162094400 1162107000 0 2:30 1800 8H 1162094400 1162094400 1 29/Oct 8H 1162094400 1162098000 0 1:00 3600 8H 1162094400 1162101600 0 1:00 3600 8H 1162094400 1162105200 0 2:00 3600 8H 1162094400 1162108800 0 3:00 3600 8H 1162094400 1162112400 0 4:00 3600 8H 1162094400 1162116000 0 5:00 3600 8H 1162094400 1162119600 0 6:00 3600 2D 1162094400 1162094400 1 29/Oct 2D 1162094400 1162112400 0 4:00 18000 2D 1162094400 1162126800 0 8:00 14400 2D 1162094400 1162141200 0 12:00 14400 2D 1162094400 1162155600 0 16:00 14400 2D 1162094400 1162170000 0 20:00 14400 2D 1162094400 1162184400 1 30/Oct 14400 2D 1162094400 1162198800 0 4:00 14400 2D 1162094400 1162213200 0 8:00 14400 2D 1162094400 1162227600 0 12:00 14400 2D 1162094400 1162242000 0 16:00 14400 2D 1162094400 1162256400 0 20:00 14400 4D 1162094400 1162094400 1 29/Oct 4D 1162094400 1162184400 0 Mon 90000 4D 1162094400 1162270800 0 Tue 86400 4D 1162094400 1162357200 0 Wed 86400 Chart-Strip-1.08/t/test1.t010064400017500000146000000000521001275244200134070ustar jawjaw use Chart::Strip; print "1..1\nok 1\n"; Chart-Strip-1.08/t/test2.t010064400017500000146000000010471043611454700134250ustar jawjaw use Chart::Strip; my $n = 1; print "1..5\n"; my $c = Chart::Strip->new(); my $data; for(my $t=10; $t<210; $t++){ my $v = ($t % 20) ? .25 : 1; push @$data, { time => $^T + $t * 5000, value => $v + $t / 100 - 1.5, }; } $c->add_data( $data, {style => 'line', color => 'FF0000'} ); my $p = $c->png(); t( $p ); t( $c->{margin_bottom} == 20 ); t( $c->{margin_left} == 34 ); t( $c->{yd_max} == 1.5 ); t( $c->{yd_min} == -1.15 ); sub t { my $x = shift; print "not " unless $x; print "ok $n\n"; $n ++; } Chart-Strip-1.08/eg004075500017500000146000000000001165706726100122575ustar jawjawChart-Strip-1.08/eg/ex6.pl010075500017500000146000000012231116344444200133630ustar jawjaw#!/usr/local/bin/perl # -*- perl -*- use Chart::Strip; use strict; my $img = Chart::Strip->new( title => 'Bee Population', data_label_style => 'box', ); my $data = []; for(my $t=0; $t<40; $t++){ my $v = (.15,0,0,-.15,1,0,-.3,0,0,0,.15,.30,.15)[$t % 25] || 0; push @$data, { time => $^T + $t * 1000, value => $v + .1, }; } # smooth graph with shadow $img->add_data( $data, { label => 'Bees', color => 'FF0000', thickness => 2, style => 'line', smooth => 1, shadow => { dx => 3, dy => 3, dw => 2, color => 'ccdddd' }, } ); print $img->png(); Chart-Strip-1.08/eg/ex2.pl010064400017500000146000000020701001326074500133500ustar jawjaw#!/usr/local/bin/perl # -*- perl -*- use Chart::Strip; my $img = Chart::Strip->new( title => 'Alien Experimentation on the Population of New England' ); my( $data ); for(my $t=0; $t<200; $t++){ my $v = sin( $t/40 ) ; my $z = abs( sin( $t/8 )) / 2; push @$data, { time => $^T + $t * 5000, value => $v, min => $v - $z, max => $v + $z, }; } $img->add_data( $data, {label => 'Drakh', style => 'range', color => '00FF00'} ); $img->add_data( $data, { style => 'line', color => '0000FF'} ); $data = []; for(my $t=10; $t<210; $t++){ my $v = (.07,0,0,-.15,1,0,-.3,0,0,0,.07,.07)[$t % 25] || 0; push @$data, { time => $^T + $t * 5000, value => ($v + $t / 100 - 1.5), }; } $img->add_data( $data, {label => 'Scarran', color => 'FF0000' } ); $data = []; for(my $t=10; $t<210; $t+=15){ push @$data, { time => $^T + $t * 5000, value => sin( $t/30 + 1 ) - .2, diam => abs(20*sin($t/55 - 1)) + 3, }; } $img->add_data( $data, {label => "G'ould", style => 'points', color => '0000FF' } ); print $img->png(); Chart-Strip-1.08/eg/Makefile010064400017500000146000000001601116160506500137560ustar jawjaw all: ex1.png ex2.png ex3.png ex4.png ex5.png ex6.png .SUFFIXES: .pl .png .pl.png: perl -I../blib/lib $< > $@ Chart-Strip-1.08/eg/ex5.png010064400017500000146000000102451043462653300135370ustar jawjawPNG  IHDR#PLTED"JtRNS@f8IDATx]͚?&3,iYEk s$Jp.ayT>u983؇9Y4ˣE㰬rx1:dXtXopj-Uc^lC`rtaufl CpPҗaqR[\0KK]a6r U\B̏'!EH<*^sttpHH:5VM*4쟾zl+8[k; l(2giGVg ~~CIUu$=9)˹GXYK <*1dRZ0SܾAaZޟrCR:L_CUNqXlnB ;O?v?Bdvwhm[edGr(FKaa'5z\Pv6szi";.:$j%CCj.8fdCj&Nu,-aU~M@-ҊxB^Y|Up!]BJ:ۃFJDAc=ZS"Îw;:A\YKz,bHW):R"=b3PL48z&&k4;AȲ,"{kOG#[Z 3ۢoҲ_ fMVk,kUM39ܑAAANvq0#1w X ¤BP,ړ<*F*y $+Ć`PO7|s D)< 'AlE<{J4'譠  g&%aI,2Pש&9ZbC'a, gI 2.A^)̆I]<l.Jqdl2KH m f[Suvrޙ.Pmw wLȺ)Y]/ zOhg%x8rs6,fc\^@^J1VUOp=m;2! Jy"Wo NwwGЬ_lE5^Au̯mybL ]Ww0_CeL; L\ r6w苓&{<8b[Bs(6*q=ة-w +s݀c8QҕU4$c$ YΑ9dK< }y֡{A(؝O=@0JmrINcf/Zӌ\&301 *xYv4%X !) CΥ |{xi2RQ2|CVIaQŷcGk`W>]+UDk%8.!{b$nX`vZ0s6,*Z+AVPb0< nbNpډl v%؆|#:m8PKм ҇݅6LA#,`P X)*>&ކU0aUJ&Zʰ"HC.U&SV(#SҏlcPGPԃ +a`2(̐@PVC 'hTz/*" K om8A -Βn7/NPA-?ׂmRm8pk2`/1-p T I6!28w\?vD`J0~ Gp@A\{僼9j lnRпUXAAU_ZQAIeeVoEpx0AV D0vpK}ox*"Mw9j`GVPO3YQ阬3I6236ARPq}hOWA|*xHap*XA?O-.']{k|2@2>DA=mz3gu'x/ׯ51Qs/o0Juw[ꗸGL  wUjxya)Aj$hZlw~]pJаtj;x\pGqSS92rLm7;~C]}9.&^Fbs߽IѤە= 5S8w@G&}cm:5*i.^)p0)>D(uxŀޖC OQ$\p xx OW)JHT3+ -^@pĪ<$MdBи$6B !Ph1Y&.zxxuZ,6?b ~sNEXp( sԩb Wi#0'1fM& eM-4X-X^`3Xe"g>~u({8ZLz;bPU" W,0M]MZ9thGQj'i+HyL6Yv9tC !Gl@r",$6E8O@"#g-&cy8H"0M@yV n[dc8TAY1T6rl" KE\ĴO.=F 3eKl& `춘$YvnJ;L6'flG}lvДW);AJN))9UՉvN"4^|/ª9htpO⻏^L)d@l 0Ydf[ualY0# f~)R@K,|\E ȶl wJd$fh1#SIy" ?@va_>Ȃ{bN4 1ndJN@J.-ZL@oQXaiL@["#Mʧpc33q2em^=(uu?d[d$#nHp(k6GBr(\ x,E[g3wGrxTD#o#y02z3e{E3K@V[1xma^Ej虜PN/b-z&KaTa?;cb/g*^NOlEVJhukOK-'| H62ITS'Rr\/z| @ga\&FȞ@(@M#P OB΋^Q|E@|ׇ@H2)Pl>φ壂 ӏ!X}6"Wܟ"})ν|Jk՘Q|M֨ճlc;02p2fI͆7ƭ܇ %}xF` +@_83WB]<HnomO@Ol<#Pɑ݌Q2{"t"B4Ėnc1W)J ~]᏿m y --+ c2bF&tBCnew( title => 'Alien Experimentation on the Population of New England' ); my( $data ); $data = []; for(my $t=10; $t<210; $t+=15){ push @$data, { time => $^T + $t * 5000, value => cos( $t/30 ), min => 0, diam => 10 * (-cos( $t/30 ) + 1.5), }; } $img->add_data( $data, {style => 'range', color => '00FFFF' } ); $img->add_data( $data, {style => 'points', color => '0000FF' } ); $data = []; for(my $t=10; $t<210; $t+=15){ push @$data, { time => $^T + $t * 5000, value => cos( $t/30 + 1.5 ), min => 0, diam => 10 * (cos( $t/30 + 1.5 ) + 1.5), }; } $img->add_data( $data, {style => 'range', color => 'FF00FF' } ); $img->add_data( $data, {style => 'points', color => '00FF00' } ); print $img->png(); Chart-Strip-1.08/eg/ex3.pl010064400017500000146000000013451001277162700133620ustar jawjaw#!/usr/local/bin/perl # -*- perl -*- use Chart::Strip; my $img = Chart::Strip->new ( width => 160, height => 64, draw_tic_labels => 0, draw_grid => 0, ); my( $data ); for(my $t=0; $t<200; $t++){ my $v = sin( $t/40 ) ; my $z = abs( sin( $t/8 )) / 2; push @$data, { time => $^T + $t * 5000, value => $v, min => $v - $z, max => $v + $z, }; } $img->add_data( $data, {style => 'range', color => '00FF00'} ); $img->add_data( $data, {style => 'line', color => '0000FF'} ); $data = []; for(my $t=10; $t<210; $t++){ my $v = ($t % 20) ? .25 : 1; push @$data, { time => $^T + $t * 5000, value => $v + $t / 100 - 1.5, }; } $img->add_data( $data, {color => 'FF0000'} ); print $img->png(); Chart-Strip-1.08/eg/ex4.png010064400017500000146000000131201043450072100135170ustar jawjawPNG  IHDR#PLTE=tRNS@fIDATx]rHE$س*ɸu&Sm i]vwC]{_ӧ߯nLn2/qf;v3 8/xܝMԶ@6O/<4Qܷ? ;I B 30{3\Χc<)ţu#Ed`ApX `uR'vv,` =^E@6ހ zq:8-ޗPހd`/#ts+./ӵq\a12R7#M v/iKf=p~>_NK4H|y}{%3TБnVOa@']_t hd!T{' BHVOF@ppԪT~<U;J"; ?؍zt4s! N;PހV$oOj#O֝ tGbz"nkɒǑO_аzqx!#s7V+g_&B"kߒ~K)-o@M[֫Pd9NϤ^PX<:=Seth퉉8|7B ]Ch?Z孼i O-k<.%~!Il'u}/`ۡ`z ҩx[[8hOXg6;:lEZHa8DѸ#"vPe7K3ƢZFZ8 jH8C6n9`.KݣKX ?d&S lğ[, Es8uRv&FTYuv$5u} Gx5npц\(@>@^sZv$M^ C(SSw9【TygNwd0ޗaUNkY#uTVٔ@N5Z@gXك8g4$VO"اcc<0XH" &_x$ I|WϜf U&xakK挌't9 P'[:68)G .lNI[<Y8_K6MFdEГfw!:A (@6Z[ wrv4 @oeqfՎ02`׌||P+d UkPL@-Mk}6kr-vtɉoTm8._@4:2)` {ޭ\)rg }iqiY"FHFhW'^YVw F k@Jw;4Y]S3V-JU񸊹;bS;0V5@{ TWm/% Club8 /ٯ3`o| %afbi}iV`!/Пć3qk=,el 1*붖q Dυ:׋`}v`@:N'!r]3;v/b0ԳJXmNgKzm sv vehblJ;H D0P|tƎm`K엑Gq BjsX",{+܁A4{;iΞw1*K(F[)|J=ChGh;Q;1{l8@.Db2f.qh>l 0SɠL3TL6>q`Vg;i2TO)N*S1ҽ@/_Z't{(͆ D^hKfrag15*簌AOIvdi'@I*@}!|Žy'/LE /ga[ NsjϾo>+2<觰 '+a0G~-5 .2#, aЊszl nA)rbD E^(; /QaΚ#G L[1i,LJx1xHWDVevs)l`V0`Be pW7Y. lТ0 @:];鳱K Q &28%2}m_(6yᅲa..=zcTs (w$R~m (q|$,2؊@fk0ؐ@mHn`jbWRwVTJ2#Je"ǖ F;ӛ5x\2ع-$28+ @6{s`ޔj`61e3mN2HϾo\5gpA/a `XBc`!6O~^|a5:lQS1OY{S`->l'}ks<plI5>|ZqB2}{0Vn3sb^ X'x|P!u, '`[l+8꫚r/ȤJ&fUL3(Cl8W@BeO:Ć!7|jE4Bl {Hqb f;IX7 DY|G|vޯ.:aҧn^ Gqv]ܲ_RT[ ``@~8V54 cCʅ @ߊR~ǣ} A: X%边 cѷꕌƵ5~K[a{?t/N|(* ;!}d{+p.t#nnMh  UQ]t≠^|Pّ^&F0}ps9 RyxAၑmN3b6y/'~J*/;qD< (yYcZYHA { HKaLaٗ?cnD}T )cF&\HFvκ8=};ZOȾd`u~SJK6t{[[Pf]  O{t&P&?n,b) +$lݕ/fnU.2O)L)}y  -cΝt{L[cHТL+ZWL1Qr \Y()m([%M ̫1eȭZ?Oz0LS6S>BoT +m[x3T`MˤZ$B[KDȒ[(ʏٙNmh .0鬥TEyڶy8*ط")u;\k(pUaV!5'PC ۟nlW@+*J+)0TB%&(oz[pQfiDe15=:WzVfp-.FB$Ӕ@ҜLփ_CKl2t@ TRT MƟ.J}L':@fyg!032Wwy,u/CL.Sv yluHco<ſ̏lFUxrQd&y c PXd QjhQH4!RxL 栮!p-U`2,zMǭ7Qck(0(kf=Fn?ڛɷJ)WP`6+3:`" *Jw\Z*XV ,k- gS?14@*C,L.j%ifXdCե1Xb8A&rvq&EF~0v(<@mH+mv\ؑ3PE7a KdۓF,IsYT)cML. & <**oƈpcy DIX\+ ŖsQE4*-^󳞲`֏&e 7 sQb69]s:vT-VR =yxIS.,u6F/&;_R`rOa$([u7R 6ٶdL"?*꽳>z+sQdY+j8Sǟ@zﬨL~Oߕr6&)_bo,[OwCY]&;]d!rU $Y E Ս,Y^sά jDBiZ4\3;GG~+R ` / 0Te9; 3^XTl} sb@ـh5eyiaֶ:axDPo#{{;'|"P膠by.ga^}||ު&_=N!.y繡?~=sH#;EP0*vl@f,/ FKzn)=5CI#x )SFɰg":" S<vŇ|4t(nމJӈ"Gg$:jbĉ@q Qx, Ϻ%$^ yB.{BDfml1ҽueG\=IENDB`Chart-Strip-1.08/eg/ex3.png010064400017500000146000000021751001344316300135250ustar jawjawPNG  IHDR@Q PLTEX|tRNS@fIDATxW;(E fPig＀ABv;0oUqsщ6Kίe6]x /|4[Ƌ3==|(o9 ^gevIp 595of 5{X}83:rQ¯qu`Jp(}$aö4AB6RH'GYRl_**eXMf3$2z nJ8&fk嬓Qc2tH>N /Otl75 U i9 AhY$KgXLw:UPѿdƣ 1ꬺGW e5 bU"V`-*+^!&p*HWqp4υ=OڎMkd@Rj {_9%.HVh;iŤK% ueZuL+5+UbF)<1ˏ؀{#ޒ&@w8'i\yFFbV)]$x!ࡩ6O)x=k{a=zkcKEկ5!2H'|AǑXB#dL%̓&wG|&/ Hza?$C)td*yDϧm"zmT.w7&& 5_^JQXX|'6oQ~7!UB}Cз?%Hډ>t* 'Kw{8z96m Y#ĝ'%t5tt^<B~45t/"S>/5$+&<0ӿ3}DHQ e?8:5Bz&y#½K 8ݹm\* XNRZ ۉ[M1e 64˜LRRՍ4,]qǭ?h35vHxkb굆}'1nÏ -kQFM ٜWߓ{8[{IENDB`Chart-Strip-1.08/eg/ex1.pl010064400017500000146000000016761021737701500133670ustar jawjaw#!/usr/local/bin/perl # -*- perl -*- use Chart::Strip; my $img = Chart::Strip->new(title => 'Happiness of Club Members', x_label => 'When', y_label => 'Happiness Factor', ); my( $t, $davey, $shelly, $harold ); my $dt = 3600; for($t=$^T; $t<$^T+$dt; $t+=$dt/200){ my $v = 10 + rand(5); push @$davey, {time => $t, value => $v}; } for($t=$^T; $t<$^T+$dt; $t+=$dt/50){ my $v = 9 + rand(5); my $x = 5 + rand(2); push @$harold, {time => $t, value => $v}; push @$shelly, {time => $t, value => $x, min => $x - 1, max => $x + 1 + rand(1) }; } $img->add_data( $davey, { label => 'Davey', style => 'filled', color => '8080FF' } ); $img->add_data( $shelly, { label => 'Shelly', style => 'range', color => '008844' } ); $img->add_data( $shelly, { style => 'line', color => '44CC44' } ); $img->add_data( $harold, { label => 'Harold', style => 'line', color => '802000' } ); print $img->png(); Chart-Strip-1.08/eg/ex5.pl010064400017500000146000000020721043450135600133600ustar jawjaw#!/usr/local/bin/perl # -*- perl -*- use Chart::Strip; my $img = Chart::Strip->new( title => 'Online Orders', data_label_style => 'box', ); my( @d1, @d2, @d3 ); for(my $t=10; $t<50; $t++){ my $v = 3 * sin( $t/10 ) ; push @d1, { time => $^T + $t * 15000, value => 3 * sin( $t/10 ) + $t / 50 + 1, }; push @d2, { time => $^T + $t * 15000, value => 2 * sin( $t/8 ) + sin($t/4) + sin($t/2)/2 + 3, width => 3000 + 2500 * sin( $t / 7 ), # wacky-width }; push @d3, { time => $^T + $t * 15000, value => ($t/5)%2 ? 2 * cos($t/10) + rand() + 4 : undef, }; } # box-graph auto-width, not-filled $img->add_data( \@d1, { style => 'box', label => 'Successful', color => 'FF0000', } ); # filled, varying width $img->add_data( \@d2, { style => 'box', label => 'Lost in Mail', color => '0000FF', filled => 1, } ); # thick line, with gaps $img->add_data( \@d3, { style => 'line', label => 'Processed', color => '448822', thickness => 4, skip_undefined => 1, } ); print $img->png(); Chart-Strip-1.08/eg/ex6.png010064400017500000146000000114101116344075500135330ustar jawjawPNG  IHDR#PLTE'F;"tRNS@fIDATx]͂(VU_\z_=+fZ35=||AFnYCk'LI.3JDB$ Yca >LC&IlHcP{~¨~J82P$gq7uˬ֎1y 2;:q<ūZsŬDŽE>h aG*>6Fre'#D`gskU 9) K8B 9~.%} wX5T\)2兡J͉]VA1<>Q(u6DR,%ަ7E5Q)k]u]ww4l+-gL5륦 F`!q_6P8ݱCF4*&mHÓ}I т g_რcc =uΟ«$U9@!aZUBco~AM"+_r(iH&vBe?3MOrO:kpI6`E䚕0kx*B(¨M jb}9}M@~m,t3 \1BX(8<#W:TJ5\~ds_ȼjKj*^=Z/YϾ^xPf< ܌gRFf;u Ed &pSMupmΰR9'SPdɜ髂FS 873- .Dd wϲ^.nzuL(yzŝQ0cN_cMwgKd7 5<5M~Qskj(iUdvL~٪F }r=L]K,ݡ8Ab bT[JFrPtLk( plY5, /EۖGtYGo(uHt7gĺJpsrp&8ԭ<ԑw6@HޑXڜM*#xn[mv{QνzW-$>UFsS OQI>UNH|t06 p@刹n|tzE+>U>[,O^=%O&6 e)ؔx [k RǤ͓| UT`yHq9)Gމ4] ~*n<`A-T|!X _ l0މw1bA` rݕ[3Xz$lf Gװވ|kHbRăp9c0ѣr2PC0g̹AZHY  Ay}lg@`KH]/,%vq:lL A=@ޫd[H^ uSyA[FbW12U0~>*B0(W*Xc4@ cr):`@VqxY@Cjt`̀`Q; 0n " GcFl_g1;a:Y3)b~Ks@DP=4AbRl­gcdHcM$wS̓ 2PТV p M᭚_Kk f$뻞gU\*548ŜP?=~SM@oD1Е,!@DG:#ox뒉oYWj/d (7,n@If}oEʓl A8 3saf 3]7O)\il%_1@9v=?AvqɂwYИӣă;,__"'fS !H`X,x6[E q\LLl$xPfͮ /A_  xO ThZhi%m(;`ZqDN[@Eh |*(} ,nb TAZ A϶r @_l*cRh uqĻ,L--0&k-P#w]@E*xP[a>w=ω:[Vw| \kMQ*5k}A?m`^8'}h_j&"xO <(,xU  tk-F! @usҗZmBX ;Z BAi+.sLh(^Y%2[x7yYYFlVXPO+mh$#x~jrJL@-&'1R t>NO&lLɾ09$$ "P ]]OpZ`L`xрݢ&@.TFE4s@bsX8 CfOa3!B`xf=, Lf ,UD|+D%NEL ABmҝ@LX )C)eՄX 7>Qxr>]"d Z\xT}WHc'ۗF UWGY dW? Ȅ>*'U#E͒a%j !@ +.  babώH,pYb <ԯ4⍀?zW_' X5y"^܇OO=F! 3~:Je 3$,);Bc>AJw$y1o 21o5.t~4EIz\9%ϐDoBX0(@%r4pLH3' kCGʗdF $p|?('#rllCfΣ!_XFU˄%M' Dd%b>M^ao EB )TE|EJrm[Y lյj |{* =Y!Y mFkPof/vZH[[e+hoC75!=(ݍn~n23]OodD P@?a h PO9LT|ۛ;$ (T djM#n/@H YAΝ T¸MɪΩ&IqV^ynPZEέn(HvSTCt|:&(@TwyOEe}@`n}nkFCe̿4ڙIENDB`Chart-Strip-1.08/eg/index.html010064400017500000146000000003471116161524100143170ustar jawjaw Example Images

Chart-Strip-1.08/eg/ex2.png010064400017500000146000000162741001344316300135310ustar jawjawPNG  IHDR#PLTEi tRNS@fOIDATx]v8@.Eg>?ͤ{,Lk^za5?{XWP AYE:jjm*նe  s#n#}^X'}xyl]kW<65 AZA],F͠B̀!GLi̤l ==OĄѡGTg<& nzDK?G" zU$4k?"wRӫIq~/[]:Ù*XZјbDQYQQ_ e))ONRMS>^mcE&Y*d6a3Pɷ`myh,Ę4պ;Sǀ6_{W GoGQ?a^zwI<upr`':8OWS(PC0b}KA -k2xԑƚPc+R,.<[+smlI%ɏ\ t/:VS?+(/\A?x hnLKǼBZEa:sݕ*V:oPx!0?"kR U %^3LAi0Da2a~2ǝvRjj =EJ|27k8({ uwhmG[Ǒ=vp>F^r'5!%ø^L*YTB! *VkbvP:Ѩؼv4A"hLaF#LiV@KGo:0zcFEhڑʜ*Hl/7+Hr$iQ_T-t#,h 5$Hs)v].`/h3V j!=RGȬ-$ZUk ؼTЭGL^i!e)Sg*zB/tXJq)u uOJ cEwiO Hllb לKNAsԦV7ڎ+ˌ IZx2)eZ" ç;.fi : /SӠڈ߱~W 1VVַ4:3XQI|GP}F,Sc*i APm 5Igmm%B8O} I0Jvq=/6B-'hN,RԮP`QaB+fk7Smz=+̥1j&= u2l(mK# VOɛ]SP'e D]4(A4O=>ђ^U9i}6S 9kGӇ®YPʀ!( 8$|gnS0 іUD-ኵڊ<Ҫ )7G|'Y:s2%v.wu٣w `CY~Z:6h7O7T߲GZo 4*LWUew ` bi[=}B!w_ v]* շ@53 {Ov̡n_-K5x$tSc;Njj(`\!hMK듑W.@)v!ׯ?1IuX? W4TWBЫu%I0aFA qaKHo [|IRN;%5a0ApWS@pqSD0IjЏ\,jƁA 1$ +v_9v@[>|!kZ妞=@(_̷g3< u| b% ƒg5NmY͚9pwYPr_%,|R0nn(s;I.͂2YYl#)U5P'UhYU2˞&¡.& T7="B /f6I6E\:'B2ˤb{0gS6K-6mg8H~q5'@;7r^8Nc V/pĸfW% "H.b̕-ՆPBA,T/-2m&/Gs zNfdi_ ?u(iBh][42疣,\-oFXW `]hT\N)1{v6GXb LESdۉHJu$:U`@ɃSŗNXwMn0 j"A#J:ݫyjsNUۨ4E^><{[ޛ%))fUwTZ4,eUU[dƝ!m)ow3차ȡ`ϜgWvd"kUnqZߨK%TѢT$2'6 +ˠJ{rʬm59$>xbȸג|/U~!k {Lz^Vo,!U(DmyJf*0r N}K ҅=ڠ* o|BK a,\ 1W(hWQ;dҨwañpyH%3HH u @ќqnXJjPX\.6Eє r[6 }(L\،.X` B6ֶ:zEI.CQL-ι\yf!>W,a0̭,h7rc *y# t#aF,( 䙞r @SPWa7N)|:d\0f0Dic:zyG2R6ưh L#Lh5Qb: !$Az< v9iҔ8BRń ^Ls;Y2)%eHQ'𦟉%?g&].SP-,0o=`+YDq2> bڱBǠsR.] ,Hc3I9tb]o&d#=r?]һ0mjc:{r_G$ϋZtD- k~cU:Ve1եAp K,Y[NIj{rR=GzT ~Y|F(zF#`f+'s~!:L/xpYF @\Gm /`) B E(TDKz 8T>_ U\)I` S6 zKͭ9) '/ɩin-叺A `ҾKdI+pu.^0h2_fwi@nwLaA~[<2hg[\=`&A3Cch+-soh$5񃼒JmهAk´ZNfAvAmz<3B0 BBnsr6 PL换 |'TIl&ݦQ~o]C V` E\7%#Q) +DCqK(?s#Òr X)K,6K.hf`pr^ A?k m@X6sAӽ-aOnGl.0(5Mg1rrҌBӏ1vnX׃8"H\WLS㫳Heh@Kf$IЭ/ @Fa:V Bv {gM6h)H3> '+fa h\3Eb0HɜH\%IX"z׌uuq-heEA{9Y<̷Άhd=-(5XY.+J<,ڢ^x]8CwIG?Vd-;/S.ںe_˿{ɯ^{̧*-=spL,1{pww@Mi*DHM:an 'R ;e@9`T3^jV@|(!,Nvrǰ=anluǞ'VM CZV>!put؉kp@`Aba==YIFك@؅ X^$-8,yq$[@`뛏ʼܴ RNc[f[Rs_9s41!pV7xʸ|IF$p|QRy}Gzsoe5[JЕ'M$n%0IKSo7J6?!3X@(dABL_cUVGVgA(jąJ9\cb9 ,,߉@I0?$\QH.27sS{L$LIrˮr{叐,p6 UKZ`'C08kw ̱3{D)e0'X/'L#XzKI6X`A'Z`Yvz(Yϝe Wx|[o*EQ4GnSzyGxդ,"(=Z`n9L~ҭZ6@A\@*n%ٳ"ٽ 4Iԍc;,Rj ,Pʁt΂EsbfxėHIY>'_P:,)lػΑJb-IibR$^2m9j ~ޘGGCc>Lɿ0$3@x[ ?p*Տ]3%n?pd@V>8X`!N9䈮AAݒ&X` ݅ռsB'ɇɰ.rQYu5-0kXY1R1 :ˮ3ؙ>!jX[J<&J@ 9Θ =rECSUV9yPGkb6j˶D[,l^qM] ?sʦˆV(mUd6IȬ\N[쏅i&.t@g_]?r޶4 9W_)& l#@o"0;c$ !rÛyYqƙ!M1KoY@SKϺLvJ1sQ,pHki5:ej9;Y&UA; iꅃ| ӊUtl#" 1-4#2~/Ml:Xu],LjϿ '_ie -P;vZ+;M)4Mń@j`5C`S>czNGtF눟K64v f@!Ie;,p4Uch^ga#] hP ,B\ja-\L9?wx> mjXdll,7טz# $-3[s,МQ j 4Bz)l0o ${@OĴz_frh]X%z@^giPv'/TM  lSx,ȹH>6 @t8Щ4bOn-f% 5a=5bp6{/ʮXpնZL[x-:NVL>߳``g68:E/vF_Ô<⌴C3P$A(c޺b?a\fٵέd *_"϶h]-TlqF,(+Na*a;&_eKÂ2E^P&ѯ~>Oˮا=}鳠GY]~?O~_[G–$QE+5jwˇH*{w:&ɾw-WUMqsJAoGA4l@9l.+ -N8dFSS>J,Z <& F^ŷX~&rOb@ Yh L509HO@e½ ůK@i< *2хE~yYyt>Ã/O)&SOO&cVRoeMuJ4RxHu ^T]jњXhZ+`K&DudLf~l 0԰v cybҰfs|M]#i[X ]3[2X(wdZXOXxTm"'o%UdɘCND _s~-m $ ZQdY[{"v@[I XA0SHDe >E#3,0ds2Y2Z(svש!PgJw$;Y'НZTҁ b1OoK̍xp}<%pts sߛYhH>[LsO7> g;d"p \! \Jm{?TZ@.ٻwdo IF#N=[ ۾=;bKWVތ#ۂwun; ptSUm!~)@B2XA(9L~,P{TVHBIH &DrV &>w"w sݗb2ye%0Dqo X:`?kbtGѹإy^9obSOaLߗ]/ μ}#fW3> (z_]9')IENDB`Chart-Strip-1.08/eg/ex1.png010064400017500000146000000214071043450063300135250ustar jawjawPNG  IHDR#PLTED DDuJtRNS@f IDATx]r먶5'}]u^$#{F6ҝUir)W`cN$ '@-A[)ݶӲvm6mulJѨ-k3E(1 քI:θp ɝ$!jm>BZ885!,:8g œC(% qcE2bZuKR )3ru  ~ƒ&t?QD9_Y3)@ #,OÁ,t WW\;qKuV)n׹lBvMW6[E[7{-viMm-\Pq߭Rk﷮ jΣbo#3JC {O>X%= 5A!U~!ȧ*5>-B`2vԢGOXCUp ·《Р[s}FN-_2b)iEl͠$=Q+E>kgBV!Pa8=>Hx|O2ouzmvT ?lv l.ټo!p@taу1h02}h!\E}-.ϡר hA%  >.6t0QGyfk}賂`~# M0=OC BχGiOl;e@7t؏4TlC &0bцi2.rPp>2zLy5 w >?FCC"g+0ҷ5A~{QX9:pv` tA}/ NzLw:aI r+iW@C;( ҡgM8t hy8@y_!4o4V@]FĜ193U9*YGHJκ:m9.g6~w˗rߡ6\je-@c|W*ۉH%&Mlh%+7 fU4ApTT6c&Z@GWapcђF53 ahB`;RϺQA; "gDhBa\<[A/C9̈10pn@= `7Zh"QH B(^@gVHP4 9!q.7}P#Bep; `05\d!`LEv2'lG-qi|Mi2fGt46:Y9$ m@. wNlr8!\dZl Tl (RST!Z`UK?LN&- Ǔ$7)'e1ל4eG-"'ENx"Nvd[>yu0)GOo|Nk2g8y7>A%!IK .ǩx*(TfIQ7e[_11[Ќ985λVDKfq[?&6 =5e/|{Oy?mhu|)pw;0shpTg쀱Y qI}WXekgh6}1}@ӑ Oj\ p#S6?X0$t; 'xrUB-8%CE]#)=bLt^8]x&s$kH ?=Bbg{nXyT]!@{qBΪa3 p,sP;q08wq0ߡC C\?"@(LwDV  cw~YLL@ `&:ʂv8cpzc=MY@e` m i~*$a !)!&< V-<Ł,, ѼYЁHtGEE@FpI ?8Y6K ;8A@d@yIgM zg\RN8 0 YCZ>/&#i88O 28a{P RmI0cHs}@NN|v<g`8)q | `N GQ1$w;yH53d6& P0X`{ϣ z=Oӑi|f ڻX5nR׵+"H+s>,bMr-M.Mȹ*9TE7Ŋd4.Y*A.gEt+~G9\5-$hXJ}S+u3LI5gZU9Ix,͠jSSJwj$'Aev EL G('.>w8e3~;JXN*ݩvv%؝W]{j1R hEM IBi|d ]TvXUCU:uPWYz@=> t.cяU/qP+!-h`pMY׃Yc\EW_癍N{1됥)/u͋@5CJfX&Rq>Q eϫ#jO 4@!KbD `3E7eemDJ.nsۼn// 띞A>=|4?]6>R⎯' p7{w=~m}.đ Ip3bOK78فήڷ];Fz |sT๹ `ðyNNI\ԩz}h[^ќRD:0t`2\o]?w͝`<=-e(uͤ/mr)P9ݿ@qR;q>h(*Ux=oƘO9~GYDVUR n8vzy!9hk]b>:r72Xlgꑁ5jѐHFT_I9}kFyqL c7\f@fe&8Z1ct.ű; ݲx)0_t W#PfЭD#yHܳkV"ɅgpS`\[FBDDZ3;ŐP`R9P2:#Yq,8ːOa^IJ)6ކE=8A[{d?2@CȠ74#8i`=rU;.){|ɂ7;b\}(!'N t֓(J/8cqNG' н+(% : x8j"3.wu]rAأ GwZ)lF p# #{l:*@gbG-=do,#&?^^q!?8qJÞΧSL 1O3h,YE| `:0)G4@ak 2xS\ 0s<6V:~\4 qQцUBGT&2CaTHm4U*^9l6#'E} _QIِfԘ#txiѲkHiy_/|X[. *SU+-$PVZ:⑿۫hlT4E\o!RNJҴ2^l֥XG+/~=jQ&Yiz?Yv3&4˥|obpX.Go?﮷I.5m9AWH9> {PG,mkL9>YvnXX G3g$C\)sw2.0 ::3䭸ČƧg>~AF4dM1mr0p=` ͤAc*8,qF]x(\T:PDh4)M^;T40Ֆi˸7#X.!fw%@y@%:/֌6@,ZY|z.=6=7utZI=9gN"_!/f@Nhc*^r餢YT+Kݩ,9ńbT8IzAq\qԊå"EQ9c%VtxoRWnKҦ*ES~eNSv>NSK訵=x-cPsb,1GV>q‹\'NQRkqORGuT?l%yG&bs8׽7;Ȓlg*Oby$)Voi@od9,.ܚ b:e 4Պo5p) LK@ٰFMS! g堀l%_]C3.%;Q}e!,e;V$-W,9 H1-NUwU!Uvꂛuy^u<oo_=[%>QF޶6p{c |ou%s\թ}#KWY++"ٛﶖ}z mo bD-}39[_"~FI rot-wk\/7/@vȥ=^|7 D7Xye?@ۡgo߾ ׀n~`h$@/@n"FwuwΊmĽp issf|ynjR 'P%pKl#;X1Rb5R arPdvr"D`{N>" ؍uQQQQQ*w,7K_T̩6E59M^SiK˖pIXD",Vژt Q" @Gu\IV9Z&@EZˏ@3(nj{Z#/ G?9JNG p)p%^ss;@ ֓S%:C^k!A>2C!^Ǡ7kVj_,<{3䒖_#XDK<ظUIK<-M U(+9!E7GU]@SM&WնۻZ_6SR_ ұFZZ;hyq*,Ndd@m@X-Jz(y\}rޥcS"YVtAeARۮws#^Ug; JFC"D6 hZ[赣P Ӄ4T@܍k3Yb6a{{’@Cc:1XrũdrHqufaCyu tc)Pu$Ťz> L`\b쁹8 dR-' 3aS8Ga.'E͎@O98thwN. L dlj@Y6OP3岥 ҈etY xa$}z$`μPZk]%}$9#P%P.}" _4c<|sWrz4p:XXfZxw  1z> @^B@{QQ;@G;j J'X5.X`mB[Єq(!и+ 3@fn>!z H$jM50BHpzC@! 'Nȗ("atbȋi&.@*PKPs~^H ׸^=:&r}"j\4> 8|>{dz?{{rcRB?}ӥ( ߻)Ct9 6)} 5b8τsǔw9`!ыp:iX7f u440xG7|i-50\+ /T ؿT(*!L=m T{ZŞnԴ*.nUK2rU&<`@kx8ZK1h3}@#jZ$%}ok{ij.9 uCGM.ZD`B؋|5C|21_"֠ -=$֩ZC->מC#)&P̂CBew4),k[FYWX8;Y#oI+tM͂@١X"tCsWqB=Xk>AMք20Vۥ| tL`lniJtS*DN` S2 \61J .#P) ^_Mt8 ƅ(i㼀& ].eOhU6 %2$5K].)psOF1YQ9pV:G}m4ܒ@qڒ,pcѵH`)ijrSmLS*KC]LRY,U ?Fq-umC u5JYA!ZdD`b~ tW07W,svS&_ WEE&ǻZ)/qTS9,i~k8Mk+6?c_ vDp&|-rQRkt\j)=LRZdAZWCLRBq~Ot痄 +W!B]w4gnT7تċ3\vF 4ǁKs;]6۾g '?C'>VnkzI@ZRWť>]aфY5LjL./50[lqM78jgp Rp58dM|Gܻ* X9]"U\oфΕ4䢖p\\3`AzT6kId%ɬlqYA,ZlϾXUu RN Y%3d P+ .V|XR t a*iZ-,!aXlYӲ.jJc3VM_sn*rC N._(?+{>uFT6SN`1[U\yLVNFv D:Bb+M'y:E)΃ELB17,нĵb4:TcfY"E)? ڟ! y̾u噬g Bm8%7{;e8yOjz;ڊ:8F)< N.NJB|L5cˆ˝7VTɂR(@g2FIDAT*Myc s>@Oi\>fu1;*Vt91zD,\H+6;#_q[L8ѨV~Ug'斳Zr'%X:XE2SM*:%!:JX14\圔s9Fe9&.h]6/SrP{pRT9U34v7YPr\;)>Dgåg"Kz? 5p gk?y܆\|sv]R4}JV ,*ۦZ?F"FKo`f 1Ewm \|}4aVqo ݡ+ݴJ˸K=>e0v6](Ji,ț,&Ef"F"FP?V>5ApN>;rŨg&p[n5ò._BQQ@^,t$u~BZ:8^'%ܿj~?Y[~H lJ 5p~qO琲A|{YX~ItdW6ŧIENDB`Chart-Strip-1.08/MANIFEST010064400017500000146000000004721165706726100130740ustar jawjawMANIFEST README INSTALL CHANGES Makefile.PL Strip.pm t/test1.t t/test2.t t/test3.t eg/index.html eg/Makefile eg/ex1.pl eg/ex2.pl eg/ex3.pl eg/ex4.pl eg/ex5.pl eg/ex6.pl eg/ex1.png eg/ex2.png eg/ex3.png eg/ex4.png eg/ex5.png eg/ex6.png META.yml Module meta-data (added by MakeMaker) Chart-Strip-1.08/CHANGES010064400017500000146000000004701165664616000127340ustar jawjaw 1.08 fixed rare divide-by-zero issue [David Precious] 1.07 drop shadows smooth curves 1.06 ylabel placement calculation 1.05 xtic changes and speedups 1.04 added missing files to MANIFEST 1.03 added thickness added skip_undefined added style box 1.02 added data_label_style Chart-Strip-1.08/Strip.pm010064400017500000146000001124021165706716300134000ustar jawjaw# -*- perl -*- # Copyright (c) 2002 by Jeff Weisberg # Author: Jeff Weisberg # Date: 2002-Nov-01 16:11 (EST) # Function: draw strip charts # # $Id: Strip.pm,v 1.22 2011/11/11 00:38:11 jaw Exp $ $Chart::Strip::VERSION = "1.08"; =head1 NAME Chart::Strip - Draw strip chart type graphs. =head1 SYNOPSIS use Chart::Strip; my $ch = Chart::Strip->new( title => 'Happiness of our Group', # other options ... ); $ch->add_data( $davey_data, { style => 'line', color => 'FF0000', label => 'Davey' } ); $ch->add_data( $jenna_data, { style => 'line', color => '00FF88', label => 'Jenna' } ); print $ch->png(); =head1 DESCRIPTION The Chart::Strip package plots data values versus time graphs, such as used for seismographs, EKGs, or network usage reports. It can plot multiple data sets on one graph. It offers several styles of plots. It automatically determines the proper ranges and labels for both axii. =head1 USAGE =head2 Create the Chart $chart = Chart::Strip->new(); $chart = Chart::Strip->new( option1 => value, option2 => value, ); If no options are specified, sensible default values will be used. The following options are recognized: =over 4 =item C The width of the image =item C The height of the image. =item C The title of the graph. Will be placed centered at the top. =item C<x_label> The label for the x axis. Will be placed centered at the bottom. =item C<y_label> The label for the y axis. Will be placed vertically along the left side. =item C<draw_grid> Should a grid be drawn on the graph? =item C<draw_border> Should a border be drawn around the edge of the image? =item C<draw_tic_labels> Should value labels be shown? =item C<draw_data_labels> Should each data set be labeled? =item C<transparent> Should the background be transparent? =item C<grid_on_top> Should the grid be drawn over the data (1) or below the data (0)? =item C<binary> Use powers of 2 instead of powers of 10 for the y axis labels. =item C<data_label_style> Style for drawing the graph labels. C<text> or C<box> =item C<thickness> Thickness of lines in pixels. (Requires GD newer than $VERSION). =item C<skip_undefined> Don\'t draw a line into or out of a datapoint whose value is undefined. If false, undefined values are treated as though they were 0. =item C<boxwidth> Width of boxes for box style graphs. The width may also be specified as C<width> in the data options or per point. If no width is specified a reasonable default is used. =back =head2 Adding Data $chart->add_data( $data, $options ); The data should be an array ref of data points. Each data point should be a hash ref containing: { time => $time_t, # must be a unix time_t value => $value, # the data value color => $color, # optional, used for this one point } or, range style graphs should contain: { time => $time_t, # must be a unix time_t min => $low, # the minimum data value max => $high, # the maximum data value color => $color, # optional, used for this one point } and the options may contain: { style => 'line', # graph style: line, filled, range, points, box color => 'FF00FF', # color used for the graph label => 'New England', # name of the data set } points style graphs may specify the point diameter, as C<diam> box style graphs may specify the box width, as C<width> line and filled graphs may specify a C<smooth> parameter, to connect points using smooth curves instead of straight lines. A value of C<1> is recommended, larger values will be less smooth. line, points, box, and filled graphs may specify a drop shadow, consisting of a hashref containing C<dx>, C<dy>, C<dw>, and optionally, C<color> shadow => { dx => 3, dy => 3, dw => 3, color => 'CCCCCC' } =head2 Outputing The Image =over 4 =item $chart->png() Will return the PNG image =item $chart->jpeg() Will return the jpeg image =item $chart->gd() Will return the underlying GD object. =back =cut ; package Chart::Strip; use GD; use Carp; use POSIX; use strict; my $LT_HM = 1; # time my $LT_HR = 2; # time/day my $LT_DW = 3; # day/date my $LT_DM = 4; # date/yr my $LT_YR = 5; # year my $MT_NO = 0; # none my $MT_HR = 1; # hrs my $MT_MN = 2; # midnight my $MT_SU = 3; # sunday my $MT_M1 = 4; # 1st my $MT_Y1 = 5; # new years sub new { my $class = shift; my %param = @_; my $me = bless { width => 640, height => 192, margin_left => 8, margin_bottom => 8, margin_right => 8, margin_top => 8, n_y_tics => 4, # aprox. transparent => 1, grid_on_top => 1, draw_grid => 1, draw_border => 1, draw_tic_labels => 1, draw_data_labels => 1, limit_factor => 0, data_label_style => 'text', # or 'box' thickness => 1, tm_time => \&POSIX::localtime, # or gmtime, or... shadow_color => '#CCCCCC', # GD can only antialias on a truecolor image, and only if thickness==1 # yes, I know what the GD documentation says. I also know what the src says... antialias => 0, truecolor => 0, # title # x_label # y_label # user specified params override defaults %param, }, $class; $me->adjust(); my $im = GD::Image->new( $me->{width}, $me->{height}, $me->{truecolor} ); $me->{img} = $im; # Nor long the sun his daily course withheld, # But added colors to the world reveal'd: # When early Turnus, wak'ning with the light, # -- Virgil, Aeneid # allocate some useful colors, 1st is used for bkg my $bkg = $me->color({ color => $me->{background_color} }) if $me->{background_color}; $me->{color}{white} = $im->colorAllocate(255,255,255); $me->{color}{black} = $im->colorAllocate(0,0,0); $me->{color}{blue} = $im->colorAllocate(0, 0, 255); $me->{color}{red} = $im->colorAllocate(255, 0, 0); $me->{color}{green} = $im->colorAllocate(0, 255, 0); $me->{color}{gray} = $im->colorAllocate(128, 128, 128); # style for grid lines $im->setStyle(gdTransparent, $me->{color}{gray}, gdTransparent, gdTransparent); $im->interlaced('true'); $im->transparent($me->{color}{white}) if $me->{transparent}; $im->filledRectangle( 0, 0, $me->{width}-1, $me->{height}-1, ($bkg || $me->{color}{white})); my $bc = $me->{border_color} ? $me->img_color($me->{border_color}) : $me->{color}{black}; $im->rectangle(0, 0, $me->{width}-1, $me->{height}-1, $bc ) if $me->{draw_border}; $me; } sub add_data { my $me = shift; my $data = shift; my $opts = shift; $me->analyze( $data, $opts ); unless( $opts->{style} ){ $opts->{style} = defined $data->[0]{min} ? 'range' : 'line'; } push @{$me->{data}}, {data => $data, opts => $opts}; $me->{has_shadow} = 1 if $opts->{shadow}; $me; } # A plot shall show us all a merry day. # -- Shakespeare, King Richard II sub plot { my $me = shift; return unless $me->{data}; return if $me->{all_done}; $me->adjust(); $me->clabels(); $me->xlabel(); $me->ylabel(); $me->title(); if( $me->{draw_tic_labels} ){ # move margin for xtics before we do ytics $me->{margin_bottom} += 12; $me->adjust(); } $me->ytics(); $me->xtics(); # draw shadows foreach my $d ( @{$me->{data}} ){ next unless $d->{opts}{shadow}; $me->plot_data( $d->{data}, $d->{opts}, $d->{opts}{shadow} ); } $me->axii(); $me->drawgrid() unless $me->{grid_on_top}; # plot foreach my $d ( @{$me->{data}} ){ $me->plot_data( $d->{data}, $d->{opts}, undef ); } $me->drawgrid() if $me->{grid_on_top}; $me->{all_done} = 1; $me; } # The axis of the earth sticks out visibly through the centre of each and every town or city. # -- Oliver Wendell Holmes, The Autocrat of the Breakfast-Table sub axii { my $me = shift; my $im = $me->{img}; # draw axii $im->line( $me->xpt(-1), $me->ypt(-1), $me->xpt(-1), $me->ypt($me->{ymax}), $me->{color}{black}); $im->line( $me->xpt(-1), $me->ypt(-1), $me->xpt($me->{xmax}), $me->ypt(-1), $me->{color}{black}); # 'Talking of axes,' said the Duchess, 'chop off her head!' # -- Alice in Wonderland $me; } sub set_thickness { my $me = shift; my $tk = shift; my $im = $me->{img}; # not available until gd 2.07 return unless $im->can('setThickness'); $im->setThickness($tk); } sub gd { my $me = shift; $me->plot(); $me->{img}; } sub png { my $me = shift; $me->plot(); $me->{img}->png( @_ ); } sub jpeg { my $me = shift; $me->plot(); $me->{img}->jpeg( @_ ); } # xpt, ypt - convert graph space => image space sub xpt { my $me = shift; my $pt = shift; $pt + $me->{margin_left}; } sub ypt { my $me = shift; my $pt = shift; # make 0 bottom $me->{height} - $pt - $me->{margin_bottom}; } # xdatapt, ydatapt - convert data space => image space sub xdatapt { my $me = shift; my $pt = shift; $me->xpt( ($pt - $me->{xd_min}) * $me->{xd_scale} ); } sub ydatapt { my $me = shift; my $pt = shift; $pt = $pt < $me->{yd_min} ? $me->{yd_min} : $pt; $pt = $pt > $me->{yd_max} ? $me->{yd_max} : $pt; $me->ypt( ($pt - $me->{yd_min}) * $me->{yd_scale} ); } sub adjust { my $me = shift; # I have touched the highest point of all my greatness; # -- Shakespeare, King Henry VIII $me->{xmax} = $me->{width} - $me->{margin_right} - $me->{margin_left}; $me->{ymax} = $me->{height} - $me->{margin_bottom} - $me->{margin_top} ; if( $me->{data} ){ $me->{xd_scale} = ($me->{xd_min} == $me->{xd_max}) ? 1 : $me->{xmax} / ($me->{xd_max} - $me->{xd_min}); $me->{yd_scale} = ($me->{yd_min} == $me->{yd_max}) ? 1 : $me->{ymax} / ($me->{yd_max} - $me->{yd_min}); } $me; } sub analyze { my $me = shift; my $data = shift; my $opts = shift; my( $st, $et, $pt, $min, $max ); $st = $data->[0]{time}; # start time $et = $data->[-1]{time}; # end time $pt = $st; foreach my $s (@$data){ croak "data point out of order" if $s->{time} < $pt; my $a = defined $s->{min} ? $s->{min} : $s->{value}; my $b = defined $s->{max} ? $s->{max} : $s->{value}; $a ||= 0 unless $me->{skip_undefined} || $opts->{skip_undefined}; $b ||= 0 unless $me->{skip_undefined} || $opts->{skip_undefined}; ($a, $b) = ($b, $a) if $a > $b; $min = $a if defined($a) && ( !defined($min) || $a < $min ); $max = $b if defined($b) && ( !defined($max) || $b > $max ); $pt = $s->{time}; } if( $opts->{style} eq 'box' ){ # stretch x axis if drawing wide boxes my $defwid = def_box_width($st, $et, scalar(@$data)); my $w = $data->[0]{width} || $opts->{width} || $me->{boxwidth} || $defwid; $st -= $w/2; $w = $data->[-1]{width} || $opts->{width} || $me->{boxwidth} || $defwid; $et += $w/2; # boxes are drawn from y=0 $min = 0 if $min > 0; } if( $opts->{smooth} || $me->{smooth} ){ # calculate derivative at each point (which may or may not be evenly spaced) for my $i (0 .. @$data-1){ my $here = $data->[$i]; my $left = $i ? $data->[$i-1] : $data->[$i]; my $right = ($i!=@$data-1) ? $data->[$i+1] : $data->[$i]; my $dxl = $here->{time} - $left->{time}; my $dxr = $right->{time} - $here->{time}; my $dyl = $here->{value} - $left->{value}; my $dyr = $right->{value} - $here->{value}; if( $dxr && $dxl ){ my $dl = $dyl / $dxl; my $dr = $dyr / $dxr; if( $dl < 0 && $dr > 0 || $dl > 0 && $dr < 0 ){ # local extrema $data->[$i]{dydx} = 0; }else{ my $dm = ( $dl * $dxr + $dr * $dxl ) / ($dxr + $dxl); # mathematicaly, $dm is the best estimate of the derivative, and gives the smoothest curve # but, this way looks nicer... my $d = (sort { abs($a) <=> abs($b) } ($dl, $dr, $dm))[0]; $data->[$i]{dydx} = ($d + $dm) / 2; } }elsif($dxr){ $data->[$i]{dydx} = $dyr / $dxr; }elsif($dxl){ $data->[$i]{dydx} = $dyl / $dxl; } } } $me->{xd_min} = $st if $st && (!defined($me->{xd_min}) || $st < $me->{xd_min}); $me->{xd_max} = $et if $et && (!defined($me->{xd_max}) || $et > $me->{xd_max}); $me->{yd_min} = $min if !defined($me->{yd_min}) || $min < $me->{yd_min}; $me->{yd_max} = $max if !defined($me->{yd_max}) || $max > $me->{yd_max}; } # I hear beyond the range of sound, # I see beyond the range of sight, # New earths and skies and seas around, # And in my day the sun doth pale his light. # -- Thoreau, Inspiration sub set_y_range { my $me = shift; my $l = shift; my $h = shift; $me->{yd_min} = $l if defined($l) && $l ne ''; $me->{yd_max} = $h if defined($h) && $h ne ''; $me->adjust(); } sub set_x_range { my $me = shift; my $l = shift; my $h = shift; $me->{xd_min} = $l if defined($l) && $l ne ''; $me->{xd_max} = $h if defined($h) && $h ne ''; $me->adjust(); } sub img_color { my $me = shift; my $color = shift; $color =~ s/^#//; $color =~ s/\s//g; return $me->{color}{$color} if $me->{color}{$color}; my($r,$g,$b) = map {hex} unpack('a2 a2 a2', $color); my $i = $me->{img}->colorAllocate( $r, $g, $b ); $me->{color}{$color} = $i; return $i; } # choose proper color for plot sub color { my $me = shift; my $data = shift; my $opts = shift; # What is your favorite color? # Blue. No yel-- Auuuuuuuugh! # -- Monty Python, Holy Grail my $c = $data->{color} || $opts->{color}; if( $c ){ return $me->img_color( $c ); } return $me->{color}{green}; } # Titles are marks of honest men, and wise; # The fool or knave that wears a title lies. # -- Edward Young, Love of Fame sub title { my $me = shift; my( $loc ); return unless $me->{title}; $me->{margin_top} += 16; $me->adjust(); # center title $loc = ($me->{width} - length($me->{title}) * 7) / 2; $me->{img}->string(gdMediumBoldFont, $loc, 2, $me->{title}, $me->{color}{black}); } # when I waked, I found This label on my bosom # -- Shakespeare, Cymbeline sub xlabel { my $me = shift; my( $loc, $y ); return unless $me->{x_label}; $me->{margin_bottom} += 16; $me->adjust(); $loc = ($me->{width} - length($me->{x_label}) * 6) / 2; $y = $me->{height} - $me->{margin_bottom} + 8; $me->{img}->string(gdSmallFont, $loc, $y, $me->{x_label}, $me->{color}{black}); } sub ylabel { my $me = shift; my( $loc ); return unless $me->{y_label}; $me->{margin_left} += 12; $me->adjust(); my $m = ($me->{height} - $me->{margin_top} - $me->{margin_bottom}) / 2 + $me->{margin_top}; $loc = $m + length($me->{y_label}) * 6 / 2; $me->{img}->stringUp(gdSmallFont, 2, $loc, $me->{y_label}, $me->{color}{black}); # small => 12,6; tiny => 10,5 } # It must be a very pretty dance # -- Alice in Wonderland # make tic numbers pretty sub pretty { my $me = shift; my $y = shift; my $st = shift; my( $ay, $sc, $b, $prec ); return $me->{fmt_value}->($y) if $me->{fmt_value}; $sc = ''; $ay = abs($y); $b = $me->{binary} ? 1024 : 1000; if( $ay < 1 ){ if( $ay < 1/$b**3 ){ return "0"; } elsif( $ay < 1/$b**2 ){ $y *= $b ** 3; $st *= $b ** 3; $sc = 'n'; } elsif( $ay < 1/$b ){ $y *= $b**2; $st *= $b**2; $sc = 'u'; } elsif( $ay < 100/$b ){ # QQQ $y *= $b; $st *= $b; $sc = 'm'; } }else{ if( $ay >= $b**4 ){ $y /= $b**4; $st /= $b**4; $sc = 'T'; } elsif( $ay >= $b**3 ){ $y /= $b**3; $st /= $b**3; $sc = 'G'; } elsif( $ay >= $b**2 ){ $y /= $b**2; $st /= $b**2; $sc = 'M'; } elsif( $ay >= $b ){ $y /= $b; $st /= $b; $sc = 'k'; } } $sc .= 'i' if $sc && $me->{binary}; # as per IEC 60027-2 if( $st > 1 ){ $prec = 0; }else{ $prec = abs(floor(log($st)/log(10))); } sprintf "%.${prec}f$sc", $y; } sub ytics { my $me = shift; my( $min, $max, $tp, $st, $is, $low, $maxw, @tics ); $min = $me->{yd_min}; $max = $me->{yd_max}; $maxw = 0; if( $min == $max ){ # not a very interesting graph... my $lb = $me->pretty($min, 1); # QQQ my $w = length($lb) * 5 + 6; push @tics, [$me->ydatapt($min), $lb, $w]; $maxw = $w; }else{ $tp = ($max - $min) / $me->{n_y_tics}; # approx spacing of tics if( $me->{binary} ){ $is = 2 ** floor( log($tp)/log(2) ); }else{ $is = 10 ** floor( log($tp)/log(10) ); } $st = floor( $tp / $is ) * $is; # -> 4 - 8, ceil -> 2 - 4 # mathematically, tp/is cannot be less than 1 # but due to floating-point lossage, in rare cases, it might $st ||= $is; $low = int( $min / $st ) * $st; for my $i ( 0 .. (2 * $me->{n_y_tics} + 2) ){ my $y = $low + $i * $st; next if $y < $min; last if $y > $max; my $yy = $me->ydatapt($y); my $label = $me->pretty($y, $st); my $w = 5 * length($label) + 6; $maxw = $w if $w > $maxw; push @tics, [$yy, $label, $w]; } } if( $me->{draw_tic_labels} ){ # move margin $me->{margin_left} += $maxw; $me->adjust(); } $me->{grid}{y} = \@tics; } sub drawgrid { my $me = shift; my $im = $me->{img}; foreach my $tic (@{$me->{grid}{y}}){ # ytics + horiz lines my $yy = $tic->[0]; $im->line($me->xpt(-1), $yy, $me->xpt(-4), $yy, $me->{color}{black}); $im->line($me->xpt(0), $yy, $me->{width} - $me->{margin_right}, $yy, gdStyled) if $me->{draw_grid}; if( $me->{draw_tic_labels} ){ my $label = $tic->[1]; my $w = $tic->[2]; $im->string(gdTinyFont, $me->xpt(-$w), $yy-4, $label, $me->{color}{black}); } } foreach my $tic (@{$me->{grid}{x}}){ # xtics + vert lines my( $t, $ll, $label ) = @$tic; # supress solid line if adjacent to axis if( $ll && ($t != $me->{xd_min}) ){ # solid line, red label $im->line($me->xdatapt($t), $me->{margin_top}, $me->xdatapt($t), $me->ypt(-4), $me->{color}{black} ); }else{ # tic and grid $im->line($me->xdatapt($t), $me->ypt(-1), $me->xdatapt($t), $me->ypt(-4), $me->{color}{black} ); $im->line($me->xdatapt($t), $me->{margin_top}, $me->xdatapt($t), $me->ypt(0), gdStyled ) if $me->{draw_grid}; } if( $me->{draw_tic_labels} ){ my $a = length($label) * 6 / 4; # it looks better not quite centered if( length($label)*6 * 3/4 + $me->xdatapt($t) > $me->{width} ){ # too close to edge, shift $a = $me->xdatapt($t) - $me->{width} + length($label) * 6 + 2; } $im->string(gdSmallFont, $me->xdatapt($t)-$a, $me->ypt(-6), $label, $ll ? $me->{color}{red} : $me->{color}{black} ); } } } sub xtic_range_data { my $me = shift; # not used my $range = shift; my $range_hrs = $range / 3600; my $range_days = $range_hrs / 24; # return: step, labeltype, marktype, lti, tmod if( $range < 720 ){ (60, $LT_HM, $MT_HR, 1, 1); # tics: 1 min } elsif( $range < 1800 ){ (300, $LT_HM, $MT_HR, 1, 5); # tics: 5 min } elsif( $range_hrs < 2 ){ (600, $LT_HM, $MT_HR, 1, 10); # tics: 10 min } elsif( $range_hrs < 6 ){ (1800, $LT_HR, $MT_MN, 1, 30); # tics: 30 min } elsif( $range_hrs < 13 ){ (3600, $LT_HR, $MT_MN, 2, 1); # tics: 1 hr } elsif( $range_hrs < 25 ){ (3600, $LT_HR, $MT_MN, 2, 2); # tics: 2 hrs } elsif( $range_hrs < 50 ){ (3600, $LT_HR, $MT_MN, 2, 4); # tics: 4 hrs } elsif( $range_hrs < 75 ){ (3600, $LT_HR, $MT_MN, 2, 6); # tics: 6 hrs } # NB: days shorter or longer than 24 hours are corrected for below elsif( $range_days < 15 ){ (3600*24, $LT_DW, $MT_SU, 3, 1); # tics 1 day } elsif( $range_days < 22 ){ (3600*24, $LT_DM, $MT_M1, 3, 2); # tics: 2 days } elsif( $range_days < 80 ){ (3600*24, $LT_DM, $MT_M1, 3, 7); # tics: 7 days } elsif( $range_days < 168 ){ (3600*24, $LT_DM, $MT_Y1, 3, 14); # tics: 14 days } # NB: months shorter than 31 days are corrected for below elsif( $range_days < 370 ){ (3600*24*31, $LT_DM, $MT_Y1, 4, 1); # tics: 1 month } elsif( $range_days < 500 ){ (3600*24*31, $LT_DM, $MT_Y1, 4, 2); # tics: 2 month } elsif( $range_days < 1000 ){ (3600*24*31, $LT_DM, $MT_Y1, 4, 3); # tics: 3 month } elsif( $range_days < 2000 ){ (3600*24*31, $LT_DM, $MT_NO, 4, 6); # tics: 6 month } else{ # NB: years less than 366 days are corrected for below (3600*24*366, $LT_YR, $MT_NO, 4, 12); # tics: 1 yr } } sub xtic_align_initial { my $me = shift; my $step = shift; my $t = ($step < 3600) ? (int($me->{xd_min} / $step) * $step) : (int($me->{xd_min} / 3600) * 3600); if( $step >= 3600*24*365 ){ while(1){ # search for 1jan my @lt = $me->{tm_time}($t); last if $lt[4] == 0 && $lt[3] == 1 && $lt[2] == 0; # jump fwd: 1M, 1D, or 1H my $dt = ($lt[4] != 11) ? 24*30 : ($lt[3] < 30) ? 24 : 1; $t += $dt * 3600; } } elsif( $step >= 3600*24*31 ){ while(1){ # find 1st of mon my @lt = $me->{tm_time}($t); last if $lt[3] == 1 && $lt[2] == 0; my $dt = ($lt[3] < 28) ? 24 : 1; $t += $dt * 3600; } } elsif( $step >= 3600*24 ){ while(1){ # search for midnight my @lt = $me->{tm_time}($t); last unless $lt[2]; $t += 3600; } } $t; } sub xtics { my $me = shift; my @tics; # this is good for (roughly) 10 mins - 10 yrs return if $me->{xd_max} == $me->{xd_min}; my $range = $me->{xd_max} - $me->{xd_min}; my $range_hrs = $range / 3600; my $range_days = $range_hrs / 24; my ($step, $labtyp, $marktyp, $lti, $tmod) = $me->xtic_range_data( $range ); my $t = $me->xtic_align_initial( $step ); # print "days: $range_days, lt: $labtyp, lti: $lti, tmod: $tmod, st: $step\n"; # print STDERR "t: $t ", scalar(localtime $t), "\n"; for( ; $t<$me->{xd_max}; $t+=$step ){ my $redmark = 0; next if $t < $me->{xd_min}; my @lt = $me->{tm_time}($t); my @rlt = @lt; # months go from 0. days from 1. absurd! $lt[3]--; # mathematically, 28 is divisible by 7. but that just looks silly. $lt[3] = 22 if $lt[3] > 22 && $lti==3 && $tmod >= 7; if( $step >= 3600*24 && $lt[2] ){ # handle daylight saving time changes - resync to midnight my $dt = ($lt[2] > 12 ? $lt[2] - 24 : $lt[2]) * 3600; $dt += $lt[1] * 60; $t -= $dt; redo; } if( $step >= 3600*24*31 && $lt[3] ){ # some months are not 31 days! # also corrects years that do not leap my $dt = $lt[3] * 3600*24; $t -= $dt; redo; } next if $lt[$lti] % $tmod; next if $lt[3] && $lti > 3; next if $lt[2] && $lti > 2; next if $lt[1] && $lti > 1; next if $lt[0] && $lti > 0; $redmark = 1 if $marktyp == $MT_HR && !$lt[1]; # on the hour $redmark = 1 if $marktyp == $MT_MN && !$lt[2] && !$lt[1]; # midnight $redmark = 1 if $marktyp == $MT_SU && !$lt[6]; # sunday $redmark = 1 if $marktyp == $MT_M1 && !$lt[3]; # 1st of month $redmark = 1 if $marktyp == $MT_Y1 && !$lt[3] && !$lt[4]; # 1 jan my $label; # NB: strftime obeys LC_TIME for localized day/month names # (if locales are supported in the OS and perl) if( $labtyp == $LT_HM ){ $label = sprintf "%d:%0.2d", $rlt[2], $rlt[1]; # time } if( $labtyp == $LT_HR ){ if( $redmark ){ $label = strftime("%d/%b", @rlt); # date DD/Mon }else{ $label = sprintf "%d:%0.2d", $rlt[2], $rlt[1]; # time } } if( $labtyp == $LT_DW ){ if( $redmark ){ $label = strftime("%d/%b", @rlt); # date DD/Mon }else{ $label = strftime("%a", @rlt); # day of week } } if( $labtyp == $LT_DM ){ if( !$lt[3] && !$lt[4] ){ $label = $rlt[5] + 1900; # year }else{ $label = strftime("%d/%b", @rlt); # date DD/Mon } } if( $labtyp == $LT_YR ){ $label = $rlt[5] + 1900; # year } push @tics, [$t, $redmark, $label]; } $me->{grid}{x} = \@tics; } # it shall be inventoried, and every particle and utensil # labelled to my will: as, item, two lips, # indifferent red; item, two grey eyes, with lids to # them; item, one neck, one chin, and so forth. Were # you sent hither to praise me? # -- Shakespeare, Twelfth Night sub clabels { my $me = shift; return unless $me->{draw_data_labels}; my $rs = 0; my $rm = 0; if( $me->{data_label_style} eq 'box' ){ $rs = 6; $rm = 3; } my( $tw, $r, @cl, @cx ); $tw = $r = 0; # round the neck of the bottle was a paper label, with the # words 'DRINK ME' beautifully printed on it in large letters # -- Alice in Wonderland foreach my $d (@{$me->{data}}){ my $l = $d->{opts}{label}; my $c = $d->{opts}{color}; next unless $l; my $w = length($l) * 5 + 6; $w += $rm + $rs; if( $tw + $w > $me->{width} - $me->{margin_left} - $me->{margin_right} ){ $r ++; $tw = 0; } push @cx, [$l, $tw, $r, $c]; $tw += $w; } my $i = 0; foreach my $x (@cx){ my $xx = $x->[1] + $me->{margin_left}; my $y = $me->{height} - ($r - $x->[2] + 1) * 10; my $c = $x->[3]; if( $rs ){ $me->{img}->filledRectangle($xx, $y+1, $xx+$rs, $y+$rs+1, $me->color({color => $c})); $me->{img}->rectangle($xx, $y+1, $xx+$rs, $y+$rs+1, $me->{color}{black}); $me->{img}->string(gdTinyFont, $xx+$rs+$rm, $y, $x->[0], $me->{color}{black}); }else{ $me->{img}->string(gdTinyFont, $xx, $y, $x->[0], $me->color({color => $c})); } } if( @cx ){ $me->{margin_bottom} += ($r + 1) * 10; $me->adjust(); } } sub plot_data { my $me = shift; my $data = shift; my $opts = shift; my $shadow = shift; return unless $data && @$data; # 'What did they draw?' said Alice, quite forgetting her promise. # -- Alice in Wonderland if( $opts->{style} eq 'line' ){ # 'You can draw water out of a water-well,' said the Hatter # -- Alice in Wonderland $me->draw_line( $data, $opts, $shadow ); } elsif( $opts->{style} eq 'filled' ){ # I should think you could draw treacle out of a treacle-well # -- Alice in Wonderland $me->draw_filled( $data, $opts, $shadow ); } elsif( $opts->{style} eq 'range' ){ # did you ever see such a thing as a drawing of a muchness? # -- Alice in Wonderland $me->draw_range( $data, $opts, $shadow ); }elsif( $opts->{style} eq 'points' ){ # and they drew all manner of things--everything that begins with an M--' # -- Alice in Wonderland $me->draw_points( $data, $opts, $shadow ); }elsif( $opts->{style} eq 'box' ){ $me->draw_boxes( $data, $opts, $shadow ); }else{ croak "unknown graph style--cannot draw"; } } # A flattering painter, who made it his care # To draw men as they ought to be, not as they are. # -- Oliver Goldsmith, Retaliation sub draw_filled { my $me = shift; my $data = shift; my $opts = shift; my $shadow = shift; my $im = $me->{img}; my $limit = $me->{limit_factor} * ($me->{xd_max} - $me->{xd_min}) / @$data; my $skipundef = $opts->{skip_undefined} || $me->{skip_undefined}; my $thick = $opts->{thickness} || $me->{thickness}; my $smooth = $opts->{smooth} || $me->{smooth}; my $shcolor = $shadow ? $me->img_color($shadow->{color} || $me->{shadow_color} ) : undef; my($px, $py, $pxdpt, $pydpt, $pdydx); my $ypt0 = $me->ypt(0); $thick += $shadow->{dw} if $shadow; $me->set_thickness( $thick ) if $thick; foreach my $s ( @$data ){ my $x = $s->{time}; my $y = $s->{value}; next if $x < $me->{xd_min} || $x > $me->{xd_max}; my $xdpt = $me->xdatapt($x); my $ydpt = $me->ydatapt($y); my $dydx; if( $shadow ){ $xdpt += $shadow->{dx}; $ydpt += $shadow->{dy}; } if( defined($y) || !$skipundef ){ my $color = $shadow ? $shcolor : $me->color($s, $opts); if( defined($px) && ($xdpt - $pxdpt > 1) && (!$limit || $x - $px <= $limit) ){ if( $smooth ){ next unless defined $s->{dydx}; $dydx = - $s->{dydx} * $me->{yd_scale} / $me->{xd_scale}; $me->curve($pxdpt, $pydpt, $pdydx, $xdpt, $ydpt, $dydx, $smooth, \&curve_filled, [$color, $ypt0]); }else{ my $poly = GD::Polygon->new; $poly->addPt($pxdpt, $ypt0); $poly->addPt($pxdpt, $pydpt); $poly->addPt($xdpt, $ydpt); $poly->addPt($xdpt, $ypt0); $im->filledPolygon($poly, $color); } }else{ $im->line( $xdpt, $ypt0, $xdpt, $ydpt, $color); } $px = $x; $pxdpt = $xdpt; $py = $y; $pydpt = $ydpt; $pdydx = $dydx; }else{ $px = undef; } } $me->set_thickness( 1 ) if $thick; } sub draw_line { my $me = shift; my $data = shift; my $opts = shift; my $shadow = shift; my $im = $me->{img}; my $limit = $me->{limit_factor} * ($me->{xd_max} - $me->{xd_min}) / @$data; my $thick = $opts->{thickness} || $me->{thickness}; my $skipundef = $opts->{skip_undefined} || $me->{skip_undefined}; my $smooth = $opts->{smooth} || $me->{smooth}; my($px, $py, $pxdpt, $pydpt, $pdydx); $thick += $shadow->{dw} if $shadow; $me->set_thickness( $thick ) if $thick; my $shcolor = $shadow ? $me->img_color($shadow->{color} || $me->{shadow_color} ) : undef; foreach my $s ( @$data ){ my $x = $s->{time}; my $y = $s->{value}; next if $x < $me->{xd_min} || $x > $me->{xd_max}; my $xdpt = $me->xdatapt($x); my $ydpt = $me->ydatapt($y); my $dydx = $smooth ? - $s->{dydx} * $me->{yd_scale} / $me->{xd_scale} : undef; if( $shadow ){ $xdpt += $shadow->{dx}; $ydpt += $shadow->{dy}; } if( defined($y) || !$skipundef ){ my $color = $shadow ? $shcolor : $me->color($s, $opts); if( $me->{antialias} && $thick == 1 ){ # GD cannot antialias a thick line $im->setAntiAliased($color); $color = gdAntiAliased; } if( defined($px) && (!$limit || $x - $px <= $limit) ){ if( $smooth ){ next unless defined $s->{dydx}; $me->curve($pxdpt, $pydpt, $pdydx, $xdpt, $ydpt, $dydx, $smooth, \&curve_line, [$color]); }else{ $im->line( $pxdpt, $pydpt, $xdpt, $ydpt, $color ); } }else{ $im->setPixel($xdpt, $ydpt, $color ); } $px = $x; $pxdpt = $xdpt; $py = $y; $pydpt = $ydpt; $pdydx = $dydx; }else{ $px = undef; } } $me->set_thickness( 1 ) if $thick; } # GD has only circular arcs, not bezier or cubic splines # bezier math is easier than trying to use circular arcs sub curve { my $me = shift; my( $x0, $y0, $dydx0, $x1, $y1, $dydx1, $smooth, $fnc, $args ) = @_; # pick bezier control points # smooth = (.5 - 1) gives nice curves # smooth > 1 gives straighter segments # smooth <= .5 takes the graph on a drug trip my $dxt = ($x1 - $x0) / ($smooth * 3); my $cx0 = $x0 + $dxt; my $cx1 = $x1 - $dxt; my $cy0 = $y0 + $dydx0 * $dxt; my $cy1 = $y1 - $dydx1 * $dxt; # bezier coefficients my $ax = - $x0 + 3 * $cx0 - 3 * $cx1 + $x1; my $ay = - $y0 + 3 * $cy0 - 3 * $cy1 + $y1; my $bx = 3 * $x0 - 6 * $cx0 + 3 * $cx1; my $by = 3 * $y0 - 6 * $cy0 + 3 * $cy1; my $cx = - 3 * $x0 + 3 * $cx0; my $cy = - 3 * $y0 + 3 * $cy0; my $dx = $x0; my $dy = $y0; # draw bezier curve my $px = $x0; my $py = $y0; # my $im = $me->{img}; # $im->line($x0,$y0, $cx0,$cy0, $me->img_color('00ff00')); # $im->line($x1,$y1, $cx1,$cy1, $me->img_color('00ff00')); # $im->line($cx0,$cy0, $cx1,$cy1, $me->img_color('0000ff')); my $ymax = $me->{height} - $me->{margin_bottom}; my $ymin = $me->{margin_top}; my $T = ($x1 - $x0) + abs($y1 - $y0); for my $tt (1 .. $T){ my $t = $tt / $T; my $x = $ax * $t**3 + $bx * $t**2 + $cx * $t + $dx; my $y = $ay * $t**3 + $by * $t**2 + $cy * $t + $dy; # QQQ - handle out-of-bounds segments how? if( $y >= $ymin && $y <= $ymax && $py >= $ymin && $py <= $ymax ){ $fnc->($me, $px,$py, $x,$y, 0, @$args); }else{ $fnc->($me, $px,$py, $x,$y, [$ymin, $ymax], @$args); } $px = $x; $py = $y; } } sub curve_line { my $me = shift; my ($px, $py, $x, $y, $oob, $color) = @_; return if $oob; $me->{img}->line($px,$py, $x,$y, $color); } sub curve_filled { my $me = shift; my ($px, $py, $x, $y, $oob, $color, $y0) = @_; if( $oob ){ my($ymin, $ymax) = @$oob; $y = $ymin if $y < $ymin; $py = $ymin if $py < $ymin; $y = $ymax if $y > $ymax; $py = $ymax if $py > $ymax; } my $poly = GD::Polygon->new; $poly->addPt($px, $y0); $poly->addPt($px, $py); $poly->addPt($x, $y); $poly->addPt($x, $y0); $me->{img}->filledPolygon($poly, $color); } sub draw_range { my $me = shift; my $data = shift; my $opts = shift; my $shadow = shift; return if $shadow; my $im = $me->{img}; my $limit = $me->{limit_factor} * ($me->{xd_max} - $me->{xd_min}) / @$data; my $skipundef = $opts->{skip_undefined} || $me->{skip_undefined}; my($px, $pn, $pm, $pxdpt); foreach my $s ( @$data ){ my $x = $s->{time}; my $a = defined $s->{min} ? $s->{min} : $s->{value}; my $b = defined $s->{max} ? $s->{max} : $s->{value}; my $xdpt = $me->xdatapt($x); next if $x < $me->{xd_min} || $x > $me->{xd_max}; $a = $b if !defined($a) && $skipundef; $b = $a if !defined($b) && $skipundef; if( defined($a) || !$skipundef ){ if( defined($px) && ($xdpt - $pxdpt > 1) && (!$limit || $x - $px <= $limit) ){ my $poly = GD::Polygon->new; $poly->addPt($pxdpt, $me->ydatapt($pn)); $poly->addPt($pxdpt, $me->ydatapt($pm)); $poly->addPt($xdpt, $me->ydatapt($b)); $poly->addPt($xdpt, $me->ydatapt($a)); $im->filledPolygon($poly, $me->color($s, $opts)); }else{ $im->line( $xdpt, $me->ydatapt($b), $xdpt, $me->ydatapt($a), $me->color($s, $opts) ); } $px = $x; $pn = $a; $pm = $b; $pxdpt = $xdpt; }else{ $px = undef; } } } sub draw_points { my $me = shift; my $data = shift; my $opts = shift; my $shadow = shift; my $im = $me->{img}; my $skipundef = $opts->{skip_undefined} || $me->{skip_undefined}; my $shcolor = $shadow ? $me->img_color($shadow->{color} || $me->{shadow_color} ) : undef; foreach my $s ( @$data ){ my $x = $s->{time}; my $y = $s->{value}; my $d = $s->{diam} || $opts->{diam} || 4; my $c = $shadow ? $shcolor : $me->color($s, $opts); next if $x < $me->{xd_min} || $x > $me->{xd_max}; next if !defined($y) && $skipundef; my $xdpt = $me->xdatapt($x); my $ydpt = $me->ydatapt($y); if( $shadow ){ $d += $shadow->{dw}; $xdpt += $shadow->{dx}; $ydpt += $shadow->{dy}; } while( $d > 0 ){ $im->arc( $xdpt, $ydpt, $d, $d, 0, 360, $c ); $d -= 2; } } } sub def_box_width { my $ta = shift; my $tb = shift; my $nd = shift; return ($tb - $ta) / ($nd - 1) if $nd > 1; return ($tb - $ta) / $nd if $nd; 1; } sub draw_boxes { my $me = shift; my $data = shift; my $opts = shift; my $shadow = shift; my $im = $me->{img}; my $defwid = def_box_width($data->[0]{time}, $data->[-1]{time}, scalar(@$data)); my $thick = $opts->{thickness} || $me->{thickness}; my $skipundef = $opts->{skip_undefined} || $me->{skip_undefined}; my $shcolor = $shadow ? $me->img_color($shadow->{color} || $me->{shadow_color} ) : undef; $thick += $shadow->{dw} if $shadow; $me->set_thickness( $thick ) if $thick; foreach my $s ( @$data ){ my $x = $s->{time}; my $y = $s->{value}; my $w = $s->{width} || $opts->{width} || $me->{boxwidth} || $defwid; my $y0 = $opts->{boxbase} || $me->{boxbase} || 0; my $c = $shadow ? $shcolor : $me->color($s, $opts); next if $x < $me->{xd_min} || $x > $me->{xd_max}; next if !defined($y) && $skipundef; # because GD cares... my $ya = $me->ydatapt($y > $y0 ? $y : $y0); my $yb = $me->ydatapt($y > $y0 ? $y0 : $y); my $xa = $me->xdatapt($x - $w/2); my $xb = $me->xdatapt($x + $w/2); if( $shadow ){ $xa += $shadow->{dx}; $xb += $shadow->{dx}; $ya += $shadow->{dy}; $yb += $shadow->{dy}; } if( $opts->{filled} || $s->{filled} ){ $im->filledRectangle( $xa, $ya, $xb, $yb, $c); }else{ $im->rectangle( $xa, $ya, $xb, $yb, $c); } } $me->set_thickness( 1 ) if $thick; } =head1 EXAMPLE IMAGES http://argus.tcp4me.com/shots.html http://search.cpan.org/src/JAW/Chart-Strip-1.07/eg/index.html =head1 LICENSE This software may be copied and distributed under the terms found in the Perl "Artistic License". A copy of the "Artistic License" may be found in the standard Perl distribution. =head1 BUGS There are no known bugs in the module. =head1 SEE ALSO Yellowstone National Park. =head1 AUTHOR Jeff Weisberg - http://www.tcp4me.com =cut ; 1; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Chart-Strip-1.08/INSTALL����������������������������������������������������������������������������0100644�0001750�0000146�00000001125�10013004647�0012750�0����������������������������������������������������������������������������������������������������ustar �jaw�����������������������������jaw�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� Installing: 1. verify that you have the prerequisites installed + perl perl is required for both this module and the perl program that uses this module. the software has been tested with 5.6.1 and should work with anything more recent, and maybe less recent, as well. Find perl at www.perl.org + GD is required in order to create images it can be found on CPAN 2. unbundle the tarball 3. run 'perl Makefile.PL' 4. run 'make' 5. run 'make install' 6. run 'perldoc Chart::Strip' 7. you are finished, sing a happy song, or, optionally, send in a bug report �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Chart-Strip-1.08/Makefile.PL������������������������������������������������������������������������0100644�0001750�0000146�00000000455�10012752316�0013700�0����������������������������������������������������������������������������������������������������ustar �jaw�����������������������������jaw��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Chart::Strip', VERSION_FROM => 'Strip.pm', ABSTRACT_FROM => 'Strip.pm', AUTHOR => 'Jeff Weisberg <http://www.tcp4me.com/>', PREREQ_PM => {GD => 0}, ); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Chart-Strip-1.08/README�����������������������������������������������������������������������������0100644�0001750�0000146�00000000723�10012751671�0012607�0����������������������������������������������������������������������������������������������������ustar �jaw�����������������������������jaw��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������SUMMARY: Chart::Strip - Draw strip chart type graphs. INSTALLATION: see the file INSTALL COPYRIGHT: see the copyright notice in Strip.pm LICENSE INFORMATION: This software may be copied and distributed under the terms found in the Perl "Artistic License". A copy of the "Artistic License" may be found in the standard Perl distribution. DOCUMENTATION: see the pod in Strip.pm AUTHOR: Jeff Weisberg - http://www.tcp4me.com/ ���������������������������������������������Chart-Strip-1.08/META.yml���������������������������������������������������������������������������0100644�0001750�0000146�00000001041�11657067261�0013205�0����������������������������������������������������������������������������������������������������ustar �jaw�����������������������������jaw��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- #YAML:1.0 name: Chart-Strip version: 1.08 abstract: Draw strip chart type graphs. author: - Jeff Weisberg <http://www.tcp4me.com/> license: unknown distribution_type: module configure_requires: ExtUtils::MakeMaker: 0 build_requires: ExtUtils::MakeMaker: 0 requires: GD: 0 no_index: directory: - t - inc generated_by: ExtUtils::MakeMaker version 6.50 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������