高分求教,关于画历史曲线图。

时间:2022-06-01 20:18:24
我有一个数据采集程序,每隔一段时间就去设备上采集数据,
现在想把这些采集到的数据通过曲线图表现出来。有什么好的类画曲线图,
就像股票软件那样,x轴表示时间,y轴表示数据。时间不是联系的。

7 个解决方案

#1


用个vector之类的保存历史数据,在OnDraw/OnPaint中绘制就行。采用双缓冲。
如果时间是离散的,你也需要记录时间数据。

#2


数据我都存好了,放在数据库里,现在就是想找一个画曲线的类把这些熟悉表现出来,希望大伙帮帮忙

#3


用CUintArray 保存数据,,然后在OnPaint中画。。。

#4


数据我都存好了,放在数据库里,现在就是想找一个画曲线的类把这些数据表现出来,希望大伙帮帮忙

#5


實時曲線    RealTime Curve

 
        顯示圖形閃爍的主要原因是: 窗口重繪時,總先用背景色將顯示區清除,然後才調用OnPaint,而背景色往往與繪圖內容反差很大,短時間內背景色與顯示圖形的交替出現,使得顯示窗口看起來在閃,可采用雙緩沖機制來消除閃屏.

實現繪圖雙緩沖的方法 (顯示窗口的    CDC *pDC=GetDC( ) ):
1.定義一個CDC  MemDC 及一個位圖對象     CBitmap bm
2.創建與原DC兼容的內存顯示設備     MemDC.CreateCompatibleDC(pDC);
3.創建一個原DC相兼容的位圖      bm.CreateCompatibleBitmap(pDC,寬,高);
4.將位圖選入內存設備中,才能在MemDC中繪圖  CBitmap *pOldbm=MemDC.SelectObject(&bm);
5.在MemDC中繪圖
        MemDC......
6.繪完圖後,將MemDC拷貝至原pDC中     pDC->BitBlt(0,0,寬,高,&MemDC,0,0,SRCCOPY);
7.清理

        bm.DeleteObject( );

        MemDC.DeleteDC( ); 

 
 

參考代碼:

代碼說明: 在CRect(25,25,425,425)的400*400區域內畫一個20行20列的表格,然後畫曲線
(用隨機數取值 , 此處替換成你采集的數據   ).

每秒左移一次.采用雙緩沖機制消除閃屏.


1.在WM_CREATE 消息中創建定時器:       SetTimer (1, 1000, NULL);

2.在WM_DESTROY消息中刪除定時器:     KillTimer (1);

3.響應WM_TIMER消息:                                   Invalidate (  );

4.響應WM_ERASEBKGND消息:                   return TRUE;

5.在WM_PAINT消息中加入:

static int iCol=4;     //當前豎線顏色標記
static int arrayHeight[21];    //存儲21條線上的每個點的高度


CPaintDC dc(this); 
CRect rc;
dc.GetClipBox (&rc);    //取得當前客戶區大小

 

CDC MemDC;
MemDC.CreateCompatibleDC (&dc);
CBitmap bm;
bm.CreateCompatibleBitmap (&dc, rc.Width( ), rc.Height( ));
CBitmap *pOldbmp=MemDC.SelectObject (&bm);

 

CBrush brWhite(RGB(255,255,255));

CBrush *oldbr=MemDC.SelectObject (&brWhite);
MemDC.FillRect (&rc, &brWhite);    //將MemDC背景刷成白色


CPen penR(PS_SOLID,1,RGB(255,0,0));    //創建畫筆
CPen penG(PS_SOLID,1,RGB(0,255,0));
CPen penB(PS_SOLID,1,RGB(0,0,255));
CPen *oldPen=MemDC.SelectObject (&penG);


//畫橫線 

 int i;
for (i=0; i<21; i++) {
        if(i%5==0) MemDC.SelectObject (&penB);
        else MemDC.SelectObject (&penG); 
        MemDC.MoveTo(25,25+20*i);
        MemDC.LineTo(425,25+20*i);
}


//畫豎線
if(iCol==-1) iCol=4;
for(i=20;i>=0;i--){
        if(i%5==iCol) MemDC.SelectObject (&penB);
        else MemDC.SelectObject (&penG);
        MemDC.MoveTo(25+i*20,25);
        MemDC.LineTo (25+i*20,425);
}
iCol--;


for(i=0;i<20;i++) arrayHeight[i]=arrayHeight[i+1];   //將數組左移一位
arrayHeight[20]=rand() % 400 +1;    //此采用你采集的數據
MemDC.MoveTo(425,426-arrayHeight[20]);
MemDC.SelectObject (&penR);
for (i=19;i>=0;i--){    //開始畫曲線(從右到左)
        if (arrayHeight[i]<1) break;
        MemDC.LineTo (25+i*20,426-arrayHeight[i]);
}


dc.BitBlt(0, 0, rc.Width ( ), rc.Height ( ), &MemDC, 0, 0, SRCCOPY);


MemDC.SelectObject (oldPen); //以下是清除工作
MemDC.SelectObject (oldbr);
bm.DeleteObject ( );
MemDC.DeleteDC ( );

#6


自己写一个CLine,成员CPoint prev,CPoint pos,建立一个CLine的CObjectArray的对象m_oaLines,
每次MoveTo,LineTo,就可以了???

