📄 teegauges.pas
字号:
{*********************************************}
{ TeeChart Gauge Series Types }
{ Copyright (c) 2002-2004 by David Berneda }
{ All Rights Reserved }
{*********************************************}
unit TeeGauges;
{$I TeeDefs.inc}
interface
uses {$IFNDEF LINUX}
Windows,
{$ENDIF}
{$IFDEF CLX}
Types,
{$ENDIF}
Classes,
{$IFDEF CLR}
Types,
{$ENDIF}
Series, TeEngine;
const TeeHandDistance=30; // default pixels distance from center to labels
type
THandStyle=(hsLine,hsTriangle);
TGaugeSeries=class(TCircledSeries)
private
FAngle : Double;
FCenter : TSeriesPointer;
FDistance : Integer;
FEndPoint : TSeriesPointer;
FFullRepaint : Boolean;
FMax : Double;
FMin : Double;
FMinorDistance : Integer;
FStyle : THandStyle;
FOnChange: TNotifyEvent;
ICenter : TPoint;
FLabelsInside: Boolean;
procedure CalcLinePoints(var P0,P1:TPoint);
Function CalcPoint(const Angle:Double; Center:TPoint;
const RadiusX,RadiusY:Double):TPoint;
procedure DrawValueLine;
procedure SetAngle(const Value: Double);
procedure SetCenter(const Value: TSeriesPointer);
procedure SetDistance(const Value: Integer);
procedure SetMax(const AValue: Double);
procedure SetMin(const AValue: Double);
procedure SetStyle(const Value: THandStyle);
procedure SetValue(const AValue: Double);
procedure SetFullRepaint(const Value: Boolean);
function GetValue: Double;
procedure SetEndPoint(const Value: TSeriesPointer);
function SizePointer(APointer:TSeriesPointer):Integer;
procedure SetMinorDistance(const Value: Integer);
procedure SetLabelsInside(const Value: Boolean);
protected
Procedure AddSampleValues(NumValues:Integer; OnlyMandatory:Boolean=False); override;
procedure DrawAllValues; override;
Procedure GalleryChanged3D(Is3D:Boolean); override;
class Function GetEditorClass:String; override;
Procedure NotifyNewValue(Sender:TChartSeries; ValueIndex:Integer); override; // 7.0
Procedure PrepareForGallery(IsEnabled:Boolean); override;
Procedure SetParentChart(Const Value:TCustomAxisPanel); override;
public
Constructor Create(AOwner:TComponent); override;
Destructor Destroy; override;
function Axis:TChartAxis;
Function Clicked(x,y:Integer):Integer; override;
Function NumSampleValues:Integer; override;
function MaxYValue:Double; override;
function MinYValue:Double; override;
published
property Center:TSeriesPointer read FCenter write SetCenter;
property Circled default True;
property CircleGradient;
property EndPoint:TSeriesPointer read FEndPoint write SetEndPoint;
property FullRepaint:Boolean read FFullRepaint write SetFullRepaint default False;
property Maximum:Double read FMax write SetMax;
property Minimum:Double read FMin write SetMin;
property MinorTickDistance:Integer read FMinorDistance write SetMinorDistance default 0;
property HandDistance:Integer read FDistance write SetDistance default TeeHandDistance;
property HandStyle:THandStyle read FStyle write SetStyle default hsLine;
property LabelsInside:Boolean read FLabelsInside write SetLabelsInside default True;
property RotationAngle default 135;
property ShowInLegend default False;
property TotalAngle:Double read FAngle write SetAngle;
property Value:Double read GetValue write SetValue;
{ events }
property OnChange:TNotifyEvent read FOnChange write FOnChange;
end;
implementation
uses {$IFDEF CLR}
Graphics,
Math,
SysUtils,
{$ELSE}
{$IFDEF CLX}
QGraphics,
{$ELSE}
Graphics,
{$ENDIF}
SysUtils, Math,
{$ENDIF}
Chart, TeCanvas, TeeProcs, TeeConst, TeeProCo;
{ TGaugeSeries }
constructor TGaugeSeries.Create(AOwner: TComponent);
begin
inherited;
FDistance:=TeeHandDistance;
Circled:=True;
ShowInLegend:=False;
FLabelsInside:=True;
FCenter:=TSeriesPointer.Create(Self);
with FCenter do
begin
Brush.Style:=bsSolid;
Color:=clBlack;
Style:=psCircle;
HorizSize:=8;
VertSize:=8;
Gradient.Visible:=True;
end;
FEndPoint:=TSeriesPointer.Create(Self);
with FEndPoint do
begin
Brush.Style:=bsSolid;
Color:=clWhite;
Style:=psCircle;
HorizSize:=3;
VertSize:=3;
Visible:=False;
end;
Add(0);
Maximum:=100;
TotalAngle:=90;
RotationAngle:=135;
end;
destructor TGaugeSeries.Destroy;
begin
FEndPoint.Free;
FCenter.Free;
inherited;
end;
Function TGaugeSeries.CalcPoint(const Angle:Double; Center:TPoint;
const RadiusX,RadiusY:Double):TPoint;
var tmpSin,
tmpCos : Extended;
begin
SinCos(Angle,tmpSin,tmpCos);
result.X:=Center.X-Round(RadiusX*tmpCos);
result.Y:=Center.Y-Round(RadiusY*tmpSin);
end;
procedure TGaugeSeries.DrawAllValues;
Procedure DrawAxis;
var P3,P4 : TPoint;
tmpR : TRect;
begin
ParentChart.Canvas.AssignVisiblePen(Axis.Axis);
P3:=CalcPoint(TeePiStep*RotationAngle,ICenter,CircleWidth,CircleHeight);
P4:=CalcPoint(TeePiStep*(360-TotalAngle+RotationAngle),ICenter,CircleWidth,CircleHeight);
tmpR:=ParentChart.ChartRect;
if Circled then
with ParentChart do
begin
if ChartWidth>ChartHeight then
begin
tmpR.Left:=ChartXCenter-(ChartHeight div 2);
tmpR.Right:=ChartXCenter+(ChartHeight div 2);
end
else
begin
tmpR.Top:=ChartYCenter-(ChartWidth div 2);
tmpR.Bottom:=ChartYCenter+(ChartWidth div 2);
end;
end;
with tmpR do
ParentChart.Canvas.Arc(Left+1,Top+1,Right,Bottom,P3.x,P3.y,P4.x,P4.y);
end;
var
tmpStep2 : Double;
IRange : Double;
tmpXRad : Double;
tmpYRad : Double;
procedure DrawMinorTicks(const Value:Double);
var t : Integer;
tmp : Double;
tmpValue : Double;
begin
for t:=1 to Axis.MinorTickCount do
begin
tmpValue:=(Value+t*tmpStep2);
if tmpValue>Maximum then break
else
begin
tmp:=TotalAngle-(tmpValue*TotalAngle/IRange);
tmp:=TeePiStep*(360-tmp+RotationAngle);
ParentChart.Canvas.Line( CalcPoint(tmp,ICenter,tmpXRad,tmpYRad),
CalcPoint(tmp,ICenter,XRadius-MinorTickDistance,YRadius-MinorTickDistance));
end;
end;
end;
var tmp : Double;
tmpAngle : Double;
tmpSin,
tmpCos : Extended;
tmpS : String;
tmpValue,
tmpStep : Double;
tmpFontH : Integer;
P3 : TPoint;
P4 : TPoint;
begin
ICenter.X:=CircleXCenter;
ICenter.Y:=CircleYCenter;
IRange:=Maximum-Minimum;
tmpStep:=Axis.Increment;
if tmpStep=0 then tmpStep:=10;
if CircleGradient.Visible then
DrawCircleGradient;
// center
if FCenter.Visible then
begin
FCenter.PrepareCanvas(ParentChart.Canvas,FCenter.Color);
FCenter.Draw(ICenter);
end;
with ParentChart,Canvas do
begin
// ticks and labels
if Axis.Ticks.Visible or Axis.Labels then
begin
AssignFont(Axis.Items.Format.Font);
AssignVisiblePen(Axis.Ticks);
BackMode:=cbmTransparent;
tmpXRad:=(XRadius-Axis.TickLength);
tmpYRad:=(YRadius-Axis.TickLength);
tmpFontH:=FontHeight;
if tmpStep<>0 then
begin
tmpValue:=Minimum;
repeat
tmp:=TotalAngle-(tmpValue*TotalAngle/IRange);
tmpAngle:=360-tmp+RotationAngle;
tmp:=TeePiStep*tmpAngle;
P3:=CalcPoint(tmp,ICenter,tmpXRad,tmpYRad);
P4:=CalcPoint(tmp,ICenter,XRadius,YRadius);
if Axis.Ticks.Visible then Line(P3,P4);
if Axis.Labels then
begin
tmpS:=FormatFloat(ValueFormat,tmpValue);
if not LabelsInside then
P3:=CalcPoint(tmp,ICenter,XRadius+tmpFontH,YRadius+tmpFontH);
Dec(P3.x,Round(TextWidth(tmpS)*0.5));
if LabelsInside then // 7.0
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -