LineChart.cpp
上传用户:hbytqc8
上传日期:2014-07-31
资源大小:527k
文件大小:10k
源码类别:

SNMP编程

开发平台:

Visual C++

  1. // LineChart.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Traffic.h"
  5. #include "LineChart.h"
  6. #include "TrafficDlg.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CLineChart
  14. CLineChart::CLineChart(CSize cs,int row)
  15. {
  16. Useage=false;
  17. StartPos=0;
  18. Cross=false;
  19. oldX=-1;
  20. oldY=-1;
  21.  title="My Chart";
  22.  xLegend="xLegend";
  23.  yLegend="yLegend";
  24.  tFont.CreatePointFont(70,"楷体_GB2132",NULL);
  25.  interval=36;
  26.  Number=0;
  27.  xAverage=0;
  28.  yAverage=0;
  29.  x_Max=0;
  30.  y_Max=0;
  31.  x_Min=1000000;
  32.  y_Min=1000000;
  33.  Count=row;
  34.  ChartSize=cs;
  35.  srand((unsigned)time(NULL));
  36.  LineData ld;
  37.  for (int i=0;i<=Count;i++)
  38.  {
  39.  ld.x=rand()%100;
  40.  ld.y=rand()%50;
  41.  ld.xTime="";
  42.      ld.show=false;
  43.  ArrayData.Add(ld);
  44.  }
  45.  yMax=100;
  46.  Temp_yMax=0;
  47. }
  48. CLineChart::~CLineChart()
  49. {
  50. }
  51. BEGIN_MESSAGE_MAP(CLineChart, CStatic)
  52. //{{AFX_MSG_MAP(CLineChart)
  53. ON_WM_PAINT()
  54. ON_WM_MOUSEMOVE()
  55. //}}AFX_MSG_MAP
  56. END_MESSAGE_MAP()
  57. /////////////////////////////////////////////////////////////////////////////
  58. // CLineChart message handlers
  59. void CLineChart::AddData(unsigned long  x1,unsigned long  y1,
  60.  CString tt,int ux,int uy,int index,bool tf)
  61. {
  62. unsigned long temp;
  63. if (x1>y1)
  64. temp=x1;
  65. else
  66. temp=y1;
  67. while (yMax<temp)
  68. yMax+=100;
  69. if (x1>x_Max) 
  70. x_Max=x1;
  71. if (x1<x_Min)
  72. x_Min=x1;
  73. if (y1>y_Max) 
  74. y_Max=y1;
  75. if (y1<y_Min)
  76. y_Min=y1;
  77. if (index<=Count)
  78. {
  79. ArrayData[index].x=x1;
  80.         ArrayData[index].y=y1;
  81.         ArrayData[index].xTime=tt;
  82.     ArrayData[index].xUse=ux;
  83.       ArrayData[index].yUse=uy;
  84.      ArrayData[index].show=tf;
  85. }
  86. else
  87. {
  88.        LineData ld;
  89.      ld.x=x1;
  90.  ld.y=y1;
  91.  ld.xTime=tt;
  92.      ld.show=tf;
  93.  ld.xUse=ux;
  94.  ld.yUse=uy;
  95.  ArrayData.Add(ld);
  96. }  
  97. }
  98. //增加数据项到队列末尾,原来每个项依次前移一项;增加的
  99. //数据如果超出Y轴目前最大值,则最大值以100为单位递增,直
  100. //到大于输入的数据为止;最后重绘图表;
  101. void CLineChart::Append(unsigned long x1,unsigned long y1,CString tt,int ux,int uy)
  102. {   
  103. unsigned long temp;
  104. if (x1>y1)
  105. temp=x1;
  106. else
  107. temp=y1;
  108. while (yMax<temp)
  109. yMax+=100;
  110. if (x1>x_Max) 
  111. x_Max=x1;
  112. if (x1<x_Min)
  113. x_Min=x1;
  114. if (y1>y_Max) 
  115. y_Max=y1;
  116. if (y1<y_Min)
  117. y_Min=y1;
  118. for(int i=0;i<Count;i++)
  119. {
  120.         ArrayData[i]=ArrayData[i+1];
  121. }
  122. ArrayData[Count].x=x1;
  123. ArrayData[Count].y=y1;
  124. ArrayData[Count].xTime=tt;
  125. ArrayData[Count].xUse=ux;
  126. ArrayData[Count].yUse=uy;
  127. ArrayData[Count].show=false;
  128. if ((Number % interval)==0)
  129.     ArrayData[Count].show=true;
  130. Number+=1;
  131. xAverage=(x1+xAverage*(Number-1))/Number;
  132.     yAverage=(y1+yAverage*(Number-1))/Number;
  133. this->Invalidate();
  134. }
  135. //初始化图表数据;
  136. void CLineChart::Init()
  137. {   
  138. yMax=100;
  139. for(int i=0;i<ArrayData.GetSize();i++)
  140. {
  141.       ArrayData[i].x=0;
  142.       ArrayData[i].y=0;
  143.   ArrayData[i].xUse=0;
  144.   ArrayData[i].yUse=0;
  145.       ArrayData[i].xTime="";
  146.   ArrayData[i].show=false;
  147. }
  148. this->Invalidate();
  149. }
  150. void CLineChart::SetTitle(CString str)
  151. {
  152. title=str;
  153. this->Invalidate();
  154. }
  155. void CLineChart::SetLegend(CString xStr,CString yStr)
  156. {
  157. xLegend=xStr;
  158. yLegend=yStr;
  159. this->Invalidate();
  160. }
  161. void CLineChart::OnPaint() 
  162. {
  163. CPaintDC dc(this); // device context for painting
  164.     CString str;
  165. int height,width;
  166. dc.Rectangle(0,0,ChartSize.cx,ChartSize.cy);
  167.     CPoint Start,xEnd,yEnd,temp;
  168. //确定坐标系,画X轴;
  169. Start.x=60;
  170. Start.y=ChartSize.cy-20;
  171. dc.MoveTo(Start);
  172. xEnd.x=60+Count;
  173. //X轴表示数据的宽度为Count+1=289个像素,一个像素对应数组
  174. //中的一个元素;
  175.     xEnd.y=Start.y;
  176. width=xEnd.x-Start.x;
  177. dc.LineTo(xEnd.x+5,xEnd.y);
  178. dc.TextOut(xEnd.x+8,xEnd.y-8,"时间");
  179. //画X轴箭头;
  180. dc.LineTo(xEnd.x,xEnd.y-3);
  181. dc.MoveTo(xEnd.x+5,xEnd.y);
  182. dc.LineTo(xEnd.x,xEnd.y+3);
  183. //画Y轴;
  184. dc.MoveTo(Start);
  185. yEnd.y=40;
  186. yEnd.x=Start.x;
  187. height=Start.y-yEnd.y;
  188. //计算Y轴每点对应的数值,这里如使用整型会影响精度;
  189.     float n=(float)yMax/(height-10);
  190. height=(height-10)/5;
  191. //Y轴以及箭头;
  192. dc.LineTo(yEnd);
  193.     dc.LineTo(yEnd.x-3,yEnd.y+5);
  194. dc.MoveTo(yEnd);
  195. dc.LineTo(yEnd.x+3,yEnd.y+5);
  196. dc.TextOut(yEnd.x-40,yEnd.y-20,"Bits Per Second");
  197.     //画Y轴虚线,标注刻度值;
  198. CPen pen,*pPen;
  199. /* pen.CreatePen(PS_DOT,1,RGB(100,100,100));
  200.     pPen=dc.SelectObject(&pen);
  201.     dc.TextOut(60-9,Start.y-7,"0");
  202. CString yText;
  203. int yCo;
  204. for (int i=0;i<5;i++)
  205. {
  206. dc.MoveTo(Start.x,Start.y-(i+1)*height);
  207. dc.LineTo(Start.x+Count,Start.y-(i+1)*height);
  208. yCo=(i+1)*(yMax/5);
  209. yText.Format("%d",yCo);
  210. dc.TextOut(60-yText.GetLength()*9,Start.y-(i+1)*height-7,yText);
  211. }
  212.     dc.SelectObject(pPen);
  213. pen.DeleteObject();
  214. dc.MoveTo(Start.x+Count+1,Start.y-5*height);
  215.     dc.LineTo(Start.x+Count+1,Start.y); */
  216. //画X轴坐标线;
  217. int xW=(width/20+0.5);
  218. for (int i=1;i<=20;i++)
  219. {
  220.       dc.MoveTo(Start.x+i*xW,Start.y-3);
  221.   dc.LineTo(Start.x+i*xW,Start.y+3);
  222. }
  223. //画曲线Y,填充区域;
  224. pen.CreatePen(PS_SOLID,1,RGB(0,255,0));
  225.     pPen=dc.SelectObject(&pen);
  226. temp.x=Start.x;
  227. for (i=0;i<=Count;i++)
  228. {
  229.       temp.y=Start.y-(int)(ArrayData[i+StartPos].y/n+0.5);
  230.       if (Useage)
  231.       temp.y=Start.y-(int)(ArrayData[i+StartPos].yUse/n+0.5);
  232.       dc.MoveTo(temp);
  233.   dc.LineTo(temp.x,Start.y);
  234.   if (ArrayData[i+StartPos].show)
  235.   {   
  236.           int n=dc.SetBkMode(TRANSPARENT);
  237.   CFont* pOld=dc.SelectObject(&tFont);
  238.   dc.TextOut(temp.x-4,Start.y+6,ArrayData[i+StartPos].xTime);
  239.   dc.SelectObject(pOld);
  240.   dc.SetBkMode(n);
  241.   }
  242.     temp.x+=1;
  243. }
  244.   dc.SelectObject(pPen);
  245. pen.DeleteObject();
  246. //如果标住了时间,画一条虚竖线;
  247.   pen.CreatePen(PS_DOT,1,RGB(100,100,100));
  248.   pPen=dc.SelectObject(&pen);
  249.     for (i=0;i<=Count;i++)
  250. {
  251.       if (ArrayData[i+StartPos].show)
  252.   {   
  253.          
  254.   dc.MoveTo(Start.x+i,Start.y);
  255.   dc.LineTo(Start.x+i,Start.y-5*height);
  256.   }
  257. }
  258.   dc.SelectObject(pPen);
  259.   pen.DeleteObject();
  260. //画曲线X,输入流量,单线;
  261. temp.y=Start.y-(int)(ArrayData[0+StartPos].x/n+0.5);
  262.     if (Useage)
  263.       temp.y=Start.y-(int)(ArrayData[0+StartPos].xUse/n+0.5);
  264. temp.x=Start.x;
  265. pen.CreatePen(PS_SOLID,1,RGB(0,0,255));
  266.     pPen=dc.SelectObject(&pen);
  267. dc.MoveTo(temp);
  268. for (i=1;i<=Count;i++)
  269. {
  270.       temp.y=Start.y-(int)(ArrayData[i+StartPos].x/n+0.5);
  271.      if (Useage)
  272.       temp.y=Start.y-(int)(ArrayData[i+StartPos].xUse/n+0.5);
  273.       temp.x+=1;
  274.   dc.LineTo(temp);
  275. }
  276.     dc.SelectObject(pPen);
  277. pen.DeleteObject();
  278.     //画Y轴虚线,标注刻度值;
  279. // CPen pen,*pPen;
  280. pen.CreatePen(PS_DOT,1,RGB(100,100,100));
  281.     pPen=dc.SelectObject(&pen);
  282.     dc.TextOut(60-9,Start.y-7,"0");
  283. CString yText;
  284. int yCo;
  285. for (i=0;i<5;i++)
  286. {
  287. dc.MoveTo(Start.x,Start.y-(i+1)*height);
  288. dc.LineTo(Start.x+Count,Start.y-(i+1)*height);
  289. yCo=(i+1)*(yMax/5);
  290. yText.Format("%d",yCo);
  291. dc.TextOut(60-yText.GetLength()*9,Start.y-(i+1)*height-7,yText);
  292. }
  293.     dc.SelectObject(pPen);
  294. pen.DeleteObject();
  295. dc.MoveTo(Start.x+Count+1,Start.y-5*height);
  296.     dc.LineTo(Start.x+Count+1,Start.y);
  297. //画标题;  
  298. dc.TextOut(yEnd.x+ChartSize.cx/4,4,title);
  299. pen.CreatePen(PS_SOLID,1,RGB(0,255,0));
  300.     pPen=dc.SelectObject(&pen);
  301.     dc.MoveTo(yEnd.x+140,yEnd.y-10);
  302. dc.LineTo(yEnd.x+160,yEnd.y-10);
  303. dc.TextOut(yEnd.x+165,yEnd.y-20,yLegend);
  304.     dc.SelectObject(pPen);
  305.     pen.DeleteObject();
  306. pen.CreatePen(PS_SOLID,1,RGB(0,0,255));
  307.     pPen=dc.SelectObject(&pen);
  308.     dc.MoveTo(yEnd.x+230,yEnd.y-10);
  309. dc.LineTo(yEnd.x+250,yEnd.y-10);
  310.     dc.TextOut(yEnd.x+255,yEnd.y-20,xLegend);
  311.     dc.SelectObject(pPen);
  312.     pen.DeleteObject();
  313. CPoint Message;
  314. Message.x=ChartSize.cx;
  315. Message.y=0;
  316.     dc.Rectangle(Message.x,Message.y,Message.x+140,Message.y+150);
  317. dc.TextOut(Message.x+30,Message.y+4,"信息显示区");
  318. str.Format("%d",ArrayData[Count+StartPos].x);
  319. str="当前X: "+str;
  320. dc.TextOut(Message.x+8,Message.y+30,str);
  321. str.Format("%d",ArrayData[Count+StartPos].y);
  322. str="当前Y: "+str;
  323. dc.TextOut(Message.x+8,Message.y+46,str);
  324. str.Format("%d",x_Max);
  325. str="最大X: "+str;
  326. dc.TextOut(Message.x+8,Message.y+62,str);
  327. str.Format("%d",y_Max);
  328. str="最大Y: "+str;
  329. dc.TextOut(Message.x+8,Message.y+78,str);
  330. str.Format("%d",xAverage);
  331. str="平均X: "+str;
  332. dc.TextOut(Message.x+8,Message.y+94,str);
  333. str.Format("%d",yAverage);
  334. str="平均Y: "+str;
  335. dc.TextOut(Message.x+8,Message.y+110,str);
  336. // TODO: Add your message handler code here
  337. // Do not call CStatic::OnPaint() for painting messages
  338. }
  339. void CLineChart::SetCross(bool tf)
  340. {
  341. Cross=tf;
  342. }
  343. unsigned long CLineChart::GetXAverage()
  344. {   
  345. return xAverage;
  346. }
  347. unsigned long CLineChart::GetYAverage()
  348. {
  349. return yAverage;
  350. }
  351. CString CLineChart::GetXMax()
  352. {
  353. CString str;
  354. str.Format("%d",x_Max);
  355. return str;
  356. }
  357. CString CLineChart::GetYMax()
  358. {
  359. CString str;
  360. str.Format("%d",y_Max);
  361. return str;
  362. }
  363. CString CLineChart::GetXMin()
  364. {
  365. CString str;
  366. str.Format("%d",x_Min);
  367. return str;
  368. }
  369. CString CLineChart::GetYMin()
  370. {
  371. CString str;
  372. str.Format("%d",y_Min);
  373. return str;
  374. }
  375. void CLineChart::OnMouseMove(UINT nFlags, CPoint point) 
  376. {  
  377. if ((Cross)&&(point.x<ChartSize.cx))
  378. {
  379. CClientDC dc(this);
  380. dc.SetROP2(R2_NOT);
  381.     dc.MoveTo(0,oldY);
  382. dc.LineTo(ChartSize.cx,oldY);
  383. dc.MoveTo(oldX,0);
  384. dc.LineTo(oldX,ChartSize.cy);
  385. dc.MoveTo(0,point.y);
  386. dc.LineTo(ChartSize.cx,point.y);
  387. dc.MoveTo(point.x,0);
  388. dc.LineTo(point.x,ChartSize.cy);
  389. if ((point.x>=60)&&(point.x<=60+Count))
  390. {
  391.      CString str;
  392.      str.Format("%d",ArrayData[point.x-60+StartPos].x);
  393.      if (Useage)
  394.          str.Format("%d",ArrayData[point.x-60+StartPos].xUse);
  395.      str="当前X: "+str;
  396.     dc.TextOut(ChartSize.cx+8,30,str);
  397. str.Format("%d",ArrayData[point.x-60+StartPos].y);
  398.      if (Useage)
  399.          str.Format("%d",ArrayData[point.x-60+StartPos].yUse);
  400. str="当前Y: "+str;
  401. dc.TextOut(ChartSize.cx+8,46,str);
  402. }
  403. oldX=point.x;
  404. oldY=point.y;
  405.    }
  406. CStatic::OnMouseMove(nFlags, point);
  407. }
  408. void CLineChart::ToLeft()
  409. {
  410. int n=(ArrayData.GetSize()-1)-(Count+1);
  411. //数组中实际元素的个数减去可显示的元素个数;
  412. if (n==0)
  413. return;
  414. //相等,不移位;
  415. else
  416. {
  417.       if (StartPos<n)
  418.       StartPos+=1;
  419.   //显示起始位置小于n,起始位置增1;
  420.    }
  421. this->Invalidate();
  422. }
  423. void CLineChart::ToRight()
  424. {
  425. if (StartPos>0)
  426. StartPos=StartPos-1;
  427. this->Invalidate();
  428. }
  429. void CLineChart::SetUse(bool tf)
  430. {
  431. Useage=tf;
  432. if (Useage)
  433. {
  434. Temp_yMax=yMax;
  435. yMax=100;
  436. }
  437. else
  438. yMax=Temp_yMax;
  439. this->Invalidate();
  440. }