用Image画X轴,要求能根据导入的数据自动变换刻度以及刻度值的大小?
X轴作为时间轴。单位值是0.01S,怎么画出来?扩大了倍数会与上面一个问题冲突。

解决方案 »

  1.   

    0.01s 就是0.01秒采集一点数据描出来。而image的lineto(x,y)的x,y都是整型数据类型。如果放大倍数吧,那么X轴的刻度值(时间轴)也应该扩大倍数,就更大了。
    就像chart画图格式一样。只不过,这里的X,Y轴都是自己画出来的,Y轴我设定范围是000---10000固定了的。而X轴就要根据导入的数据自动获得点数与间隔值,还要与image控件的宽度有联系。怎么做??
      

  2.   

    lineto(x,y) x,y你想让他变0.01吗?当然不能了x,y是1递增,看起来已经是很密的了,可以考虑循环啊,到了10000,从头开始,也可以用颜色区别一下
      

  3.   

    导入数据的个数不同,X轴等分点也不同??
    比如:像CHART控件:
      在BOTTOMAXIS轴的MAX上输入13614.30,则出现13个等分点,间隔自动变为1000递增;
      输入1592.64,出现15个等分点,间隔变为100递增;
      输入3592.64,出现17个等分点,间隔变为200递增;那么出现的等分点个数和间隔值是怎么得到的??因为这个bottomaxis我要自己画出来,并根据接收的数据不同而不同。采用IMAGE画图,而不用CHART是因为CHART画图太吃内存了。
      

  4.   

    你似乎还是没太搞清楚,写了代码,你看下的:unit Unit1;interfaceuses
      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.
      

  5.   

    好,今天做了,很好,谢谢你。
    但是考虑数据很多的情况下,画图的速度上很慢?考虑用映射进行不知道是不是好方法?
    有事情可以给我发邮件[email protected]
      

  6.   

    是的,使用控件image自己画坐标X轴、Y轴和Z轴。然后考虑再用一个image控件画图。从最多数据来考虑1G的数据吧。大概数据个数有1亿个吧。
    不要求分屏,显示在一个屏幕上,通过放大或缩小来查看图形趋势及数据。
    最初我用的chart控件,但是它的弊端是太吃内存了,而不能快速地释放所占内存。
    可以给我做做看看,有问题我也可以参考一下,一个人做太扣脑门了。