纵坐标是从串口采集到的数据,横坐标是时间累计,怎样用Tchart控件把曲线绘出,ystogxf帮帮我吧!(100分)

  • 主题发起人 主题发起人 coral0218
  • 开始时间 开始时间
C

coral0218

Unregistered / Unconfirmed
GUEST, unregistred user!
纵坐标是从串口取的数据,横坐标设计的是随着数据的取得时间不断累计(0-30S),
我不知道怎么在Tchart中动态输出曲线。是用Xvalues和Yvalues属性画曲线吗,我试过了可是写的不对!请帮帮忙吧!
 
有个基于TPaintBox的简单曲线。
TMyCurve = class
private
Fv1: array[0..100] of integer;
Fv2: array[0..100] of integer;
FMaxValue: integer;
FEnabled: boolean;
FPaintBox: TPaintBox;
procedure SetPaintBox(value: TPaintBox);
procedure PaintBoxPaint(Sender: TObject);

procedure SetV1(i: integer; value: integer);
function GetV1(i: integer): integer;
procedure SetV2(i: integer; value: integer);
function GetV2(i: integer): integer;

procedure DrawCoordinate;
procedure DrawCurve;
public
procedure Repaint;

property PaintBox: TPaintBox read FPaintBox write SetPaintBox;
property Enabled: boolean read FEnabled write FEnabled;
property MaxValue: integer read FMaxValue write FMaxValue;
property V1[i:integer]: integer read GetV1 write SetV1;
property V2[i:integer]: integer read GetV2 write SetV2;
end;

implementation

procedure TMyCurve.SetPaintBox(value: TPaintBox);
begin
if FPaintBox <> value then
begin
FPaintBox := value;
if FPaintBox <> nil then
begin
with FPaintBox do
OnPaint := PaintBoxPaint;
end;
end;
end;

procedure TMyCurve.Repaint;
begin
PaintBoxPaint(nil);
end;

procedure TMyCurve.PaintBoxPaint(Sender: TObject);
begin
if (FPaintBox = nil) or (FEnabled = false) then
exit;

with FPaintBox.Canvas do
begin
with Brush do
begin
Color := clYellow;
Style := bsSolid;
end;
FillRect(Bounds(0,0,FPaintBox.Width,FPaintBox.Height));
end;

DrawCoordinate;

DrawCurve;
end;

procedure TMyCurve.DrawCoordinate;
var
dx, dy: real;
i: integer;
begin
with FPaintBox.Canvas do
begin
with Pen do
begin
Color := clNavy;
Style := psDot;
Width := 1;
end;
Brush.Style := bsClear;

dx := (FPaintBox.Width - 20) / 10;
dy := (FPaintBox.Height - 20) / 10;

for i := 0 to 10 do
begin
MoveTo(10 + Round(i * dx), 10);
LineTo(10 + Round(i * dx), FPaintBox.Height - 10);

MoveTo(10, 10 + Round(i * dy));
LineTo(FPaintBox.Width - 10, Round(10 + i * dy));
end;
end;
end;

procedure TMyCurve.DrawCurve;
var
dx, dy: real;
i: integer;
begin
if FMaxValue < 2 then
exit;

dx := (FPaintBox.Width - 20) / 100;
dy := (FPaintBox.Height - 20) / FMaxValue; // MaxValue = 500

with FPaintBox.Canvas do
begin
with Pen do
begin
Color := clRed; //
Style := psSolid;
Width := 2;
end;
Brush.Style := bsClear;

// 第一条曲线
MoveTo(10, Round(FPaintBox.Height - 10 - FV1[0] * dy));
for i := 1 to 99 do
begin
LineTo(10 + Round(i * dx), Round(FPaintBox.Height - 10 - FV1 * dy));
end;

// 第二条曲线
Pen.Color := clLime;
MoveTo(10, Round(FPaintBox.Height - 10 - FV2[0] * dy));
for i := 1 to 99 do
begin
LineTo(10 + Round(i * dx), Round(FPaintBox.Height - 10 - FV2 * dy));
end;
end;
end;

procedure TMyCurve.SetV1(i: integer; value: integer);
begin
if (i >= 0) and (i < 100) then
begin
FV1 := value;
Repaint;
end;
end;

function TMyCurve.GetV1(i: integer): integer;
begin
if (i >= 0) and (i < 100) then
Result := FV1
else
Result := 0;
end;

procedure TMyCurve.SetV2(i: integer; value: integer);
begin
if (i >= 0) and (i < 100) then
begin
FV2 := value;
Repaint;
end;
end;

function TMyCurve.GetV2(i: integer): integer;
begin
if (i >= 0) and (i < 100) then
Result := FV2
else
Result := 0;
end;

//----------------------------------------------------------------
procedure TForm1.FormCreate(Sender: TObject);
begin
FCurve := TMyCurve.Create;
with FCurve do
begin
PaintBox := PaintBox1;
Enabled := true;
end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
FCurve.Destroy;
end;

// 正弦曲线
procedure TForm1.Button1lick(Sender: TObject);
var
i, x1, x2: integer;
begin
Randomize;
x1 := Random(50);
x2 := Random(50);
with FCurve do
begin
MaxValue := 500;
Enabled := false;

for i := 0 to 99 do
begin
V1 := Round(sin((i + x1)/ 100 * 2 * Pi) * 250 + 250);
V2 := Round(cos((i + x2)/ 100 * 2 * Pi) * 200 + 250);
end;

Enabled := true;
Repaint;
end;
end;

// 随机曲线
procedure TForm1.Button2lick(Sender: TObject);
begin
if Timer1.Enabled then
begin
Timer1.Enabled := false;
end else
begin
Randomize;
FCurve.MaxValue := 500;
Timer1.Enabled := true;
end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
i: integer;
begin
with FCurve do
begin
MaxValue := 500;
Enabled := false;

for i := 1 to 99 do
V1[i - 1] := V1;

V1[99] := Random(500);
Enabled := true;
Repaint;
end;
end;

 
你先在Chart1增加一个Series,假设是Series[0],
你要显示的数据是(t1,y1),(t2,y2)...(tn,yn)
Delphi:
for i := 1 to n do
begin
t := ti;
y := yi;
Chart1.Series[0].AddXY(y,t,'',clBlack);
end;
 
嘿嘿,我来了。
1。首先在TChart上加一条TFastLineSeries(实时数据用这个比较好),然后把横坐标设为TDateTime。这个没问题吧。
2。然后设置横坐标的显示格式和范围
with Chart1.BottomAxis do
begin
Automatic := False;
DateTimeFormat := 'hh:mm:ss';//横坐标的显示格式,可改为'ss'
SetMinMax(IncMinute(Now, -1), Now);//起始坐标从现在前的一分钟,到现在。使用IncMinute需要uese DateUtils
Increment := (tmpTime - IncMinute(tmpTime, -2)) / 4;//坐标分格
end;
3。增加实时数据(函数有很多)例:
Series1.AddXY(X, Y);//X:=Now 是时间,Y是你获得的数据。这个函数还可以根据需要加很多参数,包括颜色什么的
此时还要改变坐标,否则不会动态移动。
Chart1.BottomAxis.SetMinMax(IncMinute(Now, -1), Now);//跟初试设置一样

如果还有不明白的,再讨论


 
太感谢了![:)]
 
后退
顶部