#7


直接MoveTo,LineTo就行了,也不复杂

或者建议你使用LabViewCVI,做硬件数据采集的曲线很方便编程也简单

#1


用个vector之类的保存历史数据,在OnDraw/OnPaint中绘制就行。采用双缓冲。
如果时间是离散的,你也需要记录时间数据。

#2


数据我都存好了,放在数据库里,现在就是想找一个画曲线的类把这些熟悉表现出来,希望大伙帮帮忙

#3


用CUintArray 保存数据,,然后在OnPaint中画。。。

#4


数据我都存好了,放在数据库里,现在就是想找一个画曲线的类把这些数据表现出来,希望大伙帮帮忙

#5


實時曲線    RealTime Curve

 
        顯示圖形閃爍的主要原因是: 窗口重繪時,總先用背景色將顯示區清除,然後才調用OnPaint,而背景色往往與繪圖內容反差很大,短時間內背景色與顯示圖形的交替出現,使得顯示窗口看起來在閃,可采用雙緩沖機制來消除閃屏.

實現繪圖雙緩沖的方法 (顯示窗口的    CDC *pDC=GetDC( ) ):
1.定義一個CDC  MemDC 及一個位圖對象     CBitmap bm
2.創建與原DC兼容的內存顯示設備     MemDC.CreateCompatibleDC(pDC);
3.創建一個原DC相兼容的位圖      bm.CreateCompatibleBitmap(pDC,寬,高);
4.將位圖選入內存設備中,才能在MemDC中繪圖  CBitmap *pOldbm=MemDC.SelectObject(&bm);
5.在MemDC中繪圖
        MemDC......
6.繪完圖後,將MemDC拷貝至原pDC中     pDC->BitBlt(0,0,寬,高,&MemDC,0,0,SRCCOPY);
7.清理

        bm.DeleteObject( );

        MemDC.DeleteDC( ); 

 
 

參考代碼:

代碼說明: 在CRect(25,25,425,425)的400*400區域內畫一個20行20列的表格,然後畫曲線
(用隨機數取值 , 此處替換成你采集的數據   ).

每秒左移一次.采用雙緩沖機制消除閃屏.


1.在WM_CREATE 消息中創建定時器:       SetTimer (1, 1000, NULL);

2.在WM_DESTROY消息中刪除定時器:     KillTimer (1);

3.響應WM_TIMER消息:                                   Invalidate (  );

4.響應WM_ERASEBKGND消息:                   return TRUE;

5.在WM_PAINT消息中加入:

static int iCol=4;     //當前豎線顏色標記
static int arrayHeight[21];    //存儲21條線上的每個點的高度


CPaintDC dc(this); 
CRect rc;
dc.GetClipBox (&rc);    //取得當前客戶區大小

 

CDC MemDC;
MemDC.CreateCompatibleDC (&dc);
CBitmap bm;
bm.CreateCompatibleBitmap (&dc, rc.Width( ), rc.Height( ));
CBitmap *pOldbmp=MemDC.SelectObject (&bm);

 

CBrush brWhite(RGB(255,255,255));

CBrush *oldbr=MemDC.SelectObject (&brWhite);
MemDC.FillRect (&rc, &brWhite);    //將MemDC背景刷成白色


CPen penR(PS_SOLID,1,RGB(255,0,0));    //創建畫筆
CPen penG(PS_SOLID,1,RGB(0,255,0));
CPen penB(PS_SOLID,1,RGB(0,0,255));
CPen *oldPen=MemDC.SelectObject (&penG);


//畫橫線 

 int i;
for (i=0; i<21; i++) {
        if(i%5==0) MemDC.SelectObject (&penB);
        else MemDC.SelectObject (&penG); 
        MemDC.MoveTo(25,25+20*i);
        MemDC.LineTo(425,25+20*i);
}


//畫豎線
if(iCol==-1) iCol=4;
for(i=20;i>=0;i--){
        if(i%5==iCol) MemDC.SelectObject (&penB);
        else MemDC.SelectObject (&penG);
        MemDC.MoveTo(25+i*20,25);
        MemDC.LineTo (25+i*20,425);
}
iCol--;


for(i=0;i<20;i++) arrayHeight[i]=arrayHeight[i+1];   //將數組左移一位
arrayHeight[20]=rand() % 400 +1;    //此采用你采集的數據
MemDC.MoveTo(425,426-arrayHeight[20]);
MemDC.SelectObject (&penR);
for (i=19;i>=0;i--){    //開始畫曲線(從右到左)
        if (arrayHeight[i]<1) break;
        MemDC.LineTo (25+i*20,426-arrayHeight[i]);
}


dc.BitBlt(0, 0, rc.Width ( ), rc.Height ( ), &MemDC, 0, 0, SRCCOPY);


MemDC.SelectObject (oldPen); //以下是清除工作
MemDC.SelectObject (oldbr);
bm.DeleteObject ( );
MemDC.DeleteDC ( );

#6


自己写一个CLine,成员CPoint prev,CPoint pos,建立一个CLine的CObjectArray的对象m_oaLines,
每次MoveTo,LineTo,就可以了???

#7


直接MoveTo,LineTo就行了,也不复杂

或者建议你使用LabViewCVI,做硬件数据采集的曲线很方便编程也简单