teetools.pas

来自「Delphi TeeChartPro.6.01的源代码」· PAS 代码 · 共 2,188 行 · 第 1/5 页

PAS
2,188
字号
    Constructor Create(AOwner: TComponent); override;
    Destructor Destroy; override;

    Function BandBackColor(ABand:TGridBandBrush):TColor;
    class Function Description:String; override;
  published
    property Active;
    property Axis;
    property Band1:TGridBandBrush read FBand1 write SetBand1;
    property Band2:TGridBandBrush read FBand2 write SetBand2;
  end;

  TColorLineTool=class;

  TColorLineStyle=(clCustom,clMaximum,clCenter,clMinimum);

  TColorLineToolOnDrag=procedure(Sender:TColorLineTool) of object;

  // Color line tool, use it to display a vertical or horizontal line
  // at the specified axis and position.
  // The line can be optionally dragged at runtime.
  TColorLineTool=class(TTeeCustomToolAxis)
  private
    FAllowDrag     : Boolean;
    FDragRepaint   : Boolean;
    FDraw3D        : Boolean;
    FDrawBehind    : Boolean;
    FNoLimitDrag   : Boolean;
    FOnDragLine    : TColorLineToolOnDrag;
    FOnEndDragLine : TColorLineToolOnDrag;
    FStyle         : TColorLineStyle;
    FValue         : Double;

    IDragging      : Boolean;
    Procedure DrawColorLine(Back:Boolean); { 5.02 }
    Function LimitValue(const AValue:Double):Double;
    procedure SetDraw3D(const Value: Boolean);
    procedure SetDrawBehind(const Value: Boolean);
    procedure SetStyle(const Value: TColorLineStyle);
    procedure SetValue(const AValue: Double);
  protected
    Function CalcValue:Double;
    procedure ChartEvent(AEvent: TChartToolEvent); override;
    Procedure ChartMouseEvent( AEvent: TChartMouseEvent;
                               Button:TMouseButton;
                               Shift: TShiftState; X, Y: Integer); override;
    procedure DoEndDragLine; virtual; { 5.02 }
    class function GetEditorClass: String; override;
  public
    Constructor Create(AOwner:TComponent); override;

    Function Clicked(x,y:Integer):Boolean;
    class Function Description:String; override;
  published
    property Active;
    property Axis;
    property AllowDrag:Boolean read FAllowDrag write FAllowDrag default True;
    property DragRepaint:Boolean read FDragRepaint write FDragRepaint default False;
    property Draw3D:Boolean read FDraw3D write SetDraw3D default True;
    property DrawBehind:Boolean read FDrawBehind write SetDrawBehind default False;
    property NoLimitDrag:Boolean read FNoLimitDrag write FNoLimitDrag default False;
    property Pen;
    property Style:TColorLineStyle read FStyle write SetStyle default clCustom;
    property Value:Double read FValue write SetValue;

    property OnDragLine:TColorLineToolOnDrag read FOnDragLine write FOnDragLine;
    property OnEndDragLine:TColorLineToolOnDrag read FOnEndDragLine write FOnEndDragLine;
  end;

  // Rotate tool, use it to allow the end-user to do 3D rotation of the chart
  // at runtime by dragging the chart using the specified mouse button.

  TRotateToolStyles = ( rsAll, rsRotation, rsElevation );

  TRotateTool=class(TTeeCustomTool)
  private
    FButton    : TMouseButton;
    FInverted  : Boolean;
    FOnRotate  : TNotifyEvent;
    FStyle     : TRotateToolStyles;

    IOldX      : Integer;
    IOldY      : Integer;
    IDragging  : Boolean;
    IFirstTime : Boolean;
    IOldRepaint: Boolean;
  protected
    Procedure ChartMouseEvent( AEvent: TChartMouseEvent;
                               AButton:TMouseButton;
                               AShift: TShiftState; X, Y: Integer); override;
    class function GetEditorClass: String; override;
  public
    Constructor Create(AOwner:TComponent); override;
    class Function Description:String; override;
    class function ElevationChange(FullRotation:Boolean; AAngle,AChange:Integer):Integer;
    class function RotationChange(FullRotation:Boolean; AAngle,AChange:Integer):Integer;
  published
    property Active;
    property Button:TMouseButton read FButton write FButton default mbLeft;
    property Inverted:Boolean read FInverted write FInverted default False;
    property Pen;
    property Style:TRotateToolStyles read FStyle write FStyle default rsAll;

    property OnRotate:TNotifyEvent read FOnRotate write FOnRotate;
  end;

  // Chart Image tool, use it to display a picture using the specified
  // Series axes as boundaries. When the axis are zoomed or scrolled,
  // the picture will follow the new boundaries.
  TChartImageTool=class(TTeeCustomToolSeries)
  private
    FPicture : TPicture;
    procedure SetPicture(const Value: TPicture);
  protected
    procedure ChartEvent(AEvent: TChartToolEvent); override;
    class function GetEditorClass: String; override;
    procedure SetSeries(const Value: TChartSeries); override;
  public
    Constructor Create(AOwner:TComponent); override;
    Destructor Destroy; override;
    class Function Description:String; override;
  published
    property Active;
    property Picture:TPicture read FPicture write SetPicture;
    property Series;
  end;

  // A Shape object (with Left and Top), publishing all properties.
  TTeeShapePosition=class(TTeeCustomShapePosition)
  published
    property Bevel;
    property BevelWidth;
    property Brush;
    property Color;
    property CustomPosition;
    property Font;
    property Frame;
    property Gradient;
    property Left;
    property Shadow;
    property ShapeStyle;
    property Top;
    property Transparency;
    property Transparent;
    property Visible default True;
  end;

  TAnnotationTool=class;

  TAnnotationPosition=(ppLeftTop,ppLeftBottom,ppRightTop,ppRightBottom);

  TAnnotationClick=procedure( Sender:TAnnotationTool;
			 Button:TMouseButton;
			 Shift: TShiftState;
			 X, Y: Integer) of object;

  TAnnotationCallout=class(TCallout)
  private
    FX : Integer;
    FY : Integer;
    FZ : Integer;

    Function CloserPoint(const R:TRect; const P:TPoint):TPoint;
    procedure SetX(const Value:Integer);
    procedure SetY(const Value:Integer);
    procedure SetZ(const Value:Integer);
  public
    constructor Create(AOwner: TChartSeries);
    Procedure Assign(Source:TPersistent); override;
  published
    property Visible default False;
    property XPosition:Integer read FX write SetX default 0;
    property YPosition:Integer read FY write SetY default 0;
    property ZPosition:Integer read FZ write SetZ default 0;
  end;

  // Annotation tool, use it to display text anywhere on the chart.
  TAnnotationTool=class(TTeeCustomTool)
  private
    FCallout   : TAnnotationCallout;
    FCursor    : TCursor;
    FOnClick   : TAnnotationClick;  // 5.03
    FPosition  : TAnnotationPosition;
    FShape     : TTeeShapePosition;
    FText      : String;
    FTextAlign : TAlignment;

    procedure SetPosition(const Value: TAnnotationPosition);
    procedure SetShape(const Value: TTeeShapePosition);
    procedure SetTextAlign(const Value: TAlignment);
    procedure SetCallout(const Value: TAnnotationCallout);
  protected
    Procedure ChartEvent(AEvent:TChartToolEvent); override;
    Procedure ChartMouseEvent( AEvent: TChartMouseEvent;
                               Button:TMouseButton;
                               Shift: TShiftState; X, Y: Integer); override;
    Procedure DrawText;
    class Function GetEditorClass:String; override;
    Function GetText:String; virtual;
    procedure SetParentChart(const Value: TCustomAxisPanel); override;
    Procedure SetText(Const Value:String);
  public
    Constructor Create(AOwner:TComponent); override;
    Destructor Destroy; override;
    Function Clicked(x,y:Integer):Boolean;
    class Function Description:String; override;
  published
    property Active;
    property Callout:TAnnotationCallout read FCallout write SetCallout;
    property Cursor:TCursor read FCursor write FCursor default crDefault;
    property Position:TAnnotationPosition read FPosition write SetPosition
              default ppLeftTop;
    property Shape:TTeeShapePosition read FShape write SetShape;
    property Text:String read FText write SetText;
    property TextAlignment:TAlignment read FTextAlign
                                      write SetTextAlign default taLeftJustify;

    property OnClick:TAnnotationClick read FOnClick write FOnClick; // 5.03
  end;

  TSeriesAnimationTool=class;

  TSeriesAnimationStep=procedure(Sender:TSeriesAnimationTool; Step:Integer) of object;

  TSeriesAnimationTool=class(TTeeCustomToolSeries)
  private
    FBackup     : TChartSeries;
    FDrawEvery  : Integer;
    FStartValue : Double;
    FSteps      : Integer;
    FStartAtMin : Boolean;
    { events }
    FOnStep     : TSeriesAnimationStep;

    { internal }
    IStop       : Boolean;
  protected
    class Function GetEditorClass:String; override;
  public
    Constructor Create(AOwner:TComponent); override;
    class Function Description:String; override;
    procedure Execute; virtual;
  published
    property DrawEvery:Integer read FDrawEvery write FDrawEvery default 0;
    property Series;
    property StartAtMin:Boolean read FStartAtMin write FStartAtMin default True;
    property StartValue:Double read FStartValue write FStartValue;
    property Steps:Integer read FSteps write FSteps default 100;
    { events }
    property OnStep:TSeriesAnimationStep read FOnStep write FOnStep;
  end;

