📄 chart.pas
字号:
Begin { scroll down ASeries in SeriesList. This changes the Z order }
t:=SeriesList.IndexOf(ASeries);
if t<SeriesCount-1 then ExchangeSeries(t,t+1);
end;
Procedure TCustomChart.NextPage;
Begin
if (MaxPointsPerPage>0) and (Page<NumPages) then Page:=Page+1;
End;
Procedure TCustomChart.PreviousPage;
Begin
if (MaxPointsPerPage>0) and (Page>1) then Page:=Page-1;
End;
Procedure TCustomChart.RemoveAllSeries;
Begin
While SeriesCount>0 do RemoveSeries(Series[0]);
End;
Procedure TCustomChart.DoZoom(Const topi,topf,boti,botf,lefi,leff,rigi,rigf:Double);
Procedure DoZoomAnimated;
Procedure ZoomAxis(AAxis:TChartAxis; Const tmpA,tmpB:Double);
Begin { apply a portion of the desired zoom to achieve animation }
with AAxis do
SetMinMax(Minimum+((tmpA-Minimum)/AnimatedZoomFactor),
Maximum-((Maximum-tmpB)/AnimatedZoomFactor));
end;
Var t : Integer;
begin
for t:=1 to Zoom.AnimatedSteps-1 do
begin
ZoomAxis(LeftAxis,Lefi,Leff);
ZoomAxis(RightAxis,Rigi,Rigf);
ZoomAxis(TopAxis,Topi,Topf);
ZoomAxis(BottomAxis,Boti,Botf);
Refresh; // force repaint
// OnAnimatedZoom event ?
end;
end;
Begin
if RestoredAxisScales then
begin
FSavedScales:=SaveScales;
RestoredAxisScales:=False;
end;
if Zoom.Animated then DoZoomAnimated; { animation... }
{ final zoom }
LeftAxis.SetMinMax(Lefi,Leff);
RightAxis.SetMinMax(Rigi,Rigf);
TopAxis.SetMinMax(Topi,Topf);
BottomAxis.SetMinMax(Boti,Botf);
Zoomed:=True;
if Assigned(FOnZoom) then FOnZoom(Self);
end;
Procedure TCustomChart.ZoomRect(Const Rect:TRect);
Begin
With Zoom do
Begin
X0:=Rect.Left;
Y0:=Rect.Top;
X1:=Rect.Right;
Y1:=Rect.Bottom;
CalcZoomPoints;
end;
End;
Procedure TCustomChart.ZoomPercent(Const PercentZoom:Double);
Procedure CalcAxisScale(Axis:TChartAxis; Var tmpA,tmpB:Double);
Var tmpDelta : Double;
AMin : Double;
AMax : Double;
Begin
AMin:=Axis.Minimum;
AMax:=Axis.Maximum;
Axis.CalcMinMax(AMin,AMax);
tmpDelta:=(AMax-AMin)*(PercentZoom-100.0)*0.01;
tmpA:=AMin+tmpDelta;
tmpB:=AMax-tmpDelta;
end;
var Lefi : Double;
Leff : Double;
Rigi : Double;
Rigf : Double;
Topi : Double;
Topf : Double;
Boti : Double;
Botf : Double;
Begin { zoom a given "percent" }
CalcAxisScale(LeftAxis,Lefi,Leff);
CalcAxisScale(RightAxis,Rigi,Rigf);
CalcAxisScale(TopAxis,Topi,Topf);
CalcAxisScale(BottomAxis,Boti,Botf);
DoZoom(Topi,Topf,Boti,Botf,Lefi,Leff,Rigi,Rigf);
Repaint;
end;
Procedure TCustomChart.CalcClickedPart(Pos:TPoint; Var Part:TChartClickedPart);
begin
Part:=CalcNeedClickedPart(Pos,False);
end;
Function TCustomChart.CalcNeedClickedPart(Pos:TPoint; Needed:Boolean):TChartClickedPart;
Procedure ClickedAxis(Axis:TChartAxis);
begin
if Axis.Clicked(Pos.x,Pos.y) then
begin
result.Part:=cpAxis;
result.AAxis:=Axis;
end;
end;
var t : Integer;
begin
With result do
begin
Part:=cpNone;
PointIndex:=-1;
ASeries:=nil;
AAxis:=nil;
if Legend.Visible then
begin
PointIndex:=Legend.Clicked(Pos.X,Pos.Y);
if PointIndex<>-1 then
begin
Part:=cpLegend;
Exit;
end;
end;
{ IMPORTANT: Z order inverted }
for t:=SeriesCount-1 downto 0 do
With Self.Series[t] do
if Active and
((not Needed) or
( Assigned(OnClick) or Assigned(OnDblClick) or
Assigned(FOnClickSeries))) then
Begin
PointIndex:=Clicked(Pos.X,Pos.Y);
if PointIndex<>-1 then
begin
ASeries:=Series[t];
Part:=cpSeries;
Exit;
end;
if Marks.Visible then
begin
PointIndex:=Marks.Clicked(Pos.X,Pos.Y);
if PointIndex<>-1 then
begin
ASeries:=Series[t];
Part:=cpSeriesMarks;
Exit;
end;
end;
end;
for t:=0 to Axes.Count-1 do
begin
ClickedAxis(Axes[t]);
if Part=cpAxis then Exit;
end;
if Title.Clicked(Pos.X,Pos.Y) then Part:=cpTitle
else
if SubTitle.Clicked(Pos.X,Pos.Y) then Part:=cpSubTitle
else
if Foot.Clicked(Pos.X,Pos.Y) then Part:=cpFoot
else
if SubFoot.Clicked(Pos.X,Pos.Y) then Part:=cpSubFoot
else
if PointInRect(ChartRect,Pos.X,Pos.Y) and { <-- should be PtInCube(ChartRect,0,MaxZ) }
(CountActiveSeries>0) then
Part:=cpChartRect;
end;
end;
Function TCustomChart.AxisTitleOrName(Axis:TChartAxis):String;
Begin
result:=Axis.Title.Caption;
if result='' then
begin
if Axis=DepthAxis then result:=TeeMsg_DepthAxis
else
With Axis do
if Horizontal then
if OtherSide then result:=TeeMsg_TopAxis
else result:=TeeMsg_BottomAxis
else
if OtherSide then result:=TeeMsg_RightAxis
else result:=TeeMsg_LeftAxis;
end;
end;
type TToolAccess=class(TTeeCustomTool);
procedure TCustomChart.BroadcastMouseEvent(AEvent:TChartMouseEvent;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var t : Integer;
begin
for t:=0 to Tools.Count-1 do
With TToolAccess(Tools[t]) do
if Active then
begin
ChartMouseEvent(AEvent,Button,Shift,X,Y);
if CancelMouse then break;
end;
end;
procedure TCustomChart.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var IClicked : Boolean;
Procedure CheckZoomPanning;
Begin
if ActiveSeriesUseAxis then
begin
if Zoom.Allow and (Button=Zoom.MouseButton) and
(Zoom.KeyShift<=Shift) then
Begin
if Zoom.Direction=tzdVertical then x:=ChartRect.Left;
if Zoom.Direction=tzdHorizontal then y:=ChartRect.Top;
Zoom.Activate(x,y);
if Zoom.Direction=tzdVertical then Zoom.X1:=ChartRect.Right;
if Zoom.Direction=tzdHorizontal then Zoom.Y1:=ChartRect.Bottom;
DrawZoomRectangle;
IClicked:=True;
end;
if (AllowPanning<>pmNone) and (Button=FScrollMouse) and
(TeeScrollKeyShift<=Shift ) then
Begin
IPanning.Activate(x,y);
IClicked:=True;
end;
// was: crDefault; { <-- todo: ScrollCursor:=crHandPoint }
if IClicked then Cursor:=OriginalCursor; // 6.0
end;
end;
Procedure CheckBackground;
begin
if Assigned(FOnClickBackground) then
begin
CancelMouse:=True;
FOnClickBackGround(Self,Button,Shift,x,y);
IClicked:=CancelMouse;
end;
end;
Procedure CheckTitle(ATitle:TChartTitle);
begin
if Assigned(FOnClickTitle) then
begin
CancelMouse:=True;
FOnClickTitle(Self,ATitle,Button,Shift,x,y);
IClicked:=CancelMouse;
end;
if not IClicked then CheckZoomPanning;
end;
var tmpPart : TChartClickedPart;
Begin
inherited;
if CancelMouse or Zoom.Active or IPanning.Active then Exit;
CancelMouse:=False;
BroadcastMouseEvent(cmeDown,Button,Shift,X,Y);
if not CancelMouse then
begin
tmpPart:=CalcNeedClickedPart(TeePoint(x,y),True);
IClicked:=False;
Case tmpPart.Part of
cpLegend: begin
IClicked:=FLegend.DoMouseDown(x,y);
if Assigned(FOnClickLegend) then
begin
CancelMouse:=True;
FOnClickLegend(Self,Button,Shift,x,y);
IClicked:=CancelMouse;
end;
end;
cpSeries: Begin
With tmpPart do
begin
CancelMouse:=False;
if ssDouble in Shift then
begin
if Assigned(ASeries.OnDblClick) then
ASeries.OnDblClick(ASeries,PointIndex,Button,Shift,x,y)
end
else
if Assigned(ASeries.OnClick) then
ASeries.OnClick(ASeries,PointIndex,Button,Shift,x,y);
IClicked:=CancelMouse;
end;
if Assigned(FOnClickSeries) then
begin
CancelMouse:=True;
FOnClickSeries(Self,tmpPart.ASeries,tmpPart.PointIndex,Button,Shift,x,y);
IClicked:=CancelMouse;
end;
if not IClicked then CheckZoomPanning;
end;
cpAxis: begin
if Assigned(FOnClickAxis) then
begin
CancelMouse:=True;
FOnClickAxis(Self,TChartAxis(tmpPart.AAxis),Button,Shift,x,y);
IClicked:=CancelMouse;
end;
if not IClicked then CheckZoomPanning;
end;
cpTitle : CheckTitle(Title);
cpFoot : CheckTitle(Foot);
cpSubTitle: CheckTitle(SubTitle);
cpSubFoot : CheckTitle(SubFoot);
cpChartRect : begin
CheckBackground;
if not IClicked then CheckZoomPanning;
end;
end;
if not IClicked then CheckBackground;
end;
CancelMouse:=False;
End;
procedure TCustomChart.MouseMove(Shift: TShiftState; X, Y: Integer);
Procedure ProcessPanning(Axis:TChartAxis; IniPos,EndPos:Integer);
Var Delta : Double;
tmpMin : Double;
tmpMax : Double;
tmpAllowScroll : Boolean;
Begin
With Axis do
begin
Delta:=CalcPosPoint(IniPos)-CalcPosPoint(EndPos);
tmpMin:=Minimum+Delta;
tmpMax:=Maximum+Delta;
end;
tmpAllowScroll:=True;
if Assigned(FOnAllowScroll) then
FOnAllowScroll(TChartAxis(Axis),tmpMin,tmpMax,tmpAllowScroll);
if tmpAllowScroll then Axis.SetMinMax(tmpMin,tmpMax);
end;
Var Panned : Boolean;
Procedure PanAxis(AxisHorizontal:Boolean; Const Pos1,Pos2:Integer);
Var tmpAxis : TChartAxis;
t : Integer;
tmpMode : TPanningMode;
begin
if AxisHorizontal then tmpMode:=pmHorizontal
else tmpMode:=pmVertical;
if (Pos1<>Pos2) and
( (AllowPanning=tmpMode) or (AllowPanning=pmBoth) ) then
Begin
for t:=0 to Axes.Count-1 do
begin
tmpAxis:=Axes[t];
if not tmpAxis.IsDepthAxis then
if (AxisHorizontal and tmpAxis.Horizontal) or
((not AxisHorizontal) and (not tmpAxis.Horizontal)) then
ProcessPanning(tmpAxis,Pos2,Pos1);
end;
Panned:=True;
end;
end;
Begin
inherited;
if not (csDesigning in ComponentState) then
BroadcastMouseEvent(cmeMove,mbLeft,Shift,X,Y);
if not CancelMouse then
With Zoom do { zoom }
if Active then
Begin
if Direction=tzdVertical then x:=ChartRect.Right;
if Direction=tzdHorizontal then y:=ChartRect.Bottom;
if (x<>X1) or (y<>Y1) then
Begin
DrawZoomRectangle;
X1:=x;
Y1:=y;
DrawZoomRectangle;
end;
end
else
With IPanning do { scroll }
if Active then
Begin
if PointInRect(ChartRect,x,y) then
Begin
if (x<>X1) or (y<>Y1) then
Begin
Panned:=False;
Check;
if RestoredAxisScales then
begin
FSavedScales:=SaveScales;
RestoredAxisScales:=False;
end;
PanAxis(True,X,X1);
PanAxis(False,Y,Y1);
X1:=x;
Y1:=y;
if Panned then
Begin
if Assigned(FOnScroll) then FOnScroll(Self);
Invalidate;
end;
End;
end
else IPanning.Active:=False;
end
else
if not CheckMouseSeries(x,y) then { is mouse not over Series ? }
Cursor:=OriginalCursor; { change back original cursor }
end;
Procedure TCustomChart.ScrollVerticalAxes(Up:Boolean);
var t : Integer;
tmp : Double;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -