MFC如何画饼图详解

有个画扇形的API,但是现在先不解释,因为不懂画饼图的原理,你也不懂怎么用。接下来就一步步带大家去计算饼图的扇形两点坐标。

直接看下图,文字解释总是太抽象。 

接下来就是用Pie这个函数来画出扇形了。 
其原型如下:

BOOL Pie( 
   LPCRECT lpRect,
   POINT ptStart,
   POINT ptEnd  
);
 
 
  • 1
  • 2
  • 3
  • 4
  • 5

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];
    //验证占比加起来等不等于1
    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();
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

结果如图: 

饼图类下载(github下载) 

饼图类下载(这是CSDN下载,需要1积分) 

注:因为我是在VS2015编译的,只能保证向下兼容到2013,其它版本可能有不确定错误。或者直接把有用代码复制粘贴,这样就能保证能兼容所有VS,VC就需要改动多一点才能正常运行。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值