Some time ago, we wrote a post about using Delphi Gestures with TeeChart. It covered 3D Charts and showed how we can use TGestureManager to modify ZoomFloat
, ElevationFloat
and RotationFloat
properties of the TChart
.
This technique still works perfectly nowadays and the same concept can be applied to 2D charts. We just need to modify the Axes scales instead of the Aspect.
As before, you just need to associate the TGestureManager
to TChart
’s Touch property. Then, enable Zoom, Pan and DoubleTap interactive gestures on it and implement of TChart
‘s OnGesture event.
uses System.Math, FMXTee.Series;
procedure TForm1.FormCreate(Sender: TObject);
var Series1: TLineSeries;
begin
Chart1.View3D:=False;
Chart1.Legend.Hide;
Chart1.Color:=clWhite;
Chart1.Gradient.Visible:=False;
Chart1.Walls.Back.Color:=clWhite;
Chart1.Walls.Back.Gradient.Visible:=False;
Chart1.Hover.Hide;
Chart1.AllowZoom:=False;
Chart1.AllowPanning:=pmNone;
Series1:=TLineSeries(Chart1.AddSeries(TLineSeries));
Series1.FillSampleValues;
end;
procedure TForm1.Chart1Gesture(Sender: TObject;
const EventInfo: TGestureEventInfo; var Handled: Boolean);
begin
if EventInfo.GestureID = igiZoom then
handleZoom(EventInfo)
else if EventInfo.GestureID = igiPan then
handlePan(EventInfo)
else if EventInfo.GestureID = igiDoubleTap then
handleDoubleTap(EventInfo);
Handled:=True;
end;
procedure TForm1.handleZoom(EventInfo: TGestureEventInfo);
var
LObj: IControl;
chart: TChart;
diff: Double;
xZoom, yZoom: Double;
begin
LObj:=Self.ObjectAtPoint(ClientToScreen(EventInfo.Location));
if LObj is TChart then
begin
if not(TInteractiveGestureFlag.gfBegin in EventInfo.Flags) then
begin
chart:=TChart(LObj.GetObject);
chart.Title.Text.Text:=IntToStr(EventInfo.Distance);
diff:=(EventInfo.Distance - FLastDIstance);
XZoom:=chart.Axes.Bottom.CalcPosPoint(0) - chart.Axes.Bottom.CalcPosPoint(Round(Cos(EventInfo.Angle)*diff));
YZoom:=chart.Axes.Left.CalcPosPoint(0) - chart.Axes.Left.CalcPosPoint(Round(Sin(EventInfo.Angle)*diff));
chart.Axes.Bottom.SetMinMax(chart.Axes.Bottom.Minimum-XZoom, chart.Axes.Bottom.Maximum+XZoom);
chart.Axes.Left.SetMinMax(chart.Axes.Left.Minimum-YZoom, chart.Axes.Left.Maximum+YZoom);
end;
end;
FLastDIstance:=EventInfo.Distance;
end;
procedure TForm1.handlePan(eventInfo: TGestureEventInfo);
var
LObj: IControl;
chart: TChart;
XDiff, YDiff: Double;
begin
LObj:=Self.ObjectAtPoint(ClientToScreen(EventInfo.Location));
if LObj is TChart then
begin
if not(TInteractiveGestureFlag.gfBegin in EventInfo.Flags) then
begin
chart:=TChart(LObj.GetObject);
XDiff:=chart.Axes.Bottom.CalcPosPoint(Round(FLastPosition.X)) - chart.Axes.Bottom.CalcPosPoint(Round(EventInfo.Location.X));
chart.Axes.Bottom.SetMinMax(chart.Axes.Bottom.Minimum+XDiff, chart.Axes.Bottom.Maximum+XDiff);
YDiff:=chart.Axes.Left.CalcPosPoint(Round(FLastPosition.Y)) - chart.Axes.Left.CalcPosPoint(Round(EventInfo.Location.Y));
chart.Axes.Left.SetMinMax(chart.Axes.Left.Minimum+YDiff, chart.Axes.Left.Maximum+YDiff);
end;
FLastPosition:=EventInfo.Location;
end;
end;
procedure TForm1.handleDoubleTap(eventInfo: TGestureEventInfo);
var
LObj: IControl;
begin
LObj:=Self.ObjectAtPoint(ClientToScreen(EventInfo.Location));
if LObj is TChart then
ResetChart(TChart(LObj.GetObject));
end;
procedure TForm1.ResetChart(chart: TChart);
begin
chart.Axes.Bottom.Automatic:=True;
chart.Axes.Left.Automatic:=True;
end;