
Defect ID : 5607
Headline : [FGP Temporal] [TChartPro] Performance issue with the nearest point tool

How can we obtain best performances using nearest tool and many points in series?

Best Regards
Gerald
Code: Select all
procedure TForm1.Button1Click(Sender: TObject);
begin
self.Series1.FillSampleValues(strtoint(Edit1.Text));
ChartTool1.FullRepaint:=false;
end;
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
![]() ![]() ![]() ![]() ![]() ![]() |
Instructions - How to post in this forum |
Yes, Nearest Point tool searches points from beginning to the end. I've added your request to our wish-list for series ordered in ascending or descending mode.SteveP wrote:I ahve not looked in the source code, but does the Nearest Point tool always begin its search from the beginning or end of the data array ? If not, it might be faster to begin from the previous nearest point index and search away from that in both directions. This assumes linearity in values.
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
![]() ![]() ![]() ![]() ![]() ![]() |
Instructions - How to post in this forum |
Code: Select all
class Function TNearestTool.GetNearestPoint(Series:TChartSeries; X,Y:Integer; IncludeNulls:Boolean):Integer;
var t : Integer;
Dif : Integer;
Dist : Integer;
tmpMin : Integer;
tmpMax : Integer;
tmpX : Integer;
tmpY : Integer;
tmpZList : TChartValueList;
tmpZ : Integer;
begin
result:=-1;
Dif:=10000;
if TeeGetFirstLastSeries(Series,tmpMin,tmpMax) then
begin
tmpZList:=Series.GetYValueList('Z'); // 7.0
for t:=tmpMin to tmpMax do { <-- traverse all points in a Series... }
if IncludeNulls or (not Series.IsNull(t)) then // 7.0
begin
{ calculate position in pixels }
tmpX:=Series.CalcXPos(t);
tmpY:=Series.CalcYPos(t);
if Series.HasZValues then
begin
tmpZ:=Series.ParentChart.Axes.Depth.CalcPosValue(tmpZList.Value[t]);
with Series.ParentChart.Canvas.Calculate3DPosition(tmpX,tmpY,tmpZ) do
begin
tmpX:=X;
tmpY:=Y;
end;
end;
if PointInRect(Series.ParentChart.ChartRect,tmpX,tmpY) then { 5.01 }
begin
{ calculate distance in pixels... }
Dist:=Round(TeeDistance(X-tmpX,Y-tmpY));
if Dist<Dif then { store if distance is lower... }
begin
Dif:=Dist;
result:=t; { <-- set this point to be the nearest... }
end;
end;
end;
end;
end;
procedure TNearestTool.ChartMouseEvent(AEvent: TChartMouseEvent;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
inherited;
if (AEvent=cmeMove) and Assigned(Series) then
begin
if not FullRepaint then PaintHint;
Point:=GetNearestPoint(Series,X,Y);
IMouse:=TeePoint(x,y);
if not FullRepaint then PaintHint;
if Assigned(FOnChange) then FOnChange(Self);
if FullRepaint then Repaint;
end;
end;
I have tried this solution and effectively performances are highly improved. But in this case, the circle around focused point is not painted. In our application, we always need a black circle around nearest point. So, do you have another solution to propose?
Code: Select all
procedure TForm1.FormCreate(Sender: TObject);
begin
Series1.FillSampleValues(10000);
With ChartTool1 do
begin
FullRepaint:=false;
Pen.Color:=clBlack;
end;
end;
As I already told to SteveP, I've added the request to our wish-list to be enhanced for future releases. In the meantime, you can also FullRepaint=false.Narcis, Does Steema expects to deliver a new release fixing this performance defect?
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
![]() ![]() ![]() ![]() ![]() ![]() |
Instructions - How to post in this forum |
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
![]() ![]() ![]() ![]() ![]() ![]() |
Instructions - How to post in this forum |
9336299 wrote:Thanks SteveP,
You are right. I have looked in source code TNearestTool.GetNearestPoint and TNearestTool.ChartMouseEvent and it seems that search is always performed from beginning to end of series each time user moves mouse in chart. It is not acceptable for performance when we have more than 20000 data in series. Moreover, search algorithm in GetNearestPoint is basic. Why this GetNearestPoint method does not use a dichotomy search algorithm or more advanced search algorithm? Algorithm may be different for each kind of series to improve performance in different cases.
Narcis, Does Steema expects to deliver a new release fixing this performance defect?Code: Select all
class Function TNearestTool.GetNearestPoint(Series:TChartSeries; X,Y:Integer; IncludeNulls:Boolean):Integer; var t : Integer; Dif : Integer; Dist : Integer; tmpMin : Integer; tmpMax : Integer; tmpX : Integer; tmpY : Integer; tmpZList : TChartValueList; tmpZ : Integer; begin result:=-1; Dif:=10000; if TeeGetFirstLastSeries(Series,tmpMin,tmpMax) then begin tmpZList:=Series.GetYValueList('Z'); // 7.0 for t:=tmpMin to tmpMax do { <-- traverse all points in a Series... } if IncludeNulls or (not Series.IsNull(t)) then // 7.0 begin { calculate position in pixels } tmpX:=Series.CalcXPos(t); tmpY:=Series.CalcYPos(t); if Series.HasZValues then begin tmpZ:=Series.ParentChart.Axes.Depth.CalcPosValue(tmpZList.Value[t]); with Series.ParentChart.Canvas.Calculate3DPosition(tmpX,tmpY,tmpZ) do begin tmpX:=X; tmpY:=Y; end; end; if PointInRect(Series.ParentChart.ChartRect,tmpX,tmpY) then { 5.01 } begin { calculate distance in pixels... } Dist:=Round(TeeDistance(X-tmpX,Y-tmpY)); if Dist<Dif then { store if distance is lower... } begin Dif:=Dist; result:=t; { <-- set this point to be the nearest... } end; end; end; end; end; procedure TNearestTool.ChartMouseEvent(AEvent: TChartMouseEvent; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin inherited; if (AEvent=cmeMove) and Assigned(Series) then begin if not FullRepaint then PaintHint; Point:=GetNearestPoint(Series,X,Y); IMouse:=TeePoint(x,y); if not FullRepaint then PaintHint; if Assigned(FOnChange) then FOnChange(Self); if FullRepaint then Repaint; end; end;
Regards
Gerald
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
![]() ![]() ![]() ![]() ![]() ![]() |
Instructions - How to post in this forum |