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

SNMP编程

开发平台:

Visual C++

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