implementation

Uses {$IFDEF CLX}
     QForms,
     {$ELSE}
     Forms,
     {$ENDIF}
     Math, TeeConst, TeeProCo;

{ TCursorTool }
Constructor TCursorTool.Create(AOwner:TComponent);
begin
  inherited;
  FStyle:=cssBoth;
  IPoint.X:=-1;
  IPoint.Y:=-1;
end;

Procedure TCursorTool.CalcValuePositions(X,Y:Integer);
begin
  Case IDragging of
    ccVertical  : IXValue:=GetHorizAxis.CalcPosPoint(X);
    ccHorizontal: IYValue:=GetVertAxis.CalcPosPoint(Y);
  else
  begin
    IXValue:=GetHorizAxis.CalcPosPoint(X);
    IYValue:=GetVertAxis.CalcPosPoint(Y);
  end;
  end;
end;

Procedure TCursorTool.CalcScreenPositions;
var tmpSnap : Integer;
begin
  if (IPoint.X=-1) or (IPoint.Y=-1) then
  begin
    With GetHorizAxis do IPoint.X:=(IStartPos+IEndPos) div 2;
    With GetVertAxis do IPoint.Y:=(IStartPos+IEndPos) div 2;
    CalcValuePositions(IPoint.X,IPoint.Y);
    tmpSnap:=SnapToPoint;
    CalcScreenPositions;
    Changed(tmpSnap);
  end
  else
  begin
    IPoint.X:=GetHorizAxis.CalcPosValue(IXValue);
    IPoint.Y:=GetVertAxis.CalcPosValue(IYValue);
  end;
