summaryrefslogtreecommitdiffstats
path: root/grapheps.ps
diff options
context:
space:
mode:
Diffstat (limited to 'grapheps.ps')
-rw-r--r--grapheps.ps344
1 files changed, 344 insertions, 0 deletions
diff --git a/grapheps.ps b/grapheps.ps
new file mode 100644
index 0000000..87658dd
--- /dev/null
+++ b/grapheps.ps
@@ -0,0 +1,344 @@
+%%EndComments
+/plotdict 100 dict def
+plotdict begin
+
+% Definitions so that internal assignments are bound before setting.
+/DATA 0 def
+/DEN 0 def
+/DIAG 0 def
+/DIAG2 0 def
+/DLTA 0 def
+/EXPSN 0 def
+/GPROCS 0 def
+/GD 6 def
+/GR 3 def
+/IDX 0 def
+/ISIZ 0 def
+/MAX 0 def
+/MIN 0 def
+/NUM 0 def
+/PLOT-bmargin 0 def
+/PLOT-lmargin 0 def
+/PLOT-rmargin 0 def
+/PLOT-tmargin 0 def
+/PROC 0 def
+/ROW 0 def
+/TXT 0 def
+/WPAGE 0 def
+/X-COORD 0 def
+/XDX 0 def
+/XOFF 0 def
+/XPARTS 0 def
+/XRNG 0 def
+/XSCL 0 def
+/XSTEP 0 def
+/XSTEPH 0 def
+/XTSCL 0 def
+/XWID 0 def
+/Y-COORD 0 def
+/YDX 0 def
+/YHIT 0 def
+/YOFF 0 def
+/YPARTS 0 def
+/YRNG 0 def
+/YSCL 0 def
+/YSTEP 0 def
+/YSTEPH 0 def
+/YTSCL 0 def
+/graphrect 0 def
+/plotrect 0 def
+
+% Here are the procedure-arrays for passing as the third argument to
+% plot-column. Plot-column moves to the first coordinate before
+% calls to the first procedure. Thus both line and scatter graphs are
+% supported. Many additional glyph types can be produced as
+% combinations of these types. This is best accomplished by calling
+% plot-column with each component.
+
+% GD and GR are the graphic-glyph diameter and radius.
+% DIAG and DIAG2, used in /cross are diagonal and twice diagonal.
+% gtrans maps x, y coordinates on the stack to 72dpi page coordinates.
+
+% Render line connecting points
+/line [{} {lineto} {}] bind def
+/mountain [{currentpoint 2 copy pop bottomedge moveto lineto}
+ {lineto}
+ {currentpoint pop bottomedge lineto closepath fill}] bind def
+/cloud [{currentpoint 2 copy pop topedge moveto lineto}
+ {lineto}
+ {currentpoint pop topedge lineto closepath fill}] bind def
+% Render lines from x-axis to points
+/impulse [{} {moveto currentpoint pop 0 lineto} {}] bind def
+/bargraph [{} {exch GR sub exch 0 exch GD exch rectstroke} {}] bind def
+
+% Solid round dot.
+/disc [{GD setlinewidth 1 setlinecap}
+ {moveto 0 0 rlineto} {}] bind def
+% Minimal point -- invisible if linewidth is 0.
+/point [{1 setlinecap} {moveto 0 0 rlineto} {}] bind def
+% Square box.
+/square [{} {GR sub exch GR sub exch GD dup rectstroke} {}] bind def
+% Square box at 45.o
+/diamond [{}
+ {2 copy GR add moveto
+ GR neg GR neg rlineto GR GR neg rlineto
+ GR GR rlineto GR neg GR rlineto
+ closepath}
+ {}] bind def
+% Plus Sign
+/plus [{}
+ { GR sub moveto 0 GD rlineto
+ GR neg GR neg rmoveto GD 0 rlineto}
+ {}] bind def
+% X Sign
+/cross [{/DIAG GR .707 mul def /DIAG2 DIAG 2 mul def}
+ {exch DIAG sub exch DIAG add moveto DIAG2 dup neg rlineto
+ DIAG2 neg 0 rmoveto DIAG2 dup rlineto}
+ {}] bind def
+% Triangle pointing upward
+/triup [{}
+ {2 copy GR 1.12 mul add moveto GR neg GR -1.62 mul rlineto
+ GR 2 mul 0 rlineto GR neg GR 1.62 mul rlineto
+ closepath}
+ {}] bind def
+% Triangle pointing downward
+/tridown [{}
+ {2 copy GR 1.12 mul sub moveto GR neg GR 1.62 mul rlineto
+ GR 2 mul 0 rlineto GR neg GR -1.62 mul rlineto
+ closepath}
+ {}] bind def
+/pentagon [{}
+ {gsave translate 0 GR moveto 4 {72 rotate 0 GR lineto} repeat
+ closepath stroke grestore}
+ {}] bind def
+/circle [{stroke} {GR 0 360 arc stroke} {}] bind def
+
+% ( TITLE ) ( SUBTITLE )
+/title-top
+{ dup stringwidth pop -2 div plotrect 0 get plotrect 2 get 2 div add add
+ plotrect 1 get plotrect 3 get add pointsize .4 mul add moveto show
+ dup stringwidth pop -2 div plotrect 0 get plotrect 2 get 2 div add add
+ plotrect 1 get plotrect 3 get add pointsize 1.4 mul add moveto show
+} bind def
+
+% ( TITLE ) ( SUBTITLE )
+/title-bottom
+{ dup stringwidth pop -2 div plotrect 0 get plotrect 2 get 2 div add add
+ plotrect 1 get pointsize -2 mul add moveto show
+ dup stringwidth pop -2 div plotrect 0 get plotrect 2 get 2 div add add
+ plotrect 1 get pointsize -1 mul add moveto show
+} bind def
+
+% Plots column K against column J of given two-dimensional ARRAY.
+% The arguments are:
+% [ ARRAY J K ] J and K are column-indexes into ARRAY
+% [ PREAMBLE RENDER POSTAMBLE ] Plotting procedures:
+% PREAMBLE - Executed once before plotting row
+% RENDER - Called with each pair of coordinates to plot
+% POSTAMBLE - Called once after plotting row (often does stroke)
+/plot-column
+{ /GPROCS exch def aload pop /YDX exch def /XDX exch def /DATA exch def
+ /GD glyphsize def
+ /GR GD .5 mul def
+ gsave
+ /ROW DATA 0 get def ROW XDX get ROW YDX get gtrans moveto
+ GPROCS 0 get exec % preamble
+ /PROC GPROCS 1 get def DATA {dup XDX get exch YDX get gtrans PROC} forall
+ GPROCS 2 get exec stroke % postamble
+ grestore
+} bind def
+
+/whole-page
+{clippath pathbbox 2 index sub exch 3 index sub exch 4 array astore} bind def
+
+/partition-page
+{ /YPARTS exch def /XPARTS exch def /WPAGE exch def
+ /XWID WPAGE 2 get XPARTS div def /YHIT WPAGE 3 get YPARTS div def
+ /Y-COORD WPAGE 1 get def
+ YPARTS
+ { /X-COORD WPAGE 0 get WPAGE 2 get add XWID sub def
+ XPARTS {[X-COORD Y-COORD XWID YHIT]
+ /X-COORD X-COORD XWID sub def} repeat
+ /Y-COORD Y-COORD YHIT add def
+ } repeat
+} bind def
+
+% The arguments are:
+% [ MIN-X MIN-Y DELTA-X DELTA-Y ] whole graph rectangle
+% [ MIN-COLJ MAX-COLJ ] Numerical range of plot data
+% [ MIN-COLK MAX-COLK ] Numerical range of plot data
+% and the implicit current clippath
+/setup-plot
+{ /YRNG exch def /XRNG exch def /graphrect exch def
+ /PLOT-bmargin pointsize 2.4 mul def
+ /PLOT-tmargin pointsize 2.4 mul def
+ /PLOT-lmargin (-.0123456789) stringwidth pop pointsize 1.2 mul add def
+ /PLOT-rmargin (-.0123456789) stringwidth pop pointsize 1.2 mul add def
+ /plotrect [ graphrect 0 get PLOT-lmargin add
+ graphrect 1 get PLOT-bmargin add
+ graphrect 2 get PLOT-lmargin sub PLOT-rmargin sub
+ graphrect 3 get PLOT-bmargin sub PLOT-tmargin sub ] def
+ /XOFF XRNG 0 get def /YOFF YRNG 0 get def
+ /XSCL plotrect 2 get XRNG aload pop exch sub div def
+ /YSCL plotrect 3 get YRNG aload pop exch sub div def
+ /XOFF XOFF plotrect 0 get XSCL div sub def
+ /YOFF YOFF plotrect 1 get YSCL div sub def
+ /YTSCL plotrect 3 get YRNG aload pop exch sub find-tick-scale def
+ /YSTEP YTSCL 0 get 3 mod 0 eq {6} {8} ifelse 5 mul yuntrans def
+ /XTSCL plotrect 2 get XRNG aload pop exch sub find-tick-scale def
+ /XSTEP XTSCL 0 get 3 mod 0 eq {6} {8} ifelse 10 mul xuntrans def
+ /YSTEPH YSTEP 2 div def
+ /XSTEPH XSTEP 2 div def
+} bind def
+
+% gtrans is the utility routine mapping data coordinates to view space.
+% plot-column sets up XOFF, XSCL, and YSCL and uses it.
+/gtrans {exch XOFF sub XSCL mul exch YOFF sub YSCL mul} bind def
+%/guntrans {exch XSCL div XOFF add exch YSCL div YOFF add} bind def
+
+% /ytrans {YTSCL aload pop div mul} bind def
+% /xtrans {XTSCL aload pop div mul} bind def
+/yuntrans {YTSCL aload pop exch div mul} bind def
+/xuntrans {XTSCL aload pop exch div mul} bind def
+
+/zero-in-range? {dup 0 get 0 le exch 1 get 0 ge and} bind def
+
+/y-axis
+{ XRNG zero-in-range?
+ { 0 YRNG 0 get gtrans moveto 0 YRNG 1 get gtrans lineto stroke} if
+} bind def
+/x-axis
+{ YRNG zero-in-range?
+ {XRNG 0 get 0 gtrans moveto XRNG 1 get 0 gtrans lineto stroke} if
+} bind def
+
+% Find data range in column K of two-dimensional ARRAY.
+% ARRAY
+% K is the column-index into ARRAY
+/column-range
+{ /IDX exch def dup /MIN exch 0 get IDX get def /MAX MIN def
+ {IDX get dup dup MIN lt {/MIN exch def} {pop} ifelse
+ dup MAX gt {/MAX exch def} {pop} ifelse} forall
+ [MIN MAX]
+} bind def
+
+/min {2 copy lt {pop} {exch pop} ifelse} bind def
+/max {2 copy gt {pop} {exch pop} ifelse} bind def
+
+/combine-ranges
+{ aload pop 3 2 roll aload pop exch 4 3 roll min 3 1 roll max 2 array astore}
+bind def
+
+/pad-range
+{ exch aload pop /MAX exch def /MIN exch def
+ /EXPSN exch 100 div MAX MIN sub mul def
+ [ MIN EXPSN sub MAX EXPSN add ]
+} bind def
+
+/snap-range
+{dup aload pop exch sub 1 exch find-tick-scale aload pop
+ /DEN exch def /NUM exch def 1 NUM div DEN mul /DLTA exch def
+ aload pop /MAX exch def /MIN exch def
+ [ DLTA MAX MIN sub sub 2 div dup MIN exch sub exch MAX add ]
+} bind def
+
+% Given the width (or height) and the data-span, returns an array of
+% numerator and denominator (NUM DEN)
+%
+% NUM will be 1, 2, 3, 4, 5, 6, or 8 times a power of ten.
+% DEN will be a power of ten.
+%
+% NUM ISIZ
+% === < ====
+% DEN DLTA
+/find-tick-scale
+{/DLTA exch def /ISIZ exch def
+ /DEN 1 def
+ {DLTA ISIZ le {exit} if /DEN DEN 10 mul def /ISIZ ISIZ 10 mul def} loop
+ /NUM 1 def
+ {DLTA 10 mul ISIZ ge {exit} if /NUM NUM 10 mul def /DLTA DLTA 10 mul def} loop
+ [[8 6 5 4 3 2 1] {/MAX exch def MAX DLTA mul ISIZ le {MAX exit} if} forall
+ NUM mul DEN]
+} bind def
+
+/rule-vertical
+{ /XWID exch def
+ /TXT exch def
+ /X-COORD exch def
+ X-COORD type [] type eq {/X-COORD X-COORD 0 get def} if
+ gsave
+ X-COORD plotrect 1 get plotrect 3 get 2 div add translate
+ TXT stringwidth pop -2 div
+ XWID 0 gt { 90 rotate PLOT-lmargin} {-90 rotate PLOT-rmargin} ifelse
+ pointsize 1.2 mul sub moveto TXT show
+ grestore
+ YRNG 0 get YSTEP div ceiling YSTEP mul YSTEP YRNG 1 get
+ { /YDX exch def 0 YDX gtrans /Y-COORD exch def pop
+ X-COORD Y-COORD moveto XWID 0 rlineto stroke
+ /TXT YDX 20 string cvs def
+ X-COORD
+ XWID 0 gt {TXT stringwidth pop sub ( ) stringwidth pop sub
+ Y-COORD pointsize .3 mul sub moveto}
+ {Y-COORD pointsize .3 mul sub moveto ( ) show} ifelse
+ TXT show} for
+ YRNG 0 get YSTEPH div ceiling YSTEPH mul YSTEPH YRNG 1 get
+ { /YDX exch def 0 YDX gtrans /Y-COORD exch def pop
+ X-COORD Y-COORD moveto XWID 2 div 0 rlineto stroke} for
+} bind def
+
+/rule-horizontal
+{ /YHIT exch def
+ /TXT exch def
+ /Y-COORD exch def
+ Y-COORD type [] type eq {/Y-COORD Y-COORD 1 get def} if
+ plotrect 0 get plotrect 2 get 2 div add TXT stringwidth pop -2 div add
+ Y-COORD
+ YHIT 0 gt {pointsize -2 mul} {pointsize 1.4 mul} ifelse add moveto TXT show
+ XRNG 0 get XSTEP div ceiling XSTEP mul XSTEP XRNG 1 get
+ { dup 0 gtrans pop /X-COORD exch def
+ X-COORD Y-COORD moveto 0 YHIT rlineto stroke
+ /TXT exch 10 string cvs def
+ X-COORD TXT stringwidth pop 2.0 div sub
+ Y-COORD YHIT 0 gt {pointsize sub} {pointsize .3 mul add} ifelse
+ moveto TXT show
+ } for
+ XRNG 0 get XSTEPH div ceiling XSTEPH mul XSTEPH XRNG 1 get
+ { 0 gtrans pop Y-COORD moveto 0 YHIT 2 div rlineto stroke} for
+} bind def
+
+/grid-verticals
+{ XRNG 0 get XSTEPH div ceiling XSTEPH mul XSTEPH XRNG 1 get
+ { 0 gtrans pop /X-COORD exch def
+ X-COORD plotrect 1 get moveto 0 plotrect 3 get rlineto} for
+ stroke
+} bind def
+
+/grid-horizontals
+{ YRNG 0 get YSTEPH div ceiling YSTEPH mul YSTEPH YRNG 1 get
+ { 0 exch gtrans /Y-COORD exch def pop
+ plotrect 0 get Y-COORD moveto plotrect 2 get 0 rlineto} for
+ stroke
+} bind def
+
+/leftedge {plotrect 0 get} bind def
+/rightedge {plotrect dup 0 get exch 2 get add} bind def
+/topedge {plotrect dup 1 get exch 3 get add} bind def
+/bottomedge {plotrect 1 get} bind def
+
+/outline-rect {aload pop rectstroke} bind def
+/fill-rect {aload pop rectfill} bind def
+/clip-to-rect {aload pop rectclip} bind def
+
+% Default parameters
+
+% glyphsize is the graphic-glyph size; GR, graphic radius, is
+% glyphsize/2. Line width, set by "setlinewidth", must be much less
+% than glyphsize for readable glyphs.
+/glyphsize 6 def
+% pointsize is the height of text characters in "points", 1/72 inch; 0.353.mm
+/pointsize 12 def
+% Set default font
+/Helvetica pointsize selectfont
+
+gsave
+