Oh, I was not aware of this. It is because the "NearestGraphPoint" is calculated back from the screen pixels of the data point which leads to some inaccuracies. I don't know why it is made like this, probably because the corresponding TDataPointTool method is very general and must work also for series which do not require discrete listed data (such as TFuncSeries).
A better way is to directly read the x,y values from the series or the chart source. If your data are stored in the internal listsource of the lineseries you can simply call ser.XValue[index] and ser.YValue[index] where index is the series point index returned by ther chart tool (ser.PointIndex):
procedure TForm1.ChartToolset1DataPointHintTool1Hint(ATool: TDataPointHintTool;
const APoint: TPoint; var AHint: String);
var
ser: TLineSeries;
index: Integer;
begin
if (ATool = nil) or (ATool.Series = nil) then
AHint := ''
else begin
ser := TLineSeries(ATool.Series);
index := ATool.PointIndex;
AHint := Format('Series "%s":' + LineEnding + ' x = %.3f' + LineEnding + ' y = %.3f',
[ser.Title, ser.XValue[index], ser.YValue[index] ]);
end;
end;
If data are provided by an external chartsource you query them from there, again ATool.PointIndex is the index of the data point.
You wrote somewhere that you have the data in an array. Then you probably use a TUserDefinedChartSource to link to array to the series. In this case you can call the OnGetChartDataItem event handler to find the x,y values.