PACKET dynamo plotter (* Ă„nder.: C.Szymanski, 21.07.88 *) DEFINES b initialize plot, b new plot line, b plot, b end of program, b plot scale : LET maxvalue = 200, valuepagelength = 18, max param numb = 10; TYPE PLOTPARAM = STRUCT (TEXT name, id, INT scale pointer, REAL lower bound, upper bound, BOOL l fixed scale, u fixed scale); ROW max param numb PLOTPARAM VAR plotparam;(* Enth. Plotparameter *) ROW maxvalue REAL VAR value; (* Ausgabepuffer *) ROW max param numb ROW 5 REAL VAR scale; (* Enth. errechnete Skalierungen *) BOOL VAR plt; TEXT VAR headline; REAL VAR pltper, nextplot; INT VAR value no, param no, plot line no, plot param no, line no; INT CONST nil := 0; LET line1 = ".____________.____________.____________.____________.", line2 = ". . . . ."; PROC plot one page : init plot routine; plot values. init plot routine : print suppressed output; plot line no := nil. plot values : INT VAR act value := 1, i; TEXT VAR plot buf; line; vdt; line; IF b stop request THEN LEAVE plot one page END IF; sys page; plot output (headline); put scales; WHILE act value < value no REP put time; gen line; FOR i FROM 1 UPTO plot param no REP plot single value END REP; plot output (plot buf + line0 + collision); plot line no INCR 1; act value INCR plot param no; act value INCR 1 END REP. put time : plot buf := text (text (round (value (act value), 2)), 6). (* Erstes Pufferelement enthaelt time *) gen line : TEXT VAR line0, collision := ""; line0 := act line. act line : IF (plot line no MOD 5) = nil (* Prueft, ob gestrichelte oder durch - *) THEN line1 (* gezogene Linie gedruckt wird *) ELSE line2 FI. plot single value : INT VAR position := int ((x-low)*53.0/(up-low))+1; (*Interpolationsformel*) position := limit; IF pos ("._ ", line0 SUB position) > nil THEN replace (line0, position, plotparam (i).id) ELSE collision CAT plotparam (i).id FI. limit : IF position > 53 THEN 53 ELIF position < 1 THEN 1 ELSE position FI. up : scale (i) (5). (* Oberer Grenzwert (der Skalierung) *) low : scale (i) (1). (* Unterer Grenzwert *) x : value (act value + i). put scales : (* Gibt Skalierung der Variablen aus *) INT VAR j := 1, l, scalecounter; WHILE j <= plot param no REP plot buf := " "; FOR l FROM 1 UPTO 4 REP plot buf CAT text (text (scale (j) (l)), 13) END REP; plot buf CAT text (scale (j) (5)); scalecounter := plotparam (j).scalepointer; WHILE scalecounter = plotparam (j).scalepointer REP plot buf CAT plotparam (j).id; j INCR 1 UNTIL j > max param numb END REP; plot output (plot buf) END REP. END PROC plot one page; PROC b plot scale (TEXT CONST id, INT CONST scale pointer, REAL CONST lower bound, upper bound, BOOL CONST l fixed scale, u fixed scale) : (* Liest Skalierungen vom Zielprogramm ein *) plot param no INCR 1; plot param (plot param no).id := id; (*Variablenname *) plot param (plot param no).scale pointer := scale pointer;(*Zeiger *) plot param (plot param no).lower bound := lower bound; (*Obere Grenze *) plot param (plot param no).upper bound := upper bound; (*Untere Grenze *) plot param (plot param no).l fixed scale := l fixed scale;(*Fix-Skalierung*) plot param (plot param no).u fixed scale := u fixed scale; END PROC b plot scale; PROC gen scales : INT VAR act param, i; (* Generiert Skalierungen fuer eine Seite *) FOR act param FROM 1 UPTO plot param no REP compute single scale END REP. compute single scale : REAL VAR max := plotparam(plot param(act param).scale pointer).upper bound, min := plotparam(plot param(act param).scale pointer).lower bound; IF min > max THEN errorstop ("invalid scale") FI; compute extreme scales; FOR i FROM 1 UPTO 3 REP scale (act param) (i+1) := (scale (act param) (5) - scale (act param) (1)) * real (i) / 4.0 + scale (act param) (1) (* Interpolationsformel *) END REP. compute extreme scales : (* Wenn die Skalierungen nicht gegeben sind, muessen sie berechnet werden. Zur leichteren Lesbarkeit werden die Skalierungen nach oben bzw. unten um jeweils eine Stelle gerundet *) scale (act param) (5) := upper limit; scale (act param) (1) := lower limit. upper limit : IF plot param (plot param (act param).scale pointer).u fixed scale THEN max ELSE round (floor (max) + 0.5, 0) FI. lower limit : IF plot param (plot param (act param).scale pointer).l fixed scale THEN min ELSE round (floor (min) - 0.5, 0) FI. END PROC gen scales; PROC b initialize plot (TEXT CONST h) : headline := h; pltper := get pltper; plot line no := value pagelength; nextplot := 0.0; value no := nil; line no := nil; plot param no := nil END PROC b initialize plot; PROC b new plot line (REAL CONST time) : plt := time >= nextplot; IF plt (* Wird vom Zielprogramm aufgerufen, um *) THEN add (time); (* Zeilenvorschub durchzufuehren *) line no INCR 1; param no := nil FI; WHILE time >= nextplot REP (* Ist noetig, weil pltper ungleich dt sein *) nextplot INCR pltper (* kann *) END REP END PROC b new plot line; PROC b end of program : (* Druckt am Schluss evt. noch gepufferte *) IF plot line no = value page length AND NOT stop request (* Werte aus *) THEN gen scales; plot one page FI END PROC b end of program; PROC b plot (REAL CONST r) : IF plt (* Wenn genuegend PLOT-Werte gepuffert *) THEN get extreme value; (* sind, wird eine neue Seite gedruckt *) add (r); IF param no = plot param no AND line no = value pagelength THEN gen scales; plot one page; value no := nil; line no := nil FI FI. get extreme value : (* Sucht Maximal bzw. Minimalwert, falls keine festen Skalierungs- *) (* grenzen angegeben wurden (im Quellprogramm)*) param no INCR 1; INT VAR act pointer := plot param (param no).scalepointer; set lower bound; set upper bound. set lower bound : IF NOT plot param (act pointer).l fixed scale AND r < plot param (act pointer).lower bound THEN plot param (act pointer).lower bound := r FI. set upper bound : IF NOT plot param (act pointer).u fixed scale AND r > plot param (act pointer).upper bound THEN plot param (act pointer).upper bound := r FI. END PROC b plot; PROC add (REAL CONST r) : (* Puffert PLOT-Werte *) value no INCR 1; value (value no) := r END PROC add; END PACKET dynamo plotter;