DIRECTORY Imager, Vector2, ViewerClasses; PlotGraph: CEDAR DEFINITIONS = BEGIN ROPE: TYPE = Imager.ROPE; VEC: TYPE = Imager.VEC; --maps into Vector2.VEC TYPE = RECORD [x, y: REAL] Rectangle: TYPE = Imager.Rectangle; -- x, y, w, h AxisList: TYPE ~ LIST OF Axis; GraphList: TYPE ~ LIST OF Graph; Viewer: TYPE ~ ViewerClasses.Viewer; WorldRectangle: Rectangle = [0.0, 0.0, 0.0, 0.0]; XY: TYPE = {X, Y}; Plot: TYPE = REF PlotRec; PlotRec: TYPE = RECORD [ private: PlotGraphPrivate _ NIL, name: REF READONLY ROPE _ NIL, selection: LIST OF REF ANY _ NIL, axis: AxisList _ NIL, -- in order from bottom to top texts: LIST OF PlotText _ NIL, lowerBounds: VEC, -- Min all X, Min all Y, upperBounds: VEC, -- Max all X, Max all Y over all graphs eventProc: EventProc _ NIL, -- To interprete events unknown by the NotifyProc data: REF ANY _ NIL -- Client data. ]; EventProc: TYPE = PROC [ plot: Plot, -- the clicked Plot axis: Axis, -- the clicked Axis (could be # of the selected Axis) pos: VEC, -- client coordinates of the mouse, if available. event: ATOM -- Atom specified by the Tip table ]; PlotGraphPrivate: TYPE = REF PlotGraphPrivateRec; PlotGraphPrivateRec: TYPE = RECORD [ viewer: Viewer, -- the Viewer used for the display locked: BOOL _ FALSE, -- the Plot is protected through a CONDITION, unlocked: CONDITION -- rather than through a monitor lock. ]; Axis: TYPE = REF AxisRec; AxisRec: TYPE = RECORD[ graphs: GraphList _ NIL, bounds: Rectangle, name: ROPE _ NIL, style: DrawingStyle _ analog, maxChars: NAT _ 8, -- used to determine the heigth of the hexaV style row axisData: ARRAY XY OF AxisData]; AxisData: TYPE = RECORD[ ticks: REAL _ 1.0, visible: BOOL _ TRUE -- draw axis itself ]; DrawingStyle: TYPE = { analog, -- draws a segment between each point mark, -- draws a segment between each point, and marks the point hexaH, -- writes the rope provided or the hexadecimal value of y horizontally hexaV -- writes the rope provided or the hexadecimal value of y vertically }; GraphClass: TYPE = REF GraphClassRec; GraphClassRec: TYPE = RECORD[ insert: GraphProc _ NIL, delete: GraphProc _ NIL, enumerate: GraphEnumerateProc _ NIL]; GraphProc: TYPE = PROC [graph: Graph, x, y: REAL]; GraphEnumerateProc: TYPE = PROC [plot: Plot, graph: Graph, bounds: Rectangle, eachPoint: PointProc] RETURNS [invalidEnumeration: BOOL _ FALSE]; PointProc: TYPE = PROC [x, y: REAL, rope: ROPE _ NIL] RETURNS [quit: BOOL _ FALSE]; Graph: TYPE = REF GraphRec; GraphRec: TYPE = RECORD[ class: GraphClass _ NIL, data: REF ANY _ NIL, name: ROPE _ NIL, mark: BOOL _ FALSE]; GraphPoint: TYPE = REF GraphPointRec; GraphPointRec: TYPE = RECORD[ graph: Graph, x, y: REAL]; PlotText: TYPE = REF PlotTextRec; PlotTextRec: TYPE = RECORD[ contents: ROPE _ NIL, wrt: Axis _ NIL, -- if nil then wrt entire plot bounds: Rectangle, -- w or h = 0.0 mean use bounding box of ROPE rotation: REAL _ 0.0, -- angle of rotation, ccw, in degrees justifyX: JustifyX _ left, justifyY: JustifyY _ bottom]; JustifyX: TYPE = {left, center, right}; JustifyY: TYPE = {top, center, bottom}; CreatePlot: PROC [name: ROPE _ NIL] RETURNS [plot: Plot]; LockPlot: PROC [plot: Plot]; UnlockPlot: PROC [plot: Plot]; RefreshPlot: PROC [plot: Plot, axis: AxisList _ NIL, graphs: GraphList _ NIL, within: Rectangle _ WorldRectangle, eraseFirst: BOOL _ FALSE]; DeletePlot: PROC [plot: Plot]; DeleteSelection: PROC [plot: Plot]; SelectAxis: PROC [plot: Plot, axis: Axis]; AddAxis: PROC [plot: Plot, axis: Axis]; GetSelectedAxis: PROC [plot: Plot] RETURNS [axis: Axis]; GetSelectedAxisList: PROC [plot: Plot] RETURNS [axisList: LIST OF Axis]; InsertAxis: PROC [plot: Plot, axis, after: Axis]; DeleteAxis: PROC [plot: Plot, axis: Axis]; MoveAxis: PROC [plot: Plot, axis, after: Axis]; XChangeAxis: PROC [plot: Plot, axis1, axis2: Axis]; CopyAxis: PROC [axis: Axis] RETURNS [duplicate: Axis]; ForkAxis: PUBLIC PROC [plot: Plot, axis: Axis]; MoveGraphInAxis: PUBLIC PROC [plot: Plot, axis: Axis, graph: Graph]; NormalizeScaleAndOrigin: PUBLIC PROC [plot: Plot] RETURNS[unit: REAL]; SelectGraph: PROC [plot: Plot, graph: Graph]; AddGraph: PROC [plot: Plot, graph: Graph]; GetSelectedGraph: PROC [plot: Plot] RETURNS [graph: Graph]; GetSelectedGraphList: PROC [plot: Plot] RETURNS [graphList: LIST OF Graph]; SelectPoint: PROC [plot: Plot, point: GraphPoint]; AddPoint: PROC [plot: Plot, point: GraphPoint]; GetSelectedPoint: PROC [plot: Plot] RETURNS [point: GraphPoint]; GetSelectedPointList: PROC [plot: Plot] RETURNS [pointList: LIST OF GraphPoint]; InsertPoint: PROC [graph: Graph, x, y: REAL] RETURNS [ok: BOOL _ TRUE]; DeletePoint: PROC [graph: Graph, x, y: REAL] RETURNS [ok: BOOL _ TRUE]; SelectText: PROC [plot: Plot, text: PlotText]; AddText: PROC [plot: Plot, text: PlotText]; GetSelectedText: PROC [plot: Plot] RETURNS [text: PlotText]; GetSelectedTextList: PROC [plot: Plot] RETURNS [textList: LIST OF PlotText]; MoveText: PROC [plot: Plot, text: PlotText, position: Imager.VEC]; RotateText: PROC [plot: Plot, text: PlotText, alpha: REAL]; END. TPlotGraph.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Barth, August 25, 1986 12:11:02 pm PDT Christian Le Cocq May 12, 1987 6:58:38 pm PDT Theory This interface is used to display a collection of graphs on a collection of axis within one viewer. A graph is a set of point pairs relating x and y values. Color is used to differentiate multiple graphs on a single axis. Line styles can be used to simulate color on a black and white display. The axis are laid out within the viewer in a single vertical column. The plot coordinate system, which has [0.0, 0.0] in the lower left corner and [1.0, 1.0] in the upper right corner, is used to specify locations which are not relative to an axis. This interface provides a procedural mechanism for enumerating the points of a graph so that client code can make appropriate space-time tradeoffs. Note that this burdens the client with enforcing synchronization constraints. Types Union[Axis, Graph, GraphPoint, PlotText] The bounding rectangle is a hint to the enumeration indicating which points will really be used. eachPoint must be called for each of the points in the graph which bracket or are contained in the bounds. Points outside the bounds may also be passed to eachPoint. The implementation does a moveto for the first point and a drawto for the rest of them. If invalidEnumeration is TRUE this indicates that the data in the backing data structure has changed in such a way as to invalidate the points already enumerated. The axis will be erased and all of the graphs on the axis will be redrawn. x and y are, of course, relative to the axis upon which the graph is currently being drawn. If rope is specified then rope will be printed on the "hexa" style axis at location [x, 0.0]. If not, the value printed will be Convert.RopeFromInt[Real.Fix[y], 16, FALSE] i.e. the transcription of y in hexadecimal; rope is ignored on analog axis. If quit is true then the enumeration should be stopped. Operations Creates a new viewer. The name of the plot is immutable. Client must lock a plot prior to changing the data structures so that interactive updates will be suspended. Call this to update the display. If either graphs or axis are not NIL then only the indicated graph and/or axis will be refreshed. within will be passed to the GraphProcs as the bounding rectangle and so should include the point to which a moveto must be done to setup for drawing. Generally eraseFirst should only be TRUE if previously enumerated points have been changed. Makes the viewer disappear. Interaction General Delete the current selection. Axis Deselect all current selections and then select the axis. Add the axis to the selection. Returns last selected axis. Returns currently selected axis. Various proc to edit a plot Axis List. DO NOT INSERT THE SAME AXIS TWICE (even in two plots). unit is 1, 2 or 5 times a power of ten in client x coordinates, which are supposed to be coherent all over the graphs. Graph Deselect all current selections and then select the graph. Add the graph to the selection. Returns currently selected graph. Complains on terminal if none or more than one selected. Returns currently selected graphs. Complains on terminal if none selected or some selection is not a graph. Graph Point Deselect all current selections and then select the given point on the graph. Add the point to the selection. Returns currently selected point. Complains on terminal if none or more than one selected. Returns currently selected points. Complains on terminal if none selected or some selection is not a point. Adds the point to the graph. Not all classes support insertion and so ok may be false. An appropriate complaint will be sent to the terminal. Deletes the point from the graph. Not all classes support deletion and so ok may be false. An appropriate complaint will be sent to the terminal. Text Deselect all current selections and then select the text. Add the text to the selection. Returns currently selected text. Complains on terminal if none or more than one selected. Returns currently selected texts. Complains on terminal if none selected or some selection is not a text. Moves the text. Rotates the text. Christian LeCocq August 11, 1986 5:37:16 pm PDT Changed the Plot.name to be a REF READONLY ROPE to take care of the instability of life. I need to know the name at viewer creation. changes to: Plot.name, CreatePlot[name] added a field named "data" to the enumeration proc to ease the sharing of the "leaves" of the call tree beetween the screen procs and the interpress procs and avoid global variables. changes to: GraphClass  Christian LeCocq October 17, 1986 3:26:07 pm PDT Added the possibility to send back to the client the events notified to the viewer but not understood by its NotifyProc. Added the lock mechanism to Plot.private., InsertAxis, DeleteAxis, MoveAxis, XChangeAxis, CopyAxis Κ¦˜codešœ™Kšœ<™