1

RadStudioXE3に付属しているバージョンのTeeChartを使用しています。

TeeChartは、マウスポインタがシリーズライン上を移動したときに発生するTChartSeriesイベントを提供します。このイベントを使用して、ポインターの下にシリーズの名前を表示します。

問題は、1ピクセル幅の直列線を指定すると、線の真上にポインタを配置することが難しいことです。イベントに「パディング」を追加して、ラインの両側にX個のピクセルを発射する方法はありますか?

または、これを達成する他の方法はありますか?

4

2 に答える 2

4

これを実現するために、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;
于 2013-03-25T14:44:48.773 に答える
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;
于 2013-03-25T14:42:41.620 に答える