Mega Code Archive

 
Categories / Delphi / Graphic
 

A Component that plots graphs

Title: A Component that plots graphs Question: A component for creating graphs Answer: Here is a component that draws graphs. You can zoom in and out of the graph. The code is shown below. Copy the code to .pas file and install the component. I will add a demo to show how to use this component soon. ----------------------------code----------------------------------------------- unit UGraph; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,Math; type TOnMouseMove=procedure(Shift:TShiftState;x,y:integer) of object; TOnMouseDown=procedure(Button:TMouseButton;Shift:TShiftState;x,y:integer) of object; TOnMouseUp=procedure(Button:TMouseButton;Shift:TShiftState;x,y:integer) of object; TState=(fplotted,fjoined); TGraph = class; TPlots = class; TPoints =class(Tlist) private fplots:TPlots; fptcolor,fcrvcolor:TColor; fstate:set of Tstate; procedure fPlot; procedure fJoin; protected function Get(index:integer):PPoint; public procedure Plot; procedure Join; constructor Create(aplots:TPlots); function Add(x,y:integer):PPoint; procedure HideDots; procedure HideJoins; procedure Clear;override; property CurveColor:Tcolor read fcrvcolor write fcrvColor; property DotColor:Tcolor read fptcolor write fptColor; property Items[index:integer]:PPoint read Get;default; end; TPlots= class(Tlist) private fgraph:TGraph; protected function Get(index:integer):TPoints; public constructor Create(agraph:TGraph); function Add:TPoints; procedure Clear;override; procedure PlotAllDots; procedure PlotAllJoins; procedure HideAllDots; procedure HideAllJoins; property Items[index:integer]:TPoints read Get;default; end; TGraph = class(TGraphicControl) private faxcolor,fbkcolor,fgridcolor:Tcolor; fMouseDown:TOnMouseDown; fMouseMove:TOnMouseMove; fMouseUp:TOnMouseUp; fspc:extended; ldiv,sdiv:integer; xaxis,yaxis:integer; xlc,ylc:integer; fmag:integer; fplots:TPlots; function Translate(x,y:integer):Tpoint; function GetScale:Extended; procedure DrawGrid; procedure DrawAxes; procedure GetXLineRect(y:integer;var arect:trect); procedure GetYLineRect(x:integer;var arect:trect); procedure SetGridColor(acolor:Tcolor); procedure SetBackColor(acolor:Tcolor); procedure SetAxisColor(acolor:TColor); protected procedure loaded;override; procedure Paint; override; {procedure MsgHandler(var msg:TMessage);} procedure MouseDown(Button:TMouseButton;shift:TShiftState;x,y:integer);override; procedure MouseMove(shift:TShiftState;x,y:integer);override; procedure MouseUp(Button:TMouseButton;shift:TShiftState;x,y:integer);override; public constructor Create(AComponent:TComponent);override; destructor Destroy;override; procedure OffSetAxes(x,y:integer); procedure ResetAxes; procedure Zoom(mag:integer); property Plots:TPlots read fplots; published property OnMouseDown:TOnMouseDown read fMouseDown write fMouseDown; property OnMouseMove:TOnMouseMove read fMouseMove write fMouseMove; property OnMouseUp:TOnMouseUp read fMouseUp write fMouseUp; property GridColor:Tcolor read fgridcolor write SetGridColor; property BackColor:Tcolor read fbkcolor write SetBackColor; property AxisColor:Tcolor read faxcolor write SetAxisColor; property Scale:extended read GetScale; property ZoomFactor:integer read fmag; end; procedure Register; implementation procedure TGraph.MouseDown(Button:TMouseButton;shift:TShiftState;x,y:integer); var tp:Tpoint; begin tp.x:=x-left; tp.y:=y-top; tp.x:=trunc(tp.x/fspc-yaxis); tp.y:=trunc(xaxis-tp.y/fspc); if (assigned(fMouseDown)) then fMouseDown(button,shift,tp.x,tp.y); inherited; end; procedure TGraph.MouseMove(shift:TShiftState;x,y:integer); var tp:Tpoint; begin tp.x:=x-left; tp.y:=y-top; tp.x:=trunc(tp.x/fspc-yaxis); tp.y:=trunc(xaxis-tp.y/fspc); if (assigned(fMousemove)) then fMousemove(shift,tp.x,tp.y); inherited; end; procedure TGraph.MouseUp(Button:TMouseButton;shift:TShiftState;x,y:integer); var tp:Tpoint; begin tp.x:=x-left; tp.y:=y-top; tp.x:=trunc(tp.x/fspc-yaxis); tp.y:=trunc(xaxis-tp.y/fspc); if (assigned(fMouseUp)) then fMouseup(button,shift,tp.x,tp.y); inherited; end; constructor TPoints.Create(aplots:TPlots); begin if aplots=nil then raise Exception.Create('Not a valid Graph object.'); fplots:=aplots; end; constructor TPlots.Create(agraph:Tgraph); begin if agraph=nil then raise Exception.Create('Not a valid Graph object.'); fgraph:=agraph; end; procedure TPoints.HideDots; begin fstate:=fstate-[fplotted]; end; procedure TPoints.HideJoins; begin fstate:=fstate-[fjoined]; end; procedure TPoints.Plot; begin fstate:=fstate+[fplotted]; fplots.fgraph.invalidate; end; procedure TPoints.fPlot; var i:integer; tmp:tpoint; begin if count exit; with fplots.fgraph do begin canvas.pen.color:=fptcolor; canvas.pen.width:=1; for i:=0 to count-1 do begin tmp:=Translate(items[i].x,items[i].y); canvas.Ellipse(rect(tmp.x-1,tmp.y-1,tmp.x+1,tmp.y+1)); end; end; end; procedure TPoints.Join; begin fstate:=fstate+[fjoined]; fplots.fgraph.invalidate; end; procedure TPoints.fJoin; var i:integer; tmp:tpoint; begin if count exit; with fplots.fgraph do begin canvas.pen.color:=fcrvcolor; canvas.pen.width:=1; tmp:=Translate(items[0].x,items[0].y); canvas.moveto(tmp.x,tmp.y); for i:=1 to count-1 do begin tmp:=Translate(items[i].x,items[i].y); canvas.lineto(tmp.x,tmp.y); end; end; end; procedure TPlots.PlotAllDots; var i:integer; begin for i:= 0 to count -1 do items[i].Plot; end; procedure TPlots.PlotAllJoins; var i:integer; begin for i:= 0 to count -1 do items[i].join end; procedure TPlots.HideAllDots; var i:integer; inv:boolean; begin inv:=false; for i:= 0 to count -1 do if (fplotted in items[i].fstate) then begin items[i].fstate:=items[i].fstate-[fplotted]; inv:=true; end; if inv then fgraph.invalidate; end; procedure TPlots.HideAllJoins; var i:integer; inv:boolean; begin inv:=false; for i:= 0 to count -1 do if (fjoined in items[i].fstate) then begin items[i].fstate:=items[i].fstate-[fjoined]; inv:=true; end; if inv then fgraph.invalidate; end; function TPlots.Get(index:integer):TPoints; begin result:=TPoints(inherited Get(index)); end; function TPlots.Add:TPoints; begin result:=TPoints.create(self); inherited Add(result); end; procedure TPlots.Clear; var i:integer; tmp:Tpoints; begin for i:=0 to count-1 do begin tmp:=items[i]; freeandnil(tmp); end; inherited; end; procedure TPoints.Clear; var i:integer; begin for i:=0 to count-1 do dispose(items[i]); inherited; end; function TPoints.Get(index:integer):PPoint; begin result:=PPoint(inherited Get(index)); end; function TPoints.Add(x,y:integer):PPoint; begin new(result); result.x:=x;result.y:=y; inherited Add(result); end; function TGraph.GetScale:extended; begin if fspc result:=sdiv/fspc else result:=1; end; destructor TGraph.Destroy; begin freeandnil(fplots); inherited; end; constructor TGraph.Create(AComponent:TComponent); begin fplots:=TPlots.create(self); fmag:=100; fbkcolor:=clwhite; faxcolor:=clnavy; fgridcolor:=RGB(214,244,254); ldiv:=10;sdiv:=5;fspc:=1; inherited; end; procedure TGraph.GetXLineRect(y:integer;var arect:trect); begin arect.left:=left;arect.right:=arect.left+width; arect.top:=top+trunc(y*fspc); arect.bottom:=arect.top+2; end; procedure TGraph.GetYLineRect(x:integer;var arect:trect); begin arect.top:=top;arect.bottom:=arect.top+height; arect.left:=left+trunc(x*fspc); arect.right:=arect.left+2; end; procedure TGraph.SetGridColor(acolor:Tcolor); begin fgridcolor:=acolor; Invalidate; end; procedure TGraph.SetBackColor(acolor:Tcolor); begin fbkcolor:=acolor; Invalidate; end; procedure TGraph.SetAxisColor(acolor:TColor); begin faxcolor:=acolor; Invalidate; end; procedure TGraph.Zoom(mag:integer); begin if mag mag:=1; if mag100000 then mag:=100000; fspc:=(mag/20); if fspc1 then fspc:=trunc(fspc); fmag:=mag; xlc:=Trunc(width/fspc); ylc:=Trunc(height/fspc); xaxis:=Trunc(ylc/2); yaxis:=Trunc(xlc/2); Invalidate; end; function TGraph.Translate(x,y:integer):Tpoint; begin result.x:=trunc((x+yaxis)*fspc); result.y:=trunc((xaxis-y)*fspc); end; procedure TGraph.loaded; begin Zoom(fmag); end; procedure TGraph.ResetAxes; begin Zoom(fmag); end; procedure TGraph.OffSetAxes(x,y:integer); var tmp:trect; tmpx,tmpy:integer; begin canvas.Pen.color:=faxcolor; canvas.Pen.Width:=1; tmpx:=xaxis;tmpy:=yaxis; xaxis:=xaxis-y;yaxis:=yaxis+x; if (tmpx=xaxis) and (tmpy=yaxis) then exit; GetXlineRect(tmpx,tmp); InvalidateRect(parent.handle,@tmp,false); GetYlineRect(tmpy,tmp); InvalidateRect(parent.handle,@tmp,false); GetXlineRect(xaxis,tmp); InvalidateRect(parent.handle,@tmp,false); GetYlineRect(yaxis,tmp); InvalidateRect(parent.handle,@tmp,false); end; procedure TGraph.DrawAxes; begin canvas.Pen.color:=faxcolor; canvas.Pen.Width:=1; canvas.MoveTo(0,trunc(fspc*xaxis)); canvas.lineto(width,trunc(fspc*xaxis)); canvas.MoveTo(trunc(fspc*yaxis),0); canvas.lineto(trunc(fspc*yaxis),height); end; procedure TGraph.DrawGrid; var i,t:integer; t1,t2:Tpoint; begin i:=0;t:=0; canvas.pen.color:=fbkcolor; canvas.Brush.color:=fbkcolor; canvas.rectangle(0,0,width,height); canvas.Pen.color:=fgridcolor; canvas.Pen.Width:=1; while i begin if (t mod ldiv)=0 then canvas.pen.width:=2 else canvas.pen.width:=1; t1.x:=i; t1.y:=0; canvas.moveto(t1.x,t1.y); t2.x:=i;t2.y:=height; canvas.lineto(t2.x,t2.y); i:=i+max(trunc(fspc),sdiv); t:=t+1; end; i:=0;t:=0; while i begin if (t mod ldiv)=0 then canvas.pen.width:=2 else canvas.pen.width:=1; t1.x:=0; t1.y:=i; canvas.moveto(t1.x,t1.y); t2.x:=width;t2.y:=i; canvas.lineto(t2.x,t2.y); i:=i+max(trunc(fspc),sdiv); t:=t+1; end; end; procedure TGraph.Paint; var i:integer; begin DrawGrid; for i:=0 to fplots.count-1 do begin if (fplotted in fplots[i].fstate) then fplots[i].fplot; if fjoined in fplots[i].fstate then fplots[i].fjoin; end; DrawAxes; end; procedure Register; begin RegisterComponents('My Components', [TGraph]); end; end. -------------------------------------------------------------------------------- Please report any bugs by adding comments to this article.