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

📄 绘制饼状图3view.cpp

📁 使用VC++来显示复杂的3D饼图,一般应用数据库及数据统计领域.
💻 CPP
字号:
// 绘制饼状图3View.cpp : implementation of the CMy3View class
//

#include "stdafx.h"
#include "绘制饼状图3.h"

#include "绘制饼状图3Doc.h"
#include "绘制饼状图3View.h"

#include <cmath> //包含数学函数sin,cos等

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMy3View

IMPLEMENT_DYNCREATE(CMy3View, CView)

BEGIN_MESSAGE_MAP(CMy3View, CView)
	//{{AFX_MSG_MAP(CMy3View)
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMy3View construction/destruction

CMy3View::CMy3View()
{

	//用户在这里设置饼图的位置、大小、厚度和颜色数组等
	m_x=150;
	m_y=150;
	m_w=260;
	m_h=160;
	m_B=25;
	Serialize_piearray();
	
	pMemDC=new CDC;
	pBitmap=new CBitmap;
	//color definitions  20种颜色
	dwoncolor[0]=RGB(235,0,0);//红色
	dwoncolor[1]=RGB(0,235,0) ;//绿色
	dwoncolor[2]=RGB(0,0,225);//蓝色
	dwoncolor[3]=RGB(235,235,0);//黄色
	dwoncolor[4]=RGB(235,153,51); //橙色
	dwoncolor[5]=RGB(235,51,153) ; //粉红色
	dwoncolor[6]=RGB(153,0,204);//紫色
	dwoncolor[7]=RGB(0,225,225);//蓝绿色, 青色
	dwoncolor[8]=RGB(189,167,225);//淡紫色的
	dwoncolor[9]=RGB(235,216,177);//桃色
	dwoncolor[10]=RGB(142,235,235);//天蓝色
	dwoncolor[11]=RGB(0,182,0);//丛林绿色
	dwoncolor[12]=RGB(180,50,0);//褐色的, 棕色的
	dwoncolor[13]=RGB(0,192,192);//青绿色
	dwoncolor[14]=RGB(0,0,192);//宝蓝色
	dwoncolor[15]=RGB(192,192,192);//灰色
	dwoncolor[16]=RGB(128,128,128);// 暗灰色
	dwoncolor[17]=RGB(255,198,107);//棕褐色的, 茶色
	dwoncolor[18]=RGB(0,0,128);//暗蓝色
	dwoncolor[19]=RGB(128,0,0);//栗色
	/************************************/	
	upcolor[0]=RGB(255,0,0);
	upcolor[1]=RGB(0,255,0) ;
	upcolor[2]=RGB(0,0,255);
	upcolor[3]=RGB(255,255,0);
	upcolor[4]=RGB(255,153,51); //橙色
	upcolor[5]=RGB(255,51,153) ; //粉红色
	upcolor[6]=RGB(153,0,244);//紫色
	upcolor[7]=RGB(0,255,255);//蓝绿色, 青色
	upcolor[8]=RGB(199,177,255);//淡紫色的
	upcolor[9]=RGB(255,226,177);//桃色
	upcolor[10]=RGB(142,255,255);//天蓝色
	upcolor[11]=RGB(0,192,0);//丛林绿色
	upcolor[12]=RGB(200,50,0);//褐色的, 棕色的
	upcolor[13]=RGB(0,192,192);//青绿色
	upcolor[14]=RGB(0,0,192);//宝蓝色
	upcolor[15]=RGB(192,192,192);//灰色
	upcolor[16]=RGB(128,128,128);// 暗灰色
	upcolor[17]=RGB(255,198,107);//棕褐色的, 茶色
	upcolor[18]=RGB(0,0,128);//暗蓝色
	upcolor[19]=RGB(128,0,0);//栗色






}

CMy3View::~CMy3View()
{
}

BOOL CMy3View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMy3View drawing

void CMy3View::OnDraw(CDC* pDC)
{
	CMy3Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);


	if(m_B>=30)
		m_B=28;//太厚会有bug
	CBitmap* pOldBitmap=pMemDC->SelectObject(pBitmap);
	CBrush myBrush(RGB(255,255,255));
	pMemDC->FillRect(CRect(-1,-1,m_nMaxX,m_nMaxY),&myBrush);//画之前先擦除.
	pMemDC->SetTextColor(RGB(0,0,0));
	double pi =3.141592; //
	int zdX=m_x+m_w/2;//中点坐标,x半轴长度
	int zdY=m_y+m_h/2;//中点y坐标,y半轴长度
	int x1=m_x+m_w;//起点x,用来动态保存扇形的起点
	int y1=m_y+m_h/2;//起点y,
	int lastx1=m_x+m_w/2;//上一起点x
	int lasty1=m_y+m_h/2;//上一起点y
	lastx1=zdX;
	lasty1=zdY+m_B;
	int jd=0;//用来读取扇形各部分的值
	CPen * poldpen;//用来保存系统笔
	CPoint pt[4];//用来填补的多边形数组
	
	//画分割扇形,先画下面的
	int num=m_piearray.GetSize();
	for(int i=0;i<num;i++)
	{
		jd+=m_piearray[i];
		int p=i%20; //20,颜色数
		CBrush brush(dwoncolor[p]);
		pMemDC->SelectObject(&brush); 
		int x=m_w/2*cos(jd*pi/180);
		int y=m_h/2*sin(jd*pi/180);
		CPen pen;
		pen.CreatePen(PS_SOLID,0,dwoncolor[p]);
		poldpen=pMemDC->SelectObject(&pen);
		Pie( pMemDC->m_hDC,m_x,m_y+m_B,m_x+m_w,m_y+m_h+m_B,x1,y1+m_B,zdX+x,zdY-y+m_B);
		if(i>0)
		{
			//使用上一个扇形的画刷和笔
			CBrush lastbrush(dwoncolor[p-1]);
			pMemDC->SelectObject(&lastbrush);
			CPen spen;
			spen.CreatePen(PS_SOLID,0,dwoncolor[p-1]);
			CPen* pold=pMemDC->SelectObject(&spen);
			pt[0].x=x1-1;//为了使边能对齐,-1修正
			pt[0].y=y1+m_B;
			pt[1].x=x1-1;//为了使边能对齐,-1修正
			pt[1].y=y1;
			pt[3].x=lastx1;
			pt[3].y=lasty1;
			pt[2].x=lastx1;
			pt[2].y=lasty1-m_B;
			pMemDC->Polygon(pt,4);//修补上一次的终点边
			pMemDC->SelectObject(pold);
		}
		CBrush dqbrush(dwoncolor[p]);
		pMemDC->SelectObject(&dqbrush);
		CPen dqpen;
		dqpen.CreatePen(PS_SOLID,0,dwoncolor[p]);
		CPen* pold=pMemDC->SelectObject(&dqpen);
		pt[0].x=x1-1;//为了使边能对齐,-1修正
		pt[0].y=y1+m_B;
		pt[1].x=zdX+x;
		pt[1].y=zdY-y+m_B;
		pt[3].x=x1-1;//为了使边能对齐,-1修正
		pt[3].y=y1;
		pt[2].x=zdX+x;
		pt[2].y=zdY-y;
		pMemDC->Polygon(pt,4);//修补起点边
		//把终点传给起点,作为下一个的起点
		x1=zdX+x;
		y1=zdY-y;
	}
    //再画上边的分割扇形
	jd=0;
	
	for(i=0;i<num;i++)
	{
		jd+=m_piearray[i];
		int p=i%20;
		CBrush brush(upcolor[p]);
		pMemDC->SelectObject(&brush); 
		int x=m_w/2*cos(jd*pi/180);
		int y=m_h/2*sin(jd*pi/180);
		CPen pen;
		pen.CreatePen(PS_SOLID,0,upcolor[p]);
		poldpen=pMemDC->SelectObject(&pen);
		Pie( pMemDC->m_hDC,m_x,m_y,m_x+m_w,m_y+m_h,x1,y1,zdX+x,zdY-y);
		
		//绘制指示线和数字
		int half=m_piearray[i]/2;
		int sx=zdX+m_w/1.3*cos((jd-half)*pi/180);
		int sy=zdY-m_h/1.3*sin((jd-half)*pi/180);
		int ox=zdX+m_w/4*cos((jd-half)*pi/180);
		int oy=zdY-m_h/4*sin((jd-half)*pi/180);
		CPen spen;
		spen.CreatePen(PS_SOLID,1,RGB(0,0,0));
		CPen* plp=pMemDC->SelectObject(&spen);
		pMemDC->MoveTo(sx,sy);
		pMemDC->LineTo(ox,oy);
		pMemDC->SelectObject(plp);
		CString text;
		double baifenbi=m_piearray[i]/360.0*100.0;
		text.Format("%5.2f",baifenbi);
		pMemDC->TextOut(sx,sy,text+"%");
		
		//把终点传给起点,作为下一个的起点
		x1=zdX+x;
		y1=zdY-y;
	}
	
	//修饰一下饼的左边沿:
	
	CPen bkpen;
	bkpen.CreatePen(PS_SOLID,1,RGB(128,128,128));
	pMemDC->SelectObject(&bkpen);
	pMemDC->MoveTo(m_x,m_y+m_h/2);
	pMemDC->LineTo(m_x,m_y+m_h/2+m_B);
    ///////////////*/
	
	//绘制图例标签:
	int size=m_item.GetSize();
	for(i=0;i<size;i++)
	{
		pMemDC->TextOut(550,100+20*i,m_item[i]);
		CRect rect(620,100+20*i,650,118+20*i);
		pMemDC->Rectangle(&rect);
		CRect frect(621,101+20*i,649,117+20*i);
		CBrush bqbrush(upcolor[i]);
		pMemDC->FillRect(&frect,&bqbrush);
	}
	
	//因为使用了两组颜色,已经可以看到立体效果了,所以不需要再画边线了
    //pDC->MoveTo(m_x,m_y+m_h/2);
	//pMemDC->ArcTo(m_x,m_y,m_x+m_w,m_y+m_h,m_x,m_y+m_h/2,m_x+m_w,m_y+m_h/2);
	
	
	pMemDC->SelectObject(poldpen);//恢复系统笔
	pDC->BitBlt(0,0,m_nMaxX,m_nMaxY,pMemDC,0,0,SRCCOPY);
	pMemDC->SelectObject(pOldBitmap);
	ReleaseDC(pMemDC);
}

