⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sgr_def.pas

📁 图形控件,画实时曲线,等操作方便
💻 PAS
📖 第 1 页 / 共 4 页
字号:
end;
procedure Tsp_XYPlot.AddMarker(const FM:Tsp_PlotMarker; const WDM:Tsp_WhenDrawMarker);
begin
 if FM<>nil then begin
   with MarkerList(WDM) do if IndexOf(FM)<0 then Add(FM);
   if FM.Visible then CustomInvalidate(False,False,True);
 end;
end;
procedure Tsp_XYPlot.SetMarkerAt(const FM:Tsp_PlotMarker;
                                 const  WDM:Tsp_WhenDrawMarker; Front:boolean);
var ci:integer;
begin
 with MarkerList(WDM) do begin
   if Front and (Last<>Self) then begin
     ci:=IndexOf(Self);
     if (ci>-1) then Move(ci,Count-1);
   end
   else begin
     ci:=IndexOf(Self);
     if ci>0 then Move(ci,0);
   end;
 end;
end;
function Tsp_XYPlot.FindXAutoMin(WX:Tsp_WhatXAxis; var min:double ):boolean;
var j,k:integer; tm:double;
begin
 Result:=False;
 if fSeries.Count<1 then Exit;
 k:=-1;
 for j:=0 to fSeries.Count-1 do with Tsp_DataSeries(fSeries[j]) do
 begin
   if Active and (XAxis=WX) and GetXMin(min) then
   begin
     k:=j;
     break;
   end;
 end;
 if k > -1 then
 begin
   Result:=True;
   for j:=k+1 to fSeries.Count-1 do with Tsp_DataSeries(fSeries[j]) do
   begin
     if Active and (XAxis=WX) and GetXMin(tm) then
     begin
       if tm<min then min:=tm;
     end;
   end;
 end;       
end;
function Tsp_XYPlot.FindXAutoMax(WX:Tsp_WhatXAxis; var max:double ):boolean;
var j,k:integer; tm:double;
begin
 Result:=False;
 if fSeries.Count<1 then Exit;
 k:=-1;
 for j:=0 to fSeries.Count-1 do with Tsp_DataSeries(fSeries[j]) do
 begin
   if Active and (XAxis=WX) and GetXMax(max) then
   begin
     k:=j;
     break;
   end;
 end;
 if k > -1 then
 begin
   Result:=True;
   for j:=k+1 to fSeries.Count-1 do with Tsp_DataSeries(fSeries[j]) do
   begin
     if Active and (XAxis=WX) and GetXMax(tm) then
     begin
       if tm>max then max:=tm;
     end;
   end;
 end;       
end;
function Tsp_XYPlot.FindYAutoMin(WY:Tsp_WhatYAxis; var min:double ):boolean;
var j,k:integer; tm:double;
begin
 Result:=False;
 if fSeries.Count<1 then Exit;
 k:=-1;
 for j:=0 to fSeries.Count-1 do with Tsp_DataSeries(fSeries[j]) do
 begin
   if Active and (YAxis=WY) and GetYMin(min) then
   begin
    k:=j;
    break;
   end;
 end;
 if k > -1 then
 begin
   Result:=True;
   for j:=k+1 to fSeries.Count-1 do with Tsp_DataSeries(fSeries[j]) do
   begin
     if Active and (YAxis=WY) and GetYMin(tm) then
     begin
      if tm<min then min:=tm;
     end;
   end;
 end;       
end;
function Tsp_XYPlot.FindYAutoMax(WY:Tsp_WhatYAxis; var max:double ):boolean;
var j,k:integer; tm:double;
begin
 Result:=False;
 if fSeries.Count<1 then Exit;
 k:=-1;
 for j:=0 to fSeries.Count-1 do with Tsp_DataSeries(fSeries[j]) do
 begin
   if Active and (YAxis=WY) and GetYMax(max) then
   begin
    k:=j;
    break;
   end;
 end;
 if k > -1 then
 begin
   Result:=True;
   for j:=k+1 to fSeries.Count-1 do with Tsp_DataSeries(fSeries[j]) do
   begin
     if Active and (YAxis=WY) and GetYMax(tm) then
     begin
      if tm>max then max:=tm;
     end;
   end;
 end;       
