TAChart: Add event OnHintLocation to TDataPointHintTool which knows the size of the hint window (OnHintPosition is deprecated now). Update "financial" demo to show hint window above data points.

git-svn-id: trunk@46272 -
This commit is contained in:
wp 2014-09-21 14:42:10 +00:00
parent 05710323ef
commit c97e37c258
5 changed files with 102 additions and 25 deletions

View File

@ -9,7 +9,6 @@
<Title Value="financialdemo"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<Icon Value="0"/>
</General>
<i18n>
<EnableI18N LFM="False"/>

View File

@ -2,28 +2,28 @@ object MainForm: TMainForm
Left = 313
Height = 438
Top = 177
Width = 758
Width = 891
Caption = 'MainForm'
ClientHeight = 438
ClientWidth = 758
ClientWidth = 891
OnCreate = FormCreate
LCLVersion = '1.3'
object TopPanel: TPanel
Left = 0
Height = 42
Top = 0
Width = 758
Width = 891
Align = alTop
BevelOuter = bvNone
ClientHeight = 42
ClientWidth = 758
ClientWidth = 891
TabOrder = 0
object cbSeriesType: TComboBox
Left = 8
Height = 28
Height = 23
Top = 8
Width = 242
ItemHeight = 20
ItemHeight = 15
ItemIndex = 0
Items.Strings = (
'OHLC series'
@ -34,12 +34,20 @@ object MainForm: TMainForm
TabOrder = 0
Text = 'OHLC series'
end
object Label1: TLabel
Left = 266
Height = 15
Top = 12
Width = 523
Caption = 'Hold the left mouse button down to see a hint window with the stock prices above each data point.'
ParentColor = False
end
end
object FinancialChart: TChart
Left = 0
Height = 396
Top = 42
Width = 758
Width = 891
AxisList = <
item
Grid.Color = clSilver
@ -70,6 +78,7 @@ object MainForm: TMainForm
Title.Text.Strings = (
'TAChart'
)
Toolset = ChartToolset1
Align = alClient
ParentColor = False
object ohlcSeries: TOpenHighLowCloseSeries
@ -82,4 +91,15 @@ object MainForm: TMainForm
Mode = mOHLC
end
end
object ChartToolset1: TChartToolset
left = 160
top = 111
object DataPointHintTool: TDataPointHintTool
Shift = [ssLeft]
DistanceMode = cdmOnlyX
GrabRadius = 8
OnHint = DataPointHintToolHint
OnHintLocation = DataPointHintToolHintLocation
end
end
end

View File

@ -5,8 +5,8 @@ unit main;
interface
uses
Classes, SysUtils, FileUtil, TAGraph, TASources, TAMultiSeries, Forms,
Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;
Classes, SysUtils, FileUtil, TAGraph, TAMultiSeries, TATools,
Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, types;
type
@ -14,10 +14,17 @@ type
TMainForm = class(TForm)
cbSeriesType: TComboBox;
ChartToolset1: TChartToolset;
DataPointHintTool: TDataPointHintTool;
FinancialChart: TChart;
Label1: TLabel;
ohlcSeries: TOpenHighLowCloseSeries;
TopPanel: TPanel;
procedure cbSeriesTypeChange(Sender: TObject);
procedure DataPointHintToolHint(ATool: TDataPointHintTool;
const APoint: TPoint; var AHint: String);
procedure DataPointHintToolHintLocation(ATool: TDataPointHintTool;
AHintSize: TSize; var APoint: TPoint);
procedure FormCreate(Sender: TObject);
private
{ private declarations }
@ -53,19 +60,6 @@ begin
fs.DateSeparator := '-';
fs.ShortDateFormat := 'd/mmm/yyyy';
fs.DecimalSeparator := '.';
fs.ShortMonthNames[1] := 'Jan';
fs.ShortMonthNames[2] := 'Feb';
fs.ShortMonthNames[3] := 'Mar';
fs.ShortMonthNames[4] := 'Apr';
fs.ShortMonthNames[5] := 'May';
fs.ShortMonthNames[6] := 'Jun';
fs.ShortMonthNames[7] := 'Jul';
fs.ShortMonthNames[8] := 'Aug';
fs.ShortMonthNames[9] := 'Sep';
fs.ShortMonthNames[10] := 'Oct';
fs.ShortMonthNames[11] := 'Nov';
fs.ShortMonthNames[12] := 'Dec';
dataList := TStringList.Create;
try
dataList.LoadFromFile(DATA_FILE);
@ -81,7 +75,7 @@ begin
// We don't use the date for x because we want to skip the weekends in the chart
// Therefore, we use the index and add the date as a label. Diplay of
// the data labels is activated by BottomAxis.Marks.Style = smsLabel.
ohlcSeries.AddXOHLC(i, yOpen, yHigh, yLow, yClose, DateToStr(xDate, fs));
ohlcSeries.AddXOHLC(i, yOpen, yHigh, yLow, yClose, DateToStr(xDate));
end;
finally
lines.Free;
@ -93,10 +87,57 @@ begin
FinancialChart.BottomAxis.Marks.Source := ohlcSeries.ListSource;
end;
{ The combobox switches between OHLC and candle stick display modes. }
procedure TMainForm.cbSeriesTypeChange(Sender: TObject);
begin
ohlcSeries.Mode := TOHLCMode(CbSeriesType.ItemIndex);
end;
{ This event handler returns the text to be displayed as a mouse-over hint.
We construct the text from the date, and the open, high, low, close values. }
procedure TMainForm.DataPointHintToolHint(ATool: TDataPointHintTool;
const APoint: TPoint; var AHint: String);
var
ser: TOpenHighLowCloseSeries;
begin
ser := ATool.Series as TOpenHighLowCloseSeries;
AHint := AnsiToUTF8(Format('Date: %s'#13' Open: %.2m'#13' High: %.2m'#13' Low: %.2m'#13' Close: %.2m', [
FormatDateTime('dddddd', StrToDate(ser.ListSource[ATool.PointIndex]^.Text)),
ser.ListSource[ATool.PointIndex]^.YList[0],
ser.ListSource[ATool.PointIndex]^.YList[2],
ser.ListSource[ATool.PointIndex]^.Y,
ser.ListSource[ATool.PointIndex]^.YList[1]
]));
end;
{ This event handler returns the location of the hint on the screen. To enhance
the assosciation with the data point and to avoid covering of the data point
we move center the hint window and move it up to the top of a OHLC/candle
data point.
Note:
The tool's UseApplicationHint must be set to FALSE for this even to fire. }
procedure TMainForm.DataPointHintToolHintLocation(ATool: TDataPointHintTool;
AHintSize: TSize; var APoint: TPoint);
var
ser: TOpenHighLowCloseSeries;
x, y: Integer;
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
// Center hint horizontally relative to data point
APoint.x := x - AHintSize.CX div 2;
// Move hint 4 pixels above the "High" data point
APoint.y := y - AHintSize.CY - 4;
// Hint coordinates are relative to screen
APoint := FinancialChart.ClientToScreen(APoint);
end;
end.

View File

@ -22,6 +22,11 @@
<RangeChecks Value="True"/>
</Checks>
</CodeGeneration>
<Linking>
<Debugging>
<DebugInfoType Value="dsDwarf2"/>
</Debugging>
</Linking>
</CompilerOptions>
<Description Value="TeeChart compatible graph component"/>
<License Value=" See the file COPYING.modifiedLGPL, included in this distribution,

View File

@ -473,6 +473,9 @@ type
TChartToolHintPositionEvent = procedure (
ATool: TDataPointHintTool; var APoint: TPoint) of object;
TChartToolHintLocationEvent = procedure (
ATool: TDataPointHintTool; AHintSize: TSize; var APoint: TPoint) of object;
{ TDataPointHintTool }
TDataPointHintTool = class(TDataPointTool)
@ -480,6 +483,7 @@ type
FHintWindow: THintWindow;
FOnHint: TChartToolHintEvent;
FOnHintPosition: TChartToolHintPositionEvent;
FOnHintLocation: TChartToolHintLocationEvent;
FPrevPointIndex: Integer;
FPrevSeries: TBasicChartSeries;
FUseApplicationHint: Boolean;
@ -497,8 +501,10 @@ type
published
property ActiveCursor;
property OnHint: TChartToolHintEvent read FOnHint write FOnHint;
property OnHintLocation: TChartToolHintLocationEvent
read FOnHintLocation write FOnHintLocation;
property OnHintPosition: TChartToolHintPositionEvent
read FOnHintPosition write FOnHintPosition;
read FOnHintPosition write FOnHintPosition; deprecated;
property UseApplicationHint: Boolean
read FUseApplicationHint write SetUseApplicationHint default false;
property UseDefaultHintText: Boolean
@ -1770,6 +1776,7 @@ procedure TDataPointHintTool.MouseMove(APoint: TPoint);
var
r: TRect;
h: String;
sz: TSize;
begin
FSeries := nil;
FindNearestPoint(APoint);
@ -1800,6 +1807,11 @@ begin
FHintWindow := THintWindow.Create(nil);
if h = '' then exit;
r := FHintWindow.CalcHintRect(FChart.Width, h, Nil);
if Assigned(OnHintLocation) then begin
sz.CX := r.Right - r.Left;
sz.CY := r.Bottom - r.Top;
OnHintLocation(Self, sz, APoint);
end;
OffsetRect(r, APoint.X, APoint.Y);
FHintWindow.ActivateWithBounds(r, h);
end;