[Lazarus] Hint as text over TAChart

Werner Pamler werner.pamler at freenet.de
Sat Sep 20 22:08:13 CEST 2014


Using the TDataPointHintTool is correct. It is just a little bit awkward 
to use... In particular you are not picking the correct event.

Here's a step-by-step instruction. Code shown will be based on the 
"financial" demo which I added to TAChart recently:

  * Add a TChartToolset to the form
  * Set the chart's "Toolset" property to the toolset added.
  * Add a TDatapointHintTool.
  * Set "DistanceMode" to cdmOnlyX - this means that only the x
    coordinate of the mouse is evaluated to find the data point under
    the mouse; otherwise you'd have to move the move correctly to x and
    y. "GrabRadius" is the tolerance for point detection; you may want
    to increase the value a bit.
  * Add code to the "OnHint" event of the DatapointHintTool, this is the
    code which generates the hint text. Adapt your code to the following
    which works with the "financial" demo (note that the hint string may
    contain line breaks!):

    procedure TMainForm.ChartToolset1DataPointHintTool1Hint(ATool:
    TDataPointHintTool;
       const APoint: TPoint; var AHint: String);
    var
       ser: TOpenHighLowCloseSeries;
    begin
       ser := ATool.Series as TOpenHighLowCloseSeries;
       AHint := Format('Date: %s'#13'  Open: %.2f'#13'  High: %.2f'#13' 
    Low: %.2f'#13'  Close: %.2f', [
         ser.ListSource[Atool.PointIndex]^.Text,                // In
    this example the date is not stored in "x", but in the "Text" of the
    data point
         ser.ListSource[ATool.PointIndex]^.YList[0],
         ser.ListSource[ATool.PointIndex]^.YList[2],
         ser.ListSource[ATool.PointIndex]^.Y,
         ser.ListSource[ATool.PointIndex]^.YList[1]
       ]);
    end;

  * When you compile the hints should work already. However, they are
    not properly positioned. I'd prefer to move them above a data point
    and center them horizontally to the data points. The OnHintPosition
    event is responsible to determine the location of the upper/left
    corner of the hint window.

    procedure
    TMainForm.ChartToolset1DataPointHintTool1HintPosition(ATool:
    TDataPointHintTool;
       var APoint: TPoint);
    var
       ser: TOpenHighLowCloseSeries;
       x, y: Integer;
       w, h: Integer;
       r: TRect;
       hintwnd : THintWindow;
       s: String;
    begin
       { Calculate screen coordinates of the "high" point }

       ser := ATool.Series as TOpenHighLowCloseSeries;
       x :=
    FinancialChart.XGraphToImage(ser.ListSource[ATool.PointIndex]^.X);
       y :=
    FinancialChart.YGraphToImage(ser.ListSource[ATool.PointIndex]^.YList[2]);
         // "High" value, i.e. max of data point

       { Calculate size of hint window }

       // Get hint text - just call the event handler of OnHint
       ChartToolset1DataPointHintTool1Hint(ATool, APoint, s);

       // Calculation - borrowed from TATools
       hintwnd := THintWindow.Create(nil);
       try
         r := hintwnd.CalcHintRect(FinancialChart.Width, s, nil);
         w := r.Right - r.Left;  // Hint width
         h := r.Bottom - r.Top;  // Hint height
       finally
         hintwnd.Free;
       end;

       // Center hint horizontally relative to data point
       APoint.x := x - w div 2;

       // Move hint 10 pixels above the "High" data point
       APoint.y := y - h - 10;

       // Hint coordinates are relative to screen
       APoint := FinancialChart.ClientToScreen(APoint);
    end;


Regarding your second question how to call "OnAfterPaint": Just call it 
like I call the OnHint event in above example.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20140920/2410bcdc/attachment-0003.html>


More information about the Lazarus mailing list