end;
function Tsp_XYPlot.DoAutoMinMax(Axis:Tsp_Axis):boolean;
var WX:Tsp_WhatXAxis; WY:Tsp_WhatYAxis;
    dmin, dmax, gap:double;
    bin, bax:boolean;
begin
 Result:=False;
 if (Axis.fFlags and (sdfAutoMin or sdfAutoMax))=0 then Exit;
 if (Axis.fFlags and sdfVertical)<>0 then
 begin
   if Axis=LA then WY:=dsyLeft else WY:=dsyRight;
   bin:=((Axis.fFlags and sdfAutoMin)<>0) and FindYAutoMin(WY, dmin);
   bax:=((Axis.fFlags and sdfAutoMax)<>0) and FindYAutoMax(WY, dmax);
 end else
 begin
   if Axis=BA then WX:=dsxBottom else WX:=dsxTop;
   bin:=((Axis.fFlags and sdfAutoMin)<>0) and FindXAutoMin(WX, dmin);
   bax:=((Axis.fFlags and sdfAutoMax)<>0) and FindXAutoMax(WX, dmax);
 end;
 if not (bin or bax) then Exit;
 if not bin then dmin:=Axis.Min;
 if not bax then dmax:=Axis.Max;
 gap:=(dmax-dmin)*0.025;
 if bin then dmin:=dmin-gap;                     
 if bax then dmax:=dmax+gap;
 Result:=True;
 with Axis do if (dmin<>Min) or (dmax<>Max)then ChangeMinMax(dmin,dmax);
end;
function Tsp_XYPlot.LimitsStored:boolean;
begin
 Result:=LA.fMinMaxStored and BA.fMinMaxStored and
         RA.fMinMaxStored and TA.fMinMaxStored;
end;
procedure Tsp_XYPlot.StoreLimits;
begin
 if Not LimitsStored then begin
   LA.StoreMinMax; BA.StoreMinMax; RA.StoreMinMax; TA.StoreMinMax;
 end;
end;
procedure Tsp_XYPlot.RestoreLimits;
begin
 if LimitsStored then begin
   LA.RestoreMinMax; BA.RestoreMinMax; RA.RestoreMinMax; TA.RestoreMinMax;
   Invalidate;
 end;
end;
procedure Tsp_XYPlot.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  with Params do
   WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
end;
procedure Tsp_XYPlot.Notification(AComponent: TComponent; Operation: TOperation);
begin
 inherited Notification(AComponent, Operation);
 if (Operation=opRemove) then begin
   if (AComponent is Tsp_DataSeries) then
   RemoveSeries(AComponent as Tsp_DataSeries);
   if (AComponent is Tsp_PlotMarker) then
   RemoveMarker(AComponent as Tsp_PlotMarker,
                 (AComponent as Tsp_PlotMarker).WhenDraw);
 end;
end;
Const
 zsNone=0; zsZoomStart=1; zsZoomRect=2; zsStartPan=3; zsPaning=4;
function NormRect(var R:TRect):TRect;
begin
 Result:=R;
 with Result do begin
  if R.Left>R.Right then begin Left:=R.Right+1; Right:=R.Left+1; end;
  if R.Top>R.Bottom then begin Top:=R.Bottom+1; Bottom:=R.Top+1 end;
 end;
end;
procedure Tsp_XYPlot.DrawNotRect(R:TRect);
begin
 with Canvas do
 begin
  with Pen do
  begin
   Style:=psDot;
   Color:=clBlack;
   Mode:=pmNotXor;
  end;
  Brush.Color:=clWhite;
  with R do begin
   PolyLine([TopLeft, Point(Right,Top), BottomRight, Point(Left,Bottom),TopLeft]);
  end;
 end;
