| Class TxyGraph (unit xyGraph) |
TCustomPanel
-------------------------- TxyGraph ------------------------------
| Constructors |
constructor Create(AOwner: TComponent);| Functions |
procedure Addmark(id: Integer; x1,y1, x2,y2: Double;
c: Tcolor; name: string;
marktype:et_marktype; status:boolean);
procedure Assign(source:TPersistent);
procedure ClearAll;
procedure ClearMarks;--------------------------------------------------------------------- #6h.
procedure CopyToClipboard;
function DeleteMark(id: Integer): Boolean;
destructor Destroy;
procedure DrawFunction(F: PlotFunction; var parms; x1, x2: Double;
color: TColor; style: TPenStyle; steps: Word);
procedure FillBitmap(bmp:TBitmap);
procedure FillMetafile(wmf:TMetafile);
function findNearestPoint({var }series, x,y:integer):pgPoint;
function FindSeries(i:integer): Boolean;
function GetMouseVals(sN, x: Integer; var index: Integer;
var xNearest, yNearest: Double): Boolean;
function GetMouseX(x: Integer): Double;
function GetMouseXY(sN, x, y: Integer; var index: Integer;
var xScaled, yScaled,
xNearest, yNearest: Double): Boolean;
function GetMouseY(y: Integer): Double;
function GetMouseY2(y: Integer): Double;
procedure HookedSeriesEvent(Sender:TObject; TheMessage:TDSChangeType);
procedure Hookseries(Source:TSeries; Ahooktype:THooktype;
Dest:Integer; WantPersist:boolean);--------------------------------------------------------------------- #6g.
procedure PasteFromClipboard;
procedure Print;
procedure PrintOnPage;
procedure readfromfile(fname:string);
procedure readfromStream(f:TStream);
procedure SaveToBitmap(const fname:string);
procedure savetofile(fname:string; savedata:boolean);
procedure savetostream(f:TStream; savedata:boolean);
procedure savetoWMF(const fname:string);
procedure unhookseries(source:TSeries; WantPersist:boolean);
procedure CalcMetrics;
function CheckScalesOK: Boolean;
procedure ClipGraph;
procedure ColorBackground;
function DataFound(whichaxis:TAxis): Boolean;
procedure DoRescaleEvent;
procedure DoTightFit;
procedure DrawAxes;
procedure DrawGraphTitle;
procedure DrawLegend;
procedure DrawLineSegment(x1, y1, x2, y2: Integer);
procedure DrawMarks(when: Boolean);
procedure DrawXAxis;
procedure DrawXGridlines;
function DrawXLabels(base:integer; reverse:boolean):integer;
procedure DrawXTickMarks(base:integer; reverse:boolean);
procedure DrawY2Axis;
procedure DrawYAxis;
procedure DrawYGridlines(CYAxis: TAxis);
function DrawYLabels(CYAxis: TAxis; base:integer; reverse:boolean):integer;
procedure DrawYTickMarks(CYAxis: TAxis; base:integer; reverse:boolean);
function fx(v: Double): Integer;
function fy(v: Double): Integer;
function fy2(v: Double): Integer;
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);--------------------------------------------------------------------- #6b.
procedure MouseMove(Shift: TShiftState; X,Y: Integer);
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X,Y: Integer);
procedure Paint;
procedure PaintCross;
procedure PaintGraph;
procedure SetUpDragging(X,Y: Integer);
procedure UnclipGraph;
function CreateNewSeries(i:integer):TSeries;
procedure defineproperties(Filer: TFiler);room for future expansion
function GetSeriesInt(i:integer):TSeries;--------------------------------------------------------------------- #6f.
procedure ReadAllMarks(Stream: TStream);
procedure ReadAllSeries(Stream: TStream);
procedure ReadMarkCount(Reader: TReader);
procedure ReadSeriesCount(Reader: TReader);
procedure setDefaultPropertyValues;
procedure SetHasDragged(v:boolean);
procedure SetPlotting(v: Boolean);
procedure WriteAllMarks(Stream: TStream);
procedure WriteAllSeries(Stream: TStream);
procedure writeMarkCount(writer: TWriter);
procedure writeseriescount(writer: TWriter);| Properties |
property Align :
property Appearance : TAppearance
property BevelInner :
property BevelOuter :
property BevelWidth :
property BorderStyle :
property BorderWidth :
property Ctl3D :
property Cursor :
property Dimensions : TDimensions
property DragAllowed : Boolean
property Legend : TLegend
property ParentCtl3D :
property ParentFont :
property Plotting : Boolean
property PopupMenu :
property Visible :
property XAxis : TAxis
property YAxis : TAxis
property YAxis_Second : TAxis
property checkScales : boolean
property HasDragged : boolean
property LastSeriesIndex : integer
property Series : TSeries
property serieshandle : TSeries| Events |
event OnClick :
event OnDblClick :
event OnDeleteSeries : TSeriesEvent
event OnDragDrop :
event OnDragOver :
event OnEndDrag :
event OnEnter :
event OnExit :
event OnLogError : TSeriesEvent
event OnMouseDown :
event OnMouseMove :
event OnMouseUp :
event OnNewSeries : TSeriesEvent
event OnPaintEnd : TPaintEvent
event OnRescale : TNotifyEvent
event OnResize :
event OnScaleError : TNotifyEvent
event OnTooManyPoints : TSeriesEvent
event OnWantDesigner : TNotifyEvent| Variables |
AllScalesOK : Boolean;
dRect : tRect;
dx : Integer;
dy : Integer;
FAltCanvas : TCanvas;
FAppearance : TAppearance;
FCanvas : TCanvas;
FCurrHeight : Word;
FCurrWidth : Word;
FDimensions : TDimensions;
FDraggable : Boolean;
FDragging : Boolean;
FFilingMarksCount : word;
FFilingSeriesCount : word;
FHasDragged : Boolean;
FHoldXAS : boolean;
FHoldXmax : double;
FHoldXmin : double;
FHoldY2AS : boolean;
FHoldY2max : double;
FHoldY2min : double;
FHoldYAS : boolean;
FHoldYmax : double;
FHoldYmin : double;
FHookedSeries : pHookedSeries;
FLastSeries : integer;
FLegDragging : Boolean;
FLegend : TLegend;
FMarks : pMark;
FNoGridlines : Boolean;
FOnDeleteSeries : TSeriesEvent;
FOnLogError : TSeriesEvent;
FOnNewSeries : TSeriesEvent;
FOnPaintEnd : TPaintEvent;
FOnRescale : TNotifyEvent;
FOnScaleError : TNotifyEvent;
FOnTooManyPoints : TSeriesEvent;
FOnWantDesigner : TNotifyEvent;
FPainting : Boolean;
FPlotting : Boolean;
FSaveData : boolean;
FScale : Double;
FSeries : TSeries;
FXAxis : TAxis;
FXOffset : Word;
FYAxis : TAxis;
FYAxis2 : TAxis;
FYOffset : Word;| Constructors |
constructor Create(AOwner: TComponent);--------------------------------------------------------------------- #6a. TxyGraph - administration ---------------------------------------------------------------------
| Functions |
procedure Addmark(id: Integer; x1,y1, x2,y2: Double;
c: Tcolor; name: string;
marktype:et_marktype; status:boolean);
procedure Assign(source:TPersistent);saving graph to a file/stream These procedures save the graph to a file. As well as creating a special file, these also stream series to the .dfm file so that series created at design time are saved when compiled. Because the .dfm file includes a number of properties that shouldn't change - parents, events, etc - a whole separate subsystem has been created for savetofile methods. The 2 subsystems show marks and series procedures. The file format is intended to be forwards compatible(!). The file version number written at the start of the stream is different to the version of xyGraph - it will change when a new format is created that is not backwards compatible. use savetostream to include the same info in a stream of your wish. Format: (for file - a subset is relevent for the .dfm) header: constants declared at the top of this unit. - arbitrary identifier - file version identifier - code version of writing xygraph sections - in order: Appearance, FDimensions, FXAxis, FYAxis, FYAXis2 and FLegend followed by 2 blocks - series count & Marks Count sections - a section for each series, and then a section for each mark bytes left - 4 byte indicator of number of bytes remaining in the stream - to allow future versions to add information Each Section consists of a series of blocks ending in a block with a identifier of 0. identifier 99 is reserved for a descriptor. The Series Section consists of 3 separate sections, a TSeries section, followed by a TDataSeries section, followed by the data for the series. Each block consists of an identifier (integer < 100) and a format identifier, written as a string (optionally with the identifier name appended), followed by the value in the format indicated. Where possible, formats will be converted when reading. Because with the exception of the bytes left field all information is written with TWriter descendants each individual piece of information is separated by the TWriter separator. WantCompact can be used to increase the amount information written as strings or decrease the file size. Information not saved at all for design reasons. Hooked series - all hooks will be lost Series indexes will be changed Intercept info will be lost regression data is not saved (but will be automatically rebuilt) Pointwarning limit is not saved HoldUpdates will be ignored Function plotting will not be saved Known Bugs: When you copy to clipboard at designtime, with no series in the graph. I don't know why. Even though the error is raised, the copy had still worked successfully and you will be pasting - converting the series numbers - the reason is again unknown. Keep trying! It generally works in the end!
procedure ClearAll;
procedure ClearMarks;Marks
--------------------------------------------------------------------- #6h. TxyGraph - Marks routines ---------------------------------------------------------------------
procedure CopyToClipboard;--------------------------------------------------------------------- #6i. TxyGraph - External interaction ---------------------------------------------------------------------} {copy and paste routines modelled on Delphi Developers Guide, Pacheco & Teixeira p 352
function DeleteMark(id: Integer): Boolean;insert in list
destructor Destroy;Create
procedure DrawFunction(F: PlotFunction; var parms; x1, x2: Double;
color: TColor; style: TPenStyle; steps: Word);A convenient way to graph a function; automatically fills graph; handles singularities in the function. F must be far; parms may be of any type (usu. array of Double) -- no error checks; the graph of the function will be drawn from x=x1 to x=x2; if x1=x2, will be set to XMin, XMax; if larger, will be clipped to XMin, XMax if steps=0, will choose "enough" to be smooth
procedure FillBitmap(bmp:TBitmap);thanks to the following people for their help with the Metafiles routine: Frank Schmidt, John Biddiscombe, Hendrik Levsen
procedure FillMetafile(wmf:TMetafile);fill metafile requires a valid TMetafile to be supplied to it - resource allocation/deallocation issues. The internally created metafile is produced first, and then copied into the external one
function findNearestPoint({var }series, x,y:integer):pgPoint;FindNearestPoint - get the handle to the nearest point to the mouse. x,y: mouse position. series: a series to search, or 0 for all series. returns the series in series (hence var pars) FindNearestPoint finds the point nearest _visually_. (if scales are logged, it may not be the point closest to the data value of x,y) comment: Yes, I know, this is a slow way to do it. You could probably think of faster ways. But this is enough for me.
function FindSeries(i:integer): Boolean;ignore
function GetMouseVals(sN, x: Integer; var index: Integer;
var xNearest, yNearest: Double): Boolean;GetMouseVals returns the value of the data point matching the mouse point best, or false if the mouse is outside the plot area
function GetMouseX(x: Integer): Double;getmousex/y return the value as determined by the scales
function GetMouseXY(sN, x, y: Integer; var index: Integer;
var xScaled, yScaled,
xNearest, yNearest: Double): Boolean;---------------------- Reverse Metric Routines -------------------------------
function GetMouseY(y: Integer): Double;
function GetMouseY2(y: Integer): Double;
procedure HookedSeriesEvent(Sender:TObject; TheMessage:TDSChangeType);
procedure Hookseries(Source:TSeries; Ahooktype:THooktype;
Dest:Integer; WantPersist:boolean);hooking other graph series
--------------------------------------------------------------------- #6g. TxyGraph - series hooking routines ---------------------------------------------------------------------
procedure PasteFromClipboard;
procedure Print;stop re-entrancy problems if a window - such as a print dialog box - is cleared just before printing, calling a paint and screwing the printer metrics up
procedure PrintOnPage;PrintOnPage allows more than one graph to be printed on a page; calls to it must be preceded by BeginDoc amd followed by EndDoc. Print prints only the current graph on its own sheet. The graph is printed without change in aspect ratio. The size of the printed graph is controlled by PrintScalePct, which makes the dimension of the printed graph a percentage of the page dimension (on the axis with the larger Screen/Page ratio) The location of the upper left corner of the graph is controlled by PrintX(Y)OffsetPct, which locate the corner as percentages of the page height and width
procedure readfromfile(fname:string);write number of bytes left - for future compatibility
procedure readfromStream(f:TStream);
procedure SaveToBitmap(const fname:string);
procedure savetofile(fname:string; savedata:boolean);
procedure savetostream(f:TStream; savedata:boolean);
procedure savetoWMF(const fname:string);not sure why this is required?? Why kill the clipboard memory? It's required above because in the copy routine it may not have been handed to the clipboard. But I'm not so sure here
procedure unhookseries(source:TSeries; WantPersist:boolean);dsClearUpdates = anything might have changed
procedure CalcMetrics;procedure TxyGraph.CalcXMetrics; begin with FXAxis do begin if (FMin>=FMax) then raise Exception.Create('CalcXMetrics: XMin>=XMax'); if FLogging then FM := (FCurrWidth - FDimensions.FLeft - FDimensions.FRight) / (Ln(FMax) - Ln(FMin)) else FM := (FCurrWidth - FDimensions.FLeft - FDimensions.FRight) / (FMax - FMin); end; end; procedure TxyGraph.CalcYMetrics; begin with FYAxis do begin if (FMin>=FMax) then raise Exception.Create('CalcYMetrics: YMin>=YMax'); if FLogging then FM := (FCurrHeight - FDimensions.FTop - FDimensions.FBottom) / (Ln(FMax) - Ln(FMin)) else FM := (FCurrHeight - FDimensions.FTop - FDimensions.FBottom) / (FMax - FMin); end; end; procedure TxyGraph.CalcY2Metrics; begin with FYAxis2 do begin if (FMin>=FMax) then raise Exception.Create('CalcY2Metrics: YMin>=YMax'); if FLogging then FM := (FCurrHeight - FDimensions.FTop - FDimensions.FBottom) / (Ln(FMax) - Ln(FMin)) else FM := (FCurrHeight - FDimensions.FTop - FDimensions.FBottom) / (FMax - FMin); end; end;
function CheckScalesOK: Boolean;
procedure ClipGraph;function TxyGraph.DoResize: Boolean; var b: Boolean; begin b := FYAxis.DoResize; {force evaluation of both functions - need side effects!} b := FYAxis2.DoResize or b; Result := FXAxis.DoResize or b; end;*) {--------------------------------------------------------------------- #6d. TxyGraph - painting routines ---------------------------------------------------------------------
procedure ColorBackground;DrawMarks
function DataFound(whichaxis:TAxis): Boolean;--------------------------------------------------------------------- #6g. TxyGraph - data manipulation ---------------------------------------------------------------------
procedure DoRescaleEvent;--------------------------------------------------------------------- #6c. TxyGraph - metrics routines ---------------------------------------------------------------------
procedure DoTightFit;---------------------- graph scaling ------------------------------------
procedure DrawAxes;DrawY2Axis
procedure DrawGraphTitle;DrawYLabels
procedure DrawLegend;
procedure DrawLineSegment(x1, y1, x2, y2: Integer);note for confused readers: the shortcut to unclip that is valid for screen metrics is not valid for printers :)
procedure DrawMarks(when: Boolean);DrawGraphTitle
procedure DrawXAxis;ColorBackground
procedure DrawXGridlines;
function DrawXLabels(base:integer; reverse:boolean):integer;very small or very large
procedure DrawXTickMarks(base:integer; reverse:boolean);DrawYGridlines
procedure DrawY2Axis;DrawYAxis
procedure DrawYAxis;DrawXAxis
procedure DrawYGridlines(CYAxis: TAxis);DrawXGridlines
function DrawYLabels(CYAxis: TAxis; base:integer; reverse:boolean):integer;DrawXLabels
procedure DrawYTickMarks(CYAxis: TAxis; base:integer; reverse:boolean);DrawXTickMarks
function fx(v: Double): Integer;
function fy(v: Double): Integer;20000 is large compared with device pixel size; this avoids range error if some points are far outside the axis range
function fy2(v: Double): Integer;if not FYAxis.ScaledOk then raise exception.create('call to fy when y fails');
procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);Implements dragging and resizing:
--------------------------------------------------------------------- #6b. TxyGraph - mouse routines ---------------------------------------------------------------------} {general outline of responding to mouse events: if it's not the left mouse button, just call the inherited handler if the shift button is down, the user wants to change the plot area if the ctrl button is down, the user wants to run the designer if Draggable is set to true: if the mouse is in the top left corner, the user wants to move the graph if the mouse is in the bottom right corner, the user wants to resize the graph
procedure MouseMove(Shift: TShiftState; X,Y: Integer);
procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X,Y: Integer);
procedure Paint;Printing: linewidth for series, points thinner than for axes
procedure PaintCross;skip out-of-support x's
procedure PaintGraph;
procedure SetUpDragging(X,Y: Integer);MouseDown
procedure UnclipGraph;
function CreateNewSeries(i:integer):TSeries;
procedure defineproperties(Filer: TFiler);routines concerned with writing a full image of the graph to the component image
room for future expansion
function GetSeriesInt(i:integer):TSeries;These two are needed for Series[] property:
--------------------------------------------------------------------- #6f. TxyGraph - series routines ---------------------------------------------------------------------
procedure ReadAllMarks(Stream: TStream);
procedure ReadAllSeries(Stream: TStream);
procedure ReadMarkCount(Reader: TReader);
procedure ReadSeriesCount(Reader: TReader);
procedure setDefaultPropertyValues;initialise all properties. Run on create and before readfromfile
Create
procedure SetHasDragged(v:boolean);
procedure SetPlotting(v: Boolean);--------------------------------------------------------------------- #6e. TxyGraph - property servers ---------------------------------------------------------------------
procedure WriteAllMarks(Stream: TStream);
procedure WriteAllSeries(Stream: TStream);
procedure writeMarkCount(writer: TWriter);
procedure writeseriescount(writer: TWriter);| Properties |
property Align :
property Appearance : TAppearance
property BevelInner :
property BevelOuter :
property BevelWidth :
property BorderStyle :
property BorderWidth :
property Ctl3D :
property Cursor :
property Dimensions : TDimensions
property DragAllowed : Boolean
property Legend : TLegend
property ParentCtl3D :
property ParentFont :
property Plotting : Boolean
property PopupMenu :
property Visible :
property XAxis : TAxis
property YAxis : TAxis
property YAxis_Second : TAxis
property checkScales : boolean
property HasDragged : booleanfor mouse events
property LastSeriesIndex : integerprovided to iterate through existing series
property Series : TSeries
property serieshandle : TSeriesdata routines
| Events |
event OnClick :
event OnDblClick :
event OnDeleteSeries : TSeriesEvent
event OnDragDrop :
event OnDragOver :
event OnEndDrag :
event OnEnter :
event OnExit :
event OnLogError : TSeriesEvent
event OnMouseDown :
event OnMouseMove :
event OnMouseUp :
event OnNewSeries : TSeriesEvent
event OnPaintEnd : TPaintEvent
event OnRescale : TNotifyEvent
event OnResize :
event OnScaleError : TNotifyEvent
event OnTooManyPoints : TSeriesEvent
event OnWantDesigner : TNotifyEvent| Variables |
AllScalesOK : Boolean;
dRect : tRect;dragging:
dx : Integer;
dy : Integer;
FAltCanvas : TCanvas;
FAppearance : TAppearance;
FCanvas : TCanvas;Private declarations
FCurrHeight : Word;
FCurrWidth : Word;
FDimensions : TDimensions;
FDraggable : Boolean;
FDragging : Boolean;
FFilingMarksCount : word;
FFilingSeriesCount : word;
FHasDragged : Boolean;
FHoldXAS : boolean;
FHoldXmax : double;
FHoldXmin : double;
FHoldY2AS : boolean;
FHoldY2max : double;
FHoldY2min : double;
FHoldYAS : boolean;
FHoldYmax : double;
FHoldYmin : double;
FHookedSeries : pHookedSeries;
FLastSeries : integer;
FLegDragging : Boolean;
FLegend : TLegend;
FMarks : pMark;
FNoGridlines : Boolean;
FOnDeleteSeries : TSeriesEvent;
FOnLogError : TSeriesEvent;
FOnNewSeries : TSeriesEvent;Events:
FOnPaintEnd : TPaintEvent;
FOnRescale : TNotifyEvent;
FOnScaleError : TNotifyEvent;
FOnTooManyPoints : TSeriesEvent;
FOnWantDesigner : TNotifyEvent;
FPainting : Boolean;
FPlotting : Boolean;Graph property data:
FSaveData : boolean;
FScale : Double;
FSeries : TSeries;FAltCanvas always points a full FCanvas. this is important when a metafile is being drawn, as some information, such as textwidth is not available from FCanvas (D1.0) i.e. when painting, FCanvas = FAltCanvas = Canvas when printing, FCanvas = FAltCanvas = printer.canvas when metafiling, FCanvas = Metafile.canvas, and FAltCanvas := Canvas
FXAxis : TAxis;
FXOffset : Word;
FYAxis : TAxis;
FYAxis2 : TAxis;
FYOffset : Word;