我正在使用Rad Studio XE3附带的TeeChart版本。
TeeChart提供TChartSeries事件,当鼠标指针移过一个系列行时会触发该事件。我使用此事件在指针下显示系列的名称。
问题是,给出一个1像素宽的系列线,很难将指针精确地放在线上。是否有某种方法可以为事件添加“填充”,以便向该行的每一侧激发X个像素数?
或者还有其他方法可以实现这个目标吗?
答案 0 :(得分:3)
我正在为Line(TLineSeries)和FastLine(TFastLineSeries)类添加一个新属性来完成此任务。
Series1.ClickTolerance := 4; // <-- number of pixels around mouse XY
默认值为零(鼠标XY应该恰好在线上),就像当前行为一样。
作为一种解决方法,如果您正在使用TLineSeries,则指针可以显示在线点位置,而内部“clicked”函数将考虑指针大小:
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;
答案 1 :(得分:1)
您可以使用PointInLineTolerance
功能在OnMouseMove
事件中进行检查。
但是,您必须手动循环系列点以将系列值转换为像素并将它们传递给此函数。
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;