end;
procedure Tsp_XYPlot.RectToLimits(ZR:TRect; D:Tsp_zpDirections);
 procedure ZoomAxis(A:Tsp_Axis; p1,p2:integer);
 var mi, ma, sw :double; CanZoom:boolean;
 begin
   with A do
   begin
     mi:=P2V(p1); ma:=P2V(p2);
     if mi>ma then begin sw:=mi; mi:=ma; ma:=sw end;
     CanZoom:=True;
     if Assigned(fOnZoom) then fOnZoom(A, mi, ma, CanZoom);
     if CanZoom then ChangeMinMax(mi,ma);
    end;
 end;
begin
  if D=zpdNone then Exit;
  with ZR do begin
    if ((Right-Left)>2) and ((Bottom-Top)>2) then
    begin
      StoreLimits;
      if ((Right-Left)>1) and (D in [zpdHorizontal, zpdBoth]) then begin
        ZoomAxis(BA, Left, Right);
        ZoomAxis(TA, Left, Right);
      end;
      if ((Bottom-Top)>1) and (D in [zpdVertical, zpdBoth]) then begin
        ZoomAxis(LA, Bottom, Top);
        ZoomAxis(RA, Bottom, Top);
      end;
      Invalidate;
    end;     
  end;       
end;
procedure Tsp_XYPlot.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 if (Button = mbLeft) then
 begin
   if (Shift=fZoomShift) and (fZoomEnabled<>zpdNone) and
       (fZoomData.State=zsNone) then  with fZoomData do                 
   begin
       R.Left:=X; R.Top:=Y;
       case fZoomEnabled of
         zpdHorizontal: R.Top:=FR.Top;
         zpdVertical: R.Left:=FR.Left;
        end;
       State:=zsZoomStart;
   end
   else if (Shift=fPanShift) and (fPanEnabled<>zpdNone) and
           (fZoomData.State=zsNone) then  with fZoomData do            
   begin
      R.Left:=X; R.Top:=Y;
      State:=zsStartPan;
      Screen.Cursor := fPanCursor;         
   end;
 end;
 inherited MouseDown(Button, Shift, X, Y);
end;
procedure Tsp_XYPlot.MouseMove(Shift: TShiftState; X, Y: Integer);
  procedure PanPlot(var ZR:TRect; D:Tsp_zpDirections);
  begin
   StoreLimits;
   with ZR do begin
     if ((Right-Left)<>0) and (D in [zpdHorizontal, zpdBoth]) then begin
       with BA do ScrollBy(Right-Left);
       with TA do ScrollBy(Right-Left);
       CustomInvalidate(False,True,True);                       
     end;
     if ((Bottom-Top)<>0) and (D in [zpdVertical, zpdBoth]) then begin
      with LA do ScrollBy(Bottom-Top);
      with RA do ScrollBy(Bottom-Top);
      CustomInvalidate(False,True,True);                       
     end;
   end;       
  end;           
begin            
 if fZoomData.State<>zsNone then with fZoomData do
 case State of
   zsZoomStart: if (abs(R.Left-X)>3) or (abs(R.Top-Y)>3) then
     begin
       State:=zsZoomRect;
       Screen.Cursor := crCross;
       R.Right:=X;  R.Bottom:=Y;
       case fZoomEnabled of
        zpdHorizontal: R.Bottom:=FR.Bottom;
        zpdVertical:   R.Right:=FR.Right;
       end;
       DrawNotRect(R);
     end;
   zsZoomRect :
     begin
       DrawNotRect(R);
       R.Right:=X;  R.Bottom:=Y;
       case fZoomEnabled of
        zpdHorizontal: R.Bottom:=FR.Bottom;
        zpdVertical:   R.Right:=FR.Right;
       end;
       DrawNotRect(R);
     end;
   zsStartPan: with R do
       if (Left<>X) or (Top<>Y) then
       begin
        Right:=Left; Bottom:=Top;                      
        Left:=X; Top:=Y;
        State:=zsPaning;
        PanPlot(R, fPanEnabled);
       end;
   zsPaning : with R do
     begin
       Right:=Left; Bottom:=Top;                      
       Left:=X; Top:=Y;
       PanPlot(R, fPanEnabled);
     end;
 end;       
 inherited MouseMove(Shift, X, Y);
