在发球区的每个新点上画一个标记

Draw a marker on each new point on teechart

我正在 Embarcadero XE 上开发一个应用程序,我从以太网端口接收实时数据并显示在屏幕上的 teechart 图表上。

该应用程序的工作方式类似于示波器,即图表显示数据的时间 window(例如 10 秒),每个新的传入点都会覆盖屏幕上已有的数据。

我需要你的帮助来制作一个代码,只在最新添加的点上放置一个标记,这样用户就可以跟踪屏幕上的哪些点是最新的点。我不想要所有带有标记的点,我只想要最新的。

正在使用的系列是快线。

这是我用来向图表添加数据的代码:

//Delete already existing point
if (Oscilografia.Series[0].Count>1) then
begin
Oscilografia.Series[0].Delete(cont);
end;
//Write point
Oscilografia.Series[0].addxy(cont,data, '', clblue);

您有多种选择。最简单的就是新建一个TPointSeries来显示当前点。如果你不想在图例中显示这个系列,那么只需设置:

 Oscilografia.Series[n].ShowInLegend := false;

其中 n 是您希望从图例中排除的系列的索引。

或者,您可以在 OnAfterDraw 处理程序中自定义绘制任何相关项目。例如:

procedure TForm1.Chart1AfterDraw(Sender: TObject);
var
  xPos, yPos : integer;
begin
  Chart1.Canvas.Pen.Color := clRed;
  Chart1.Canvas.Pen.Style := psSolid;
  Chart1.Canvas.Pen.Width := 1;
  Chart1.Canvas.Pen.Mode := pmCopy;

  xPos := Chart1.BottomAxis.CalcPosValue(CurrentXValue);
  yPos := Chart1.LeftAxis.CalcPosValue(CurrentYValue);

  // Parameters are 
  //  X-Coord, Y-Coord, X-Radius, Y-Radius, Start Angle, End Angle, Hole%
  Chart1.Canvas.Donut(xPos, yPos, 3, 3, 0, 360, 0);
end;

这会产生,例如:

自定义绘图还可以让您做其他事情,例如添加标记等。例如:

procedure TForm1.Chart1AfterDraw(Sender: TObject);
var
  xPos, yPos : integer;
  yMax, yMin : integer;
begin
  Chart1.Canvas.Pen.Color := clRed;
  Chart1.Canvas.Pen.Style := psSolid;
  Chart1.Canvas.Pen.Width := 1;
  Chart1.Canvas.Pen.Mode := pmCopy;

  xPos := Chart1.BottomAxis.CalcPosValue(CurrentXValue);
  yPos := Chart1.LeftAxis.CalcPosValue(CurrentYValue);

  Chart1.Canvas.Donut(xPos, yPos, 3, 3, 0, 360, 0);

  Chart1.Canvas.Pen.Color := clGreen;
  Chart1.Canvas.Pen.Style := psDash;

  yMax := Chart1.LeftAxis.CalcPosValue(Chart1.LeftAxis.Maximum);
  yMin := Chart1.LeftAxis.CalcPosValue(Chart1.LeftAxis.Minimum);
  Chart1.Canvas.DoVertLine(xPos, yMax, yMin);
end;

给出一条跟随当前点的垂直虚线:

请注意,CalcPosValue 函数由图表轴公开,并允许您将轴中的点 - space 转换为图表 [=37= 中的整数(屏幕)坐标] space.

作为 J 使用自定义绘图技术绘制指针的建议的替代方法,您可以将 TFastLineSeries 更改为使用 TLineSeries 并使其指针可见。然后,您可以使用 OnGetPointerStyle 事件隐藏除最后一个指针之外的所有指针:

uses Series;

var Series1: TLineSeries;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.View3D:=false;

  Series1:=Chart1.AddSeries(TLineSeries) as TLineSeries;
  for i:=0 to 360 do
    Series1.Add(Sin(PI*i/180));

  Series1.Pointer.Visible:=true;
  Series1.OnGetPointerStyle:=SeriesGetPointerStyle;
end;

function TForm1.SeriesGetPointerStyle(Sender:TChartSeries; ValueIndex:Integer):TSeriesPointerStyle;
begin
  result:=(Sender as TLineSeries).Pointer.Style;

  if (ValueIndex<>Sender.Count-1) then
    result:=psNothing;
end;

作为补充,如果你想显示系列中最后一个点的标记,你可以使系列的标记可见并使用 OnGetMarkText 事件隐藏除最后一个以外的所有标记:

uses Series;

var Series1: TLineSeries;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Chart1.View3D:=false;

  Series1:=Chart1.AddSeries(TLineSeries) as TLineSeries;
  for i:=0 to 360 do
    Series1.Add(Sin(PI*i/180));

  Series1.Pointer.Visible:=true;
  Series1.OnGetPointerStyle:=SeriesGetPointerStyle;

  Series1.Marks.Visible:=true;
  Series1.OnGetMarkText:=SeriesGetMarkText;
end;

function TForm1.SeriesGetPointerStyle(Sender:TChartSeries; ValueIndex:Integer):TSeriesPointerStyle;
begin
  result:=(Sender as TLineSeries).Pointer.Style;

  if (ValueIndex<>Sender.Count-1) then
    result:=psNothing;
end;

procedure TForm1.SeriesGetMarkText(Sender:TChartSeries; ValueIndex:Integer; var MarkText:String);
begin
  if (ValueIndex<>Sender.Count-1) then
    MarkText:='';
end;

请注意,我在这里也使用 TLineSeries,但如果您只对显示标记而不是指针感兴趣,您仍然可以使用 TFastLineSeries