📄 linechart.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 + -