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.
<code lang="pascal">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;</code>