end;

Procedure TCursorTool.Changed(SnapPoint:Integer);
begin
  if Assigned(FOnChange) then
     FOnChange(Self,IPoint.X,IPoint.Y,IXValue,IYValue,Series,SnapPoint);
end;

class Function TCursorTool.GetEditorClass:String;
begin
  result:='TCursorToolEditor';
end;

class Function TCursorTool.Description:String;
begin
  result:=TeeMsg_CursorTool;
end;

Function TeeGetFirstLastSeries(Series:TChartSeries;
                               Var AMin,AMax:Integer):Boolean; { 5.01 }
begin
  AMin:=Series.FirstValueIndex;
  if AMin<0 then AMin:=0;

  AMax:=Series.LastValueIndex;
  if AMax<0 then AMax:=Series.Count-1
  else
  if AMax>=Series.Count then AMax:=Series.Count-1; { 5.03 }

  result:=(Series.Count>0) and (AMin<=Series.Count) and (AMax<=Series.Count);
end;

Function TCursorTool.NearestPoint(AStyle:TCursorToolStyle;
                                  Var Difference:Double):Integer;
var t      : Integer;
    tmpDif : Double;
    tmpMin : Integer;
    tmpMax : Integer;
begin
  result:=-1;
  Difference:=-1;

  if TeeGetFirstLastSeries(Series,tmpMin,tmpMax) then
  for t:=tmpMin to tmpMax do
  begin
    With Series do
    Case AStyle of
      cssHorizontal: tmpDif:=Abs(IYValue-YValues.Value[t]);
      cssVertical  : tmpDif:=Abs(IXValue-XValues.Value[t]);
    else
      tmpDif:=Sqrt(Sqr(IXValue-XValues.Value[t])+Sqr(IYValue-YValues.Value[t]));
    end;

    if (Difference=-1) or (tmpDif<Difference) then
    begin
      Difference:=tmpDif;
      result:=t;
    end;
  end;