end;            
procedure Tsp_XYPlot.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 with fZoomData do
 case State of
  zsZoomStart: RestoreLimits;                                                   
  zsZoomRect:            
    begin
      DrawNotRect(R);
      RectToLimits(NormRect(R), fZoomEnabled);
    end;
  zsStartPan:;
  zsPaning:
    begin
    end;
 end;       
 if fZoomData.State<>zsNone then begin
   fZoomData.State:=zsNone;
   Screen.Cursor := Cursor;            
 end;
 inherited MouseUp(Button, Shift, X, Y);
end;
function MaxI(a,b:integer):integer;
begin
 if a>b then Result:=a else Result:=b;
end;
procedure Tsp_XYPlot.Arrange(AvgFntW,FntH:integer);
var BR:TRect;  h,w:integer;
begin
 FR:=Rect(0,0, DWidth, DHeight);
 h:=FntH;
 w:=AvgFntW;                           
 with BR do begin                                  
  Left:=MaxI(LA.BandWidth(w,h), MaxI(BA.OrgIndent(w,h), TA.OrgIndent(w,h)))+LA.Margin;
  Bottom:=MaxI(BA.BandWidth(w,h), MaxI(LA.OrgIndent(w,h), RA.OrgIndent(w,h)))+BA.Margin;
  Right:=MaxI(RA.BandWidth(w,h), MaxI(BA.EndIndent(w,h), TA.EndIndent(w,h)))+RA.Margin;
  Top:=MaxI(TA.BandWidth(w,h), MaxI(LA.EndIndent(w,h), RA.EndIndent(w,h)))+TA.Margin;
 end;
 with FR do begin
  inc(Left,BR.Left);
  dec(Right,BR.Right);
  dec(Bottom,BR.Bottom);
  inc(Top,BR.Top);
  if Left+3>Right then Right:=Left+3;
  if Top+3>Bottom then Bottom:=Top+3;
  LA.SetLine(Left-1, Bottom-1, Bottom-Top-1);
  RA.SetLine(Right,  Bottom-1, Bottom-Top-1);
  BA.SetLine(Left, Bottom, Right-Left-1);
  TA.SetLine(Left, Top-1,  Right-Left-1);
 end;
 ValidArrange:=True;
end;
procedure Tsp_XYPlot.FreshVFont;
var LF:TLogFont; HF:HFont;
begin
 VFont.Assign(Font);
 GetObject(VFont.Handle, SizeOf(LF), @LF);
 with LF do begin
  lfEscapement:=900;
  lfOrientation:= lfEscapement;
  lfWeight:= FW_BOLD;
 end;
 HF:=CreateFontIndirect(LF);
 if HF<>0 then VFont.Handle:=HF;
end;
procedure Tsp_XYPlot.DrawAroundField;
 procedure ClearBack;
 begin
  with DCanvas do
  begin
   Brush.Style:=bsSolid;
   Brush.Color:=Self.Color;
   FillRect(Rect(0, 0, DWidth, FR.Top));                            
   FillRect(Rect(0, FR.Bottom+1, DWidth, DHeight));                    
   FillRect(Rect(0, FR.Top, FR.Left, FR.Bottom+1));                  
   FillRect(Rect(FR.Right, FR.Top, DWidth, FR.Bottom+1));             
  end;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -