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

📄 teerose.pas

📁 BCB第三方组件
💻 PAS
字号:
{**********************************************}
{   TWindRoseSeries                            }
{   TClockSeries                               }
{   Copyright (c) 1998-2007 by David Berneda   }
{**********************************************}
unit TeeRose;
{$I TeeDefs.inc}

interface

Uses {$IFNDEF LINUX}
     Windows,
     {$ENDIF}
     SysUtils, Classes,
     {$IFDEF CLX}
     QGraphics, QExtCtrls,
     {$ELSE}
     Graphics, ExtCtrls,
     {$ENDIF}
     {$IFDEF D9}
     Types,
     {$ENDIF}
     TeEngine, Chart, TeCanvas, Series, TeePolar;

{  This unit contains two Series components:

   TWindRoseSeries --  A Polar Series displaying Wind directions.
   TClockSeries    --  A Polar Series showing a watch.
}

type
  TCustom2DPolarSeries=class(TCustomPolarSeries)
  protected
    Procedure GalleryChanged3D(Is3D:Boolean); override;
    Procedure PrepareForGallery(IsEnabled:Boolean); override;
  end;

  TWindRoseSeries=class(TCustom2DPolarSeries)
  private
    FMirrorAngles : Boolean;
    FMirrorLabels : Boolean;

    procedure SetMirrorAngles(const Value: Boolean);
    procedure SetMirrorLabels(const Value: Boolean);
  protected
    class Procedure CreateSubGallery(AddSubChart:TChartSubGalleryProc); override;
    Function GetCircleLabel(Const Angle:Double; Index:Integer):String; override;
    class Function GetEditorClass:String; override;
    Function GetxValue(ValueIndex:Integer):TChartValue; override;
    Procedure PrepareForGallery(IsEnabled:Boolean); override;
    class Procedure SetSubGallery(ASeries:TChartSeries; Index:Integer); override;
  public
    Constructor Create(AOwner: TComponent); override;
    procedure Assign(Source:TPersistent); override;
  published
    property Active;
    property ColorEachPoint;
    property HorizAxis;
    property SeriesColor;
    property VertAxis;

    property AngleIncrement;
    property AngleValues;
    property Brush;
    property CircleBackColor;
    property CircleGradient;
    property CircleLabels default True;
    property CircleLabelsFont;
    property CircleLabelsInside;
    property CircleLabelsRotated;
    property CirclePen;
    property CloseCircle;
    property MirrorAngles:Boolean read FMirrorAngles write SetMirrorAngles default False;
    property MirrorLabels:Boolean read FMirrorLabels write SetMirrorLabels default False;
    property Pen;
    property Pointer;
    property RadiusIncrement;
    property RadiusValues;
    property RotationAngle default 90;
    property Transparency;
    property TreatNulls;

    { events }
    property OnGetCircleLabel;
    property OnGetPointerStyle;
  end;

  TClockSeriesStyle=(cssDecimal,cssRoman);

  TClockSeries=class;

  TClockSeriesGetTimeEvent=procedure(Sender:TClockSeries; Var ATime:TDateTime) of object;

  TClockSeries=class(TCustom2DPolarSeries)
  private
    FOnGetTime  : TClockSeriesGetTimeEvent;
    FPenHours   : TChartPen;
    FPenMinutes : TChartPen;
    FPenSeconds : TChartPen;
    FStyle      : TClockSeriesStyle;

    OldAxesVisible : Boolean;
    ITimer      : TTimer;
    Procedure SetPenHours(Value:TChartPen);
    Procedure SetPenMinutes(Value:TChartPen);
    Procedure SetPenSeconds(Value:TChartPen);
    Procedure SetStyle(Value:TClockSeriesStyle);
    Procedure OnTimerExpired(Sender:TObject);
  protected
    Procedure DoBeforeDrawValues; override;
    Procedure DrawAllValues; override;
    Function GetCircleLabel(Const Angle:Double; Index:Integer):String; override;
    class Function GetEditorClass:String; override;
    Procedure SetParentChart(Const Value:TCustomAxisPanel); override;
  public
    Constructor Create(AOwner: TComponent); override;
    Destructor Destroy; override;

    Procedure Assign(Source:TPersistent); override;
    Function ClockTime:TDateTime;
    Function CountLegendItems:Integer; override;
    Function LegendItemColor(LegendIndex:Integer):TColor; override;
    Function LegendString( LegendIndex:Integer;
                           LegendTextStyle:TLegendTextStyle ):String; override;
    Function NumSampleValues:Integer; override;
    property Timer:TTimer read ITimer;
  published
    property Active;
    property Brush;
    property CircleBackColor;
    property CircleGradient;
    property Circled default True;
    property CircleLabels default True;
    property CircleLabelsFont;
    property CircleLabelsInside;
    property CircleLabelsRotated;
    property CirclePen;
    property PenHours:TChartPen read FPenHours write SetPenHours;
    property PenMinutes:TChartPen read FPenMinutes write SetPenMinutes;
    property PenSeconds:TChartPen read FPenSeconds write SetPenSeconds;
    property RotationAngle default 90;
    property ShowInLegend default False;
    property Style:TClockSeriesStyle read FStyle write SetStyle
                                     default cssRoman;
    property Transparency;

    { events }
    property OnGetCircleLabel;
    property OnGetTime  : TClockSeriesGetTimeEvent read FOnGetTime
                                                   write FOnGetTime;
  end;

implementation

uses
  TeeProCo;

{ TCustom2DPolarSeries }
Procedure TCustom2DPolarSeries.GalleryChanged3D(Is3D:Boolean);
begin
  inherited;
  ParentChart.View3D:=False;
end;

Procedure TCustom2DPolarSeries.PrepareForGallery(IsEnabled:Boolean);
begin
  inherited;
  CircleLabelsFont.Size:=6;
  Pointer.HorizSize:=2;
  Pointer.VertSize:=2;
end;

{ TWindRoseSeries }
Constructor TWindRoseSeries.Create(AOwner: TComponent);
begin
  inherited;
  CircleLabels:=True;
  RotationAngle:=90;
end;

// Alternate method
(*
 function DegreesToWindDir(const Angle: Double): String;
 const WindDirs: Array[0..15] of String =
  ('N','NNW','NW','WNW','W','WSW','SW','SSW','S','SSE','SE','ESE','E','ENE','NE','NNE' );
 var i : Integer;
 begin
   i:=Trunc((Angle + 11.25) / (360/16));
   result := WindDirs[i];
 end;
*)

// Return the string corresponding to the "Angle" degree parameter
Function TWindRoseSeries.GetCircleLabel(Const Angle:Double; Index:Integer):String;
var tmp : Double;
begin
  if FMirrorLabels then tmp:=360-Angle
                   else tmp:=Angle;

  Case Round(tmp) of
      0: result:='N';
     15: result:='NNNW';
     30: result:='NNW';
     45: result:='NW';
     60: result:='NWW';
     75: result:='NWWW';
     90: result:='W';
    105: result:='SWWW';
    120: result:='SWW';
    135: result:='SW';
    150: result:='SSW';
    165: result:='SSSW';
    180: result:='S';
    195: result:='SSSE';
    210: result:='SSE';
    225: result:='SE';
    240: result:='SEE';
    255: result:='SEEE';
    270: result:='E';
    285: result:='NEEE';
    300: result:='NEE';
    315: result:='NE';
    330: result:='NNE';
    345: result:='NNNE';
    360: result:='N';
  else
    if tmp=22.5 then result:='NNW' else
    if tmp=67.5 then result:='WNW' else
    if tmp=112.5 then result:='WSW' else
    if tmp=157.5 then result:='SSW' else
    if tmp=202.5 then result:='SSE' else
    if tmp=247.5 then result:='ESE' else
    if tmp=292.5 then result:='ENE' else
    if tmp=337.5 then result:='NNE' else
       result:='';
  end;
end;

class function TWindRoseSeries.GetEditorClass: String;
begin
  result:='TWindRoseEditor';
end;

procedure TWindRoseSeries.PrepareForGallery(IsEnabled: Boolean);
begin
  inherited;
  AngleIncrement:=45;
end;

procedure TWindRoseSeries.SetMirrorAngles(const Value: Boolean);
begin
  SetBooleanProperty(FMirrorAngles,Value);
end;

procedure TWindRoseSeries.SetMirrorLabels(const Value: Boolean);
begin
  SetBooleanProperty(FMirrorLabels,Value);
end;

Function TWindRoseSeries.GetxValue(ValueIndex:Integer):TChartValue;
begin
  result:=inherited GetxValue(ValueIndex);

  if FMirrorAngles then
     result:=360-result;
end;

procedure TWindRoseSeries.Assign(Source: TPersistent);
begin
  if Source is TWindRoseSeries then
  with TWindRoseSeries(Source) do
  begin
    Self.FMirrorAngles:=FMirrorAngles;
    Self.FMirrorLabels:=FMirrorLabels;
  end;

  inherited;
end;

class procedure TWindRoseSeries.CreateSubGallery(
  AddSubChart: TChartSubGalleryProc);
begin
  inherited;
  AddSubChart(TeeMsg_Mirrored);
end;

class procedure TWindRoseSeries.SetSubGallery(ASeries: TChartSeries;
  Index: Integer);
begin
  inherited;
  if Index=14 then
     TWindRoseSeries(ASeries).MirrorAngles:=True;
end;

{ TClockSeries }
Constructor TClockSeries.Create(AOwner: TComponent);
begin
  inherited;
  OldAxesVisible:=True;
  Pointer.Hide;
  FStyle:=cssRoman;
  Brush.Style:=bsSolid;
  CircleLabels:=True;
  RotationAngle:=90;
  Circled:=True;

  Add(0);

  FPenHours:=CreateChartPen;
  FPenMinutes:=CreateChartPen;
  FPenSeconds:=CreateChartPen;

  ITimer:=TTimer.Create(Self);
  With ITimer do
  begin
    Interval:=1000;
    Enabled:=True;
    OnTimer:=OnTimerExpired;
  end;
end;

Destructor TClockSeries.Destroy;
begin
  FPenHours.Free;
  FPenMinutes.Free;
  FPenSeconds.Free;
  ITimer.Free;
  inherited;
end;

Procedure TClockSeries.OnTimerExpired(Sender:TObject);
begin
  ITimer.Enabled:=False;
  Repaint;
  ITimer.Enabled:=True;
end;

Procedure TClockSeries.Assign(Source:TPersistent);
begin
  if Source is TClockSeries then
  With TClockSeries(Source) do
  begin
    Self.PenHours   :=FPenHours;
    Self.PenMinutes :=FPenMinutes;
    Self.PenSeconds :=FPenSeconds;
    Self.FStyle     :=FStyle;
  end;
  inherited;
end;

Procedure TClockSeries.DoBeforeDrawValues;
var tmpBlend : TTeeBlend; { 5.02 }
begin
  if Transparency>0 then
     tmpBlend:=ParentChart.Canvas.BeginBlending(ParentChart.ChartRect,Transparency)
  else
     tmpBlend:=nil;

  inherited;

  if Transparency>0 then
     ParentChart.Canvas.EndBlending(tmpBlend);
end;

Function TClockSeries.ClockTime:TDateTime;
begin
  result:=Now;
  if Assigned(FOnGetTime) then FOnGetTime(Self,result);
end;

Procedure TClockSeries.DrawAllValues;
Var X : Integer;
    Y : Integer;

  Procedure CalcPos(Const AAngle,ASize:Double);
  begin
    AngleToPos(AAngle*PiDegree,ASize*XRadius/2.0,ASize*YRadius/2.0,X,Y);
  end;

Var H  : Word;
    M  : Word;
    S  : Word;
    Ms : Word;
    tmp : TDateTime;
