Graph.pas

Top  Previous  Next

{*****************************************************************************}

{                                                                             }

{    Graph Package 1.0.1                                                      }

{    Date released : July 29, 2005                                            }

{    http://www.bk02.net/gpack                                                }

{    Copyright (c) 2004-2005 BK02 Team                                        }

{                                                                             }

{*****************************************************************************}

 

unit Graph;

 

interface

 

uses Graphics,SysUtils, Classes, Controls, ExtCtrls, UnitTool;

 

type

ShapeStyle=(OrdString,OrdPoint,OrdLine,OrdLineDraw,OrdEllipse,OrdRectangle,OrdFillRectangle,OrdArc,OrdPie,OrdYX,OrdXY,OrdRT,OrdYXT);

 

  TShape=record

     Color:TColor;

     Style:ShapeStyle;

     Expression:string[100];

     X,Y,X0,Y0,V1,V2,R:float;

     X1,Y1,X2,Y2:float;

     A,B,C,D,E,F,G,M,N,P:float;

  end;

 

   TGraph = class (TPaintBox)

   private

       AxisVisible: Boolean;

       Bit: array[0..MaxResolutionX,0..MaxResolutionY]of smallint;

       Claxis: TColor;

       Clbackground: TColor;

       Clborder1: TColor;

       Clborder2: TColor;

       Clgrid: TColor;

       Cloxy: TColor;

       Cltext: TColor;

       Grid: Boolean;

       IsMouseDown: Boolean;

       Linespace: Integer;

       Linewidth: Integer;

       MaxX: Integer;

       MaxY: Integer;

       MinX: Integer;

       MinY: Integer;

       MouseDownX: Integer;

       MouseDownY: Integer;

       Op: Integer;

       Ox: Integer;

       OxOld: Integer;

       Oy: Integer;

       OyOld: Integer;

       Selected: array[0..MaxShape]of boolean;

       Sizeline: Integer;

       Sizeoxy: Integer;

       Sizetext: Integer;

       TempBitmap: TBitmap;

       TempR: array[0..1000]of float;

       TempS: TStringDynArray;

       TempT: array[0..1000]of float;

       TempX: array[0..1000]of float;

       TempY: array[0..1000]of float;

       function Check(x,y:integer): Boolean;

       function CheckX(x:integer): Boolean;

       function CheckY(y:integer): Boolean;

       procedure Lin(x1,y1,x2,y2:integer);

       procedure OnMouseDownCustom(Sender: TObject; Button: TMouseButton;

           Shift: TShiftState; X, Y: Integer);

       procedure OnMouseMoveCustom(Sender: TObject; Shift: TShiftState; X, Y:

           Integer);

       procedure OnMouseUpCustom(Sender: TObject; Button: TMouseButton; Shift:

           TShiftState; X, Y: Integer);

       procedure OnPaintCustom(Sender:TObject);

       procedure PointRealToForm(inpx,inpy:float;var outx,outy:integer);

       procedure Rec(x1,y1,x2,y2:integer);

       procedure SetAxisVisible(Value: Boolean);

       procedure SetColorAxis(Value: TColor);

       procedure SetColorBackground(Value: TColor);

       procedure SetColorBorder1(Value: TColor);

       procedure SetColorBorder2(Value: TColor);

       procedure SetColorGrid(Value: TColor);

       procedure SetColorOxy(Value: TColor);

       procedure SetColorText(Value: TColor);

       procedure SetGrid(Value: Boolean);

       procedure SetLine(x1,y1,x2,y2:integer);

       procedure SetLineSpace(Value: Integer);

       procedure SetLineWidth(Value: Integer);

       procedure SetOP(Value: Integer);

       procedure SetOx(Value: Integer);

       procedure SetOy(Value: Integer);

       procedure SetSizeLine(Value: Integer);

       procedure SetSizeOxy(Value: Integer);

       procedure SetSizeText(Value: Integer);

       procedure DrawArc(x,y,a,b,v1,v2:float);

       procedure DrawAxis;

       procedure DrawBorder(x1,y1,x2,y2:integer);

       procedure DrawEllipse(x,y,a,b:float);

       procedure DrawFillRectangle(x1,y1,x2,y2:float);

       procedure DrawLine(x1,y1,x2,y2:float); overload;

       procedure DrawLine(a,b,c,v1,v2:float); overload;

       procedure DrawPie(x,y,a,b,v1,v2:float);

       procedure DrawPoint(x,y:float);

       procedure DrawRectangle(x1,y1,x2,y2:float);

       procedure DrawRT(exp:string;v1,v2,xo,yo:float);

       procedure DrawString(x,y:float;exp:string;Size:integer);

       procedure DrawXY(exp:string;v1,v2,xo,yo:float);

       procedure DrawYX(exp:string;v1,v2,xo,yo:float);

       procedure DrawYXT(exp:string;v1,v2,xo,yo:float);

   public

       Count: Integer;

       Items: array[0..MaxShape]of TShape;

       constructor Create(AOwner:TComponent); override;

       procedure Add(s:string;Color:TColor);

       procedure Clear;

       function GetObjectIndexAt(X,Y:integer): Integer;

       procedure Remove(index:integer);

       procedure Replace(index : integer; S : string);

       procedure Render;

       procedure Select(index:integer);

       procedure SelectAll;

       procedure SetColor(Foreground,Background:TColor);

       procedure UnSelectAll;

       procedure UnSelect(index:integer);

   published

       property PAxisVisible: Boolean read AxisVisible write SetAxisVisible;

       property PColorAxis: TColor read Claxis write SetColorAxis;

       property PColorBackground: TColor read Clbackground write

           SetColorBackground;

       property PColorBorder1: TColor read Clborder1 write SetColorBorder1;

       property PColorBorder2: TColor read Clborder2 write SetColorBorder2;

       property PColorGrid: TColor read Clgrid write SetColorGrid;

       property PColorOxy: TColor read Cloxy write SetColorOxy;

       property PColorText: TColor read Cltext write SetColorText;

       property PGrid: Boolean read Grid write SetGrid;

       property PLineSpace: Integer read Linespace write SetLineSpace;

       property PLineWidth: Integer read Linewidth write SetLineWidth;

       property POP: Integer read Op write SetOP;

       property POx: Integer read Ox write SetOx;

       property POy: Integer read Oy write SetOy;

       property PSizeLine: Integer read Sizeline write SetSizeLine;

       property PSizeOxy: Integer read Sizeoxy write SetSizeOxy;

       property PSizeText: Integer read Sizetext write SetSizeText;

   end;

 

implementation

 

(*-------------------------------------CREATE & INITIALIZE GRAPH--------------------------*)

 

{

************************************ TGraph ************************************

}

constructor TGraph.Create(AOwner:TComponent);

begin

   inherited;

   Randomize;

   Self.OnPaint:=OnPaintCustom;

   TempBitmap:=TBitmap.Create;

   //Color

   ClBackground:=0;ClAxis:=16503172;ClGrid:=16777215;ClText:=16777215;

   ClOxy:=65280;ClBorder1:=16777215;ClBorder2:=16711680;

   SizeOxy:=12;SizeText:=8;SizeLine:=5;

   LineWidth:=1;LineSpace:=1;

   Grid:=true;AxisVisible:=true;

   //Size

   Self.Width:=400;Self.Height:=400;

   Ox:=Width div 2;Oy:=Height div 2;

   Op:=17;Count:=0;

   OnMouseDown:=OnMouseDownCustom;

   OnMouseUp:=OnMouseUpCustom;

   OnMouseMove:=OnMouseMoveCustom;

end;

 

procedure TGraph.Add(s:string;Color:TColor);

begin

   inc(Count);

   Items[Count-1].Color:=Color;

   Replace(Count-1, S);

end;

 

function TGraph.Check(x,y:integer): Boolean;

begin

   check:=(0<=x)and(x<=width)and(0<=y)and(y<=height);

end;

 

function TGraph.CheckX(x:integer): Boolean;

begin

   checkx:=(0<=x)and(x<=width);

end;

 

function TGraph.CheckY(y:integer): Boolean;

begin

   checky:=(0<=y)and(y<=height);

end;

 

procedure TGraph.Clear;

begin

   Count:=0;

end;

 

procedure TGraph.DrawArc(x,y,a,b,v1,v2:float);

var

   intx, inty, intx1, inty1, inta, intb: Integer;

   dv: float;

begin

   //Draw

   PointRealToForm(x,y,intx,inty);

   PointRealToForm(a,b,inta,intb);

   inta:=round(a*op);intb:=round(b*op);

   v1:=(360-v1)*pi/180;

   v2:=(360-v2)*pi/180;

   TempBitmap.Canvas.Arc(intx-inta,inty-intb,intx+inta,inty+intb,intx+round(inta*cos(v1)),inty+round(intb*sin(v1)),intx+round(inta*cos(v2)),inty+round(inta*sin(v2)));

   //Assign

   if v1>v2 then Swap(v1,v2);

   dv:=pi/180;

   MinX:=maxint;MinY:=maxint;MaxX:=-maxint;MaxY:=-maxint;

   while v1<=v2 do

      begin

         intx1:=intx+round(inta*cos(v1));

         inty1:=inty+round(intb*sin(v1));

         if check(intx1,inty1)then bit[intx1,inty1]:=Count;

         if MinX>intx1 then MinX:=intx1;

         if MaxX<intx1 then MaxX:=intx1;

         if MinY>inty1 then MinY:=inty1;

         if MaxY<inty1 then MaxY:=inty1;

         v1:=v1+dv;

      end;

end;

 

procedure TGraph.DrawAxis;

var

   x, y, k, t1: Integer;

begin

   with TempBitmap.Canvas do

      begin

         //Background

         brush.Color:=clbackground;

         FillRect(rect(0,0,width,height));

         if(not AxisVisible)then exit;

         //Grid & Number

         font.Style:=[];

         font.color:=cltext;

         font.Size:=sizetext;

         pen.Width:=linewidth;

         pen.Color:=claxis;

         if op<40 then k:=40 div op else k:=1;

         x:=ox-op;t1:=0;

         while x>10 do

            begin

               dec(t1);

               if grid then

                  if op>=10 then lin(x,0,x,height);

               if t1 mod k=0 then

                  begin

                     if t1 mod(k*linespace)=0 then

                        textout(x+5,oy+5,inttostr(t1));

                     moveto(x,oy-sizeline);

                     lineto(x,oy+sizeline);

                  end;

             x:=x-op;

           end;

         x:=ox+op;t1:=0;

         while x<width do

            begin

               inc(t1);

               if grid then

                  if op>=10 then lin(x,0,x,height);

               if t1 mod k=0 then

                  begin

                     if t1 mod(k*linespace)=0 then

                        textout(x+5,oy+5,inttostr(t1));

                     moveto(x,oy-sizeline);

                     lineto(x,oy+sizeline);

                  end;

             x:=x+op;

           end;

         y:=oy-op;t1:=0;

         while y>0 do

            begin

               inc(t1);

               if grid then

                  if op>=10 then lin(0,y,width,y);

               if t1 mod k=0 then

                  begin

                     if ox>5 then

                        begin

                           moveto(ox-sizeline,y);

                           lineto(ox+sizeline,y)

                        end

                     else

                        begin

                           moveto(0,y);

                           lineto(ox+sizeline,y);

                        end;

                     if t1 mod(k*linespace)=0 then

                        textout(ox+10,y-5,inttostr(t1));

                  end;

               y:=y-op;

            end;

         y:=oy+op;t1:=0;

         while y<height do

            begin

               dec(t1);

               if grid then

                  if op>=10 then lin(0,y,width,y);

               if t1 mod k=0 then

                  begin

                     if ox>5 then

                        begin

                           moveto(ox-sizeline,y);

                           lineto(ox+sizeline,y)

                        end

                     else

                        begin

                           moveto(0,y);

                           lineto(ox+sizeline,y);

                        end;

                     if t1 mod(k*linespace)=0 then

                        textout(ox+10,y-5,inttostr(t1));

                  end;

               y:=y+op;

            end;

         {Axis}

         font.color:=cloxy;

         font.Size:=sizeoxy;

         font.Style:=[fsbold];

         pen.Style:=pssolid;

         pen.Color:=claxis;

         textout(ox+2,oy+2,'O');

         textout(ox+5,0,'y');

         textout(width-20,oy,'x');

         moveto(0,oy);lineto(width,oy);

         moveto(ox,0);lineto(ox,height);

         moveto(width-sizeline,oy-sizeline);lineto(width,oy);

         moveto(width-sizeline,oy+sizeline);lineto(width,oy);

         moveto(ox-sizeline,sizeline);lineto(ox,0);

         moveto(ox+sizeline,sizeline);lineto(ox,0);

      end;

end;

 

procedure TGraph.DrawBorder(x1,y1,x2,y2:integer);

begin

   with TempBitmap.Canvas do

      begin

         pen.Style:=psdot;

         pen.color:=clborder1;

         brush.Color:=clborder2;

         Rec(x1-1,y1-1,x2+1,y2+1);

         //Button

         pen.Style:=pssolid;

         pen.Color:=clwhite;

         brush.Color:=clblue;

         if(x1>3)and(y1>3)then rectangle(rect(x1-3,y1-3,x1+3,y1+3));

         if(x2<width-3)and(y1>3)then rectangle(rect(x2-3,y1-3,x2+3,y1+3));

         if(x1>3)and(y2<height-3)then rectangle(rect(x1-3,y2-3,x1+3,y2+3));

         if(x2<width-3)and(y2<height-3)then rectangle(rect(x2-3,y2-3,x2+3,y2+3));

         //Mark

         if check(x1,y1)then bit[x1,y1]:=Count;

         if check(x2,y2)then bit[x2,y2]:=Count;

         if check(x1,y2)then bit[x1,y2]:=Count;

         if check(x2,y1)then bit[x2,y1]:=Count;

      end;

end;

 

procedure TGraph.DrawEllipse(x,y,a,b:float);

var

   v1, v2, x1, y1, a1, b1: Integer;

   i, j: Integer;

   ab, realx, realy: float;

begin

   if(a=0)or(b=0)then exit;

   {Draw}

   Pointrealtoform(x,y,x1,y1);

   a1:=round(a*op);b1:=round(b*op);

   TempBitmap.Canvas.Arc(x1-a1,y1-b1,x1+a1,y1+b1,x1,y1,x1,y1);

   {Set}

   v1:=x1-a1;if v1<0 then v1:=0;

   v2:=x1+a1;if v2>width then v2:=width;

   ab:=sqr(a*b);

   for i:=v1 to v2 do

      if checkx(i)then

      begin

         realx:=(i-ox)/op-x;

         realy:=(ab-sqr(b*realx))/sqr(a);

         if realy>=0 then

            begin

               j:=oy-round((sqrt(realy)+y)*op);

               if checky(j)then

                  if bit[i,j]=0 then bit[i,j]:=Count;

               j:=oy-round((-sqrt(realy)+y)*op);

               if checky(j)then

                  if bit[i,j]=0 then bit[i,j]:=Count;

            end;

      end;

   Pointrealtoform(x-a,y-b,MinX,MinY);

   pointrealtoform(x+a,y+b,MaxX,MaxY);

end;

 

procedure TGraph.DrawFillRectangle(x1,y1,x2,y2:float);

var

   i, j, intx1, inty1, intx2, inty2: Integer;

begin

   PointRealToForm(x1,y1,intx1,inty1);

   PointRealToForm(x2,y2,intx2,inty2);

   TempBitmap.Canvas.Rectangle(intx1,inty1,intx2,inty2);

   if intx1>intx2 then Swap(intx1,intx2);

   if inty1>inty2 then Swap(inty1,inty2);

   for i:=0 to(intx2-intx1)div 10 do

      if checkx(intx1+i*10)then

      for j:=0 to(inty2-inty1)div 10 do

         if checky(inty1+j*10)then

         bit[intx1+i*10,inty1+j*10]:=Count;

   MinX:=intx1;MinY:=inty1;

   MaxX:=intx2;MaxY:=inty2;

end;

 

procedure TGraph.DrawLine(x1,y1,x2,y2:float);

var

   Intx1, Inty1, Intx2, Inty2: Integer;

begin

   PointRealToForm(X1,Y1,Intx1,Inty1);

   PointRealToForm(X2,Y2,Intx2,Inty2);

   TempBitmap.Canvas.Moveto(Intx1,Inty1);

   TempBitmap.Canvas.LineTo(Intx2,Inty2);

   SetLine(Intx1,Inty1,Intx2,Inty2);

    if MinX>Intx1 then MinX:=Intx1;

    if MaxX<Intx1 then MaxX:=Intx1;

    if MinY>Inty1 then MinY:=Inty1;

    if MaxY<Inty1 then MaxY:=Inty1;

    if MinX>Intx2 then MinX:=Intx2;

    if MaxX<Intx2 then MaxX:=Intx2;

    if MinY>Inty2 then MinY:=Inty2;

    if MaxY<Inty2 then MaxY:=Inty2;

end;

 

procedure TGraph.DrawLine(a,b,c,v1,v2:float);

begin

   if(a=0)and(b=0)then exit;

   if b=0 then DrawLine(-c/a,v1,-c/a,v2)

   else DrawLine(v1,(-a*v1-c)/b,v2,(-a*v2-c)/b);

end;

 

procedure TGraph.DrawPie(x,y,a,b,v1,v2:float);

var

   intx, inty, intx1, inty1, inta, intb: Integer;

   dv: float;

begin

   //Draw

   PointRealToForm(x,y,intx,inty);

   PointRealToForm(a,b,inta,intb);

   inta:=round(a*op);intb:=round(b*op);

   v1:=(360-v1)*pi/180;

   v2:=(360-v2)*pi/180;

   TempBitmap.Canvas.Pie(intx-inta,inty-intb,intx+inta,inty+intb,intx+round(inta*cos(v1)),inty+round(intb*sin(v1)),intx+round(inta*cos(v2)),inty+round(inta*sin(v2)));

   //Assign

   if v1>v2 then Swap(v1,v2);

   dv:=pi/30;

   MinX:=maxint;MinY:=maxint;MaxX:=-maxint;MaxY:=-maxint;

   while v1<=v2 do

      begin

         intx1:=intx+round(inta*cos(v1));

         inty1:=inty+round(intb*sin(v1));

         SetLine(intx,inty,intx1,inty1);

         if MinX>intx1 then MinX:=intx1;

         if MaxX<intx1 then MaxX:=intx1;

         if MinY>inty1 then MinY:=inty1;

         if MaxY<inty1 then MaxY:=inty1;

         v1:=v1+dv;

      end;

end;

 

procedure TGraph.DrawPoint(x,y:float);

var

   x1, y1: Integer;

begin

   with TempBitmap.Canvas do

   begin

      Pointrealtoform(x,y,x1,y1);

      if check(x1,y1)then

         begin

            Ellipse(x1-3,y1-3,x1+3,y1+3);

            bit[x1,y1]:=Count;

            bit[x1+1,y1]:=Count;

            bit[x1,y1+1]:=Count;

            bit[x1+1,y1+1]:=Count;

         end;

      MinX:=x1-5;MinY:=y1-5;MaxX:=x1+5;MaxY:=y1+5;

   end;

end;

 

procedure TGraph.DrawRectangle(x1,y1,x2,y2:float);

var

   intx1, inty1, intx2, inty2: Integer;

begin

   PointRealToForm(x1,y1,intx1,inty1);

   PointRealToForm(x2,y2,intx2,inty2);

   with TempBitmap.Canvas do

   begin

      Moveto(intx1,inty1);

      Lineto(intx2,inty1);

      Lineto(intx2,inty2);

      Lineto(intx1,inty2);

      Lineto(intx1,inty1);

   end;

   SetLine(intx1,inty1,intx2,inty1);

   SetLine(intx2,inty1,intx2,inty2);

   SetLine(intx2,inty2,intx1,inty2);

   SetLine(intx1,inty2,intx1,inty1);

   MinX:=intx1;MinY:=inty1;

   MaxX:=intx2;MaxY:=inty2;

end;

 

procedure TGraph.DrawRT(exp:string;v1,v2,xo,yo:float);

var

   i, k: Integer;

   intx, inty, intx1, inty1: Integer;

   d: float;

begin

   exp:=Strdelspc(exp);

   k:=pos('R=',exp);

   if k>0 then delete(exp,k,2);

   //Build TempT,TempR

   v1:=v1*pi/180;v2:=v2*pi/180;

   d:=(v2-v1)/Lcount;

   for i:=0 to LCount-1 do

      TempT[i]:=v1+d*i;

   evaluate(exp,'T',LCount,TempT,TempR);

   //Draw

   pointrealtoform(TempR[0]*cos(TempT[0])+xo,TempY[0]*sin(TempT[0])+yo,intx1,inty1);

   MinX:=intx1;MinY:=inty1;MaxX:=intx1;MaxY:=inty1;

   with TempBitmap.Canvas do

   for i:=1 to LCount-1 do

      begin

         PointRealtoForm(TempR[i]*cos(TempT[i])+xo,TempR[i]*sin(TempT[i])+yo,intx,inty);

         if check(intx,inty)or check(intx1,inty1)then

            begin

               moveto(intx1,inty1);

               lineto(intx,inty);

               SetLine(intx1,inty1,intx,inty);

            end;

         if MinX>intx then MinX:=intx;

         if MaxX<intx then MaxX:=intx;

         if MinY>inty then MinY:=inty;

         if MaxY<inty then MaxY:=inty;

         intx1:=intx;inty1:=inty;

      end;

end;

 

procedure TGraph.DrawString(x,y:float;exp:string;Size:integer);

var

   i, j, w, h, x1, y1: Integer;

begin

   with TempBitmap.Canvas do

   begin

      Brush.Color:=Clbackground;

      Font.Color:=Pen.Color;

      PointRealToForm(x,y,x1,y1);

      Font.Size:=Size;

      TextOut(x1,y1,exp);

      w:=textwidth(exp);

      h:=textheight(exp);

      for j:=0 to h div 5 do

         if checky(y1+j*10)then

            for i:=0 to w div 5 do

               if checkx(x1+i*5)then

                  bit[x1+i*5,y1+j*5]:=Count;

      MinX:=x1;MinY:=y1;MaxX:=x1+w;MaxY:=y1+h;

   end;

end;

 

procedure TGraph.DrawXY(exp:string;v1,v2,xo,yo:float);

var

   LCount, i, k: Integer;

   intx, inty, intx1, inty1: Integer;

   d: float;

begin

   exp:=StrDelspc(exp);

   k:=pos('X=',exp);

   if k>0 then delete(exp,k,2);

   //Build TempT,TempR

   if v1<-ox/op then v1:=-ox/op;

   if v2>(width-ox)/op then v2:=(width-ox)/op;

   LCount:=round((v2-v1)*op);

   if Lcount=0 then exit;

   d:=(v2-v1)/Lcount;

   for i:=0 to LCount-1 do

      TempY[i]:=v1+d*i;

   Evaluate(exp,'Y',LCount,TempY,TempX);

   //Draw

   pointrealtoform(TempX[0]+xo,TempY[0]+yo,intx1,inty1);

   MinX:=intx1;MinY:=inty1;MaxX:=intx1;MaxY:=inty1;

   with TempBitmap.Canvas do

   for i:=1 to LCount-1 do

      if TempY[i]=Infinite then

         begin intx1:=intx+1;inty1:=0;end

      else

         begin

            PointRealtoForm(TempX[i]+xo,TempY[i]+yo,intx,inty);

            if check(intx,inty)or check(intx1,inty1)then

               if abs(inty-inty1)<height div 2 then

                  begin

                     moveto(intx1,inty1);

                     lineto(intx,inty);

                     SetLine(intx1,inty1,intx,inty);

                  end;

            if MinX>intx then MinX:=intx;

            if MaxX<intx then MaxX:=intx;

            if MinY>inty then MinY:=inty;

            if MaxY<inty then MaxY:=inty;

            intx1:=intx;inty1:=inty;

         end;

end;

 

procedure TGraph.DrawYX(exp:string;v1,v2,xo,yo:float);

var

   LCount, i, k: Integer;

   intx, inty, intx1, inty1: Integer;

   d: float;

begin

   exp:=StrDelspc(exp);

   k:=pos('Y=',exp);

   if k>0 then delete(exp,k,2);

   //Build TempT,TempR

   if v1<-ox/op then v1:=-ox/op;

   if v2>(width-ox)/op then v2:=(width-ox)/op;

   LCount:=round((v2-v1)*op);

   if Lcount=0 then exit;

   d:=(v2-v1)/Lcount;

   for i:=0 to LCount-1 do

      TempX[i]:=v1+d*i;

   Evaluate(exp,'X',LCount,TempX,TempY);

   //Draw

   Pointrealtoform(TempX[0]+xo,TempY[0]+yo,intx1,inty1);

   MinX:=intx1;MinY:=inty1;MaxX:=intx1;MaxY:=inty1;

   with TempBitmap.Canvas do

   for i:=1 to LCount-1 do

      if TempY[i]=Infinite then

         begin intx1:=intx+1;inty1:=0;end

      else

         begin

            PointRealtoForm(TempX[i]+xo,TempY[i]+yo,intx,inty);

            if check(intx,inty)or check(intx1,inty1)then

               if abs(inty-inty1)<height div 2 then

                  begin

                     moveto(intx1,inty1);

                     lineto(intx,inty);

                     SetLine(intx1,inty1,intx,inty);

                  end;

            if MinX>intx then MinX:=intx;

            if MaxX<intx then MaxX:=intx;

            if MinY>inty then MinY:=inty;

            if MaxY<inty then MaxY:=inty;

            intx1:=intx;inty1:=inty;

         end;

end;

 

procedure TGraph.DrawYXT(exp:string;v1,v2,xo,yo:float);

var

   i, k, l: Integer;

   intx, inty, intx1, inty1: Integer;

   sx, sy: string;

   d: float;

begin

   //Split up

   exp:=Strdelspc(exp);

   k:=pos('X=',exp);l:=pos('Y=',exp);

   if k<l then

      begin sx:=copy(exp,3,l-k-3);sy:=copy(exp,l+2,255);end

   else

      begin sy:=copy(exp,3,k-l-3);sx:=copy(exp,k+2,255);end;

   //Build TempT,TempX,TempY

   d:=(v2-v1)/Lcount;

   for i:=0 to LCount-1 do

      TempT[i]:=v1+d*i;

   evaluate(sx,'T',LCount,TempT,TempX);

   evaluate(sy,'T',LCount,TempT,TempY);

   //Draw

   pointrealtoform(tempx[0]+xo,tempy[0]+yo,intx1,inty1);

   MinX:=intx1;MinY:=inty1;MaxX:=intx1;MaxY:=inty1;

   with TempBitmap.Canvas do

   for i:=0 to LCount-1 do

      begin

         PointRealtoForm(tempx[i]+xo,tempy[i]+yo,intx,inty);

         if check(intx,inty)or check(intx1,inty1)then

            begin

               moveto(intx1,inty1);

               lineto(intx,inty);

               SetLine(intx1,inty1,intx,inty);

            end;

         if MinX>intx then MinX:=intx;

         if MaxX<intx then MaxX:=intx;

         if MinY>inty then MinY:=inty;

         if MaxY<inty then MaxY:=inty;

         intx1:=intx;inty1:=inty;

      end;

end;

 

function TGraph.GetObjectIndexAt(X,Y:integer): Integer;

var

   i, j, Max: Integer;

begin

   Max:=-Maxint;

     for i:=X-2 to X+2 do

       for j:=Y-2 to Y+2 do

           if(Max<Bit[i,j])then Max:=Bit[i,j];

   if(Max=0)then

       Result:=-1

     else

       Result:=Max-1;

end;

 

procedure TGraph.Lin(x1,y1,x2,y2:integer);

var

   tt: Integer;

begin

   with TempBitmap.Canvas do

   begin

      pen.Color:=clgrid;

      if x1=x2 then

         begin

            tt:=oy mod op;

            while tt<=height do

               begin

                  pixels[x1,tt]:=clgrid;

                  tt:=tt+op;

               end

         end

      else

         begin

            tt:=ox mod op;

            while tt<=width do

               begin

                  pixels[tt,y1]:=clgrid;

                  tt:=tt+op;

               end

         end;

      pen.Color:=claxis;

   end;

end;

 

procedure TGraph.OnMouseDownCustom(Sender: TObject; Button: TMouseButton;

   Shift: TShiftState; X, Y: Integer);

begin

   if(X<20)or(X>Width-20)or(Y<20)or(Y>Height-20)then begin

       MouseDownX:=X;

       MouseDownY:=Y;

       OxOld:=Ox;

       OyOld:=Oy;

       IsMouseDown:=true;

   end;

end;

 

procedure TGraph.OnMouseMoveCustom(Sender: TObject; Shift: TShiftState; X, Y:

   Integer);

begin

   if(IsMouseDown)then begin

       Ox:=OxOld;

       Oy:=OyOld;

       Ox:=Ox+(X-MouseDownX);

       Oy:=Oy+(Y-MouseDownY);

       Render();

   end

   else

       if(X<20)or(X>Width-20)or(Y<20)or(Y>Height-20)then Cursor:=crSizeAll

       else Cursor:=crDefault;

end;

 

procedure TGraph.OnMouseUpCustom(Sender: TObject; Button: TMouseButton; Shift:

   TShiftState; X, Y: Integer);

begin

   IsMouseDown:=false;

end;

 

procedure TGraph.OnPaintCustom(Sender:TObject);

begin

   Render();

end;

 

procedure TGraph.PointRealToForm(inpx,inpy:float;var outx,outy:integer);

begin

   outx:=ox+round(inpx*op);

   outy:=oy-round(inpy*op);

end;

 

procedure TGraph.Rec(x1,y1,x2,y2:integer);

begin

   with TempBitmap.Canvas do

      begin

         moveto(x1,y1);

         lineto(x1,y2);

         lineto(x2,y2);

         lineto(x2,y1);

         lineto(x1,y1);

      end;

end;

 

procedure TGraph.Remove(index:integer);

var

   i: Integer;

begin

   dec(Count);

   for i:=index to Count-1 do

       begin

         Items[i]:=Items[i+1];

             Selected[i]:=Selected[i+1];

         end;

     Selected[Count]:=false;

end;

 

procedure TGraph.Render;

var

   i: Integer;

begin

   //Set size equal to TGraph

   TempBitmap.Width:=Width;

   TempBitmap.Height:=Height;

   //Draw Axis

   fillchar(Bit,2*Width*MaxResolutionY,0);

   DrawAxis();

   for i:=0 to Count-1 do begin

       MinX:=MaxInt;MinY:=MaxInt;

       MaxX:=-MaxInt;MaxY:=-MaxInt;

       TempBitmap.Canvas.Pen.Color:=Items[i].Color;

        TempBitmap.Canvas.Brush.Color:=Items[i].Color;

        with Items[i]do

        case Style of

            OrdPoint:DrawPoint(x,y);

            OrdString:DrawString(x,y,Expression,Round(F));

            OrdLine:DrawLine(a,b,c,v1,v2);

            OrdLineDraw:DrawLine(x0,y0,x1,y1);

            OrdEllipse:DrawEllipse(x,y,a,b);

            OrdRectangle:DrawRectangle(x0,y0,x1,y1);

            OrdFillRectangle:DrawFillRectangle(x0,y0,x1,y1);

            OrdArc:DrawArc(x,y,a,b,v1,v2);

            OrdPie:DrawPie(x,y,a,b,v1,v2);

            OrdXY:DrawXY(expression,v1,v2,X0,Y0);

            OrdYX:DrawYX(expression,v1,v2,X0,Y0);

            OrdRT:DrawRT(expression,v1,v2,X0,Y0);

            OrdYXT:DrawYXT(expression,v1,v2,X0,Y0);

        end;

       if(Selected[i])then

          DrawBorder(MinX,Miny,MaxX,MaxY);

   end;

   Canvas.Draw(0,0,TempBitmap);

end;

 

procedure TGraph.Select(index:integer);

begin

   Selected[index]:=true;

end;

 

procedure TGraph.SelectAll;

var

   i: Integer;

begin

   for i:=0 to Count-1 do

       Selected[i]:=true;

end;

 

procedure TGraph.SetAxisVisible(Value: Boolean);

begin

   AxisVisible:=Value;

     Render();

end;

 

procedure TGraph.SetColor(Foreground,Background:TColor);

begin

   TempBitmap.Canvas.Pen.Color:=Foreground;

   TempBitmap.Canvas.Brush.Color:=Background;

end;

 

procedure TGraph.SetColorAxis(Value: TColor);

begin

   ClAxis:=Value;

     Render();

end;

 

procedure TGraph.SetColorBackground(Value: TColor);

begin

   ClBackground:=Value;

     Render();

end;

 

procedure TGraph.SetColorBorder1(Value: TColor);

begin

   ClBorder1:=Value;

     Render();

end;

 

procedure TGraph.SetColorBorder2(Value: TColor);

begin

   ClBorder2:=Value;

     Render();

end;

 

procedure TGraph.SetColorGrid(Value: TColor);

begin

   ClGrid:=Value;

     Render();

end;

 

procedure TGraph.SetColorOxy(Value: TColor);

begin

   ClOxy:=Value;

     Render();

end;

 

procedure TGraph.SetColorText(Value: TColor);

begin

   ClText:=Value;

     Render();

end;

 

procedure TGraph.SetGrid(Value: Boolean);

begin

   Grid:=Value;

     Render();

end;

 

procedure TGraph.SetLine(x1,y1,x2,y2:integer);

var

   i: Integer;

   y, d: float;

begin

   if x1>x2 then

      begin Swap(x1,x2);Swap(y1,y2);end;

   if(x1=x2)or(x2=x1+1)then

      begin

         if(x1>0)and(x1<width)then

            if y1<y2 then

               begin

                  for i:=y1 to y2 do

                     if(i>0)and(i<height)then

                        Bit[x1,i]:=Count

               end

            else

                  for i:=y1 downto y2 do

                     if(i>0)and(i<height)then bit[x1,i]:=Count

      end

   else

      begin

         d:=(y2-y1)/(x2-x1);

         y:=y1;

         for i:=x1 to x2 do

            if(i>0)and(i<width)then

               begin

                  y:=y+d;y1:=round(y);

                  if(y1>0)and(y1<height)then bit[i,y1]:=Count;

               end

            else y:=y+d;

      end;

end;

 

procedure TGraph.SetLineSpace(Value: Integer);

begin

   LineSpace:=Value;

     Render();

end;

 

procedure TGraph.SetLineWidth(Value: Integer);

begin

   LineWidth:=Value;

     Render();

end;

 

procedure TGraph.SetOP(Value: Integer);

begin

   Op:=Value;

     Render();

end;

 

procedure TGraph.SetOx(Value: Integer);

begin

   Ox:=Value;

   Render();

end;

 

procedure TGraph.SetOy(Value: Integer);

begin

   Oy:=Value;

     Render();

end;

 

procedure TGraph.SetSizeLine(Value: Integer);

begin

   SizeLine:=Value;

     Render();

end;

 

procedure TGraph.SetSizeOxy(Value: Integer);

begin

   SizeOxy:=Value;

     Render();

end;

 

procedure TGraph.SetSizeText(Value: Integer);

begin

   SizeText:=Value;

     Render();

end;

 

procedure TGraph.UnSelectAll;

var

   i: Integer;

begin

   for i:=0 to Count-1 do

       Selected[i]:=false;

end;

 

procedure TGraph.UnSelect(index:integer);

begin

   Selected[index]:=false;

end;

 

procedure TGraph.Replace(index: integer; S: string);

var i, L : integer;

begin

   //Format S

   for i:=1 to length(s)do

       if s[i]='('then break;

   s[i]:=',';

   for i:=length(s)downto 1 do

       if s[i]=')'then break;

   delete(s,i,1);

   s:=StrDelSpc(s);

   TempS := StrSplit(s,',');

   //Create TempX to hold Array

   L := length(TempS);

   for i:=1 to L-1 do

       trystrtofloat(TempS[i],TempX[i]);

   with Items[Index]do

   if(TempS[0]='ARC')then

       begin

           Style:=OrdArc;

           X:=TempX[1];Y:=TempX[2];A:=TempX[3];

           B:=TempX[4];V1:=TempX[5];V2:=TempX[6];

       end

   else if(TempS[0]='ELLIPSE')then

       begin

           Style:=OrdEllipse;

           X:=TempX[1];Y:=TempX[2];A:=TempX[3];B:=TempX[4];

       end

   else if(TempS[0]='FILLRECTANGLE')then

       begin

           Style:=OrdFillRectangle;

           X0:=TempX[1];Y0:=TempX[2];X1:=TempX[3];Y1:=TempX[4];

       end

   else if(TempS[0]='LINE')then

       begin

           Style:=OrdLine;

           A:=TempX[1];B:=TempX[2];C:=TempX[3];

           V1:=TempX[4];V2:=TempX[5];

       end

   else if(TempS[0]='LINEDRAW')then

       begin

           Style:=OrdLineDraw;

           X0:=TempX[1];Y0:=TempX[2];X1:=TempX[3];Y1:=TempX[4];

       end

   else if(TempS[0]='PIE')then

       begin

           Style:=OrdPie;

           X:=TempX[1];Y:=TempX[2];A:=TempX[3];

           B:=TempX[4];V1:=TempX[5];V2:=TempX[6];

       end

   else if(TempS[0]='POINT')then

       begin

           Style:=OrdPoint;

           X:=TempX[1];Y:=TempX[2];

       end

   else if(TempS[0]='RECTANGLE')then

       begin

           Style:=OrdRectangle;

           X0:=TempX[1];Y0:=TempX[2];

           X1:=TempX[3];Y1:=TempX[4];

       end

   else if(TempS[0]='STRING')then

       begin

           Style:=OrdString;

           Expression:=TempS[1];

           X:=TempX[2];Y:=TempX[3];F:=TempX[4];

       end

   else if(TempS[0]='YX')then

       begin

           Style:=OrdYX;

           Expression:=TempS[1];

           X0:=TempX[4];Y0:=TempX[5];

           V1:=TempX[2];V2:=TempX[3];

       end

   else if(TempS[0]='XY')then

       begin

           Style:=OrdXY;

           Expression:=TempS[1];

           X0:=TempX[4];Y0:=TempX[5];

           V1:=TempX[2];V2:=TempX[3];

       end

   else if(TempS[0]='RT')then

       begin

           Style:=OrdRT;

           Expression:=TempS[1];

           X0:=TempX[4];Y0:=TempX[5];

           V1:=TempX[2];V2:=TempX[3];

       end

   else if(TempS[0]='YXT')then

       begin

           Style:=OrdYXT;

           Expression:=TempS[1];

           X0:=TempX[4];Y0:=TempX[5];

           V1:=TempX[2];V2:=TempX[3];

       end;

   Render();       

end;

 

end.