【问题标题】:TeeChart Series OnMouseEnter eventTeeChart 系列 OnMouseEnter 事件
【发布时间】:2013-03-25 13:45:22
【问题描述】:

我正在使用 Rad Studio XE3 附带的 TeeChart 版本。

TeeChart 提供了一个 TChartSeries 事件,当鼠标指针移过系列线时会触发该事件。我使用这个事件来显示指针下的系列名称。

问题是,给一个 1 像素宽的系列行,很难让指针准确地越过该行。有什么方法可以为事件添加“填充”,以便在行的每一侧触发 X 个像素?

或者有没有其他方法可以做到这一点?

【问题讨论】:

    标签: delphi teechart


    【解决方案1】:

    我正在向 Line (TLineSeries) 和 FastLine (TFastLineSeries) 类添加一个新属性来完成此操作。

    Series1.ClickTolerance := 4;   // <-- number of pixels around mouse XY
    

    默认值为零(鼠标 XY 应该正好在直线上),就像当前的行为一样。

    作为一种解决方法,如果您使用的是 TLineSeries,可以在线点位置显示指针,并且内部“点击”函数会考虑指针大小:

    Series1.Pointer.Visible:=True;
    

    对于更多自定义控件,下面的代码与用于检测鼠标点击的内部代码非常相似。 Tolerance 常数指定要考虑的“行中”的额外像素数。

    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;
    

    【讨论】:

    • 谢谢,大卫,工作得很好。 XE3 附带的版本会有更新吗?
    • 如果您能看一下下面的问题(在下一条评论中),我将不胜感激。我一直在努力让它工作一段时间,但我的时间不多了。
    • 最后,我们这些使用与 Rad Studio XE3 捆绑的 TeeChart 版本的人如何获得支持和更新?
    • 我试图弄清楚如何做到这一点,无论鼠标指针是否在系列线上。我想在鼠标指向的任何地方画一条垂直线,但它目前仅在鼠标直接位于系列线上时才有效。我如何让OnMouseMove 触发图表中的anywhere
    【解决方案2】:

    您可以使用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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-25
      • 1970-01-01
      • 1970-01-01
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多