⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linechart.cpp

📁 非常好的测量网络流量及MIB浏览器编译-过!
💻 CPP
字号:
// 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();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -