我使用的是Rad Studio XE3附带的TeeChart版本。
TeeChart提供了一个TChartSeries事件,当鼠标指针移到序列线上时会触发该事件。我使用此事件在指针下显示系列的名称。
问题是,给出一条1像素宽的序列线,很难将指针准确地放在这条线上。有没有什么方法可以给事件添加“填充”,这样它就会在每一条线的两边激发X个像素?
或者有其他方法来实现这一点吗?
发布于 2013-03-25 22:44:49
我正在为Line (TLineSeries)和FastLine (TFastLineSeries)类添加一个新的属性来实现这一点。
Series1.ClickTolerance := 4; // <-- number of pixels around mouse XY默认值为零(鼠标XY应恰好位于线上),与当前行为类似。
作为一种解决方法,如果您使用的是TLineSeries,指针可以显示在线点位置,并且内部的“单击”函数将考虑指针的大小:
Series1.Pointer.Visible:=True;对于更多的自定义控件,下面的代码与用于检测鼠标点击的内部代码非常相似。公差常量指定要考虑“行中”的额外像素数。
procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
const
Tolerance=4;
var Clicked,
t : Integer;
Position,
P,Old : TPoint;
begin
Clicked:= -1;
Position.X:=X;
Position.Y:=Y;
for t:=Series1.FirstValueIndex to Series1.LastValueIndex do
begin
P.X:=Series1.CalcXPos(t);
P.Y:=Series1.CalcYPos(t);
if t>Series1.FirstValueIndex then
if PointInLine(Position,P.X,P.Y,Old.X,Old.Y,Tolerance) then
begin
Clicked:=t;
break;
end;
Old:=P;
end;
if Clicked = -1 then
Caption:=''
else
Caption:=IntToStr(Clicked);
end;发布于 2013-03-25 22:42:42
您可以在OnMouseMove事件中使用PointInLineTolerance函数来检查它。但是,您必须手动循环序列点,以将序列值转换为像素并将其传递给此函数。
uses Series;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
Chart1.View3D:=false;
for i:=0 to 5 do
Chart1.AddSeries(TLineSeries).FillSampleValues;
end;
procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var series, valueIndex: Integer;
P0, P1: TPoint;
begin
Chart1.Draw;
for series:=0 to Chart1.SeriesCount-1 do
with Chart1[series] do
for valueIndex:=FirstValueIndex to LastValueIndex-1 do
begin
P0.X:=CalcXPos(valueIndex);
P0.Y:=CalcYPos(valueIndex);
P1.X:=CalcXPos(valueIndex+1);
P1.Y:=CalcYPos(valueIndex+1);
if PointInLineTolerance(Point(X, Y), P0.X, P0.Y, P1.X, P1.Y, 5) then
begin
Chart1.Canvas.TextOut(X+5,Y-10,'Series ' + IntToStr(series));
exit;
end;
end;
end;https://stackoverflow.com/questions/15616516
复制相似问题