end;

Function TCursorTool.SnapToPoint:Integer;
var Difference : Double;
begin
  if Assigned(Series) and FSnap then result:=NearestPoint(FStyle,Difference)
                                else result:=-1;
  if result<>-1 then
  Case FStyle of
    cssHorizontal: IYValue:=Series.YValues.Value[result];
    cssVertical  : IXValue:=Series.XValues.Value[result];
  else
    begin
      IXValue:=Series.XValues.Value[result];
      IYValue:=Series.YValues.Value[result]
    end;
  end;
end;

Function TCursorTool.GetAxisRect:TRect;
begin
  if UseChartRect then result:=ParentChart.ChartRect
  else
  begin
    With GetHorizAxis do
    begin
      result.Left:=IStartPos;
      result.Right:=IEndPos;
    end;
    With GetVertAxis do
    begin
      result.Top:=IStartPos;
      result.Bottom:=IEndPos;
    end;
    if Assigned(FOnGetAxisRect) then FOnGetAxisRect(Self,result);
  end;
end;

procedure TCursorTool.RedrawCursor;

  Procedure DrawCursorLines(Draw3D:Boolean; Const R:TRect; X,Y:Integer);

    Procedure DrawHorizontal;
    begin
      With ParentChart.Canvas do
      if Draw3D then HorizLine3D(R.Left,R.Right,Y,0)
                else DoHorizLine(R.Left,R.Right,Y);
    end;

    Procedure DrawVertical;
    begin
      With ParentChart.Canvas do
      if Draw3D then VertLine3D(X,R.Top,R.Bottom,0)
                else DoVertLine(X,R.Top,R.Bottom);
    end;

  begin
    Case FStyle of
      cssHorizontal: DrawHorizontal;
      cssVertical  : DrawVertical;
    else
    begin
      DrawHorizontal;
      DrawVertical;
    end;
    end;
  end;

var tmpColor : TColor;
begin
  if Assigned(ParentChart) then
  begin
    tmpColor:=ParentChart.Color;
    if tmpColor=clTeeColor then tmpColor:=clBtnFace;
    With ParentChart.Canvas do
    begin
      AssignVisiblePenColor(Self.Pen,Self.Pen.Color xor ColorToRGB(tmpColor));
      Brush.Style:=bsClear;
      Pen.Mode:=pmXor;

⌨️ 快捷键说明

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