Search code examples
delphiteechart

TeeChart Series OnMouseEnter event


I am using the version of TeeChart that ships with Rad Studio XE3.

TeeChart provides a TChartSeries event which fires when the mouse pointer moves over a series line. I use this event to display the name of the series under the pointer.

The problem is, give a series line 1 pixel wide, it’s difficult to get the pointer exactly over the line. Is there some way to add ‘padding’ to the event so it fires X number of pixels to each side of the line?

Or is there some other way to accomplish this?


Solution

  • I'm adding a new property to Line (TLineSeries) and FastLine (TFastLineSeries) classes to accomplish this.

    Series1.ClickTolerance := 4;   // <-- number of pixels around mouse XY
    

    The default value is zero (mouse XY should be exactly over the line), like the current behavior.

    As a workaround, if you are using TLineSeries, pointers can be displayed at line point positions, and the internal "clicked" function will consider pointer size:

    Series1.Pointer.Visible:=True;
    

    And for more custom control, the code below is very similar to the internal code use to detect mouse clicks. The Tolerance constant specifies the number of extra pixels to consider "in the line".

    procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    
    const
      Tolerance=4;
    
    var Clicked,
        t : Integer;
        Position,
        P,Old : TPoint;
    begin
      Clicked:= -1;
    
      Position.X:=X;
      Position.Y:=Y;
    
      for t:=Series1.FirstValueIndex to Series1.LastValueIndex do
      begin
        P.X:=Series1.CalcXPos(t);
        P.Y:=Series1.CalcYPos(t);
    
        if t>Series1.FirstValueIndex then
           if PointInLine(Position,P.X,P.Y,Old.X,Old.Y,Tolerance) then
           begin
             Clicked:=t;
             break;
           end;
    
        Old:=P;
      end;
    
      if Clicked = -1 then
         Caption:=''
      else
         Caption:=IntToStr(Clicked);
    end;