begin
  With ParentChart.Canvas do
  begin
    tmp:=ClockTime;
    DecodeTime(tmp,H,M,S,Ms);

    AssignBrush(Self.Brush,SeriesColor);

    if FPenHours.Visible then
    begin
      AssignVisiblePen(FPenHours);
      CalcPos(360.0-(360.0*(60.0*H+M)/(12.0*60.0)),1.3);
      Arrow(True,TeePoint(CircleXCenter,CircleYCenter),TeePoint(X,Y),14,20,EndZ);
    end;

    if FPenMinutes.Visible then
    begin
      AssignVisiblePen(FPenMinutes);
      CalcPos(360.0-(360.0*M/60.0),1.7);
      Arrow(True,TeePoint(CircleXCenter,CircleYCenter),TeePoint(X,Y),10,16,EndZ);
    end;

    CalcPos(360.0-(360.0*(S+(Ms/1000.0))/60.0),1.8); // 5.02
    if FPenSeconds.Visible then
    begin
      AssignVisiblePen(FPenSeconds);
      MoveTo3D(CircleXCenter,CircleYCenter,EndZ);
      LineTo3D(X,Y,EndZ);
    end;

    With Pointer do
    if Visible then
    begin
      PrepareCanvas(ParentChart.Canvas,Color);
      Draw(X,Y);
    end;
  end;
end;

Procedure TClockSeries.SetParentChart(Const Value:TCustomAxisPanel);
begin
  if not Assigned(Value) then
     if Assigned(ParentChart) then
        ParentChart.Axes.Visible:=OldAxesVisible;

  inherited;

  AngleIncrement:=30;

  if Assigned(ParentChart) then
  begin
    OldAxesVisible:=ParentChart.Axes.Visible;
    ParentChart.Axes.Visible:=False;
  end;
end;

{ Return the string corresponding to the "Angle" degree parameter }
Function TClockSeries.GetCircleLabel(Const Angle:Double; Index:Integer):String;
Const RomanNumber:Array[1..12] of String=
  ('I','II','III','IV','V','VI','VII','VIII','IX','X','XI','XII');
var tmpAngle : Integer;
begin
  tmpAngle:=Round((360.0-Angle)/30.0);

  if FStyle=cssDecimal then
     Str(tmpAngle,result)
  else
  begin
    if tmpAngle=0 then
       tmpAngle:=12;

    result:=RomanNumber[tmpAngle];
  end;
end;

Procedure TClockSeries.SetPenHours(Value:TChartPen);
begin
  FPenHours.Assign(Value);
end;

Procedure TClockSeries.SetPenMinutes(Value:TChartPen);
begin
  FPenMinutes.Assign(Value);
end;

Procedure TClockSeries.SetPenSeconds(Value:TChartPen);
begin
  FPenSeconds.Assign(Value);
end;

Procedure TClockSeries.SetStyle(Value:TClockSeriesStyle);
begin
  if FStyle<>Value then
  begin
    FStyle:=Value;
    Repaint;
  end;
end;

Function TClockSeries.NumSampleValues:Integer;
begin
  result:=1;
end;

class function TClockSeries.GetEditorClass: String;
begin
  result:='TClockEditor';
end;

function TClockSeries.CountLegendItems: Integer;
begin
  result:=1;
end;

function TClockSeries.LegendItemColor(LegendIndex: Integer): TColor;
begin
  result:=clNone;
end;

function TClockSeries.LegendString(LegendIndex: Integer;
  LegendTextStyle: TLegendTextStyle): String;
begin
  result:=TimeToStr(ClockTime);
end;

initialization
  RegisterTeeSeries( TWindRoseSeries, {$IFNDEF CLR}@{$ENDIF}TeeMsg_GalleryWindRose,
                                      {$IFNDEF CLR}@{$ENDIF}TeeMsg_GallerySamples, 1 );
  RegisterTeeSeries( TClockSeries, {$IFNDEF CLR}@{$ENDIF}TeeMsg_GalleryClock,
                                   {$IFNDEF CLR}@{$ENDIF}TeeMsg_GallerySamples, 1 );
finalization
  UnRegisterTeeSeries([ TWindRoseSeries, TClockSeries ]);
end.

⌨️ 快捷键说明

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