delphi - TeeChart: Fast way to show series values at current mouse position -


i want show values of series @ current mouse position if cursor on chart. displayed in figure:

target display

to accomplish behavior used tannotationtool , onmousemove event. additionally use tcursortool style := cssvertical , followmouse := true draw vertical line @ current mouve position. unfortunately solution slow. if series count greater 10 user observe annotation run after mouse lag of 500ms. during investigation of issue, found out part of mousemoveevent bottleneck:

chtmain  : tchart;  fvalanno : tannotationtool; ... tfrmmain.chtmainmousemove(sender: tobject; shift: tshiftstate; x, y: integer) var   hasdata : boolean;   annolst : tstrings; begin   ...     if hasdata     self.fvalanno.text := annolst.text   else     self.fvalanno.text := 'no data';   //   if (x < self.chtmain.width - self.fvalanno.width - 5)     self.fvalanno.shape.left := x + 10   else     self.fvalanno.shape.left := x - self.fvalanno.width - 15;   //   if (y < self.chtmain.height - self.fvalanno.height - 5)     self.fvalanno.shape.top := y + 10   else     self.fvalanno.shape.top := y - self.fvalanno.height - 15;   //   if (fx >= self.chtmain.bottomaxis.istartpos) ,     (fx <= self.chtmain.bottomaxis.iendpos) ,     (fy >= self.chtmain.leftaxis.istartpos) ,     (fy <= self.chtmain.leftaxis.iendpos)     self.fvalanno.active := true   else     self.fvalanno.active := false;   ... end; 

if use code above vertical line , annotation run after cursor 500ms @ series count of 100. lag increases higher series count is. on other hand if not use annotation code vertical line run after lag of 100ms.

is there other tool accomplish benaviour faster tchart components? or there properties can play make faster?

thanks in advance support!

edit: example code reproduce issue

  1. create new vcl project
  2. drop tchart component , checkbox on form
  3. create formcreate form , mousemoveevent chart
  4. switch code view insert following code:

code:

unit unit1;  interface  uses   winapi.windows, winapi.messages, system.sysutils, system.variants, system.classes, vcl.graphics,   vcl.controls, vcl.forms, vcl.dialogs, vcltee.teegdiplus,   vcltee.teengine, vcl.extctrls, vcltee.teeprocs, vcltee.chart, vcltee.teetools,   vcl.stdctrls;  type   tform1 = class(tform)     chtmain: tchart;     chkanno: tcheckbox;     procedure formcreate(sender: tobject);     procedure chtmainmousemove(sender: tobject; shift: tshiftstate; x,       y: integer);   private     fcursor : tcursortool;     fanno   : tannotationtool;   public     { public-deklarationen }   end;  var   form1: tform1;  implementation  {$r *.dfm}  uses   vcltee.series,   system.dateutils;  const   arr_maxs : array[0..3] of double = (12.5, 25.8, 2.8, 56.7);  procedure tform1.chtmainmousemove(sender: tobject; shift: tshiftstate; x, y: integer);    function getxvalueindex(const aserie: tchartseries; const ax: double): integer;   var     index: integer;   begin     index := 0 aserie.xvalues.count - 1     begin       if aserie.xvalue[index] >= ax         break;     end;     //     result := index - 1;   end;  var   idx,    : integer;   cursorx,   cursory,   value     : double;   serie     : tchartseries;   legendtxt : string;   annolst   : tstrings;   hasdata   : boolean;   showndate : tdatetime; begin   //   if not self.chkanno.checked   begin     //     fanno.text := format('position:'#13#10'  x: %d'#13#10'  y: %d', [x, y]);   end   else   begin     //     if (self.chtmain.seriescount < 1)     begin       //       if assigned(self.fanno)         self.fanno.active := false;       exit;     end;     //     self.chtmain.series[0].getcursorvalues(cursorx, cursory);     //     annolst := tstringlist.create;     try       //       showndate := 0;       hasdata   := false;       := 0 self.chtmain.seriescount - 1       begin         //         serie := self.chtmain.series[i];         //         idx := getxvalueindex(serie, cursorx);          if serie.xvalue[idx] > showndate         begin           //           legendtxt := datetimetostr(serie.xvalue[idx]);           if (annolst.count > 0) ,             (showndate > 0)             annolst[0] := legendtxt           else if annolst.count > 0             annolst.insert(0, legendtxt)           else             annolst.add(legendtxt);           hasdata   := true;           showndate := serie.xvalue[idx];         end;         //         legendtxt := format('serie: %d', [i]);         if length(legendtxt) <= 25           legendtxt := format('%-25s', [legendtxt])         else           legendtxt := format('%s...', [legendtxt.substring(0, 22)]);         //         value     := serie.yvalue[idx] * abs(arr_maxs[i]);         legendtxt := format('%s: %3.3f %s', [legendtxt, value, 'none']);         annolst.add(legendtxt);       end;        fanno.text := annolst.text;           freeandnil(annolst);     end;   end;    if (x < self.chtmain.width - self.fanno.width - 5)     self.fanno.shape.left := x + 10   else     self.fanno.shape.left := x - self.fanno.width - 15;   //   if (y < self.chtmain.height - self.fanno.height - 5)     self.fanno.shape.top := y + 10   else     self.fanno.shape.top := y - self.fanno.height - 15;   //   if (x >= self.chtmain.bottomaxis.istartpos) ,     (x <= self.chtmain.bottomaxis.iendpos) ,     (y >= self.chtmain.leftaxis.istartpos) ,     (y <= self.chtmain.leftaxis.iendpos)     self.fanno.active := true   else     self.fanno.active := false; end;  procedure tform1.formcreate(sender: tobject); var   idx, j : integer;   serie  : tfastlineseries;   start  : tdatetime;   value  : double; begin   //   self.chtmain.view3d                    := false;   self.chtmain.align                     := alclient;   self.chtmain.backcolor                 := clwhite;   self.chtmain.color                     := clwhite;   self.chtmain.gradient.visible          := false;   self.chtmain.legend.legendstyle        := lsseries;   self.chtmain.zoom.allow                := false;    self.chtmain.allowpanning              := pmnone;     self.chtmain.backwall.color            := clwhite;   self.chtmain.backwall.gradient.visible := false;    self.chtmain.leftaxis.automatic        := false;   self.chtmain.leftaxis.minimum          := 0;   self.chtmain.leftaxis.maximum          := 2;   self.chtmain.leftaxis.increment        := 0.1;   self.chtmain.leftaxis.visible          := true;   self.chtmain.leftaxis.axisvaluesformat := '#,##0.## lv';   //   self.chtmain.bottomaxis.datetimeformat   := 'dd.mm.yyyy hh:mm:ss';   self.chtmain.bottomaxis.increment        := 1 / 6;    self.chtmain.bottomaxis.automatic        := true;   self.chtmain.bottomaxis.labelssize       := 32;   self.chtmain.bottomaxis.labelsmultiline  := true;   self.chtmain.marginbottom                := 6;   self.chtmain.bottomaxis.title.caption    := 'date';   self.chtmain.bottomaxis.visible          := false;     fanno := self.chtmain.tools.add(tannotationtool) tannotationtool;   fanno.active := false;   fanno.shape.customposition := true;    fcursor := self.chtmain.tools.add(tcursortool) tcursortool;   fcursor.followmouse := true;   fcursor.style := cssvertical;    randomize;   start := now;   idx := 0 3   begin     //     serie := self.chtmain.addseries(tfastlineseries) tfastlineseries;     serie.fastpen := true;     serie.showinlegend := false;     serie.xvalues.datetime := true;     serie.vertaxis := aleftaxis;     serie.parentchart := self.chtmain;      j := 1 1000     begin       //       value := random * arr_maxs[idx] * 1.8;       serie.addxy(incsecond(start, j), value / arr_maxs[idx]);     end;   end; end;  end. 
  1. press [f9]

i not observe difference, whether use position annotation code or other one.

the tcursortool has fullrepaint property (false default) draw using xor full chart doesn't need repainted everytime updates position. , fast.

however, tannotationtool doesn't include possibility so, when update fannot text or position, forcing chart repaint, , having many points makes process slower.

you use tlabel component instead of using tannotationtool draw text.