📄 teetools.pas
字号:
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;
TRectangleTool=class(TAnnotationTool)
private
FOnDragging : TNotifyEvent;
FOnResizing : TNotifyEvent;
P : TPoint;
IDrag : Boolean;
IEdge : Integer;
protected
Procedure ChartMouseEvent( AEvent: TChartMouseEvent;
Button:TMouseButton;
Shift: TShiftState; X, Y: Integer); override;
public
Constructor Create(AOwner:TComponent); override;
Function Bitmap(ChartOnly:Boolean=False):TBitmap;
Function ClickedEdge(x,y:Integer):Integer;
class Function Description:String; override;
published
property OnDragging:TNotifyEvent read FOnDragging write FOnDragging;
property OnResizing:TNotifyEvent read FOnResizing write FOnResizing;
end;
TClipSeriesTool=class(TTeeCustomToolSeries)
private
IActive : Boolean;
procedure AddClip(Sender: TObject);
procedure RemoveClip(Sender: TObject);
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure SetSeries(const Value: TChartSeries); override;
public
class Function Description:String; override;
published
property Active;
property Series;
end;
implementation
Uses {$IFDEF CLX}
QForms,
{$ELSE}
Forms,
{$ENDIF}
Math, TeeConst, TeeProCo;
{ TCursorTool }
Constructor TCursorTool.Create(AOwner:TComponent);
begin
inherited;
FClick:=TeeClickTolerance;
FStyle:=cssBoth;
IPoint.X:=-1;
IPoint.Y:=-1;
IOldSnap:=-1;
end;
Procedure TCursorTool.CalcValuePositions(X,Y:Integer);
begin
if UseSeriesZ then
ParentChart.Canvas.Calculate2DPosition(x,y,Z);
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;
Function TCursorTool.Z:Integer;
begin
if UseSeriesZ and Assigned(Series) then
result:=Series.StartZ
else
result:=0;
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,Z)
else DoHorizLine(R.Left,R.Right,Y);
end;
Procedure DrawVertical;
begin
With ParentChart.Canvas do
if Draw3D then VertLine3D(X,R.Top,R.Bottom,Z)
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;
DrawCursorLines(ParentChart.View3D,GetAxisRect,IPoint.X,IPoint.Y);
Pen.Mode:=pmCopy;
ParentChart.Canvas.Invalidate;
end;
end;
end;
Function TCursorTool.InAxisRectangle(x,y:Integer):Boolean;
begin
if UseSeriesZ then
ParentChart.Canvas.Calculate2DPosition(x,y,Z);
result:=PointInRect(GetAxisRect,x,y);
end;
Procedure TCursorTool.ChartMouseEvent( AEvent: TChartMouseEvent;
Button:TMouseButton;
Shift: TShiftState; X, Y: Integer);
Procedure MouseMove;
var tmpSnap : Integer;
tmp : TCursorClicked;
begin
{ if mouse button is pressed and dragging then... }
if ((IDragging<>ccNone) or FollowMouse) and InAxisRectangle(X,Y) then
begin
RedrawCursor; { hide the cursor }
CalcValuePositions(X,Y);
tmpSnap:=SnapToPoint; { snap to the nearest point of SnapSeries }
{ draw again the cursor at the new position }
CalcScreenPositions;
RedrawCursor;
Changed(tmpSnap);
if Assigned(FOnSnapChange) and (IOldSnap<>tmpSnap) then // 7.0
FOnSnapChange(Self,IPoint.X,IPoint.Y,IXValue,IYValue,Series,tmpSnap);
IOldSnap:=tmpSnap;
end
else
begin { mouse button is not pressed, user is not dragging the cursor }
{ change the mouse cursor when passing over the Cursor }
tmp:=Clicked(x,y);
case tmp of
ccHorizontal : ParentChart.Cursor:=crVSplit;
ccVertical : ParentChart.Cursor:=crHSplit;
ccBoth : ParentChart.Cursor:=crSizeAll;
end;
ParentChart.CancelMouse:=tmp<>ccNone;
end;
end;
begin
Case AEvent of
cmeUp: IDragging:=ccNone;
cmeMove: MouseMove;
cmeDown: if not FFollowMouse then
begin
IDragging:=Clicked(x,y);
if IDragging<>ccNone then ParentChart.CancelMouse:=True;
end;
end;
end;
Function TCursorTool.Clicked(x,y:Integer):TCursorClicked;
var tmp : TPoint;
begin
result:=ccNone;
if InAxisRectangle(x,y) then
begin
tmp:=IPoint;
if UseSeriesZ then
ParentChart.Canvas.Calculate2DPosition(x,y,Z);
if (FStyle=cssBoth) and (Abs(Y-tmp.Y)<=ClickTolerance)
and (Abs(X-tmp.X)<=ClickTolerance) then
result:=ccBoth
else
if ((FStyle=cssHorizontal) or (FStyle=cssBoth))
and (Abs(Y-tmp.Y)<=ClickTolerance) then
result:=ccHorizontal
else
if ((FStyle=cssVertical) or (FStyle=cssBoth))
and (Abs(X-tmp.X)<=ClickTolerance) then
result:=ccVertical
end;
end;
Procedure TCursorTool.SetStyle(Value:TCursorToolStyle);
begin
if FStyle<>Value then
begin
FStyle:=Value;
SnapToPoint;
Repaint;
end;
end;
procedure TCursorTool.SetSeries(const Value: TChartSeries);
begin
inherited;
IOldSnap:=-1;
if Assigned(Series) and (not (csLoading in ComponentState)) then
begin
SnapToPoint;
Repaint;
end;
end;
procedure TCursorTool.ChartEvent(AEvent: TChartToolEvent);
begin
inherited;
if (AEvent=cteAfterDraw) then
begin
CalcScreenPositions;
RedrawCursor;
end;
end;
procedure TCursorTool.SetXValue(const Value: Double);
begin
if IXValue<>Value then
begin
IXValue:=Value;
IOldSnap:=-1;
DoChange;
end;
end;
procedure TCursorTool.DoChange;
begin
CalcScreenPositions;
Changed(-1);
Repaint;
end;
procedure TCursorTool.SetYValue(const Value: Double);
begin
if IYValue<>Value then
begin
IYValue:=Value;
IOldSnap:=-1;
DoChange;
end;
end;
procedure TCursorTool.SetUseChartRect(const Value: Boolean);
begin
SetBooleanProperty(FUseChartRect,Value);
end;
procedure TCursorTool.SetUseSeriesZ(const Value: Boolean);
begin
SetBooleanProperty(FUseSeriesZ,Value);
end;
{ TDragMarksTool }
class function TDragMarksTool.Description: String;
begin
result:=TeeMsg_DragMarksTool;
end;
Procedure TDragMarksTool.ChartMouseEvent( AEvent: TChartMouseEvent;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -