[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