#!/bin/sh # # From dss@Sun.COM Tue Nov 29 03:01:11 1988 # Date: Mon, 28 Nov 88 12:50:19 PST # From: dss@Sun.COM (Daniel Steinberg) # To: don@bensun.cs.umd.edu # Subject: Re: Permission to distribute NeWS software # # feel free to distribute psgraph, though it's not exactly elegant. # here's my latest copy, in case you have an old version: # ------------------------------------------------------------------ # # @(#)psgraph.sh 1.7 87/11/10 SMI # # PostScript graphing tool # # usage: # psgraph [-blsx] [file [label]] # where: # -b binary (doubles) input (default is ascii) # -l log10 y-scaling (default is linear) # -s square waves (lines inbetween points are ordinarily direct) # -x label the axes # file name of file containing ascii data samples ('-' for stdin) # label ascii graph label (default "") # USAGE="PostScript Graphing Tool -- usage:\n \tpsgraph [-blsx] [file [label]]\nwhere:\n \t-b\tread samples as binary doubles (default: ascii)\n \t-l\tuse log (base 10) y-scaling (default: linear)\n \t-s\tplot square waves (default: connect-the-dots)\n \t-x\tput numeric labels on the axes\n \tfile\tinput file (if NULL or '-', read stdin)\n \tlabel\tlabel for graph (default: NULL)" # PATH=/usr/5bin:$PATH set -- `getopt blsx $@` if [ $? != 0 ] then echo $USAGE exit 1 fi for i in $* do case $i in -b) ASCII=false; shift;; -l) LOG=true; shift;; -s) SQUARE=true; shift;; -x) AXES=true; shift;; --) shift; break;; esac done # if [ -f ${1:-"-"} ] then Input=$1 else Input= fi tmp='/tmp/psgraph'$$ echo '% psgraph - graph data' >$tmp echo '/Square '${SQUARE:-false}' def' >>$tmp echo '/Log '${LOG:-false}' def' >>$tmp echo '/Labelxy '${AXES:-false}' def' >>$tmp # # stupid kludge because getopt() doesn't quote arguments correctly # if [ $# -ge 1 ]; then shift; fi echo '/Label ('$*') def' >>$tmp # echo '/Samples [' >>$tmp if [ ${ASCII:-true} = true ] then tr ';#' '%%' <$Input >>$tmp else ftoa <$Input >>$tmp fi echo '] def' >>$tmp cat $tmp - <<'@@@ Fin @@@' | psh % x & y ratios of graphing area to displayed canvas /Xoff .95 def /Yoff .9 def % Number of tick marks to display on the x & y axes /Xticks 5 def /Yticks 5 def % Derived constants /Xborder 1 Xoff sub 2 div def /Yborder 1 Yoff sub 2 div def % Draw the graph, with horizontal lines between points if /Square is true /drawgraph { newpath 0 Samples 0 get moveto 0 Samples { 2 copy lineto exch 1 add exch Square {2 copy lineto} if pop } forall stroke } def % Save the current matrix and rescale for text /saveandscale { % saveandscale -> matrix matrix currentmatrix initmatrix } def % Write a string at the current location /putlabel { % string putlabel -> saveandscale exch show setmatrix } def % Write a string centered at the current location /centerlabel { % string centerlabel -> saveandscale exch dup stringbbox pop exch pop 2 div exch pop neg 0 rmoveto show setmatrix } def % Find minimum and maximum among the data points /minmax { % array minmax -> min max 1E38 -1E38 3 -1 roll { % min max num 2 copy gt {exch} {exch pop dup} ifelse 3 1 roll % max min num 2 copy lt {} {exch} ifelse pop exch % min max } forall } def % Calculate the min/max of the data; [take the log if /Log is true] % Save min/max sample values in Minval/Maxval % Save min/max display values (may be logarithmic) in Miny/Maxy /scaledata { /Nsamp Samples length def Nsamp 0 eq { (psgraph: no sample data\n) printf quit } if Samples minmax /Maxy exch def /Miny exch def /Maxval Maxy def /Minval Miny def Log { Miny 0 le { (psgraph: log data <= 0\n) printf quit } if Samples 0 Samples { % array index val log 3 copy put pop 1 add % array index } forall pop pop Samples minmax /Maxy exch def /Miny exch def } if } def % Set the scaling and translation so that the data fits in the window /scalegraph { % 1/(N-1) 2/(Max-Min) scale 1 Nsamp 1 sub div 2 Maxy Miny sub div scale % 0 -(Max-((Max-Min)/2)) translate 0 Maxy Miny sub 2 div Maxy sub translate } def % Draw tick marks on the graph and label them /labelgraph { currentfont dup .8 scalefont setfont .5 Yoff 2 sub Yborder sub moveto Label centerlabel setfont newpath -1 2 Xticks 1 sub div 1 { dup 0 exch moveto Xborder neg exch lineto } for 0 1 Yticks 1 sub div 1 { dup -1 moveto -1 Yborder sub lineto } for stroke Labelxy { currentfont (Screen) findfont setfont Xborder neg 1 moveto (%) [Maxval] sprintf putlabel Xborder neg Yoff 2 sub Yborder sub moveto (%) [Minval] sprintf putlabel 1 Yoff 1 sub moveto (%) [Nsamp] sprintf centerlabel setfont } if } def % Here is where execution actually begins scaledata /win framebuffer /new DefaultWindow send def { /PaintClient { ClientCanvas setcanvas textcolor setcolor 1 setlinequality % Rescale so that 0