1

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?

Yeray
  • 5,009
  • 1
  • 13
  • 25
casterle
  • 1,037
  • 2
  • 12
  • 27

2 Answers2

4

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;
David Berneda
  • 490
  • 5
  • 9
  • Thanks, David, worked perfectly. Will there be an update to the version that ships with XE3? – casterle Apr 17 '13 at 13:27
  • I'd really appreciate if you would you please take a look at the question below (in the next comment). I've been trying to get this to work for some time and I'm running out of time. – casterle Apr 19 '13 at 18:29
  • Finally, how do those of us who use the version of TeeChart bundled with Rad Studio XE3 get support and updates? – casterle Apr 19 '13 at 18:33
  • I'm trying to figure out how to do this regardless of whether the mouse pointer is over a series line or not. I'd like to draw a vertical line wherever the mouse is pointed, but it currently only works if the mouse is directly over a series line. How would I make `OnMouseMove` trigger for *anywhere* in the chart? – Jerry Dodge Feb 21 '22 at 14:38
1

You can use the PointInLineTolerance function to check it at OnMouseMove event. However, you have to loop the series points manually to transform the series values into pixels and pass them to this function.

uses Series;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.View3D:=false;

  for i:=0 to 5 do
    Chart1.AddSeries(TLineSeries).FillSampleValues;
end;

procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var series, valueIndex: Integer;
    P0, P1: TPoint;
begin
  Chart1.Draw;
  for series:=0 to Chart1.SeriesCount-1 do
    with Chart1[series] do
    for valueIndex:=FirstValueIndex to LastValueIndex-1 do
    begin
      P0.X:=CalcXPos(valueIndex);
      P0.Y:=CalcYPos(valueIndex);
      P1.X:=CalcXPos(valueIndex+1);
      P1.Y:=CalcYPos(valueIndex+1);
      if PointInLineTolerance(Point(X, Y), P0.X, P0.Y, P1.X, P1.Y, 5) then
      begin
        Chart1.Canvas.TextOut(X+5,Y-10,'Series ' + IntToStr(series));
        exit;
      end;
    end;
end;
Yeray
  • 5,009
  • 1
  • 13
  • 25