[Lazarus] Hint as text over TAChart

"Leonardo M. Ramé" l.rame at griensu.com
Sun Sep 21 00:47:30 CEST 2014


On 20/09/14 17:08, Werner Pamler wrote:
> 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.
>
>

Great, calling onAfterPaint did the trick. Btw, thanks for the example.


-- 
Leonardo M. Ramé
http://leonardorame.blogspot.com




More information about the Lazarus mailing list