/////////////////////////////////////////////////////////////////////////////
// CMy3View printing

BOOL CMy3View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CMy3View::OnBeginPrinting(CDC* /*pMemDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CMy3View::OnEndPrinting(CDC* /*pMemDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CMy3View diagnostics

#ifdef _DEBUG
void CMy3View::AssertValid() const
{
	CView::AssertValid();
}

void CMy3View::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CMy3Doc* CMy3View::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy3Doc)));
	return (CMy3Doc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMy3View message handlers

void CMy3View::Serialize_piearray()
{

	//用户在这里初始化数据
	
	m_piearray.Add(160);
	m_piearray.Add(60);
	m_piearray.Add(40);
	m_piearray.Add(120);
	m_piearray.Add(60);
	m_piearray.Add(40);
	m_piearray.Add(80);

	//转换成角度,用户只需直接输入数值就好了
	ReformatPieary();

	m_item.Add("厦新电子");
	m_item.Add("星马汽车");
	m_item.Add("龙头股份");
	m_item.Add("丰乐种业");
	m_item.Add("氯碱化工");



	
}

int CMy3View::ReformatPieary()//转换成角度
{
	int num=m_piearray.GetSize();
	double totail=0.00;
	for(int i=0;i<num;i++)
	{

		totail+=m_piearray[i];
	}
	for(i=0;i<num;i++)
	{
		m_piearray[i]=m_piearray[i]/totail*360;
	}
	return 0;


}

int CMy3View::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	

	pMemDC=new CDC;
pBitmap=new CBitmap;
//得到屏幕大小:
m_nMaxX=GetSystemMetrics(SM_CXSCREEN);
m_nMaxY=GetSystemMetrics(SM_CYSCREEN);
CDC* pDC=GetDC();//获得显示DC的指针
pMemDC->CreateCompatibleDC(pDC);//创建显示DC的兼容内存DC
//创建与显示DC的位图兼容的位图,位图和屏幕一样大:
pBitmap->CreateCompatibleBitmap(pDC,m_nMaxX,m_nMaxY);

//将兼容位图选进内存DC,pOldBirmap用来保存内存DC中的原位图:
CBitmap* pOldBitmap=pMemDC->SelectObject(pBitmap);
//创建一个白色画刷:
CBrush brush;
brush.CreateStockObject(WHITE_BRUSH);
//将内存DC得位图整个填上白色:
CRect rect(-1,-1,m_nMaxX,m_nMaxY);
pMemDC->FillRect(rect,&brush);
pMemDC->SelectObject(pOldBitmap);
ReleaseDC(pDC);
	return 0;
}

⌨️ 快捷键说明

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