LineChart.cpp
上传用户:hbytqc8
上传日期:2014-07-31
资源大小:527k
文件大小:10k
- // LineChart.cpp: implementation of the CLineChart class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "Rsh.h"
- #include "LineChart.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CLineChart::CLineChart(CSize cs,int row)
- {
- Useage=false;
- StartPos=0;
- Cross=false;
- oldX=-1;
- oldY=-1;
- title="My Chart";
- xLegend="xLegend";
- yLegend="yLegend";
- tFont.CreatePointFont(70,"楷体_GB2132",NULL);
- interval=36;
- Number=0;
- xAverage=0;
- yAverage=0;
- x_Max=0;
- y_Max=0;
- x_Min=1000000;
- y_Min=1000000;
- Count=row;
- ChartSize=cs;
- srand((unsigned)time(NULL));
- LineData ld;
- for (int i=0;i<=Count;i++)
- {
- ld.x=rand()%100;
- ld.y=rand()%50;
- ld.xTime="";
- ld.show=false;
- ArrayData.Add(ld);
- }
- yMax=100;
- Temp_yMax=0;
- }
- CLineChart::~CLineChart()
- {
- }
- BEGIN_MESSAGE_MAP(CLineChart, CStatic)
- //{{AFX_MSG_MAP(CLineChart)
- ON_WM_PAINT()
- ON_WM_MOUSEMOVE()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CLineChart message handlers
- void CLineChart::AddData(unsigned long x1,unsigned long y1,
- CString tt,int ux,int uy,int index,bool tf)
- {
- unsigned long temp;
- if (x1>y1)
- temp=x1;
- else
- temp=y1;
- while (yMax<temp)
- yMax+=100;
- if (x1>x_Max)
- x_Max=x1;
- if (x1<x_Min)
- x_Min=x1;
- if (y1>y_Max)
- y_Max=y1;
- if (y1<y_Min)
- y_Min=y1;
- if (index<=Count)
- {
- ArrayData[index].x=x1;
- ArrayData[index].y=y1;
- ArrayData[index].xTime=tt;
- ArrayData[index].xUse=ux;
- ArrayData[index].yUse=uy;
- ArrayData[index].show=tf;
- }
- else
- {
- LineData ld;
- ld.x=x1;
- ld.y=y1;
- ld.xTime=tt;
- ld.show=tf;
- ld.xUse=ux;
- ld.yUse=uy;
- ArrayData.Add(ld);
- }
- }
- //增加数据项到队列末尾,原来每个项依次前移一项;增加的
- //数据如果超出Y轴目前最大值,则最大值以100为单位递增,直
- //到大于输入的数据为止;最后重绘图表;
- void CLineChart::Append(unsigned long x1,unsigned long y1,CString tt,int ux,int uy)
- {
- unsigned long temp;
- if (x1>y1)
- temp=x1;
- else
- temp=y1;
- while (yMax<temp)
- yMax+=100;
- if (x1>x_Max)
- x_Max=x1;
- if (x1<x_Min)
- x_Min=x1;
- if (y1>y_Max)
- y_Max=y1;
- if (y1<y_Min)
- y_Min=y1;
- for(int i=0;i<Count;i++)
- {
- ArrayData[i]=ArrayData[i+1];
- }
- ArrayData[Count].x=x1;
- ArrayData[Count].y=y1;
- ArrayData[Count].xTime=tt;
- ArrayData[Count].xUse=ux;
- ArrayData[Count].yUse=uy;
- ArrayData[Count].show=false;
- if ((Number % interval)==0)
- ArrayData[Count].show=true;
- Number+=1;
- xAverage=(x1+xAverage*(Number-1))/Number;
- yAverage=(y1+yAverage*(Number-1))/Number;
- this->Invalidate();
- }
- //初始化图表数据;
- void CLineChart::Init()
- {
- yMax=100;
- for(int i=0;i<ArrayData.GetSize();i++)
- {
- ArrayData[i].x=0;
- ArrayData[i].y=0;
- ArrayData[i].xUse=0;
- ArrayData[i].yUse=0;
- ArrayData[i].xTime="";
- ArrayData[i].show=false;
- }
- this->Invalidate();
- }
- void CLineChart::SetTitle(CString str)
- {
- title=str;
- this->Invalidate();
- }
- void CLineChart::SetLegend(CString xStr,CString yStr)
- {
- xLegend=xStr;
- yLegend=yStr;
- this->Invalidate();
- }
- void CLineChart::OnPaint()
- {
- CPaintDC dc(this); // device context for painting
- CString str;
- int height,width;
- dc.Rectangle(0,0,ChartSize.cx,ChartSize.cy);
- CPoint Start,xEnd,yEnd,temp;
- //确定坐标系,画X轴;
- Start.x=60;
- Start.y=ChartSize.cy-20;
- dc.MoveTo(Start);
- xEnd.x=60+Count;
- //X轴表示数据的宽度为Count+1=289个像素,一个像素对应数组
- //中的一个元素;
- xEnd.y=Start.y;
- width=xEnd.x-Start.x;
- dc.LineTo(xEnd.x+5,xEnd.y);
- dc.TextOut(xEnd.x+8,xEnd.y-8,"时间");
- //画X轴箭头;
- dc.LineTo(xEnd.x,xEnd.y-3);
- dc.MoveTo(xEnd.x+5,xEnd.y);
- dc.LineTo(xEnd.x,xEnd.y+3);
- //画Y轴;
- dc.MoveTo(Start);
- yEnd.y=40;
- yEnd.x=Start.x;
- height=Start.y-yEnd.y;
- //计算Y轴每点对应的数值,这里如使用整型会影响精度;
- float n=(float)yMax/(height-10);
- height=(height-10)/5;
- //Y轴以及箭头;
- dc.LineTo(yEnd);
- dc.LineTo(yEnd.x-3,yEnd.y+5);
- dc.MoveTo(yEnd);
- dc.LineTo(yEnd.x+3,yEnd.y+5);
- dc.TextOut(yEnd.x-10,yEnd.y-20,"数据");
- //画Y轴虚线,标注刻度值;
- CPen pen,*pPen;
- pen.CreatePen(PS_DOT,1,RGB(100,100,100));
- pPen=dc.SelectObject(&pen);
- dc.TextOut(60-9,Start.y-7,"0");
- CString yText;
- int yCo;
- for (int i=0;i<5;i++)
- {
- dc.MoveTo(Start.x,Start.y-(i+1)*height);
- dc.LineTo(Start.x+Count,Start.y-(i+1)*height);
- yCo=(i+1)*(yMax/5);
- yText.Format("%d",yCo);
- dc.TextOut(60-yText.GetLength()*9,Start.y-(i+1)*height-7,yText);
- }
- // dc.LineTo(Start.x+Count,Start.y);
- dc.SelectObject(pPen);
- pen.DeleteObject();
- dc.MoveTo(Start.x+Count+1,Start.y-5*height);
- dc.LineTo(Start.x+Count+1,Start.y);
- //画X轴坐标线;
- int xW=(width/20+0.5);
- for (i=1;i<=20;i++)
- {
- dc.MoveTo(Start.x+i*xW,Start.y-3);
- dc.LineTo(Start.x+i*xW,Start.y+3);
- }
- //画曲线Y,填充区域;
- pen.CreatePen(PS_SOLID,1,RGB(0,255,0));
- pPen=dc.SelectObject(&pen);
- temp.x=Start.x;
- for (i=0;i<=Count;i++)
- {
- temp.y=Start.y-(int)(ArrayData[i+StartPos].y/n+0.5);
- if (Useage)
- temp.y=Start.y-(int)(ArrayData[i+StartPos].yUse/n+0.5);
- dc.MoveTo(temp);
- dc.LineTo(temp.x,Start.y);
- if (ArrayData[i+StartPos].show)
- {
- int n=dc.SetBkMode(TRANSPARENT);
- CFont* pOld=dc.SelectObject(&tFont);
- dc.TextOut(temp.x-4,Start.y+6,ArrayData[i+StartPos].xTime);
- dc.SelectObject(pOld);
- dc.SetBkMode(n);
- }
- temp.x+=1;
- }
- dc.SelectObject(pPen);
- pen.DeleteObject();
- //如果标住了时间,画一条虚竖线;
- pen.CreatePen(PS_DOT,1,RGB(100,100,100));
- pPen=dc.SelectObject(&pen);
- for (i=0;i<=Count;i++)
- {
- if (ArrayData[i+StartPos].show)
- {
-
- dc.MoveTo(Start.x+i,Start.y);
- dc.LineTo(Start.x+i,Start.y-5*height);
- }
- }
- dc.SelectObject(pPen);
- pen.DeleteObject();
- //画曲线X,流入流量,单线;
- temp.y=Start.y-(int)(ArrayData[0+StartPos].x/n+0.5);
- if (Useage)
- temp.y=Start.y-(int)(ArrayData[0+StartPos].xUse/n+0.5);
- temp.x=Start.x;
- pen.CreatePen(PS_SOLID,1,RGB(0,0,255));
- pPen=dc.SelectObject(&pen);
- dc.MoveTo(temp);
- for (i=1;i<=Count;i++)
- {
- temp.y=Start.y-(int)(ArrayData[i+StartPos].x/n+0.5);
- if (Useage)
- temp.y=Start.y-(int)(ArrayData[i+StartPos].xUse/n+0.5);
- temp.x+=1;
- dc.LineTo(temp);
- }
- dc.SelectObject(pPen);
- pen.DeleteObject();
- //画标题;
- dc.TextOut(yEnd.x+ChartSize.cx/4,4,title);
- pen.CreatePen(PS_SOLID,1,RGB(0,255,0));
- pPen=dc.SelectObject(&pen);
- dc.MoveTo(yEnd.x+140,yEnd.y-10);
- dc.LineTo(yEnd.x+160,yEnd.y-10);
- dc.TextOut(yEnd.x+165,yEnd.y-20,yLegend);
- dc.SelectObject(pPen);
- pen.DeleteObject();
- pen.CreatePen(PS_SOLID,1,RGB(0,0,255));
- pPen=dc.SelectObject(&pen);
- dc.MoveTo(yEnd.x+230,yEnd.y-10);
- dc.LineTo(yEnd.x+250,yEnd.y-10);
- dc.TextOut(yEnd.x+255,yEnd.y-20,xLegend);
- dc.SelectObject(pPen);
- pen.DeleteObject();
- CPoint Message;
- Message.x=ChartSize.cx;
- Message.y=0;
- dc.Rectangle(Message.x,Message.y,Message.x+140,Message.y+150);
- dc.TextOut(Message.x+30,Message.y+4,"信息显示区");
- str.Format("%d",ArrayData[Count+StartPos].x);
- str="当前X: "+str;
- dc.TextOut(Message.x+8,Message.y+30,str);
- str.Format("%d",ArrayData[Count+StartPos].y);
- str="当前Y: "+str;
- dc.TextOut(Message.x+8,Message.y+46,str);
- str.Format("%d",x_Max);
- str="最大X: "+str;
- dc.TextOut(Message.x+8,Message.y+62,str);
- str.Format("%d",y_Max);
- str="最大Y: "+str;
- dc.TextOut(Message.x+8,Message.y+78,str);
- str.Format("%d",xAverage);
- str="平均X: "+str;
- dc.TextOut(Message.x+8,Message.y+94,str);
- str.Format("%d",yAverage);
- str="平均Y: "+str;
- dc.TextOut(Message.x+8,Message.y+110,str);
- // TODO: Add your message handler code here
-
- // Do not call CStatic::OnPaint() for painting messages
- }
- void CLineChart::SetCross(bool tf)
- {
- Cross=tf;
- }
- unsigned long CLineChart::GetXAverage()
- {
- return xAverage;
- }
- unsigned long CLineChart::GetYAverage()
- {
- return yAverage;
- }
- CString CLineChart::GetXMax()
- {
- CString str;
- str.Format("%d",x_Max);
- return str;
- }
- CString CLineChart::GetYMax()
- {
- CString str;
- str.Format("%d",y_Max);
- return str;
- }
- CString CLineChart::GetXMin()
- {
- CString str;
- str.Format("%d",x_Min);
- return str;
- }
- CString CLineChart::GetYMin()
- {
- CString str;
- str.Format("%d",y_Min);
- return str;
- }
- void CLineChart::OnMouseMove(UINT nFlags, CPoint point)
- {
- if ((Cross)&&(point.x<ChartSize.cx))
- {
- CClientDC dc(this);
- dc.SetROP2(R2_NOT);
- dc.MoveTo(0,oldY);
- dc.LineTo(ChartSize.cx,oldY);
- dc.MoveTo(oldX,0);
- dc.LineTo(oldX,ChartSize.cy);
- dc.MoveTo(0,point.y);
- dc.LineTo(ChartSize.cx,point.y);
- dc.MoveTo(point.x,0);
- dc.LineTo(point.x,ChartSize.cy);
- if ((point.x>=60)&&(point.x<=60+Count))
- {
- CString str;
- str.Format("%d",ArrayData[point.x-60+StartPos].x);
- if (Useage)
- str.Format("%d",ArrayData[point.x-60+StartPos].xUse);
- str="当前X: "+str;
- dc.TextOut(ChartSize.cx+8,30,str);
- str.Format("%d",ArrayData[point.x-60+StartPos].y);
- if (Useage)
- str.Format("%d",ArrayData[point.x-60+StartPos].yUse);
- str="当前Y: "+str;
- dc.TextOut(ChartSize.cx+8,46,str);
- }
- oldX=point.x;
- oldY=point.y;
- }
- CStatic::OnMouseMove(nFlags, point);
- }
- void CLineChart::ToLeft()
- {
- int n=(ArrayData.GetSize()-1)-(Count+1);
- //数组中实际元素的个数减去可显示的元素个数;
- if (n==0)
- return;
- //相等,不移位;
- else
- {
- if (StartPos<n)
- StartPos+=1;
- //显示起始位置小于n,起始位置增1;
- }
- this->Invalidate();
- }
- void CLineChart::ToRight()
- {
- if (StartPos>0)
- StartPos=StartPos-1;
- this->Invalidate();
- }
- void CLineChart::SetUse(bool tf)
- {
- Useage=tf;
- if (Useage)
- {
- Temp_yMax=yMax;
- yMax=100;
- }
- else
- yMax=Temp_yMax;
- this->Invalidate();
- }