📄 绘制饼状图3view.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 + -