有个画扇形的API,但是现在先不解释,因为不懂画饼图的原理,你也不懂怎么用。接下来就一步步带大家去计算饼图的扇形两点坐标。
直接看下图,文字解释总是太抽象。
![](https://img-blog.csdn.net/20170620203555817?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMTgyOTc2NzU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
接下来就是用Pie这个函数来画出扇形了。
其原型如下:
BOOL Pie(
LPCRECT lpRect,
POINT ptStart,
POINT ptEnd
);
lpRect: 这个就是上图中的外接矩形
ptStart: 扇形的起点
ptEnd: 扇形的终点
这里的起点终点指的是,从圆心引出的直线,相交于圆的两点,一般假设角度大的为终点。
还有一个比较重要的问题,那就是坐标原点的设置,要知道在MFC中,坐标原点是左上角开始(0,0)处,如果我们接着用这个坐标原点的话,会导致坐标的计算很复杂。所以要用SetViewportOrgEx函数设置坐标的原点。设置后,其增长方式仍然没变,往右是x增大的方向,往下是y增大的方向,相反即为负。
核心代码如下:
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
CBrush brush(RGB(255, 255, 255));
dc.FillRect(&rect, &brush);
SetViewportOrgEx(dc, m_COpt.x, m_COpt.y, NULL);
CRect pieRect(-m_Radius, -m_Radius, m_Radius, m_Radius);
dc.Ellipse(&pieRect);
POINT pt_start;
POINT pt_end;
double R = m_Radius;
const double PI = 3.1415926;
double sum = 0;
for (int i = 0; i < m_itemNums; i++)
sum += m_percentage[i];
if (sum == 1)
{
int angle = m_percentage[0] * 360;
POINT pt_s_e;
pt_start = { (int)R,0 };
pt_s_e = pt_start;
pt_end = { int(R*cos(angle * PI / 180)),int(-R*sin(angle * PI / 180)) };
dc.SelectObject(CreateSolidBrush(m_color[0]));
dc.Pie(&pieRect, pt_start, pt_end);
for (int i = 1; i < m_itemNums; i++)
{
pt_start = pt_end;
angle += m_percentage[i] * 360;
pt_end = { int(R*cos(angle * PI / 180)),int(-R*sin(angle * PI / 180)) };
dc.SelectObject(CreateSolidBrush(m_color[i]));
if(i == m_itemNums - 1)
dc.Pie(&pieRect, pt_start, pt_s_e);
else
dc.Pie(&pieRect, pt_start, pt_end);
}
CRect expRect;
int l = 0, t = 0;
for (int i = 0; i < m_itemNums; i++)
{
l = m_Radius + 50;
t = -2*m_Radius + m_expH*i;
expRect = {l,t + 10,l + m_expW,t + m_expH };
dc.SelectObject(CreateSolidBrush(m_color[i]));
dc.Rectangle(&expRect);
dc.TextOut(l + m_expW + 10, t + m_expH / 3, m_itemName[i]);
}
CString s;
int strLen = m_itemName[0].GetLength();
for (int i = 0; i < m_itemNums; i++)
{
l = -2*m_Radius - strLen*10;
t = -2 * m_Radius + m_expH*i;
s.Format(TEXT("%s -- %0.2f%s"), m_itemName[i],m_percentage[i] * 100,TEXT("%"));
dc.TextOut(l, t + m_expH / 3, s);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
我把画饼图的方法,封装成一个通用的类,以添加item的方式,添加扇形。
使用示例如下:
PieChart piechart
piechart.SetCoordinateOrigin({ 300,200 })
piechart.SetRadius(100)
piechart.SetExplainRect(50,30)
piechart.AddItem("苹果", RGB(255, 0, 0), 0.4)
piechart.AddItem("雪梨", RGB(0, 255, 0), 0.1)
piechart.AddItem("香蕉", RGB(0, 0, 255), 0.2)
piechart.AddItem("木瓜", RGB(0, 255, 255), 0.3)
piechart.DoModal()
结果如图:
![](https://img-blog.csdn.net/20170620204722328?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcXFfMTgyOTc2NzU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
饼图类下载(github下载)
饼图类下载(这是CSDN下载,需要1积分)
注:因为我是在VS2015编译的,只能保证向下兼容到2013,其它版本可能有不确定错误。或者直接把有用代码复制粘贴,这样就能保证能兼容所有VS,VC就需要改动多一点才能正常运行。