用Image画X轴,要求能根据导入的数据自动变换刻度以及刻度值的大小?
X轴作为时间轴。单位值是0.01S,怎么画出来?扩大了倍数会与上面一个问题冲突。
0.01s 就是0.01秒采集一点数据描出来。而image的lineto(x,y)的x,y都是整型数据类型。如果放大倍数吧,那么X轴的刻度值(时间轴)也应该扩大倍数,就更大了。
就像chart画图格式一样。只不过,这里的X,Y轴都是自己画出来的,Y轴我设定范围是000---10000固定了的。而X轴就要根据导入的数据自动获得点数与间隔值,还要与image控件的宽度有联系。怎么做??
lineto(x,y) x,y你想让他变0.01吗?当然不能了
x,y是1递增,看起来已经是很密的了,可以考虑循环啊,到了10000,从头开始,也可以用颜色区别一下
导入数据的个数不同,X轴等分点也不同??
比如:像CHART控件:
在BOTTOMAXIS轴的MAX上输入13614.30,则出现13个等分点,间隔自动变为1000递增;
输入1592.64,出现15个等分点,间隔变为100递增;
输入3592.64,出现17个等分点,间隔变为200递增;
那么出现的等分点个数和间隔值是怎么得到的??因为这个bottomaxis我要自己画出来,并根据接收的数据不同而不同。
采用IMAGE画图,而不用CHART是因为CHART画图太吃内存了。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormResize(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
xMax,yMax: double;
xValue,yValue: array of double;
pCount: integer;
mImage: TImage;
implementation
{$R *.dfm}
procedure mPaint();
var
vxBegin,vxEnd,vyBegin,vyEnd: integer;
mTemp: integer;
i: integer;
mCanvas: TCanvas;
begin
mImage.Picture := nil;
mCanvas := mImage.Canvas;
mCanvas.Font.Color := clBlack;
//定义显示区域
vxBegin := 10;
vxEnd := mCanvas.ClipRect.Right-20;
vyBegin := 20;
vyEnd := mCanvas.ClipRect.Bottom-60;
//画坐标轴
mCanvas.Pen.Width := 2;
mCanvas.Pen.Color := clBlack;
mCanvas.MoveTo(vxEnd,vyEnd);
mCanvas.LineTo(vxBegin,vyEnd);
mCanvas.LineTo(vxBegin,vyBegin);
//画刻度
mCanvas.Pen.Width := 1;
for i:= 1 to 10 do
begin
mTemp := vxBegin+i*((vxEnd-vxBegin) div 10);
mCanvas.MoveTo(mTemp,vyEnd+4);
mCanvas.LineTo(mTemp,vyEnd-5);
mCanvas.TextOut(mTemp-10,vyEnd+10,FloatToStr(round(xMax*i*10)/100));
mTemp := vyEnd-i*((vyEnd-vyBegin) div 10);
mCanvas.MoveTo(vxBegin+4,mTemp);
mCanvas.LineTo(vxBegin-5,mTemp);
mCanvas.TextOut(vxBegin+4,mTemp,FloatToStr(round(yMax*i*10)/100));
end;
//画线
mCanvas.Font.Color := clBlue;
mCanvas.MoveTo(Round(vxBegin+xValue[0]*(vxEnd-vxBegin)/xMax)
,Round(vyBegin+(yMax-yValue[0])*(vyEnd-vyBegin)/yMax));
for i:=1 to pCount-1 do
begin
mCanvas.LineTo(Round(vxBegin+xValue[i]*(vxEnd-vxBegin)/xMax)
,Round(vyBegin+(yMax-yValue[i])*(vyEnd-vyBegin)/yMax));
//显示中间10等分点的坐标,方便验证图形正确与否
if (i mod (pCount div 10))=0 then
begin
mCanvas.TextOut(Round(vxBegin+xValue[i]*(vxEnd-vxBegin)/xMax)
,Round(vyBegin+(yMax-yValue[i])*(vyEnd-vyBegin)/yMax)
,'('+IntToStr(i) + ',' + FloatToStr(xValue[i])+','+FloatToStr(yValue[i])+')');
mCanvas.MoveTo(Round(vxBegin+xValue[i]*(vxEnd-vxBegin)/xMax)
,Round(vyBegin+(yMax-yValue[i])*(vyEnd-vyBegin)/yMax));
end;
//显示最高点坐标
if yValue[i]=yMax then
begin
mCanvas.Font.Color := clRed;
mCanvas.TextOut(Round(vxBegin+xValue[i]*(vxEnd-vxBegin)/xMax)
,Round(vyBegin+(yMax-yValue[i])*(vyEnd-vyBegin)/yMax)
,'('+IntToStr(i) + ',' + FloatToStr(xValue[i])+','+FloatToStr(yValue[i])+')');
mCanvas.MoveTo(Round(vxBegin+xValue[i]*(vxEnd-vxBegin)/xMax)
,Round(vyBegin+(yMax-yValue[i])*(vyEnd-vyBegin)/yMax));
mCanvas.Font.Color := clBlue;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
Randomize;
//数据生成
pCount := Random(500);
SetLength(xValue,pCount);
SetLength(yValue,pCount);
for i:=0 to pCount-1 do
begin
xValue[i] := i*0.01;
yValue[i] := Random(600);
end;
//数据分析
xMax := xValue[pCount-1];
yMax := 0;
for i:=0 to pCount-1 do
if yValue[i]>yMax then
yMax := yValue[i];
mImage := TImage.Create(Form1);
mImage.Align := alClient;
mImage.Parent := Form1;
mImage.Visible := True;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
mPaint();
end;end.