[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