#!/usr/bin/perl #Copyright (c) 2008 Emin Gabrielyan, Switzernet $k=1.6; $width=400; $height=200; $xscaleh=140; $yscalew=50; $fsz=10; $ptsz=2; $sample_len=20; $legendw=75; $grid_color="0.85 0.85 1"; $xscalen=18; $yscalen=10; $yscaledecpt=2; $width*=$k; $height*=$k; $xscaleh*=$k; $yscalew*=$k; $fsz*=$k; $ptsz*=$k; $sample_len*=$k; $legendw*=$k; if(@ARGV != 2) { print "two arguments are required: \n"; exit 1; } $psfname=$ARGV[1]; $fname=$ARGV[0]; if(! open fh, $fname) { print "error opening file $fname\n"; exit 1; } @lines=; close fh; foreach $_ (@lines) { s/[\r\n]//g; @r=split/,/; if(/^([\d]+)(,([\d.]*))+$/) { if(!defined($xmax) || $r[0]>=$xmax) { $xmax=$r[0]; } else { print "time is not increasing\n"; exit 2; } if(!defined($xmin) || $r[0]<$xmin) { $xmin=$r[0]; } for($i=1;$i<@r;$i++) { if(defined($r[$i]) && $r[$i] ne "") { if(!defined($ymax) || $r[$i]>$ymax) { $ymax=$r[$i]; } if(!defined($ymin) || $r[$i]<$ymin) { $ymin=$r[$i]; } } } } elsif(/^time(,([\w]+))+$/) { if(!defined(@h)) { @h=@r; } else { print "multiple header lines\n"; exit 2; } } else { print "file format error\n"; exit 2; } } if(!defined(@h)) { print "no header line\n"; exit 2; } if(!defined($xmin) || !defined($xmax)) { print "no value on the X scale\n"; exit 2; } if(!defined($ymin) || !defined($ymax)) { print "no value on the Y scale\n"; exit 2; } if($xmin==$xmax) { print "only one value on the X scale\n"; exit 3; } if($ymin==$ymax) { print "only one value on the Y scale\n"; exit 3; } if(! open ps,">".$psfname) { print "error opening file $psfname\n"; exit 4; } print ps "%!PS-Adobe-3.0 EPSF-3.0\r\n"; printf ps "%%%%BoundingBox: 0 0 %f %f\r\n",$yscalew+$width+$legendw,$xscaleh+$height+$fsz; print ps "/Courier findfont $fsz scalefont setfont\r\n"; print ps "1 setlinecap\r\n"; for($i=0;$i<$xscalen;$i++) { $t=$xmin+$i/($xscalen-1)*($xmax-$xmin); $x=$yscalew+$i/($xscalen-1)*$width; print ps "gsave $grid_color setrgbcolor\r\n"; print ps "$x $xscaleh $fsz 3 div sub moveto $x $xscaleh $height add lineto stroke\r\n"; print ps "grestore\r\n"; print ps "gsave\r\n"; print ps "$x $xscaleh translate\r\n"; print ps "90 rotate\r\n"; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($t); printf ps "(%s-%02d-%02d %02d:%02d:%02d) dup\r\n",$year+1900,$mon+1,$mday,$hour,$min,$sec; print ps "stringwidth pop $fsz 2 div add neg $fsz 1 3 div mul neg moveto\r\n"; print ps "show\r\n"; print ps "grestore\r\n"; } for($i=0;$i<$yscalen;$i++) { $v=$ymin+$i/($yscalen-1)*($ymax-$ymin); $y=$xscaleh+$i/($yscalen-1)*$height; print ps "gsave $grid_color setrgbcolor\r\n"; print ps "$yscalew $fsz 3 div sub $y moveto $yscalew $width add $y lineto stroke\r\n"; print ps "grestore\r\n"; print ps "gsave\r\n"; print ps "$yscalew $y translate\r\n"; printf ps "(%.${yscaledecpt}f) dup\r\n",$v; print ps "stringwidth pop $fsz 2 div add neg $fsz 1 3 div mul neg moveto\r\n"; print ps "show\r\n"; print ps "grestore\r\n"; } print ps "$yscalew $xscaleh moveto\r\n"; print ps "$width 0 rlineto stroke\r\n"; print ps "$yscalew $xscaleh moveto\r\n"; print ps "0 $height rlineto stroke\r\n"; sub green { local($a)=($_[0]); if($a>=0 && $a<=0.5) { $a*2; } elsif($a>=0.5 && $a<=1.5) { 1; } elsif($a>=1.5 && $a<=2) { 1-($a-1.5)*2; } elsif($a>=2 && $a<=3) { 0; } else { -1; } } sub red { local($a)=($_[0]); $a+=1; $a=$a>=3?$a-3:$a; &green($a); } sub blue { local($a)=($_[0]); $a+=2; $a=$a>=3?$a-3:$a; &green($a); } sub rgb { #according to: http://4z.com/People/emin-gabrielyan/public/050401-linkviews/ local($a,$k)=($_[0],0.75); $a*=3; (&red($a)*$k,&green($a)*$k,&blue($a)*$k); } for($i=1;$i<=@h-1;$i++) { ($rgb_r,$rgb_g,$rgb_b)=&rgb(($i-1)/(@h-1)); $rgb_color[$i]="$rgb_r $rgb_g $rgb_b"; } $y=$xscaleh+$height; for($i=1;$i<=@h-1;$i++) { print ps "gsave $rgb_color[$i] setrgbcolor\r\n"; print ps "$yscalew $width add 1.0 $sample_len mul add $y moveto $sample_len 0 rlineto stroke\r\n"; print ps "$yscalew $width add 1.5 $sample_len mul add $y $ptsz 2 div 0 360 arc fill\r\n"; print ps "$yscalew $width add 2.0 $sample_len mul add $y moveto\r\n"; print ps "$fsz 2 div $fsz 1 4 div mul neg rmoveto ($h[$i]) show\r\n"; print ps "grestore\r\n"; $y-=$fsz; } for($i=1;$i<=@h-1;$i++) { print ps "gsave $rgb_color[$i] setrgbcolor\r\n"; $mvln="moveto"; foreach $_ (@lines) { s/[\r\n]//g; @r=split/,/; if(/^([\d]+)(,([\d.]*))+$/) { if(defined($r[$i]) && $r[$i]!~/^\s*$/) { $x=$yscalew+($r[0]-$xmin)/($xmax-$xmin)*$width; $y=$xscaleh+($r[$i]-$ymin)/($ymax-$ymin)*$height; print ps "$x $y $mvln\r\n"; $mvln="lineto"; } else { $mvln="moveto"; } } } print ps "stroke\r\n"; foreach $_ (@lines) { s/[\r\n]//g; @r=split/,/; if(/^([\d]+)(,([\d.]*))+$/) { if(defined($r[$i]) && $r[$i]!~/^\s*$/) { $x=$yscalew+($r[0]-$xmin)/($xmax-$xmin)*$width; $y=$xscaleh+($r[$i]-$ymin)/($ymax-$ymin)*$height; print ps "$x $y $ptsz 2 div 0 360 arc fill\r\n"; } } } print ps "grestore\r\n"; } print ps "showpage\r\n"; close ps